1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/prefs/pref_value_map.h"
13 #include "base/strings/string_piece.h"
14 #include "base/values.h"
16 PrefValueMap::PrefValueMap() {}
18 PrefValueMap::~PrefValueMap() {}
20 bool PrefValueMap::GetValue(base::StringPiece key,
21 const base::Value** value) const {
22 auto it = prefs_.find(key);
23 if (it == prefs_.end())
32 bool PrefValueMap::GetValue(base::StringPiece key, base::Value** value) {
33 auto it = prefs_.find(key);
34 if (it == prefs_.end())
43 bool PrefValueMap::SetValue(const std::string& key, base::Value value) {
44 base::Value& existing_value = prefs_[key];
45 if (value == existing_value)
48 existing_value = std::move(value);
52 bool PrefValueMap::RemoveValue(const std::string& key) {
53 return prefs_.erase(key) != 0;
56 void PrefValueMap::Clear() {
60 void PrefValueMap::ClearWithPrefix(const std::string& prefix) {
61 Map::iterator low = prefs_.lower_bound(prefix);
62 // Appending maximum possible character so that there will be no string with
63 // prefix |prefix| that we may miss.
64 Map::iterator high = prefs_.upper_bound(prefix + char(CHAR_MAX));
65 prefs_.erase(low, high);
68 void PrefValueMap::Swap(PrefValueMap* other) {
69 prefs_.swap(other->prefs_);
72 PrefValueMap::iterator PrefValueMap::begin() {
73 return prefs_.begin();
76 PrefValueMap::iterator PrefValueMap::end() {
80 PrefValueMap::const_iterator PrefValueMap::begin() const {
81 return prefs_.begin();
84 PrefValueMap::const_iterator PrefValueMap::end() const {
88 bool PrefValueMap::empty() const {
89 return prefs_.empty();
92 bool PrefValueMap::GetBoolean(const std::string& key, bool* value) const {
93 const base::Value* stored_value = nullptr;
94 if (GetValue(key, &stored_value) && stored_value->is_bool()) {
95 *value = stored_value->GetBool();
101 void PrefValueMap::SetBoolean(const std::string& key, bool value) {
102 SetValue(key, base::Value(value));
105 bool PrefValueMap::GetString(const std::string& key, std::string* value) const {
106 const base::Value* stored_value = nullptr;
107 if (GetValue(key, &stored_value) && stored_value->is_string()) {
108 *value = stored_value->GetString();
114 void PrefValueMap::SetString(const std::string& key, const std::string& value) {
115 SetValue(key, base::Value(value));
118 bool PrefValueMap::GetInteger(const std::string& key, int* value) const {
119 const base::Value* stored_value = nullptr;
120 if (GetValue(key, &stored_value) && stored_value->is_int()) {
121 *value = stored_value->GetInt();
127 void PrefValueMap::SetInteger(const std::string& key, const int value) {
128 SetValue(key, base::Value(value));
131 void PrefValueMap::SetDouble(const std::string& key, const double value) {
132 SetValue(key, base::Value(value));
135 void PrefValueMap::GetDifferingKeys(
136 const PrefValueMap* other,
137 std::vector<std::string>* differing_keys) const {
138 differing_keys->clear();
140 // Put everything into ordered maps.
141 std::map<std::string, const base::Value*> this_prefs;
142 std::map<std::string, const base::Value*> other_prefs;
143 for (const auto& pair : prefs_)
144 this_prefs.emplace(pair.first, &pair.second);
145 for (const auto& pair : other->prefs_)
146 other_prefs.emplace(pair.first, &pair.second);
148 // Walk over the maps in lockstep, adding everything that is different.
149 auto this_pref = this_prefs.begin();
150 auto other_pref = other_prefs.begin();
151 while (this_pref != this_prefs.end() && other_pref != other_prefs.end()) {
152 const int diff = this_pref->first.compare(other_pref->first);
154 if (*this_pref->second != *other_pref->second)
155 differing_keys->push_back(this_pref->first);
158 } else if (diff < 0) {
159 differing_keys->push_back(this_pref->first);
161 } else if (diff > 0) {
162 differing_keys->push_back(other_pref->first);
167 // Add the remaining entries.
168 for (; this_pref != this_prefs.end(); ++this_pref)
169 differing_keys->push_back(this_pref->first);
170 for (; other_pref != other_prefs.end(); ++other_pref)
171 differing_keys->push_back(other_pref->first);
174 base::Value::Dict PrefValueMap::AsDict() const {
175 base::Value::Dict dictionary;
176 for (const auto& value : prefs_)
177 dictionary.SetByDottedPath(value.first, value.second.Clone());