xref: /netbsd-src/external/bsd/elftosb/dist/common/OptionDictionary.cpp (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
1*993229b6Sjkunz /*
2*993229b6Sjkunz  * File:	OptionDictionary.h
3*993229b6Sjkunz  *
4*993229b6Sjkunz  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5*993229b6Sjkunz  * See included license file for license details.
6*993229b6Sjkunz  */
7*993229b6Sjkunz 
8*993229b6Sjkunz #include "OptionDictionary.h"
9*993229b6Sjkunz 
10*993229b6Sjkunz using namespace elftosb;
11*993229b6Sjkunz 
12*993229b6Sjkunz //! Deletes all of the option values that have been assigned locally.
13*993229b6Sjkunz //!
~OptionDictionary()14*993229b6Sjkunz OptionDictionary::~OptionDictionary()
15*993229b6Sjkunz {
16*993229b6Sjkunz 	option_map_t::iterator it = m_options.begin();
17*993229b6Sjkunz 	for (; it != m_options.end(); ++it)
18*993229b6Sjkunz 	{
19*993229b6Sjkunz 		if (it->second.m_value)
20*993229b6Sjkunz 		{
21*993229b6Sjkunz 			delete it->second.m_value;
22*993229b6Sjkunz 		}
23*993229b6Sjkunz 	}
24*993229b6Sjkunz }
25*993229b6Sjkunz 
26*993229b6Sjkunz //! If a parent context has been set and the option does not exist in
27*993229b6Sjkunz //! this instance, then the parent is asked if it contains the option.
28*993229b6Sjkunz //!
29*993229b6Sjkunz //! \param name The name of the option to query.
30*993229b6Sjkunz //! \retval true The option is present in this instance or one of the parent.
31*993229b6Sjkunz //! \retval false No option with that name is in the dictionary, or any parent
hasOption(const std::string & name) const32*993229b6Sjkunz bool OptionDictionary::hasOption(const std::string & name) const
33*993229b6Sjkunz {
34*993229b6Sjkunz 	bool hasIt = (m_options.find(name) != m_options.end());
35*993229b6Sjkunz 	if (!hasIt && m_parent)
36*993229b6Sjkunz 	{
37*993229b6Sjkunz 		return m_parent->hasOption(name);
38*993229b6Sjkunz 	}
39*993229b6Sjkunz 	return hasIt;
40*993229b6Sjkunz }
41*993229b6Sjkunz 
42*993229b6Sjkunz //! If this object does not contain an option with the name of \a name,
43*993229b6Sjkunz //! then the parent is asked for the value (if a parent has been set).
44*993229b6Sjkunz //!
45*993229b6Sjkunz //! \param name The name of the option.
46*993229b6Sjkunz //! \return The value for the option named \a name.
47*993229b6Sjkunz //! \retval NULL No option is in the table with that name. An option may also
48*993229b6Sjkunz //!		explicitly be set to a NULL value. The only way to tell the difference
49*993229b6Sjkunz //!		is to use the hasOption() method.
getOption(const std::string & name) const50*993229b6Sjkunz const Value * OptionDictionary::getOption(const std::string & name) const
51*993229b6Sjkunz {
52*993229b6Sjkunz 	option_map_t::const_iterator it = m_options.find(name);
53*993229b6Sjkunz 	if (it == m_options.end())
54*993229b6Sjkunz 	{
55*993229b6Sjkunz 		if (m_parent)
56*993229b6Sjkunz 		{
57*993229b6Sjkunz 			return m_parent->getOption(name);
58*993229b6Sjkunz 		}
59*993229b6Sjkunz 		else
60*993229b6Sjkunz 		{
61*993229b6Sjkunz 			return NULL;
62*993229b6Sjkunz 		}
63*993229b6Sjkunz 	}
64*993229b6Sjkunz 
65*993229b6Sjkunz 	return it->second.m_value;
66*993229b6Sjkunz }
67*993229b6Sjkunz 
68*993229b6Sjkunz //! If the option was not already present in the table, it is added.
69*993229b6Sjkunz //! Otherwise the old value is replaced. The option is always set locally;
70*993229b6Sjkunz //! parent objects are never modified.
71*993229b6Sjkunz //!
72*993229b6Sjkunz //! If the option has been locked with a call to lockOption() before trying
73*993229b6Sjkunz //! to set its value, the setOption() is effectively ignored. To tell if
74*993229b6Sjkunz //! an option is locked, use the isOptionLocked() method.
75*993229b6Sjkunz //!
76*993229b6Sjkunz //! \warning If the option already had a value, that previous value is deleted.
77*993229b6Sjkunz //!		This means that it cannot currently be in use by another piece of code.
78*993229b6Sjkunz //!		See the note in getOption().
79*993229b6Sjkunz //!
80*993229b6Sjkunz //! \param name The option's name.
81*993229b6Sjkunz //! \param value New value for the option.
setOption(const std::string & name,Value * value)82*993229b6Sjkunz void OptionDictionary::setOption(const std::string & name, Value * value)
83*993229b6Sjkunz {
84*993229b6Sjkunz 	option_map_t::iterator it = m_options.find(name);
85*993229b6Sjkunz 	OptionValue newValue;
86*993229b6Sjkunz 
87*993229b6Sjkunz 	// delete the option value instance before replacing it
88*993229b6Sjkunz 	if (it != m_options.end())
89*993229b6Sjkunz 	{
90*993229b6Sjkunz 		// Cannot modify value if locked.
91*993229b6Sjkunz 		if (it->second.m_isLocked)
92*993229b6Sjkunz 		{
93*993229b6Sjkunz 			return;
94*993229b6Sjkunz 		}
95*993229b6Sjkunz 
96*993229b6Sjkunz 		if (it->second.m_value)
97*993229b6Sjkunz 		{
98*993229b6Sjkunz 			delete it->second.m_value;
99*993229b6Sjkunz 		}
100*993229b6Sjkunz 
101*993229b6Sjkunz 		// save previous locked value
102*993229b6Sjkunz 		newValue.m_isLocked = it->second.m_isLocked;
103*993229b6Sjkunz 	}
104*993229b6Sjkunz 
105*993229b6Sjkunz 	// set new option value
106*993229b6Sjkunz 	newValue.m_value = value;
107*993229b6Sjkunz 	m_options[name] = newValue;
108*993229b6Sjkunz }
109*993229b6Sjkunz 
110*993229b6Sjkunz //! \param name The name of the option to remove.
111*993229b6Sjkunz //!
deleteOption(const std::string & name)112*993229b6Sjkunz void OptionDictionary::deleteOption(const std::string & name)
113*993229b6Sjkunz {
114*993229b6Sjkunz 	if (m_options.find(name) != m_options.end())
115*993229b6Sjkunz 	{
116*993229b6Sjkunz 		if (m_options[name].m_value)
117*993229b6Sjkunz 		{
118*993229b6Sjkunz 			delete m_options[name].m_value;
119*993229b6Sjkunz 		}
120*993229b6Sjkunz 		m_options.erase(name);
121*993229b6Sjkunz 	}
122*993229b6Sjkunz }
123*993229b6Sjkunz 
124*993229b6Sjkunz //! \param name Name of the option to query.
125*993229b6Sjkunz //!
126*993229b6Sjkunz //! \return True if the option is locked, false if unlocked or not present.
127*993229b6Sjkunz //!
isOptionLocked(const std::string & name) const128*993229b6Sjkunz bool OptionDictionary::isOptionLocked(const std::string & name) const
129*993229b6Sjkunz {
130*993229b6Sjkunz 	option_map_t::const_iterator it = m_options.find(name);
131*993229b6Sjkunz 	if (it != m_options.end())
132*993229b6Sjkunz 	{
133*993229b6Sjkunz 		return it->second.m_isLocked;
134*993229b6Sjkunz 	}
135*993229b6Sjkunz 
136*993229b6Sjkunz 	return false;
137*993229b6Sjkunz }
138*993229b6Sjkunz 
139*993229b6Sjkunz //! \param name Name of the option to lock.
140*993229b6Sjkunz //!
lockOption(const std::string & name)141*993229b6Sjkunz void OptionDictionary::lockOption(const std::string & name)
142*993229b6Sjkunz {
143*993229b6Sjkunz 	if (!hasOption(name))
144*993229b6Sjkunz 	{
145*993229b6Sjkunz 		m_options[name].m_value = 0;
146*993229b6Sjkunz 	}
147*993229b6Sjkunz 
148*993229b6Sjkunz 	m_options[name].m_isLocked = true;
149*993229b6Sjkunz }
150*993229b6Sjkunz 
151*993229b6Sjkunz //! \param name Name of the option to unlock.
152*993229b6Sjkunz //!
unlockOption(const std::string & name)153*993229b6Sjkunz void OptionDictionary::unlockOption(const std::string & name)
154*993229b6Sjkunz {
155*993229b6Sjkunz 	if (!hasOption(name))
156*993229b6Sjkunz 	{
157*993229b6Sjkunz 		m_options[name].m_value = 0;
158*993229b6Sjkunz 	}
159*993229b6Sjkunz 
160*993229b6Sjkunz 	m_options[name].m_isLocked = false;
161*993229b6Sjkunz }
162*993229b6Sjkunz 
163*993229b6Sjkunz 
164*993229b6Sjkunz //! Simply calls getOption().
165*993229b6Sjkunz //!
operator [](const std::string & name) const166*993229b6Sjkunz const Value * OptionDictionary::operator [] (const std::string & name) const
167*993229b6Sjkunz {
168*993229b6Sjkunz 	return getOption(name);
169*993229b6Sjkunz }
170*993229b6Sjkunz 
171