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
PrefValueMap()12 PrefValueMap::PrefValueMap() {}
13
~PrefValueMap()14 PrefValueMap::~PrefValueMap() {
15 Clear();
16 }
17
GetValue(const std::string & key,const Value ** value) const18 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
GetValue(const std::string & key,Value ** value)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
SetValue(const std::string & key,Value * value)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
RemoveValue(const std::string & key)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
Clear()67 void PrefValueMap::Clear() {
68 STLDeleteValues(&prefs_);
69 prefs_.clear();
70 }
71
begin()72 PrefValueMap::iterator PrefValueMap::begin() {
73 return prefs_.begin();
74 }
75
end()76 PrefValueMap::iterator PrefValueMap::end() {
77 return prefs_.end();
78 }
79
begin() const80 PrefValueMap::const_iterator PrefValueMap::begin() const {
81 return prefs_.begin();
82 }
83
end() const84 PrefValueMap::const_iterator PrefValueMap::end() const {
85 return prefs_.end();
86 }
87
GetBoolean(const std::string & key,bool * value) const88 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
GetString(const std::string & key,std::string * value) const94 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
SetString(const std::string & key,const std::string & value)100 void PrefValueMap::SetString(const std::string& key,
101 const std::string& value) {
102 SetValue(key, Value::CreateStringValue(value));
103 }
104
GetDifferingKeys(const PrefValueMap * other,std::vector<std::string> * differing_keys) const105 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