Home | History | Annotate | Download | only in shill
      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/property_store.h"
     18 
     19 #include <map>
     20 #include <string>
     21 #include <vector>
     22 
     23 #include <base/stl_util.h>
     24 #include <dbus/object_path.h>
     25 
     26 #include "shill/error.h"
     27 #include "shill/logging.h"
     28 #include "shill/property_accessor.h"
     29 
     30 using std::map;
     31 using std::string;
     32 using std::vector;
     33 
     34 namespace shill {
     35 
     36 namespace Logging {
     37 static auto kModuleLogScope = ScopeLogger::kProperty;
     38 static string ObjectID(const PropertyStore* p) { return "(property_store)"; }
     39 }
     40 
     41 PropertyStore::PropertyStore() {}
     42 
     43 PropertyStore::PropertyStore(PropertyChangeCallback on_property_changed) :
     44     property_changed_callback_(on_property_changed) {}
     45 
     46 PropertyStore::~PropertyStore() {}
     47 
     48 bool PropertyStore::Contains(const string& prop) const {
     49   return (ContainsKey(bool_properties_, prop)  ||
     50           ContainsKey(int16_properties_, prop) ||
     51           ContainsKey(int32_properties_, prop) ||
     52           ContainsKey(key_value_store_properties_, prop) ||
     53           ContainsKey(string_properties_, prop) ||
     54           ContainsKey(stringmap_properties_, prop) ||
     55           ContainsKey(stringmaps_properties_, prop) ||
     56           ContainsKey(strings_properties_, prop) ||
     57           ContainsKey(uint8_properties_, prop) ||
     58           ContainsKey(bytearray_properties_, prop) ||
     59           ContainsKey(uint16_properties_, prop) ||
     60           ContainsKey(uint16s_properties_, prop) ||
     61           ContainsKey(uint32_properties_, prop) ||
     62           ContainsKey(uint64_properties_, prop) ||
     63           ContainsKey(rpc_identifier_properties_, prop) ||
     64           ContainsKey(rpc_identifiers_properties_, prop));
     65 }
     66 
     67 bool PropertyStore::SetAnyProperty(const string& name,
     68                                    const brillo::Any& value,
     69                                    Error* error) {
     70   bool ret = false;
     71   if (value.IsTypeCompatible<bool>()) {
     72     ret = SetBoolProperty(name, value.Get<bool>(), error);
     73   } else if (value.IsTypeCompatible<uint8_t>()) {
     74     ret = SetUint8Property(name, value.Get<uint8_t>(), error);
     75   } else if (value.IsTypeCompatible<int16_t>()) {
     76     ret = SetInt16Property(name, value.Get<int16_t>(), error);
     77   } else if (value.IsTypeCompatible<int32_t>()) {
     78     ret = SetInt32Property(name, value.Get<int32_t>(), error);
     79   } else if (value.IsTypeCompatible<dbus::ObjectPath>()) {
     80     ret = SetStringProperty(name, value.Get<dbus::ObjectPath>().value(), error);
     81   } else if (value.IsTypeCompatible<string>()) {
     82     ret = SetStringProperty(name, value.Get<string>(), error);
     83   } else if (value.IsTypeCompatible<Stringmap>()) {
     84     ret = SetStringmapProperty(name, value.Get<Stringmap>(), error);
     85   } else if (value.IsTypeCompatible<Stringmaps>()) {
     86     SLOG(nullptr, 1) << " can't yet handle setting type "
     87                      << value.GetUndecoratedTypeName();
     88     error->Populate(Error::kInternalError);
     89   } else if (value.IsTypeCompatible<Strings>()) {
     90     ret = SetStringsProperty(name, value.Get<Strings>(), error);
     91   } else if (value.IsTypeCompatible<ByteArray>()) {
     92     ret = SetByteArrayProperty(name, value.Get<ByteArray>(), error);
     93   } else if (value.IsTypeCompatible<uint16_t>()) {
     94     ret = SetUint16Property(name, value.Get<uint16_t>(), error);
     95   } else if (value.IsTypeCompatible<Uint16s>()) {
     96     ret = SetUint16sProperty(name, value.Get<Uint16s>(), error);
     97   } else if (value.IsTypeCompatible<uint32_t>()) {
     98     ret = SetUint32Property(name, value.Get<uint32_t>(), error);
     99   } else if (value.IsTypeCompatible<uint64_t>()) {
    100     ret = SetUint64Property(name, value.Get<uint64_t>(), error);
    101   } else if (value.IsTypeCompatible<brillo::VariantDictionary>()) {
    102     KeyValueStore store;
    103     KeyValueStore::ConvertFromVariantDictionary(
    104         value.Get<brillo::VariantDictionary>(), &store);
    105     ret = SetKeyValueStoreProperty(name, store, error);
    106   } else {
    107     NOTREACHED() << " unknown type: " << value.GetUndecoratedTypeName();
    108     error->Populate(Error::kInternalError);
    109   }
    110   return ret;
    111 }
    112 
    113 bool PropertyStore::SetProperties(const brillo::VariantDictionary& in,
    114                                   Error* error) {
    115   for (const auto& kv : in) {
    116     if (!SetAnyProperty(kv.first, kv.second, error)) {
    117       return false;
    118     }
    119   }
    120   return true;
    121 }
    122 
    123 bool PropertyStore::GetProperties(brillo::VariantDictionary* out,
    124                                   Error* error) const {
    125   {
    126     ReadablePropertyConstIterator<bool> it = GetBoolPropertiesIter();
    127     for ( ; !it.AtEnd(); it.Advance()) {
    128       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    129     }
    130   }
    131   {
    132     ReadablePropertyConstIterator<int16_t> it = GetInt16PropertiesIter();
    133     for ( ; !it.AtEnd(); it.Advance()) {
    134       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    135     }
    136   }
    137   {
    138     ReadablePropertyConstIterator<int32_t> it = GetInt32PropertiesIter();
    139     for ( ; !it.AtEnd(); it.Advance()) {
    140       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    141     }
    142   }
    143   {
    144     ReadablePropertyConstIterator<RpcIdentifier> it =
    145         GetRpcIdentifierPropertiesIter();
    146     for ( ; !it.AtEnd(); it.Advance()) {
    147       out->insert(
    148           std::make_pair(it.Key(),
    149                          brillo::Any(dbus::ObjectPath(it.value()))));
    150     }
    151   }
    152   {
    153     ReadablePropertyConstIterator<RpcIdentifiers> it =
    154         GetRpcIdentifiersPropertiesIter();
    155     for ( ; !it.AtEnd(); it.Advance()) {
    156       vector<dbus::ObjectPath> rpc_identifiers_as_paths;
    157       for (const auto& path : it.value()) {
    158         rpc_identifiers_as_paths.push_back(dbus::ObjectPath(path));
    159       }
    160       out->insert(
    161           std::make_pair(it.Key(), brillo::Any(rpc_identifiers_as_paths)));
    162     }
    163   }
    164   {
    165     ReadablePropertyConstIterator<string> it = GetStringPropertiesIter();
    166     for ( ; !it.AtEnd(); it.Advance()) {
    167       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    168     }
    169   }
    170   {
    171     ReadablePropertyConstIterator<Stringmap> it = GetStringmapPropertiesIter();
    172     for ( ; !it.AtEnd(); it.Advance()) {
    173       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    174     }
    175   }
    176   {
    177     ReadablePropertyConstIterator<Stringmaps> it =
    178         GetStringmapsPropertiesIter();
    179     for ( ; !it.AtEnd(); it.Advance()) {
    180       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    181     }
    182   }
    183   {
    184     ReadablePropertyConstIterator<Strings> it = GetStringsPropertiesIter();
    185     for ( ; !it.AtEnd(); it.Advance()) {
    186       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    187     }
    188   }
    189   {
    190     ReadablePropertyConstIterator<uint8_t> it = GetUint8PropertiesIter();
    191     for ( ; !it.AtEnd(); it.Advance()) {
    192       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    193     }
    194   }
    195   {
    196     ReadablePropertyConstIterator<ByteArray> it = GetByteArrayPropertiesIter();
    197     for ( ; !it.AtEnd(); it.Advance()) {
    198       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    199     }
    200   }
    201   {
    202     ReadablePropertyConstIterator<uint16_t> it = GetUint16PropertiesIter();
    203     for ( ; !it.AtEnd(); it.Advance()) {
    204       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    205     }
    206   }
    207   {
    208     ReadablePropertyConstIterator<Uint16s> it = GetUint16sPropertiesIter();
    209     for ( ; !it.AtEnd(); it.Advance()) {
    210       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    211     }
    212   }
    213   {
    214     ReadablePropertyConstIterator<uint32_t> it = GetUint32PropertiesIter();
    215     for ( ; !it.AtEnd(); it.Advance()) {
    216       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    217     }
    218   }
    219   {
    220     ReadablePropertyConstIterator<uint64_t> it = GetUint64PropertiesIter();
    221     for ( ; !it.AtEnd(); it.Advance()) {
    222       out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    223     }
    224   }
    225   {
    226     ReadablePropertyConstIterator<KeyValueStore> it =
    227         GetKeyValueStorePropertiesIter();
    228     for ( ; !it.AtEnd(); it.Advance()) {
    229       brillo::VariantDictionary dict;
    230       KeyValueStore::ConvertToVariantDictionary(it.value(), &dict);
    231       out->insert(std::make_pair(it.Key(), dict));
    232     }
    233   }
    234 
    235   return true;
    236 }
    237 
    238 bool PropertyStore::GetBoolProperty(const string& name,
    239                                     bool* value,
    240                                     Error* error) const {
    241   return GetProperty(name, value, error, bool_properties_, "a bool");
    242 }
    243 
    244 bool PropertyStore::GetInt16Property(const string& name,
    245                                      int16_t* value,
    246                                      Error* error) const {
    247   return GetProperty(name, value, error, int16_properties_, "an int16_t");
    248 }
    249 
    250 bool PropertyStore::GetInt32Property(const string& name,
    251                                      int32_t* value,
    252                                      Error* error) const {
    253   return GetProperty(name, value, error, int32_properties_, "an int32_t");
    254 }
    255 
    256 bool PropertyStore::GetKeyValueStoreProperty(const string& name,
    257                                              KeyValueStore* value,
    258                                              Error* error) const {
    259   return GetProperty(name, value, error, key_value_store_properties_,
    260                      "a key value store");
    261 }
    262 
    263 bool PropertyStore::GetRpcIdentifierProperty(const string& name,
    264                                              RpcIdentifier* value,
    265                                              Error* error) const {
    266   return GetProperty(name, value, error, rpc_identifier_properties_,
    267                      "an rpc_identifier");
    268 }
    269 
    270 bool PropertyStore::GetStringProperty(const string& name,
    271                                       string* value,
    272                                       Error* error) const {
    273   return GetProperty(name, value, error, string_properties_, "a string");
    274 }
    275 
    276 bool PropertyStore::GetStringmapProperty(const string& name,
    277                                          Stringmap* values,
    278                                          Error* error) const {
    279   return GetProperty(name, values, error, stringmap_properties_,
    280                      "a string map");
    281 }
    282 
    283 bool PropertyStore::GetStringmapsProperty(const string& name,
    284                                           Stringmaps* values,
    285                                           Error* error) const {
    286   return GetProperty(name, values, error, stringmaps_properties_,
    287                      "a string map list");
    288 }
    289 
    290 bool PropertyStore::GetStringsProperty(const string& name,
    291                                        Strings* values,
    292                                        Error* error) const {
    293   return GetProperty(name, values, error, strings_properties_, "a string list");
    294 }
    295 
    296 bool PropertyStore::GetUint8Property(const string& name,
    297                                      uint8_t* value,
    298                                      Error* error) const {
    299   return GetProperty(name, value, error, uint8_properties_, "a uint8_t");
    300 }
    301 
    302 bool PropertyStore::GetByteArrayProperty(const string& name,
    303                                          ByteArray* value,
    304                                          Error *error) const {
    305   return GetProperty(name, value, error, bytearray_properties_, "a byte array");
    306 }
    307 
    308 bool PropertyStore::GetUint16Property(const string& name,
    309                                       uint16_t* value,
    310                                       Error* error) const {
    311   return GetProperty(name, value, error, uint16_properties_, "a uint16_t");
    312 }
    313 
    314 bool PropertyStore::GetUint16sProperty(const string& name,
    315                                        Uint16s* value,
    316                                        Error* error) const {
    317   return GetProperty(name, value, error, uint16s_properties_,
    318                      "a uint16_t list");
    319 }
    320 
    321 bool PropertyStore::GetUint32Property(const string& name,
    322                                       uint32_t* value,
    323                                       Error* error) const {
    324   return GetProperty(name, value, error, uint32_properties_, "a uint32_t");
    325 }
    326 
    327 bool PropertyStore::GetUint64Property(const string& name,
    328                                       uint64_t* value,
    329                                       Error* error) const {
    330   return GetProperty(name, value, error, uint64_properties_, "a uint64_t");
    331 }
    332 
    333 bool PropertyStore::SetBoolProperty(const string& name,
    334                                     bool value,
    335                                     Error* error) {
    336   return SetProperty(name, value, error, &bool_properties_, "a bool");
    337 }
    338 
    339 bool PropertyStore::SetInt16Property(const string& name,
    340                                      int16_t value,
    341                                      Error* error) {
    342   return SetProperty(name, value, error, &int16_properties_, "an int16_t");
    343 }
    344 
    345 bool PropertyStore::SetInt32Property(const string& name,
    346                                      int32_t value,
    347                                      Error* error) {
    348   return SetProperty(name, value, error, &int32_properties_, "an int32_t.");
    349 }
    350 
    351 bool PropertyStore::SetKeyValueStoreProperty(const string& name,
    352                                              const KeyValueStore& value,
    353                                              Error* error) {
    354   return SetProperty(name, value, error, &key_value_store_properties_,
    355                      "a key value store");
    356 }
    357 
    358 bool PropertyStore::SetStringProperty(const string& name,
    359                                       const string& value,
    360                                       Error* error) {
    361   return SetProperty(name, value, error, &string_properties_, "a string");
    362 }
    363 
    364 bool PropertyStore::SetStringmapProperty(const string& name,
    365                                          const map<string, string>& values,
    366                                          Error* error) {
    367   return SetProperty(name, values, error, &stringmap_properties_,
    368                      "a string map");
    369 }
    370 
    371 bool PropertyStore::SetStringmapsProperty(
    372     const string& name,
    373     const vector<map<string, string>>& values,
    374     Error* error) {
    375   return SetProperty(name, values, error, &stringmaps_properties_,
    376                      "a stringmaps");
    377 }
    378 
    379 bool PropertyStore::SetStringsProperty(const string& name,
    380                                        const vector<string>& values,
    381                                        Error* error) {
    382   return SetProperty(name, values, error, &strings_properties_,
    383                      "a string list");
    384 }
    385 
    386 bool PropertyStore::SetUint8Property(const string& name,
    387                                      uint8_t value,
    388                                      Error* error) {
    389   return SetProperty(name, value, error, &uint8_properties_, "a uint8_t");
    390 }
    391 
    392 bool PropertyStore::SetByteArrayProperty(const string& name,
    393                                          const ByteArray& value,
    394                                          Error *error) {
    395   return SetProperty(name, value, error, &bytearray_properties_, "a byte array");
    396 }
    397 
    398 bool PropertyStore::SetUint16Property(const string& name,
    399                                       uint16_t value,
    400                                       Error* error) {
    401   return SetProperty(name, value, error, &uint16_properties_, "a uint16_t");
    402 }
    403 
    404 bool PropertyStore::SetUint16sProperty(const string& name,
    405                                        const vector<uint16_t>& value,
    406                                        Error* error) {
    407   return SetProperty(name, value, error, &uint16s_properties_,
    408                      "a uint16_t list");
    409 }
    410 
    411 bool PropertyStore::SetUint32Property(const string& name,
    412                                       uint32_t value,
    413                                       Error* error) {
    414   return SetProperty(name, value, error, &uint32_properties_, "a uint32_t");
    415 }
    416 
    417 bool PropertyStore::SetUint64Property(const string& name,
    418                                       uint64_t value,
    419                                       Error* error) {
    420   return SetProperty(name, value, error, &uint64_properties_, "a uint64_t");
    421 }
    422 
    423 bool PropertyStore::SetRpcIdentifierProperty(const string& name,
    424                                              const RpcIdentifier& value,
    425                                              Error* error) {
    426   return SetProperty(name, value, error, &rpc_identifier_properties_,
    427                      "an rpc_identifier");
    428 }
    429 
    430 bool PropertyStore::ClearProperty(const string& name, Error* error) {
    431   SLOG(this, 2) << "Clearing " << name << ".";
    432 
    433   if (ContainsKey(bool_properties_, name)) {
    434     bool_properties_[name]->Clear(error);
    435   } else if (ContainsKey(int16_properties_, name)) {
    436     int16_properties_[name]->Clear(error);
    437   } else if (ContainsKey(int32_properties_, name)) {
    438     int32_properties_[name]->Clear(error);
    439   } else if (ContainsKey(key_value_store_properties_, name)) {
    440     key_value_store_properties_[name]->Clear(error);
    441   } else if (ContainsKey(string_properties_, name)) {
    442     string_properties_[name]->Clear(error);
    443   } else if (ContainsKey(stringmap_properties_, name)) {
    444     stringmap_properties_[name]->Clear(error);
    445   } else if (ContainsKey(stringmaps_properties_, name)) {
    446     stringmaps_properties_[name]->Clear(error);
    447   } else if (ContainsKey(strings_properties_, name)) {
    448     strings_properties_[name]->Clear(error);
    449   } else if (ContainsKey(uint8_properties_, name)) {
    450     uint8_properties_[name]->Clear(error);
    451   } else if (ContainsKey(uint16_properties_, name)) {
    452     uint16_properties_[name]->Clear(error);
    453   } else if (ContainsKey(uint16s_properties_, name)) {
    454     uint16s_properties_[name]->Clear(error);
    455   } else if (ContainsKey(uint32_properties_, name)) {
    456     uint32_properties_[name]->Clear(error);
    457   } else if (ContainsKey(uint64_properties_, name)) {
    458     uint64_properties_[name]->Clear(error);
    459   } else if (ContainsKey(rpc_identifier_properties_, name)) {
    460     rpc_identifier_properties_[name]->Clear(error);
    461   } else if (ContainsKey(rpc_identifiers_properties_, name)) {
    462     rpc_identifiers_properties_[name]->Clear(error);
    463   } else {
    464     error->Populate(
    465         Error::kInvalidProperty, "Property " + name + " does not exist.");
    466   }
    467   if (error->IsSuccess()) {
    468     if (!property_changed_callback_.is_null()) {
    469       property_changed_callback_.Run(name);
    470     }
    471   }
    472   return error->IsSuccess();
    473 }
    474 
    475 ReadablePropertyConstIterator<bool> PropertyStore::GetBoolPropertiesIter()
    476     const {
    477   return ReadablePropertyConstIterator<bool>(bool_properties_);
    478 }
    479 
    480 ReadablePropertyConstIterator<int16_t> PropertyStore::GetInt16PropertiesIter()
    481     const {
    482   return ReadablePropertyConstIterator<int16_t>(int16_properties_);
    483 }
    484 
    485 ReadablePropertyConstIterator<int32_t> PropertyStore::GetInt32PropertiesIter()
    486     const {
    487   return ReadablePropertyConstIterator<int32_t>(int32_properties_);
    488 }
    489 
    490 ReadablePropertyConstIterator<KeyValueStore>
    491 PropertyStore::GetKeyValueStorePropertiesIter() const {
    492   return
    493       ReadablePropertyConstIterator<KeyValueStore>(key_value_store_properties_);
    494 }
    495 
    496 ReadablePropertyConstIterator<RpcIdentifier>
    497 PropertyStore::GetRpcIdentifierPropertiesIter() const {
    498   return ReadablePropertyConstIterator<RpcIdentifier>(
    499       rpc_identifier_properties_);
    500 }
    501 
    502 ReadablePropertyConstIterator<RpcIdentifiers>
    503 PropertyStore::GetRpcIdentifiersPropertiesIter() const {
    504   return ReadablePropertyConstIterator<RpcIdentifiers>(
    505       rpc_identifiers_properties_);
    506 }
    507 
    508 ReadablePropertyConstIterator<string>
    509 PropertyStore::GetStringPropertiesIter() const {
    510   return ReadablePropertyConstIterator<string>(string_properties_);
    511 }
    512 
    513 ReadablePropertyConstIterator<Stringmap>
    514 PropertyStore::GetStringmapPropertiesIter() const {
    515   return ReadablePropertyConstIterator<Stringmap>(stringmap_properties_);
    516 }
    517 
    518 ReadablePropertyConstIterator<Stringmaps>
    519 PropertyStore::GetStringmapsPropertiesIter()
    520     const {
    521   return ReadablePropertyConstIterator<Stringmaps>(stringmaps_properties_);
    522 }
    523 
    524 ReadablePropertyConstIterator<Strings> PropertyStore::GetStringsPropertiesIter()
    525     const {
    526   return ReadablePropertyConstIterator<Strings>(strings_properties_);
    527 }
    528 
    529 ReadablePropertyConstIterator<uint8_t> PropertyStore::GetUint8PropertiesIter()
    530     const {
    531   return ReadablePropertyConstIterator<uint8_t>(uint8_properties_);
    532 }
    533 
    534 ReadablePropertyConstIterator<ByteArray> PropertyStore::GetByteArrayPropertiesIter()
    535     const {
    536   return ReadablePropertyConstIterator<ByteArray>(bytearray_properties_);
    537 }
    538 
    539 ReadablePropertyConstIterator<uint16_t> PropertyStore::GetUint16PropertiesIter()
    540     const {
    541   return ReadablePropertyConstIterator<uint16_t>(uint16_properties_);
    542 }
    543 
    544 ReadablePropertyConstIterator<Uint16s> PropertyStore::GetUint16sPropertiesIter()
    545     const {
    546   return ReadablePropertyConstIterator<Uint16s>(uint16s_properties_);
    547 }
    548 
    549 ReadablePropertyConstIterator<uint32_t> PropertyStore::GetUint32PropertiesIter()
    550     const {
    551   return ReadablePropertyConstIterator<uint32_t>(uint32_properties_);
    552 }
    553 
    554 ReadablePropertyConstIterator<uint64_t> PropertyStore::GetUint64PropertiesIter()
    555     const {
    556   return ReadablePropertyConstIterator<uint64_t>(uint64_properties_);
    557 }
    558 
    559 void PropertyStore::RegisterBool(const string& name, bool* prop) {
    560   DCHECK(!Contains(name) || ContainsKey(bool_properties_, name))
    561       << "(Already registered " << name << ")";
    562   bool_properties_[name] = BoolAccessor(new PropertyAccessor<bool>(prop));
    563 }
    564 
    565 void PropertyStore::RegisterConstBool(const string& name, const bool* prop) {
    566   DCHECK(!Contains(name) || ContainsKey(bool_properties_, name))
    567       << "(Already registered " << name << ")";
    568   bool_properties_[name] = BoolAccessor(new ConstPropertyAccessor<bool>(prop));
    569 }
    570 
    571 void PropertyStore::RegisterWriteOnlyBool(const string& name, bool* prop) {
    572   DCHECK(!Contains(name) || ContainsKey(bool_properties_, name))
    573       << "(Already registered " << name << ")";
    574   bool_properties_[name] = BoolAccessor(
    575       new WriteOnlyPropertyAccessor<bool>(prop));
    576 }
    577 
    578 void PropertyStore::RegisterInt16(const string& name, int16_t* prop) {
    579   DCHECK(!Contains(name) || ContainsKey(int16_properties_, name))
    580       << "(Already registered " << name << ")";
    581   int16_properties_[name] = Int16Accessor(new PropertyAccessor<int16_t>(prop));
    582 }
    583 
    584 void PropertyStore::RegisterConstInt16(const string& name,
    585                                        const int16_t* prop) {
    586   DCHECK(!Contains(name) || ContainsKey(int16_properties_, name))
    587       << "(Already registered " << name << ")";
    588   int16_properties_[name] =
    589       Int16Accessor(new ConstPropertyAccessor<int16_t>(prop));
    590 }
    591 
    592 void PropertyStore::RegisterWriteOnlyInt16(const string& name, int16_t* prop) {
    593   DCHECK(!Contains(name) || ContainsKey(int16_properties_, name))
    594       << "(Already registered " << name << ")";
    595   int16_properties_[name] =
    596       Int16Accessor(new WriteOnlyPropertyAccessor<int16_t>(prop));
    597 }
    598 void PropertyStore::RegisterInt32(const string& name, int32_t* prop) {
    599   DCHECK(!Contains(name) || ContainsKey(int32_properties_, name))
    600       << "(Already registered " << name << ")";
    601   int32_properties_[name] = Int32Accessor(new PropertyAccessor<int32_t>(prop));
    602 }
    603 
    604 void PropertyStore::RegisterConstInt32(const string& name,
    605                                        const int32_t* prop) {
    606   DCHECK(!Contains(name) || ContainsKey(int32_properties_, name))
    607       << "(Already registered " << name << ")";
    608   int32_properties_[name] =
    609       Int32Accessor(new ConstPropertyAccessor<int32_t>(prop));
    610 }
    611 
    612 void PropertyStore::RegisterWriteOnlyInt32(const string& name, int32_t* prop) {
    613   DCHECK(!Contains(name) || ContainsKey(int32_properties_, name))
    614       << "(Already registered " << name << ")";
    615   int32_properties_[name] =
    616       Int32Accessor(new WriteOnlyPropertyAccessor<int32_t>(prop));
    617 }
    618 
    619 void PropertyStore::RegisterString(const string& name, string* prop) {
    620   DCHECK(!Contains(name) || ContainsKey(string_properties_, name))
    621       << "(Already registered " << name << ")";
    622   string_properties_[name] = StringAccessor(new PropertyAccessor<string>(prop));
    623 }
    624 
    625 void PropertyStore::RegisterConstString(const string& name,
    626                                         const string* prop) {
    627   DCHECK(!Contains(name) || ContainsKey(string_properties_, name))
    628       << "(Already registered " << name << ")";
    629   string_properties_[name] =
    630       StringAccessor(new ConstPropertyAccessor<string>(prop));
    631 }
    632 
    633 void PropertyStore::RegisterWriteOnlyString(const string& name, string* prop) {
    634   DCHECK(!Contains(name) || ContainsKey(string_properties_, name))
    635       << "(Already registered " << name << ")";
    636   string_properties_[name] =
    637       StringAccessor(new WriteOnlyPropertyAccessor<string>(prop));
    638 }
    639 
    640 void PropertyStore::RegisterStringmap(const string& name, Stringmap* prop) {
    641   DCHECK(!Contains(name) || ContainsKey(stringmap_properties_, name))
    642       << "(Already registered " << name << ")";
    643   stringmap_properties_[name] =
    644       StringmapAccessor(new PropertyAccessor<Stringmap>(prop));
    645 }
    646 
    647 void PropertyStore::RegisterConstStringmap(const string& name,
    648                                            const Stringmap* prop) {
    649   DCHECK(!Contains(name) || ContainsKey(stringmap_properties_, name))
    650       << "(Already registered " << name << ")";
    651   stringmap_properties_[name] =
    652       StringmapAccessor(new ConstPropertyAccessor<Stringmap>(prop));
    653 }
    654 
    655 void PropertyStore::RegisterWriteOnlyStringmap(const string& name,
    656                                                Stringmap* prop) {
    657   DCHECK(!Contains(name) || ContainsKey(stringmap_properties_, name))
    658       << "(Already registered " << name << ")";
    659   stringmap_properties_[name] =
    660       StringmapAccessor(new WriteOnlyPropertyAccessor<Stringmap>(prop));
    661 }
    662 
    663 void PropertyStore::RegisterStringmaps(const string& name, Stringmaps* prop) {
    664   DCHECK(!Contains(name) || ContainsKey(stringmaps_properties_, name))
    665       << "(Already registered " << name << ")";
    666   stringmaps_properties_[name] =
    667       StringmapsAccessor(new PropertyAccessor<Stringmaps>(prop));
    668 }
    669 
    670 void PropertyStore::RegisterConstStringmaps(const string& name,
    671                                             const Stringmaps* prop) {
    672   DCHECK(!Contains(name) || ContainsKey(stringmaps_properties_, name))
    673       << "(Already registered " << name << ")";
    674   stringmaps_properties_[name] =
    675       StringmapsAccessor(new ConstPropertyAccessor<Stringmaps>(prop));
    676 }
    677 
    678 void PropertyStore::RegisterWriteOnlyStringmaps(const string& name,
    679                                                 Stringmaps* prop) {
    680   DCHECK(!Contains(name) || ContainsKey(stringmaps_properties_, name))
    681       << "(Already registered " << name << ")";
    682   stringmaps_properties_[name] =
    683       StringmapsAccessor(new WriteOnlyPropertyAccessor<Stringmaps>(prop));
    684 }
    685 
    686 void PropertyStore::RegisterStrings(const string& name, Strings* prop) {
    687   DCHECK(!Contains(name) || ContainsKey(strings_properties_, name))
    688       << "(Already registered " << name << ")";
    689   strings_properties_[name] =
    690       StringsAccessor(new PropertyAccessor<Strings>(prop));
    691 }
    692 
    693 void PropertyStore::RegisterConstStrings(const string& name,
    694                                          const Strings* prop) {
    695   DCHECK(!Contains(name) || ContainsKey(strings_properties_, name))
    696       << "(Already registered " << name << ")";
    697   strings_properties_[name] =
    698       StringsAccessor(new ConstPropertyAccessor<Strings>(prop));
    699 }
    700 
    701 void PropertyStore::RegisterWriteOnlyStrings(const string& name,
    702                                              Strings* prop) {
    703   DCHECK(!Contains(name) || ContainsKey(strings_properties_, name))
    704       << "(Already registered " << name << ")";
    705   strings_properties_[name] =
    706       StringsAccessor(new WriteOnlyPropertyAccessor<Strings>(prop));
    707 }
    708 
    709 void PropertyStore::RegisterUint8(const string& name, uint8_t* prop) {
    710   DCHECK(!Contains(name) || ContainsKey(uint8_properties_, name))
    711       << "(Already registered " << name << ")";
    712   uint8_properties_[name] = Uint8Accessor(new PropertyAccessor<uint8_t>(prop));
    713 }
    714 
    715 void PropertyStore::RegisterConstUint8(const string& name,
    716                                        const uint8_t* prop) {
    717   DCHECK(!Contains(name) || ContainsKey(uint8_properties_, name))
    718       << "(Already registered " << name << ")";
    719   uint8_properties_[name] =
    720       Uint8Accessor(new ConstPropertyAccessor<uint8_t>(prop));
    721 }
    722 
    723 void PropertyStore::RegisterWriteOnlyUint8(const string& name, uint8_t* prop) {
    724   DCHECK(!Contains(name) || ContainsKey(uint8_properties_, name))
    725       << "(Already registered " << name << ")";
    726   uint8_properties_[name] =
    727       Uint8Accessor(new WriteOnlyPropertyAccessor<uint8_t>(prop));
    728 }
    729 
    730 void PropertyStore::RegisterByteArray(const string& name, ByteArray* prop) {
    731   DCHECK(!Contains(name) || ContainsKey(bytearray_properties_, name))
    732       << "(Already registered " << name << ")";
    733   bytearray_properties_[name] =
    734       ByteArrayAccessor(new PropertyAccessor<ByteArray>(prop));
    735 }
    736 
    737 void PropertyStore::RegisterConstByteArray(const string& name,
    738                                            const ByteArray* prop) {
    739   DCHECK(!Contains(name) || ContainsKey(bytearray_properties_, name))
    740       << "(Already registered " << name << ")";
    741   bytearray_properties_[name] =
    742       ByteArrayAccessor(new ConstPropertyAccessor<ByteArray>(prop));
    743 }
    744 
    745 void PropertyStore::RegisterWriteOnlyByteArray(const string& name,
    746                                                ByteArray* prop) {
    747   DCHECK(!Contains(name) || ContainsKey(bytearray_properties_, name))
    748       << "(Already registered " << name << ")";
    749   bytearray_properties_[name] =
    750       ByteArrayAccessor(new WriteOnlyPropertyAccessor<ByteArray>(prop));
    751 }
    752 
    753 void PropertyStore::RegisterUint16(const string& name, uint16_t* prop) {
    754   DCHECK(!Contains(name) || ContainsKey(uint16_properties_, name))
    755       << "(Already registered " << name << ")";
    756   uint16_properties_[name] =
    757       Uint16Accessor(new PropertyAccessor<uint16_t>(prop));
    758 }
    759 
    760 void PropertyStore::RegisterUint16s(const string& name, Uint16s* prop) {
    761   DCHECK(!Contains(name) || ContainsKey(uint16s_properties_, name))
    762       << "(Already registered " << name << ")";
    763   uint16s_properties_[name] =
    764       Uint16sAccessor(new PropertyAccessor<Uint16s>(prop));
    765 }
    766 
    767 void PropertyStore::RegisterUint32(const std::string& name, uint32_t* prop) {
    768   DCHECK(!Contains(name) || ContainsKey(uint32_properties_, name))
    769       << "(Already registered " << name << ")";
    770   uint32_properties_[name] =
    771       Uint32Accessor(new PropertyAccessor<uint32_t>(prop));
    772 }
    773 
    774 void PropertyStore::RegisterConstUint32(const string& name,
    775                                         const uint32_t* prop) {
    776   DCHECK(!Contains(name) || ContainsKey(uint32_properties_, name))
    777       << "(Already registered " << name << ")";
    778   uint32_properties_[name] =
    779       Uint32Accessor(new ConstPropertyAccessor<uint32_t>(prop));
    780 }
    781 
    782 void PropertyStore::RegisterConstUint16(const string& name,
    783                                         const uint16_t* prop) {
    784   DCHECK(!Contains(name) || ContainsKey(uint16_properties_, name))
    785       << "(Already registered " << name << ")";
    786   uint16_properties_[name] =
    787       Uint16Accessor(new ConstPropertyAccessor<uint16_t>(prop));
    788 }
    789 
    790 void PropertyStore::RegisterConstUint16s(const string& name,
    791                                          const Uint16s* prop) {
    792   DCHECK(!Contains(name) || ContainsKey(uint16s_properties_, name))
    793       << "(Already registered " << name << ")";
    794   uint16s_properties_[name] =
    795       Uint16sAccessor(new ConstPropertyAccessor<Uint16s>(prop));
    796 }
    797 
    798 void PropertyStore::RegisterWriteOnlyUint16(const string& name,
    799                                             uint16_t* prop) {
    800   DCHECK(!Contains(name) || ContainsKey(uint16_properties_, name))
    801       << "(Already registered " << name << ")";
    802   uint16_properties_[name] =
    803       Uint16Accessor(new WriteOnlyPropertyAccessor<uint16_t>(prop));
    804 }
    805 
    806 void PropertyStore::RegisterDerivedBool(const string& name,
    807                                         const BoolAccessor& accessor) {
    808   DCHECK(!Contains(name) || ContainsKey(bool_properties_, name))
    809       << "(Already registered " << name << ")";
    810   bool_properties_[name] = accessor;
    811 }
    812 
    813 void PropertyStore::RegisterDerivedInt32(const string& name,
    814                                          const Int32Accessor& accessor) {
    815   DCHECK(!Contains(name) || ContainsKey(int32_properties_, name))
    816       << "(Already registered " << name << ")";
    817   int32_properties_[name] = accessor;
    818 }
    819 
    820 void PropertyStore::RegisterDerivedKeyValueStore(
    821     const string& name,
    822     const KeyValueStoreAccessor& acc) {
    823   DCHECK(!Contains(name) || ContainsKey(key_value_store_properties_, name))
    824       << "(Already registered " << name << ")";
    825   key_value_store_properties_[name] = acc;
    826 }
    827 
    828 void PropertyStore::RegisterDerivedRpcIdentifier(
    829     const string& name,
    830     const RpcIdentifierAccessor& acc) {
    831   DCHECK(!Contains(name) || ContainsKey(rpc_identifier_properties_, name))
    832       << "(Already registered " << name << ")";
    833   rpc_identifier_properties_[name] = acc;
    834 }
    835 
    836 void PropertyStore::RegisterDerivedRpcIdentifiers(
    837     const string& name,
    838     const RpcIdentifiersAccessor& accessor) {
    839   DCHECK(!Contains(name) || ContainsKey(rpc_identifiers_properties_, name))
    840       << "(Already registered " << name << ")";
    841   rpc_identifiers_properties_[name] = accessor;
    842 }
    843 
    844 void PropertyStore::RegisterDerivedString(const string& name,
    845                                           const StringAccessor& accessor) {
    846   DCHECK(!Contains(name) || ContainsKey(string_properties_, name))
    847       << "(Already registered " << name << ")";
    848   string_properties_[name] = accessor;
    849 }
    850 
    851 void PropertyStore::RegisterDerivedStrings(const string& name,
    852                                            const StringsAccessor& accessor) {
    853   DCHECK(!Contains(name) || ContainsKey(strings_properties_, name))
    854       << "(Already registered " << name << ")";
    855   strings_properties_[name] = accessor;
    856 }
    857 
    858 void PropertyStore::RegisterDerivedStringmap(const string& name,
    859                                              const StringmapAccessor& acc) {
    860   DCHECK(!Contains(name) || ContainsKey(stringmap_properties_, name))
    861       << "(Already registered " << name << ")";
    862   stringmap_properties_[name] = acc;
    863 }
    864 
    865 void PropertyStore::RegisterDerivedStringmaps(const string& name,
    866                                               const StringmapsAccessor& acc) {
    867   DCHECK(!Contains(name) || ContainsKey(stringmaps_properties_, name))
    868       << "(Already registered " << name << ")";
    869   stringmaps_properties_[name] = acc;
    870 }
    871 
    872 void PropertyStore::RegisterDerivedUint16(const string& name,
    873                                           const Uint16Accessor& acc) {
    874   DCHECK(!Contains(name) || ContainsKey(uint16_properties_, name))
    875       << "(Already registered " << name << ")";
    876   uint16_properties_[name] = acc;
    877 }
    878 
    879 void PropertyStore::RegisterDerivedUint64(const string& name,
    880                                           const Uint64Accessor& acc) {
    881   DCHECK(!Contains(name) || ContainsKey(uint64_properties_, name))
    882       << "(Already registered " << name << ")";
    883   uint64_properties_[name] = acc;
    884 }
    885 
    886 void PropertyStore::RegisterDerivedByteArray(const string& name,
    887                                              const ByteArrayAccessor& acc) {
    888   DCHECK(!Contains(name) || ContainsKey(bytearray_properties_, name))
    889       << "(Already registered " << name << ")";
    890   bytearray_properties_[name] = acc;
    891 }
    892 
    893 // private methods
    894 
    895 template <class V>
    896 bool PropertyStore::GetProperty(
    897     const string& name,
    898     V* value,
    899     Error* error,
    900     const map<string, std::shared_ptr<AccessorInterface<V>>>& collection,
    901     const string& value_type_english) const {
    902   SLOG(this, 2) << "Getting " << name << " as " << value_type_english
    903                 << ".";
    904   typename map<string, std::shared_ptr<AccessorInterface<V>>>::const_iterator
    905       it = collection.find(name);
    906   if (it != collection.end()) {
    907     V val = it->second->Get(error);
    908     if (error->IsSuccess()) {
    909       *value = val;
    910     }
    911   } else {
    912     if (Contains(name)) {
    913       error->Populate(
    914           Error::kInvalidArguments,
    915           "Property " + name + " is not " + value_type_english + ".");
    916     } else {
    917       error->Populate(
    918           Error::kInvalidProperty, "Property " + name + " does not exist.");
    919     }
    920   }
    921   return error->IsSuccess();
    922 }
    923 
    924 template <class V>
    925 bool PropertyStore::SetProperty(
    926     const string& name,
    927     const V& value,
    928     Error* error,
    929     map<string, std::shared_ptr<AccessorInterface<V>>>* collection,
    930     const string& value_type_english) {
    931   bool ret = false;
    932   SLOG(this, 2) << "Setting " << name << " as " << value_type_english
    933                 << ".";
    934   if (ContainsKey(*collection, name)) {
    935     ret = (*collection)[name]->Set(value, error);
    936     if (ret) {
    937       if (!property_changed_callback_.is_null()) {
    938         property_changed_callback_.Run(name);
    939       }
    940     }
    941   } else {
    942     if (Contains(name)) {
    943       error->Populate(
    944           Error::kInvalidArguments,
    945           "Property " + name + " is not " + value_type_english + ".");
    946     } else {
    947       error->Populate(
    948           Error::kInvalidProperty, "Property " + name + " does not exist.");
    949     }
    950   }
    951   return ret;
    952 }
    953 
    954 }  // namespace shill
    955