1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
3 #include "base/dictionary.hpp"
4 #include "base/objectlock.hpp"
5 #include "base/debug.hpp"
6 #include "base/primitivetype.hpp"
7 #include "base/configwriter.hpp"
10 using namespace icinga;
12 template class std::map<String, Value>;
14 REGISTER_PRIMITIVE_TYPE(Dictionary, Object, Dictionary::GetPrototype());
16 Dictionary::Dictionary(const DictionaryData& other)
18 for (const auto& kv : other)
22 Dictionary::Dictionary(DictionaryData&& other)
24 for (auto& kv : other)
25 m_Data.insert(std::move(kv));
28 Dictionary::Dictionary(std::initializer_list<Dictionary::Pair> init)
33 * Retrieves a value from a dictionary.
35 * @param key The key whose value should be retrieved.
36 * @returns The value of an empty value if the key was not found.
38 Value Dictionary::Get(const String& key) const
40 ObjectLock olock(this);
42 auto it = m_Data.find(key);
44 if (it == m_Data.end())
51 * Retrieves a value from a dictionary.
53 * @param key The key whose value should be retrieved.
54 * @param result The value of the dictionary item (only set when the key exists)
55 * @returns true if the key exists, false otherwise.
57 bool Dictionary::Get(const String& key, Value *result) const
59 ObjectLock olock(this);
61 auto it = m_Data.find(key);
63 if (it == m_Data.end())
71 * Sets a value in the dictionary.
74 * @param value The value.
75 * @param overrideFrozen Whether to allow modifying frozen dictionaries.
77 void Dictionary::Set(const String& key, Value value, bool overrideFrozen)
79 ObjectLock olock(this);
81 if (m_Frozen && !overrideFrozen)
82 BOOST_THROW_EXCEPTION(std::invalid_argument("Value in dictionary must not be modified."));
84 m_Data[key] = std::move(value);
88 * Returns the number of elements in the dictionary.
90 * @returns Number of elements.
92 size_t Dictionary::GetLength() const
94 ObjectLock olock(this);
100 * Checks whether the dictionary contains the specified key.
102 * @param key The key.
103 * @returns true if the dictionary contains the key, false otherwise.
105 bool Dictionary::Contains(const String& key) const
107 ObjectLock olock(this);
109 return (m_Data.find(key) != m_Data.end());
113 * Returns an iterator to the beginning of the dictionary.
115 * Note: Caller must hold the object lock while using the iterator.
117 * @returns An iterator.
119 Dictionary::Iterator Dictionary::Begin()
123 return m_Data.begin();
127 * Returns an iterator to the end of the dictionary.
129 * Note: Caller must hold the object lock while using the iterator.
131 * @returns An iterator.
133 Dictionary::Iterator Dictionary::End()
141 * Removes the item specified by the iterator from the dictionary.
143 * @param it The iterator.
144 * @param overrideFrozen Whether to allow modifying frozen dictionaries.
146 void Dictionary::Remove(Dictionary::Iterator it, bool overrideFrozen)
150 if (m_Frozen && !overrideFrozen)
151 BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be modified."));
157 * Removes the specified key from the dictionary.
159 * @param key The key.
160 * @param overrideFrozen Whether to allow modifying frozen dictionaries.
162 void Dictionary::Remove(const String& key, bool overrideFrozen)
164 ObjectLock olock(this);
166 if (m_Frozen && !overrideFrozen)
167 BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be modified."));
169 Dictionary::Iterator it;
170 it = m_Data.find(key);
172 if (it == m_Data.end())
179 * Removes all dictionary items.
181 * @param overrideFrozen Whether to allow modifying frozen dictionaries.
183 void Dictionary::Clear(bool overrideFrozen)
185 ObjectLock olock(this);
187 if (m_Frozen && !overrideFrozen)
188 BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be modified."));
193 void Dictionary::CopyTo(const Dictionary::Ptr& dest) const
195 ObjectLock olock(this);
197 for (const Dictionary::Pair& kv : m_Data) {
198 dest->Set(kv.first, kv.second);
203 * Makes a shallow copy of a dictionary.
205 * @returns a copy of the dictionary.
207 Dictionary::Ptr Dictionary::ShallowClone() const
209 Dictionary::Ptr clone = new Dictionary();
215 * Makes a deep clone of a dictionary
218 * @returns a copy of the dictionary.
220 Object::Ptr Dictionary::Clone() const
225 ObjectLock olock(this);
227 dict.reserve(GetLength());
229 for (const Dictionary::Pair& kv : m_Data) {
230 dict.emplace_back(kv.first, kv.second.Clone());
234 return new Dictionary(std::move(dict));
238 * Returns an array containing all keys
239 * which are currently set in this directory.
241 * @returns an array of key names
243 std::vector<String> Dictionary::GetKeys() const
245 ObjectLock olock(this);
247 std::vector<String> keys;
249 for (const Dictionary::Pair& kv : m_Data) {
250 keys.push_back(kv.first);
256 String Dictionary::ToString() const
258 std::ostringstream msgbuf;
259 ConfigWriter::EmitScope(msgbuf, 1, const_cast<Dictionary *>(this));
263 void Dictionary::Freeze()
265 ObjectLock olock(this);
269 Value Dictionary::GetFieldByName(const String& field, bool, const DebugInfo& debugInfo) const
273 if (Get(field, &value))
276 return GetPrototypeField(const_cast<Dictionary *>(this), field, false, debugInfo);
279 void Dictionary::SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo&)
281 Set(field, value, overrideFrozen);
284 bool Dictionary::HasOwnField(const String& field) const
286 return Contains(field);
289 bool Dictionary::GetOwnField(const String& field, Value *result) const
291 return Get(field, result);
294 Dictionary::Iterator icinga::begin(const Dictionary::Ptr& x)
299 Dictionary::Iterator icinga::end(const Dictionary::Ptr& x)