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 29 KeyValueStore::KeyValueStore() {} 30 31 void KeyValueStore::Clear() { 32 properties_.clear(); 33 } 34 35 bool KeyValueStore::IsEmpty() { 36 return properties_.empty(); 37 } 38 39 void KeyValueStore::CopyFrom(const KeyValueStore& b) { 40 properties_ = b.properties_; 41 } 42 43 bool KeyValueStore::operator==(const KeyValueStore& rhs) const { 44 return properties_ == rhs.properties_; 45 } 46 47 bool KeyValueStore::operator!=(const KeyValueStore& rhs) const { 48 return properties_ != rhs.properties_; 49 } 50 51 bool KeyValueStore::ContainsBool(const string& name) const { 52 return ContainsKey(properties_, name) && 53 properties_.find(name)->second.IsTypeCompatible<bool>(); 54 } 55 56 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 62 bool KeyValueStore::ContainsInt(const string& name) const { 63 return ContainsKey(properties_, name) && 64 properties_.find(name)->second.IsTypeCompatible<int32_t>(); 65 } 66 67 bool KeyValueStore::ContainsInt16(const string& name) const { 68 return ContainsKey(properties_, name) && 69 properties_.find(name)->second.IsTypeCompatible<int16_t>(); 70 } 71 72 bool KeyValueStore::ContainsKeyValueStore(const string& name) const { 73 return ContainsKey(properties_, name) && 74 properties_.find(name)->second.IsTypeCompatible<KeyValueStore>(); 75 } 76 77 bool KeyValueStore::ContainsRpcIdentifier(const string& name) const { 78 return ContainsKey(properties_, name) && 79 properties_.find(name)->second.IsTypeCompatible<dbus::ObjectPath>(); 80 } 81 82 bool KeyValueStore::ContainsRpcIdentifiers(const string& name) const { 83 return ContainsKey(properties_, name) && 84 properties_.find(name)->second 85 .IsTypeCompatible<vector<dbus::ObjectPath>>(); 86 } 87 88 bool KeyValueStore::ContainsString(const string& name) const { 89 return ContainsKey(properties_, name) && 90 properties_.find(name)->second.IsTypeCompatible<string>(); 91 } 92 93 bool KeyValueStore::ContainsStringmap(const std::string& name) const { 94 return ContainsKey(properties_, name) && 95 properties_.find(name)->second.IsTypeCompatible<Stringmap>(); 96 } 97 98 bool KeyValueStore::ContainsStrings(const string& name) const { 99 return ContainsKey(properties_, name) && 100 properties_.find(name)->second.IsTypeCompatible<Strings>(); 101 } 102 103 bool KeyValueStore::ContainsUint(const string& name) const { 104 return ContainsKey(properties_, name) && 105 properties_.find(name)->second.IsTypeCompatible<uint32_t>(); 106 } 107 108 bool KeyValueStore::ContainsUint8(const string& name) const { 109 return ContainsKey(properties_, name) && 110 properties_.find(name)->second.IsTypeCompatible<uint8_t>(); 111 } 112 113 bool KeyValueStore::ContainsUint16(const string& name) const { 114 return ContainsKey(properties_, name) && 115 properties_.find(name)->second.IsTypeCompatible<uint16_t>(); 116 } 117 118 bool KeyValueStore::ContainsUint8s(const string& name) const { 119 return ContainsKey(properties_, name) && 120 properties_.find(name)->second.IsTypeCompatible<vector<uint8_t>>(); 121 } 122 123 bool KeyValueStore::ContainsUint32s(const string& name) const { 124 return ContainsKey(properties_, name) && 125 properties_.find(name)->second.IsTypeCompatible<vector<uint32_t>>(); 126 } 127 128 bool KeyValueStore::Contains(const string& name) const { 129 return ContainsKey(properties_, name); 130 } 131 132 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 139 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 148 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 155 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 162 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 169 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 177 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 188 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 195 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 203 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 210 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 217 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 224 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 231 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 239 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 247 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 253 void KeyValueStore::SetBool(const string& name, bool value) { 254 properties_[name] = brillo::Any(value); 255 } 256 257 void KeyValueStore::SetByteArrays(const string& name, 258 const vector<vector<uint8_t>>& value) { 259 properties_[name] = brillo::Any(value); 260 } 261 262 void KeyValueStore::SetInt(const string& name, int32_t value) { 263 properties_[name] = brillo::Any(value); 264 } 265 266 void KeyValueStore::SetInt16(const string& name, int16_t value) { 267 properties_[name] = brillo::Any(value); 268 } 269 270 void KeyValueStore::SetKeyValueStore(const string& name, 271 const KeyValueStore& value) { 272 properties_[name] = brillo::Any(value); 273 } 274 275 void KeyValueStore::SetRpcIdentifier(const string& name, const string& value) { 276 properties_[name] = brillo::Any(dbus::ObjectPath(value)); 277 } 278 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 288 void KeyValueStore::SetString(const string& name, const string& value) { 289 properties_[name] = brillo::Any(value); 290 } 291 292 void KeyValueStore::SetStringmap(const string& name, 293 const map<string, string>& value) { 294 properties_[name] = brillo::Any(value); 295 } 296 297 void KeyValueStore::SetStrings(const string& name, 298 const vector<string>& value) { 299 properties_[name] = brillo::Any(value); 300 } 301 302 void KeyValueStore::SetUint(const string& name, uint32_t value) { 303 properties_[name] = brillo::Any(value); 304 } 305 306 void KeyValueStore::SetUint16(const string& name, uint16_t value) { 307 properties_[name] = brillo::Any(value); 308 } 309 310 void KeyValueStore::SetUint8(const string& name, uint8_t value) { 311 properties_[name] = brillo::Any(value); 312 } 313 314 void KeyValueStore::SetUint8s(const string& name, 315 const vector<uint8_t>& value) { 316 properties_[name] = brillo::Any(value); 317 } 318 319 void KeyValueStore::SetUint32s(const string& name, 320 const vector<uint32_t>& value) { 321 properties_[name] = brillo::Any(value); 322 } 323 324 void KeyValueStore::Set(const string& name, const brillo::Any& value) { 325 properties_[name] = value; 326 } 327 328 void KeyValueStore::RemoveByteArrays(const string& name) { 329 properties_.erase(name); 330 } 331 332 void KeyValueStore::RemoveInt(const string& name) { 333 properties_.erase(name); 334 } 335 336 void KeyValueStore::RemoveInt16(const string& name) { 337 properties_.erase(name); 338 } 339 340 void KeyValueStore::RemoveKeyValueStore(const string& name) { 341 properties_.erase(name); 342 } 343 344 void KeyValueStore::RemoveRpcIdentifier(const string& name) { 345 properties_.erase(name); 346 } 347 348 void KeyValueStore::RemoveString(const string& name) { 349 properties_.erase(name); 350 } 351 352 void KeyValueStore::RemoveStringmap(const string& name) { 353 properties_.erase(name); 354 } 355 356 void KeyValueStore::RemoveStrings(const string& name) { 357 properties_.erase(name); 358 } 359 360 void KeyValueStore::RemoveUint16(const string& name) { 361 properties_.erase(name); 362 } 363 364 void KeyValueStore::RemoveUint8(const string& name) { 365 properties_.erase(name); 366 } 367 368 void KeyValueStore::RemoveUint8s(const string& name) { 369 properties_.erase(name); 370 } 371 372 void KeyValueStore::RemoveUint32s(const string& name) { 373 properties_.erase(name); 374 } 375 376 void KeyValueStore::Remove(const string& name) { 377 properties_.erase(name); 378 } 379 380 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 389 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 398 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. 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. 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. 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