• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "components/prefs/pref_value_map.h"
6 
7 #include <limits.h>
8 #include <map>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 
13 #include "base/strings/string_piece.h"
14 #include "base/values.h"
15 
PrefValueMap()16 PrefValueMap::PrefValueMap() {}
17 
~PrefValueMap()18 PrefValueMap::~PrefValueMap() {}
19 
GetValue(base::StringPiece key,const base::Value ** value) const20 bool PrefValueMap::GetValue(base::StringPiece key,
21                             const base::Value** value) const {
22   auto it = prefs_.find(key);
23   if (it == prefs_.end())
24     return false;
25 
26   if (value)
27     *value = &it->second;
28 
29   return true;
30 }
31 
GetValue(base::StringPiece key,base::Value ** value)32 bool PrefValueMap::GetValue(base::StringPiece key, base::Value** value) {
33   auto it = prefs_.find(key);
34   if (it == prefs_.end())
35     return false;
36 
37   if (value)
38     *value = &it->second;
39 
40   return true;
41 }
42 
SetValue(const std::string & key,base::Value value)43 bool PrefValueMap::SetValue(const std::string& key, base::Value value) {
44   base::Value& existing_value = prefs_[key];
45   if (value == existing_value)
46     return false;
47 
48   existing_value = std::move(value);
49   return true;
50 }
51 
RemoveValue(const std::string & key)52 bool PrefValueMap::RemoveValue(const std::string& key) {
53   return prefs_.erase(key) != 0;
54 }
55 
Clear()56 void PrefValueMap::Clear() {
57   prefs_.clear();
58 }
59 
ClearWithPrefix(const std::string & prefix)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);
66 }
67 
Swap(PrefValueMap * other)68 void PrefValueMap::Swap(PrefValueMap* other) {
69   prefs_.swap(other->prefs_);
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 
empty() const88 bool PrefValueMap::empty() const {
89   return prefs_.empty();
90 }
91 
GetBoolean(const std::string & key,bool * value) const92 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();
96     return true;
97   }
98   return false;
99 }
100 
SetBoolean(const std::string & key,bool value)101 void PrefValueMap::SetBoolean(const std::string& key, bool value) {
102   SetValue(key, base::Value(value));
103 }
104 
GetString(const std::string & key,std::string * value) const105 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();
109     return true;
110   }
111   return false;
112 }
113 
SetString(const std::string & key,const std::string & value)114 void PrefValueMap::SetString(const std::string& key, const std::string& value) {
115   SetValue(key, base::Value(value));
116 }
117 
GetInteger(const std::string & key,int * value) const118 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();
122     return true;
123   }
124   return false;
125 }
126 
SetInteger(const std::string & key,const int value)127 void PrefValueMap::SetInteger(const std::string& key, const int value) {
128   SetValue(key, base::Value(value));
129 }
130 
SetDouble(const std::string & key,const double value)131 void PrefValueMap::SetDouble(const std::string& key, const double value) {
132   SetValue(key, base::Value(value));
133 }
134 
GetDifferingKeys(const PrefValueMap * other,std::vector<std::string> * differing_keys) const135 void PrefValueMap::GetDifferingKeys(
136     const PrefValueMap* other,
137     std::vector<std::string>* differing_keys) const {
138   differing_keys->clear();
139 
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);
147 
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);
153     if (diff == 0) {
154       if (*this_pref->second != *other_pref->second)
155         differing_keys->push_back(this_pref->first);
156       ++this_pref;
157       ++other_pref;
158     } else if (diff < 0) {
159       differing_keys->push_back(this_pref->first);
160       ++this_pref;
161     } else if (diff > 0) {
162       differing_keys->push_back(other_pref->first);
163       ++other_pref;
164     }
165   }
166 
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);
172 }
173 
AsDict() const174 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());
178 
179   return dictionary;
180 }
181