Home | History | Annotate | Download | only in prefs
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/prefs/pref_value_map.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/stl_util-inl.h"
     10 #include "base/values.h"
     11 
     12 PrefValueMap::PrefValueMap() {}
     13 
     14 PrefValueMap::~PrefValueMap() {
     15   Clear();
     16 }
     17 
     18 bool PrefValueMap::GetValue(const std::string& key, const Value** value) const {
     19   const Map::const_iterator entry = prefs_.find(key);
     20   if (entry != prefs_.end()) {
     21     if (value)
     22       *value = entry->second;
     23     return true;
     24   }
     25 
     26   return false;
     27 }
     28 
     29 bool PrefValueMap::GetValue(const std::string& key, Value** value) {
     30   const Map::const_iterator entry = prefs_.find(key);
     31   if (entry != prefs_.end()) {
     32     if (value)
     33       *value = entry->second;
     34     return true;
     35   }
     36 
     37   return false;
     38 }
     39 
     40 bool PrefValueMap::SetValue(const std::string& key, Value* value) {
     41   DCHECK(value);
     42   scoped_ptr<Value> value_ptr(value);
     43   const Map::iterator entry = prefs_.find(key);
     44   if (entry != prefs_.end()) {
     45     if (Value::Equals(entry->second, value))
     46       return false;
     47     delete entry->second;
     48     entry->second = value_ptr.release();
     49   } else {
     50     prefs_[key] = value_ptr.release();
     51   }
     52 
     53   return true;
     54 }
     55 
     56 bool PrefValueMap::RemoveValue(const std::string& key) {
     57   const Map::iterator entry = prefs_.find(key);
     58   if (entry != prefs_.end()) {
     59     delete entry->second;
     60     prefs_.erase(entry);
     61     return true;
     62   }
     63 
     64   return false;
     65 }
     66 
     67 void PrefValueMap::Clear() {
     68   STLDeleteValues(&prefs_);
     69   prefs_.clear();
     70 }
     71 
     72 PrefValueMap::iterator PrefValueMap::begin() {
     73   return prefs_.begin();
     74 }
     75 
     76 PrefValueMap::iterator PrefValueMap::end() {
     77   return prefs_.end();
     78 }
     79 
     80 PrefValueMap::const_iterator PrefValueMap::begin() const {
     81   return prefs_.begin();
     82 }
     83 
     84 PrefValueMap::const_iterator PrefValueMap::end() const {
     85   return prefs_.end();
     86 }
     87 
     88 bool PrefValueMap::GetBoolean(const std::string& key,
     89                               bool* value) const {
     90   const Value* stored_value = NULL;
     91   return GetValue(key, &stored_value) && stored_value->GetAsBoolean(value);
     92 }
     93 
     94 bool PrefValueMap::GetString(const std::string& key,
     95                              std::string* value) const {
     96   const Value* stored_value = NULL;
     97   return GetValue(key, &stored_value) && stored_value->GetAsString(value);
     98 }
     99 
    100 void PrefValueMap::SetString(const std::string& key,
    101                              const std::string& value) {
    102   SetValue(key, Value::CreateStringValue(value));
    103 }
    104 
    105 void PrefValueMap::GetDifferingKeys(
    106     const PrefValueMap* other,
    107     std::vector<std::string>* differing_keys) const {
    108   differing_keys->clear();
    109 
    110   // Walk over the maps in lockstep, adding everything that is different.
    111   Map::const_iterator this_pref(prefs_.begin());
    112   Map::const_iterator other_pref(other->prefs_.begin());
    113   while (this_pref != prefs_.end() && other_pref != other->prefs_.end()) {
    114     const int diff = this_pref->first.compare(other_pref->first);
    115     if (diff == 0) {
    116       if (!this_pref->second->Equals(other_pref->second))
    117         differing_keys->push_back(this_pref->first);
    118       ++this_pref;
    119       ++other_pref;
    120     } else if (diff < 0) {
    121       differing_keys->push_back(this_pref->first);
    122       ++this_pref;
    123     } else if (diff > 0) {
    124       differing_keys->push_back(other_pref->first);
    125       ++other_pref;
    126     }
    127   }
    128 
    129   // Add the remaining entries.
    130   for ( ; this_pref != prefs_.end(); ++this_pref)
    131       differing_keys->push_back(this_pref->first);
    132   for ( ; other_pref != other->prefs_.end(); ++other_pref)
    133       differing_keys->push_back(other_pref->first);
    134 }
    135