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