xref: /aosp_15_r20/external/cronet/components/prefs/pref_value_map.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "components/prefs/pref_value_map.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <limits.h>
8*6777b538SAndroid Build Coastguard Worker #include <map>
9*6777b538SAndroid Build Coastguard Worker #include <memory>
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker #include <utility>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
15*6777b538SAndroid Build Coastguard Worker 
PrefValueMap()16*6777b538SAndroid Build Coastguard Worker PrefValueMap::PrefValueMap() {}
17*6777b538SAndroid Build Coastguard Worker 
~PrefValueMap()18*6777b538SAndroid Build Coastguard Worker PrefValueMap::~PrefValueMap() {}
19*6777b538SAndroid Build Coastguard Worker 
GetValue(base::StringPiece key,const base::Value ** value) const20*6777b538SAndroid Build Coastguard Worker bool PrefValueMap::GetValue(base::StringPiece key,
21*6777b538SAndroid Build Coastguard Worker                             const base::Value** value) const {
22*6777b538SAndroid Build Coastguard Worker   auto it = prefs_.find(key);
23*6777b538SAndroid Build Coastguard Worker   if (it == prefs_.end())
24*6777b538SAndroid Build Coastguard Worker     return false;
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker   if (value)
27*6777b538SAndroid Build Coastguard Worker     *value = &it->second;
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker   return true;
30*6777b538SAndroid Build Coastguard Worker }
31*6777b538SAndroid Build Coastguard Worker 
GetValue(base::StringPiece key,base::Value ** value)32*6777b538SAndroid Build Coastguard Worker bool PrefValueMap::GetValue(base::StringPiece key, base::Value** value) {
33*6777b538SAndroid Build Coastguard Worker   auto it = prefs_.find(key);
34*6777b538SAndroid Build Coastguard Worker   if (it == prefs_.end())
35*6777b538SAndroid Build Coastguard Worker     return false;
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker   if (value)
38*6777b538SAndroid Build Coastguard Worker     *value = &it->second;
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker   return true;
41*6777b538SAndroid Build Coastguard Worker }
42*6777b538SAndroid Build Coastguard Worker 
SetValue(const std::string & key,base::Value value)43*6777b538SAndroid Build Coastguard Worker bool PrefValueMap::SetValue(const std::string& key, base::Value value) {
44*6777b538SAndroid Build Coastguard Worker   base::Value& existing_value = prefs_[key];
45*6777b538SAndroid Build Coastguard Worker   if (value == existing_value)
46*6777b538SAndroid Build Coastguard Worker     return false;
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   existing_value = std::move(value);
49*6777b538SAndroid Build Coastguard Worker   return true;
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker 
RemoveValue(const std::string & key)52*6777b538SAndroid Build Coastguard Worker bool PrefValueMap::RemoveValue(const std::string& key) {
53*6777b538SAndroid Build Coastguard Worker   return prefs_.erase(key) != 0;
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker 
Clear()56*6777b538SAndroid Build Coastguard Worker void PrefValueMap::Clear() {
57*6777b538SAndroid Build Coastguard Worker   prefs_.clear();
58*6777b538SAndroid Build Coastguard Worker }
59*6777b538SAndroid Build Coastguard Worker 
ClearWithPrefix(const std::string & prefix)60*6777b538SAndroid Build Coastguard Worker void PrefValueMap::ClearWithPrefix(const std::string& prefix) {
61*6777b538SAndroid Build Coastguard Worker   Map::iterator low = prefs_.lower_bound(prefix);
62*6777b538SAndroid Build Coastguard Worker   // Appending maximum possible character so that there will be no string with
63*6777b538SAndroid Build Coastguard Worker   // prefix |prefix| that we may miss.
64*6777b538SAndroid Build Coastguard Worker   Map::iterator high = prefs_.upper_bound(prefix + char(CHAR_MAX));
65*6777b538SAndroid Build Coastguard Worker   prefs_.erase(low, high);
66*6777b538SAndroid Build Coastguard Worker }
67*6777b538SAndroid Build Coastguard Worker 
Swap(PrefValueMap * other)68*6777b538SAndroid Build Coastguard Worker void PrefValueMap::Swap(PrefValueMap* other) {
69*6777b538SAndroid Build Coastguard Worker   prefs_.swap(other->prefs_);
70*6777b538SAndroid Build Coastguard Worker }
71*6777b538SAndroid Build Coastguard Worker 
begin()72*6777b538SAndroid Build Coastguard Worker PrefValueMap::iterator PrefValueMap::begin() {
73*6777b538SAndroid Build Coastguard Worker   return prefs_.begin();
74*6777b538SAndroid Build Coastguard Worker }
75*6777b538SAndroid Build Coastguard Worker 
end()76*6777b538SAndroid Build Coastguard Worker PrefValueMap::iterator PrefValueMap::end() {
77*6777b538SAndroid Build Coastguard Worker   return prefs_.end();
78*6777b538SAndroid Build Coastguard Worker }
79*6777b538SAndroid Build Coastguard Worker 
begin() const80*6777b538SAndroid Build Coastguard Worker PrefValueMap::const_iterator PrefValueMap::begin() const {
81*6777b538SAndroid Build Coastguard Worker   return prefs_.begin();
82*6777b538SAndroid Build Coastguard Worker }
83*6777b538SAndroid Build Coastguard Worker 
end() const84*6777b538SAndroid Build Coastguard Worker PrefValueMap::const_iterator PrefValueMap::end() const {
85*6777b538SAndroid Build Coastguard Worker   return prefs_.end();
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker 
empty() const88*6777b538SAndroid Build Coastguard Worker bool PrefValueMap::empty() const {
89*6777b538SAndroid Build Coastguard Worker   return prefs_.empty();
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker 
GetBoolean(const std::string & key,bool * value) const92*6777b538SAndroid Build Coastguard Worker bool PrefValueMap::GetBoolean(const std::string& key, bool* value) const {
93*6777b538SAndroid Build Coastguard Worker   const base::Value* stored_value = nullptr;
94*6777b538SAndroid Build Coastguard Worker   if (GetValue(key, &stored_value) && stored_value->is_bool()) {
95*6777b538SAndroid Build Coastguard Worker     *value = stored_value->GetBool();
96*6777b538SAndroid Build Coastguard Worker     return true;
97*6777b538SAndroid Build Coastguard Worker   }
98*6777b538SAndroid Build Coastguard Worker   return false;
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker 
SetBoolean(const std::string & key,bool value)101*6777b538SAndroid Build Coastguard Worker void PrefValueMap::SetBoolean(const std::string& key, bool value) {
102*6777b538SAndroid Build Coastguard Worker   SetValue(key, base::Value(value));
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker 
GetString(const std::string & key,std::string * value) const105*6777b538SAndroid Build Coastguard Worker bool PrefValueMap::GetString(const std::string& key, std::string* value) const {
106*6777b538SAndroid Build Coastguard Worker   const base::Value* stored_value = nullptr;
107*6777b538SAndroid Build Coastguard Worker   if (GetValue(key, &stored_value) && stored_value->is_string()) {
108*6777b538SAndroid Build Coastguard Worker     *value = stored_value->GetString();
109*6777b538SAndroid Build Coastguard Worker     return true;
110*6777b538SAndroid Build Coastguard Worker   }
111*6777b538SAndroid Build Coastguard Worker   return false;
112*6777b538SAndroid Build Coastguard Worker }
113*6777b538SAndroid Build Coastguard Worker 
SetString(const std::string & key,const std::string & value)114*6777b538SAndroid Build Coastguard Worker void PrefValueMap::SetString(const std::string& key, const std::string& value) {
115*6777b538SAndroid Build Coastguard Worker   SetValue(key, base::Value(value));
116*6777b538SAndroid Build Coastguard Worker }
117*6777b538SAndroid Build Coastguard Worker 
GetInteger(const std::string & key,int * value) const118*6777b538SAndroid Build Coastguard Worker bool PrefValueMap::GetInteger(const std::string& key, int* value) const {
119*6777b538SAndroid Build Coastguard Worker   const base::Value* stored_value = nullptr;
120*6777b538SAndroid Build Coastguard Worker   if (GetValue(key, &stored_value) && stored_value->is_int()) {
121*6777b538SAndroid Build Coastguard Worker     *value = stored_value->GetInt();
122*6777b538SAndroid Build Coastguard Worker     return true;
123*6777b538SAndroid Build Coastguard Worker   }
124*6777b538SAndroid Build Coastguard Worker   return false;
125*6777b538SAndroid Build Coastguard Worker }
126*6777b538SAndroid Build Coastguard Worker 
SetInteger(const std::string & key,const int value)127*6777b538SAndroid Build Coastguard Worker void PrefValueMap::SetInteger(const std::string& key, const int value) {
128*6777b538SAndroid Build Coastguard Worker   SetValue(key, base::Value(value));
129*6777b538SAndroid Build Coastguard Worker }
130*6777b538SAndroid Build Coastguard Worker 
SetDouble(const std::string & key,const double value)131*6777b538SAndroid Build Coastguard Worker void PrefValueMap::SetDouble(const std::string& key, const double value) {
132*6777b538SAndroid Build Coastguard Worker   SetValue(key, base::Value(value));
133*6777b538SAndroid Build Coastguard Worker }
134*6777b538SAndroid Build Coastguard Worker 
GetDifferingKeys(const PrefValueMap * other,std::vector<std::string> * differing_keys) const135*6777b538SAndroid Build Coastguard Worker void PrefValueMap::GetDifferingKeys(
136*6777b538SAndroid Build Coastguard Worker     const PrefValueMap* other,
137*6777b538SAndroid Build Coastguard Worker     std::vector<std::string>* differing_keys) const {
138*6777b538SAndroid Build Coastguard Worker   differing_keys->clear();
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker   // Put everything into ordered maps.
141*6777b538SAndroid Build Coastguard Worker   std::map<std::string, const base::Value*> this_prefs;
142*6777b538SAndroid Build Coastguard Worker   std::map<std::string, const base::Value*> other_prefs;
143*6777b538SAndroid Build Coastguard Worker   for (const auto& pair : prefs_)
144*6777b538SAndroid Build Coastguard Worker     this_prefs.emplace(pair.first, &pair.second);
145*6777b538SAndroid Build Coastguard Worker   for (const auto& pair : other->prefs_)
146*6777b538SAndroid Build Coastguard Worker     other_prefs.emplace(pair.first, &pair.second);
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker   // Walk over the maps in lockstep, adding everything that is different.
149*6777b538SAndroid Build Coastguard Worker   auto this_pref = this_prefs.begin();
150*6777b538SAndroid Build Coastguard Worker   auto other_pref = other_prefs.begin();
151*6777b538SAndroid Build Coastguard Worker   while (this_pref != this_prefs.end() && other_pref != other_prefs.end()) {
152*6777b538SAndroid Build Coastguard Worker     const int diff = this_pref->first.compare(other_pref->first);
153*6777b538SAndroid Build Coastguard Worker     if (diff == 0) {
154*6777b538SAndroid Build Coastguard Worker       if (*this_pref->second != *other_pref->second)
155*6777b538SAndroid Build Coastguard Worker         differing_keys->push_back(this_pref->first);
156*6777b538SAndroid Build Coastguard Worker       ++this_pref;
157*6777b538SAndroid Build Coastguard Worker       ++other_pref;
158*6777b538SAndroid Build Coastguard Worker     } else if (diff < 0) {
159*6777b538SAndroid Build Coastguard Worker       differing_keys->push_back(this_pref->first);
160*6777b538SAndroid Build Coastguard Worker       ++this_pref;
161*6777b538SAndroid Build Coastguard Worker     } else if (diff > 0) {
162*6777b538SAndroid Build Coastguard Worker       differing_keys->push_back(other_pref->first);
163*6777b538SAndroid Build Coastguard Worker       ++other_pref;
164*6777b538SAndroid Build Coastguard Worker     }
165*6777b538SAndroid Build Coastguard Worker   }
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker   // Add the remaining entries.
168*6777b538SAndroid Build Coastguard Worker   for (; this_pref != this_prefs.end(); ++this_pref)
169*6777b538SAndroid Build Coastguard Worker     differing_keys->push_back(this_pref->first);
170*6777b538SAndroid Build Coastguard Worker   for (; other_pref != other_prefs.end(); ++other_pref)
171*6777b538SAndroid Build Coastguard Worker     differing_keys->push_back(other_pref->first);
172*6777b538SAndroid Build Coastguard Worker }
173*6777b538SAndroid Build Coastguard Worker 
AsDict() const174*6777b538SAndroid Build Coastguard Worker base::Value::Dict PrefValueMap::AsDict() const {
175*6777b538SAndroid Build Coastguard Worker   base::Value::Dict dictionary;
176*6777b538SAndroid Build Coastguard Worker   for (const auto& value : prefs_)
177*6777b538SAndroid Build Coastguard Worker     dictionary.SetByDottedPath(value.first, value.second.Clone());
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker   return dictionary;
180*6777b538SAndroid Build Coastguard Worker }
181