1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "shill/key_value_store.h"
18 
19 #include <base/stl_util.h>
20 
21 #include "shill/logging.h"
22 
23 using std::map;
24 using std::string;
25 using std::vector;
26 
27 namespace shill {
28 
KeyValueStore()29 KeyValueStore::KeyValueStore() {}
30 
Clear()31 void KeyValueStore::Clear() {
32   properties_.clear();
33 }
34 
IsEmpty()35 bool KeyValueStore::IsEmpty() {
36   return properties_.empty();
37 }
38 
CopyFrom(const KeyValueStore & b)39 void KeyValueStore::CopyFrom(const KeyValueStore& b) {
40   properties_ = b.properties_;
41 }
42 
operator ==(const KeyValueStore & rhs) const43 bool KeyValueStore::operator==(const KeyValueStore& rhs) const {
44   return properties_ == rhs.properties_;
45 }
46 
operator !=(const KeyValueStore & rhs) const47 bool KeyValueStore::operator!=(const KeyValueStore& rhs) const {
48   return properties_ != rhs.properties_;
49 }
50 
ContainsBool(const string & name) const51 bool KeyValueStore::ContainsBool(const string& name) const {
52   return ContainsKey(properties_, name) &&
53       properties_.find(name)->second.IsTypeCompatible<bool>();
54 }
55 
ContainsByteArrays(const string & name) const56 bool KeyValueStore::ContainsByteArrays(const string& name) const {
57   return ContainsKey(properties_, name) &&
58       properties_.find(name)->second
59           .IsTypeCompatible<vector<vector<uint8_t>>>();
60 }
61 
ContainsInt(const string & name) const62 bool KeyValueStore::ContainsInt(const string& name) const {
63   return ContainsKey(properties_, name) &&
64       properties_.find(name)->second.IsTypeCompatible<int32_t>();
65 }
66 
ContainsInt16(const string & name) const67 bool KeyValueStore::ContainsInt16(const string& name) const {
68   return ContainsKey(properties_, name) &&
69       properties_.find(name)->second.IsTypeCompatible<int16_t>();
70 }
71 
ContainsKeyValueStore(const string & name) const72 bool KeyValueStore::ContainsKeyValueStore(const string& name) const {
73   return ContainsKey(properties_, name) &&
74       properties_.find(name)->second.IsTypeCompatible<KeyValueStore>();
75 }
76 
ContainsRpcIdentifier(const string & name) const77 bool KeyValueStore::ContainsRpcIdentifier(const string& name) const {
78   return ContainsKey(properties_, name) &&
79       properties_.find(name)->second.IsTypeCompatible<dbus::ObjectPath>();
80 }
81 
ContainsRpcIdentifiers(const string & name) const82 bool KeyValueStore::ContainsRpcIdentifiers(const string& name) const {
83   return ContainsKey(properties_, name) &&
84       properties_.find(name)->second
85           .IsTypeCompatible<vector<dbus::ObjectPath>>();
86 }
87 
ContainsString(const string & name) const88 bool KeyValueStore::ContainsString(const string& name) const {
89   return ContainsKey(properties_, name) &&
90       properties_.find(name)->second.IsTypeCompatible<string>();
91 }
92 
ContainsStringmap(const std::string & name) const93 bool KeyValueStore::ContainsStringmap(const std::string& name) const {
94   return ContainsKey(properties_, name) &&
95       properties_.find(name)->second.IsTypeCompatible<Stringmap>();
96 }
97 
ContainsStrings(const string & name) const98 bool KeyValueStore::ContainsStrings(const string& name) const {
99   return ContainsKey(properties_, name) &&
100       properties_.find(name)->second.IsTypeCompatible<Strings>();
101 }
102 
ContainsUint(const string & name) const103 bool KeyValueStore::ContainsUint(const string& name) const {
104   return ContainsKey(properties_, name) &&
105       properties_.find(name)->second.IsTypeCompatible<uint32_t>();
106 }
107 
ContainsUint8(const string & name) const108 bool KeyValueStore::ContainsUint8(const string& name) const {
109   return ContainsKey(properties_, name) &&
110       properties_.find(name)->second.IsTypeCompatible<uint8_t>();
111 }
112 
ContainsUint16(const string & name) const113 bool KeyValueStore::ContainsUint16(const string& name) const {
114   return ContainsKey(properties_, name) &&
115       properties_.find(name)->second.IsTypeCompatible<uint16_t>();
116 }
117 
ContainsUint8s(const string & name) const118 bool KeyValueStore::ContainsUint8s(const string& name) const {
119   return ContainsKey(properties_, name) &&
120       properties_.find(name)->second.IsTypeCompatible<vector<uint8_t>>();
121 }
122 
ContainsUint32s(const string & name) const123 bool KeyValueStore::ContainsUint32s(const string& name) const {
124   return ContainsKey(properties_, name) &&
125       properties_.find(name)->second.IsTypeCompatible<vector<uint32_t>>();
126 }
127 
Contains(const string & name) const128 bool KeyValueStore::Contains(const string& name) const {
129   return ContainsKey(properties_, name);
130 }
131 
GetBool(const string & name) const132 bool KeyValueStore::GetBool(const string& name) const {
133   const auto it(properties_.find(name));
134   CHECK(it != properties_.end() && it->second.IsTypeCompatible<bool>())
135       << "for bool property " << name;
136   return it->second.Get<bool>();
137 }
138 
GetByteArrays(const string & name) const139 const vector<vector<uint8_t>>& KeyValueStore::GetByteArrays(
140     const string& name) const {
141   const auto it(properties_.find(name));
142   CHECK(it != properties_.end() &&
143         it->second.IsTypeCompatible<vector<vector<uint8_t>>>())
144       << "for byte arrays property " << name;
145   return it->second.Get<vector<vector<uint8_t>>>();
146 }
147 
GetInt(const string & name) const148 int32_t KeyValueStore::GetInt(const string& name) const {
149   const auto it(properties_.find(name));
150   CHECK(it != properties_.end() && it->second.IsTypeCompatible<int32_t>())
151       << "for int property " << name;
152   return it->second.Get<int32_t>();
153 }
154 
GetInt16(const string & name) const155 int16_t KeyValueStore::GetInt16(const string& name) const {
156   const auto it(properties_.find(name));
157   CHECK(it != properties_.end() && it->second.IsTypeCompatible<int16_t>())
158       << "for int16 property " << name;
159   return it->second.Get<int16_t>();
160 }
161 
GetKeyValueStore(const string & name) const162 const KeyValueStore& KeyValueStore::GetKeyValueStore(const string& name) const {
163   const auto it(properties_.find(name));
164   CHECK(it != properties_.end() && it->second.IsTypeCompatible<KeyValueStore>())
165       << "for key value store property " << name;
166   return it->second.Get<KeyValueStore>();
167 }
168 
GetRpcIdentifier(const string & name) const169 const string& KeyValueStore::GetRpcIdentifier(const string& name) const {
170   const auto it(properties_.find(name));
171   CHECK(it != properties_.end() &&
172         it->second.IsTypeCompatible<dbus::ObjectPath>())
173       << "for rpc identifier property " << name;
174   return it->second.Get<dbus::ObjectPath>().value();
175 }
176 
GetRpcIdentifiers(const string & name) const177 vector<string> KeyValueStore::GetRpcIdentifiers(const string& name) const {
178   const auto it(properties_.find(name));
179   CHECK(it != properties_.end() &&
180         it->second.IsTypeCompatible<vector<dbus::ObjectPath>>())
181       << "for rpc identifier property " << name;
182   RpcIdentifiers ids;
183   KeyValueStore::ConvertPathsToRpcIdentifiers(
184       it->second.Get<vector<dbus::ObjectPath>>(), &ids);
185   return ids;
186 }
187 
GetString(const string & name) const188 const string& KeyValueStore::GetString(const string& name) const {
189   const auto it(properties_.find(name));
190   CHECK(it != properties_.end() && it->second.IsTypeCompatible<string>())
191       << "for string property " << name;
192   return it->second.Get<string>();
193 }
194 
GetStringmap(const string & name) const195 const map<string, string>& KeyValueStore::GetStringmap(
196     const string& name) const {
197   const auto it(properties_.find(name));
198   CHECK(it != properties_.end() && it->second.IsTypeCompatible<Stringmap>())
199       << "for stringmap property " << name;
200   return it->second.Get<Stringmap>();
201 }
202 
GetStrings(const string & name) const203 const vector<string>& KeyValueStore::GetStrings(const string& name) const {
204   const auto it(properties_.find(name));
205   CHECK(it != properties_.end() && it->second.IsTypeCompatible<Strings>())
206       << "for strings property " << name;
207   return it->second.Get<Strings>();
208 }
209 
GetUint(const string & name) const210 uint32_t KeyValueStore::GetUint(const string& name) const {
211   const auto it(properties_.find(name));
212   CHECK(it != properties_.end() && it->second.IsTypeCompatible<uint32_t>())
213       << "for uint32 property " << name;
214   return it->second.Get<uint32_t>();
215 }
216 
GetUint16(const string & name) const217 uint16_t KeyValueStore::GetUint16(const string& name) const {
218   const auto it(properties_.find(name));
219   CHECK(it != properties_.end() && it->second.IsTypeCompatible<uint16_t>())
220       << "for uint16 property " << name;
221   return it->second.Get<uint16_t>();
222 }
223 
GetUint8(const string & name) const224 uint8_t KeyValueStore::GetUint8(const string& name) const {
225   const auto it(properties_.find(name));
226   CHECK(it != properties_.end() && it->second.IsTypeCompatible<uint8_t>())
227       << "for uint8 property " << name;
228   return it->second.Get<uint8_t>();
229 }
230 
GetUint8s(const string & name) const231 const vector<uint8_t>& KeyValueStore::GetUint8s(const string& name) const {
232   const auto it(properties_.find(name));
233   CHECK(it != properties_.end() &&
234         it->second.IsTypeCompatible<vector<uint8_t>>())
235       << "for uint8s property " << name;
236   return it->second.Get<vector<uint8_t>>();
237 }
238 
GetUint32s(const string & name) const239 const vector<uint32_t>& KeyValueStore::GetUint32s(const string& name) const {
240   const auto it(properties_.find(name));
241   CHECK(it != properties_.end() &&
242         it->second.IsTypeCompatible<vector<uint32_t>>())
243       << "for uint32s property " << name;
244   return it->second.Get<vector<uint32_t>>();
245 }
246 
Get(const string & name) const247 const brillo::Any& KeyValueStore::Get(const string& name) const {
248   const auto it(properties_.find(name));
249   CHECK(it != properties_.end());
250   return it->second;
251 }
252 
SetBool(const string & name,bool value)253 void KeyValueStore::SetBool(const string& name, bool value) {
254   properties_[name] = brillo::Any(value);
255 }
256 
SetByteArrays(const string & name,const vector<vector<uint8_t>> & value)257 void KeyValueStore::SetByteArrays(const string& name,
258                                   const vector<vector<uint8_t>>& value) {
259   properties_[name] = brillo::Any(value);
260 }
261 
SetInt(const string & name,int32_t value)262 void KeyValueStore::SetInt(const string& name, int32_t value) {
263   properties_[name] = brillo::Any(value);
264 }
265 
SetInt16(const string & name,int16_t value)266 void KeyValueStore::SetInt16(const string& name, int16_t value) {
267   properties_[name] = brillo::Any(value);
268 }
269 
SetKeyValueStore(const string & name,const KeyValueStore & value)270 void KeyValueStore::SetKeyValueStore(const string& name,
271                                      const KeyValueStore& value) {
272   properties_[name] = brillo::Any(value);
273 }
274 
SetRpcIdentifier(const string & name,const string & value)275 void KeyValueStore::SetRpcIdentifier(const string& name, const string& value) {
276   properties_[name] = brillo::Any(dbus::ObjectPath(value));
277 }
278 
SetRpcIdentifiers(const string & name,const vector<string> & value)279 void KeyValueStore::SetRpcIdentifiers(const string& name,
280                                       const vector<string>& value) {
281   vector<dbus::ObjectPath> paths;
282   for (const auto& rpcid : value) {
283     paths.push_back(dbus::ObjectPath(rpcid));
284   }
285   properties_[name] = brillo::Any(paths);
286 }
287 
SetString(const string & name,const string & value)288 void KeyValueStore::SetString(const string& name, const string& value) {
289   properties_[name] = brillo::Any(value);
290 }
291 
SetStringmap(const string & name,const map<string,string> & value)292 void KeyValueStore::SetStringmap(const string& name,
293                                  const map<string, string>& value) {
294   properties_[name] = brillo::Any(value);
295 }
296 
SetStrings(const string & name,const vector<string> & value)297 void KeyValueStore::SetStrings(const string& name,
298                                const vector<string>& value) {
299   properties_[name] = brillo::Any(value);
300 }
301 
SetUint(const string & name,uint32_t value)302 void KeyValueStore::SetUint(const string& name, uint32_t value) {
303   properties_[name] = brillo::Any(value);
304 }
305 
SetUint16(const string & name,uint16_t value)306 void KeyValueStore::SetUint16(const string& name, uint16_t value) {
307   properties_[name] = brillo::Any(value);
308 }
309 
SetUint8(const string & name,uint8_t value)310 void KeyValueStore::SetUint8(const string& name, uint8_t value) {
311   properties_[name] = brillo::Any(value);
312 }
313 
SetUint8s(const string & name,const vector<uint8_t> & value)314 void KeyValueStore::SetUint8s(const string& name,
315                               const vector<uint8_t>& value) {
316   properties_[name] = brillo::Any(value);
317 }
318 
SetUint32s(const string & name,const vector<uint32_t> & value)319 void KeyValueStore::SetUint32s(const string& name,
320                                const vector<uint32_t>& value) {
321   properties_[name] = brillo::Any(value);
322 }
323 
Set(const string & name,const brillo::Any & value)324 void KeyValueStore::Set(const string& name, const brillo::Any& value) {
325   properties_[name] = value;
326 }
327 
RemoveByteArrays(const string & name)328 void KeyValueStore::RemoveByteArrays(const string& name) {
329   properties_.erase(name);
330 }
331 
RemoveInt(const string & name)332 void KeyValueStore::RemoveInt(const string& name) {
333   properties_.erase(name);
334 }
335 
RemoveInt16(const string & name)336 void KeyValueStore::RemoveInt16(const string& name) {
337   properties_.erase(name);
338 }
339 
RemoveKeyValueStore(const string & name)340 void KeyValueStore::RemoveKeyValueStore(const string& name) {
341   properties_.erase(name);
342 }
343 
RemoveRpcIdentifier(const string & name)344 void KeyValueStore::RemoveRpcIdentifier(const string& name) {
345   properties_.erase(name);
346 }
347 
RemoveString(const string & name)348 void KeyValueStore::RemoveString(const string& name) {
349   properties_.erase(name);
350 }
351 
RemoveStringmap(const string & name)352 void KeyValueStore::RemoveStringmap(const string& name) {
353   properties_.erase(name);
354 }
355 
RemoveStrings(const string & name)356 void KeyValueStore::RemoveStrings(const string& name) {
357   properties_.erase(name);
358 }
359 
RemoveUint16(const string & name)360 void KeyValueStore::RemoveUint16(const string& name) {
361   properties_.erase(name);
362 }
363 
RemoveUint8(const string & name)364 void KeyValueStore::RemoveUint8(const string& name) {
365   properties_.erase(name);
366 }
367 
RemoveUint8s(const string & name)368 void KeyValueStore::RemoveUint8s(const string& name) {
369   properties_.erase(name);
370 }
371 
RemoveUint32s(const string & name)372 void KeyValueStore::RemoveUint32s(const string& name) {
373   properties_.erase(name);
374 }
375 
Remove(const string & name)376 void KeyValueStore::Remove(const string& name) {
377   properties_.erase(name);
378 }
379 
LookupBool(const string & name,bool default_value) const380 bool KeyValueStore::LookupBool(const string& name, bool default_value) const {
381   const auto it(properties_.find(name));
382   if (it == properties_.end()) {
383     return default_value;
384   }
385   CHECK(it->second.IsTypeCompatible<bool>()) << "type mismatched";
386   return it->second.Get<bool>();
387 }
388 
LookupInt(const string & name,int default_value) const389 int KeyValueStore::LookupInt(const string& name, int default_value) const {
390   const auto it(properties_.find(name));
391   if (it == properties_.end()) {
392     return default_value;
393   }
394   CHECK(it->second.IsTypeCompatible<int32_t>()) << "type mismatched";
395   return it->second.Get<int32_t>();
396 }
397 
LookupString(const string & name,const string & default_value) const398 string KeyValueStore::LookupString(const string& name,
399                                    const string& default_value) const {
400   const auto it(properties_.find(name));
401   if (it == properties_.end()) {
402     return default_value;
403   }
404   CHECK(it->second.IsTypeCompatible<string>()) << "type mismatched";
405   return it->second.Get<string>();
406 }
407 
408 // static.
ConvertToVariantDictionary(const KeyValueStore & in_store,brillo::VariantDictionary * out_dict)409 void KeyValueStore::ConvertToVariantDictionary(
410     const KeyValueStore& in_store, brillo::VariantDictionary* out_dict) {
411   for (const auto& key_value_pair : in_store.properties_) {
412     if (key_value_pair.second.IsTypeCompatible<KeyValueStore>()) {
413       // Special handling for nested KeyValueStore (convert it to
414       // nested brillo::VariantDictionary).
415       brillo::VariantDictionary dict;
416       ConvertToVariantDictionary(
417           key_value_pair.second.Get<KeyValueStore>(), &dict);
418       out_dict->emplace(key_value_pair.first, dict);
419     } else {
420       out_dict->insert(key_value_pair);
421     }
422   }
423 }
424 
425 // static.
ConvertFromVariantDictionary(const brillo::VariantDictionary & in_dict,KeyValueStore * out_store)426 void KeyValueStore::ConvertFromVariantDictionary(
427     const brillo::VariantDictionary& in_dict, KeyValueStore* out_store) {
428   for (const auto& key_value_pair : in_dict) {
429     if (key_value_pair.second.IsTypeCompatible<brillo::VariantDictionary>()) {
430       // Special handling for nested brillo::VariantDictionary (convert it to
431       // nested KeyValueStore).
432       KeyValueStore store;
433       ConvertFromVariantDictionary(
434           key_value_pair.second.Get<brillo::VariantDictionary>(), &store);
435       out_store->properties_.emplace(key_value_pair.first, store);
436     } else {
437       out_store->properties_.insert(key_value_pair);
438     }
439   }
440 }
441 
442 // static.
ConvertPathsToRpcIdentifiers(const vector<dbus::ObjectPath> & paths,vector<string> * rpc_identifiers)443 void KeyValueStore::ConvertPathsToRpcIdentifiers(
444   const vector<dbus::ObjectPath>& paths, vector<string>* rpc_identifiers) {
445   for (const auto& path : paths) {
446     rpc_identifiers->push_back(path.value());
447   }
448 }
449 
450 }  // namespace shill
451