[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
brettw | f00b9b4 | 2016-02-01 22:11:38 | [diff] [blame] | 5 | #include "components/prefs/pref_value_map.h" |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 6 | |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 7 | #include <map> |
dcheng | 5f043bc | 2016-04-22 19:09:06 | [diff] [blame] | 8 | #include <memory> |
danakj | 0c8d4aa | 2015-11-25 05:29:58 | [diff] [blame] | 9 | #include <utility> |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 10 | |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 11 | #include "base/logging.h" |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 12 | #include "base/values.h" |
| 13 | |
[email protected] | e4be2dd | 2010-12-14 00:44:39 | [diff] [blame] | 14 | PrefValueMap::PrefValueMap() {} |
| 15 | |
estade | 0bd407f | 2015-06-26 18:16:18 | [diff] [blame] | 16 | PrefValueMap::~PrefValueMap() {} |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 17 | |
[email protected] | a43a667b | 2013-06-14 17:56:08 | [diff] [blame] | 18 | bool PrefValueMap::GetValue(const std::string& key, |
| 19 | const base::Value** value) const { |
avi | ad545a8 | 2017-01-04 20:09:29 | [diff] [blame] | 20 | auto it = prefs_.find(key); |
| 21 | if (it == prefs_.end()) |
| 22 | return false; |
| 23 | |
| 24 | const base::Value* got_value = it->second.get(); |
estade | 0bd407f | 2015-06-26 18:16:18 | [diff] [blame] | 25 | if (value && got_value) |
| 26 | *value = got_value; |
[email protected] | 68bf41a | 2011-03-25 16:38:31 | [diff] [blame] | 27 | |
estade | 0bd407f | 2015-06-26 18:16:18 | [diff] [blame] | 28 | return !!got_value; |
[email protected] | 68bf41a | 2011-03-25 16:38:31 | [diff] [blame] | 29 | } |
| 30 | |
[email protected] | a43a667b | 2013-06-14 17:56:08 | [diff] [blame] | 31 | bool PrefValueMap::GetValue(const std::string& key, base::Value** value) { |
avi | ad545a8 | 2017-01-04 20:09:29 | [diff] [blame] | 32 | auto it = prefs_.find(key); |
| 33 | if (it == prefs_.end()) |
| 34 | return false; |
| 35 | |
| 36 | base::Value* got_value = it->second.get(); |
estade | 0bd407f | 2015-06-26 18:16:18 | [diff] [blame] | 37 | if (value && got_value) |
| 38 | *value = got_value; |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 39 | |
estade | 0bd407f | 2015-06-26 18:16:18 | [diff] [blame] | 40 | return !!got_value; |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 41 | } |
| 42 | |
estade | 0bd407f | 2015-06-26 18:16:18 | [diff] [blame] | 43 | bool PrefValueMap::SetValue(const std::string& key, |
dcheng | 5f043bc | 2016-04-22 19:09:06 | [diff] [blame] | 44 | std::unique_ptr<base::Value> value) { |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 45 | DCHECK(value); |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 46 | |
avi | ad545a8 | 2017-01-04 20:09:29 | [diff] [blame] | 47 | std::unique_ptr<base::Value>& existing_value = prefs_[key]; |
| 48 | if (existing_value && value->Equals(existing_value.get())) |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 49 | return false; |
| 50 | |
avi | ad545a8 | 2017-01-04 20:09:29 | [diff] [blame] | 51 | existing_value = std::move(value); |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 52 | return true; |
| 53 | } |
| 54 | |
| 55 | bool PrefValueMap::RemoveValue(const std::string& key) { |
estade | 0bd407f | 2015-06-26 18:16:18 | [diff] [blame] | 56 | return prefs_.erase(key) != 0; |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | void PrefValueMap::Clear() { |
estade | 0bd407f | 2015-06-26 18:16:18 | [diff] [blame] | 60 | prefs_.clear(); |
[email protected] | f2d1f61 | 2010-12-09 15:10:17 | [diff] [blame] | 61 | } |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 62 | |
[email protected] | 617b8379 | 2011-12-21 17:53:18 | [diff] [blame] | 63 | void PrefValueMap::Swap(PrefValueMap* other) { |
| 64 | prefs_.swap(other->prefs_); |
| 65 | } |
| 66 | |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 67 | PrefValueMap::iterator PrefValueMap::begin() { |
| 68 | return prefs_.begin(); |
| 69 | } |
| 70 | |
| 71 | PrefValueMap::iterator PrefValueMap::end() { |
| 72 | return prefs_.end(); |
| 73 | } |
| 74 | |
| 75 | PrefValueMap::const_iterator PrefValueMap::begin() const { |
| 76 | return prefs_.begin(); |
| 77 | } |
| 78 | |
| 79 | PrefValueMap::const_iterator PrefValueMap::end() const { |
| 80 | return prefs_.end(); |
| 81 | } |
| 82 | |
thestig | e7615d6c | 2016-07-19 19:43:46 | [diff] [blame] | 83 | bool PrefValueMap::empty() const { |
| 84 | return prefs_.empty(); |
| 85 | } |
| 86 | |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 87 | bool PrefValueMap::GetBoolean(const std::string& key, |
| 88 | bool* value) const { |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 89 | const base::Value* stored_value = nullptr; |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 90 | return GetValue(key, &stored_value) && stored_value->GetAsBoolean(value); |
| 91 | } |
| 92 | |
[email protected] | 233bb3ec | 2011-12-02 16:15:49 | [diff] [blame] | 93 | void PrefValueMap::SetBoolean(const std::string& key, bool value) { |
Jinho Bang | 84b58bd | 2018-01-01 21:44:48 | [diff] [blame] | 94 | SetValue(key, std::make_unique<base::Value>(value)); |
[email protected] | 233bb3ec | 2011-12-02 16:15:49 | [diff] [blame] | 95 | } |
| 96 | |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 97 | bool PrefValueMap::GetString(const std::string& key, |
| 98 | std::string* value) const { |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 99 | const base::Value* stored_value = nullptr; |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 100 | return GetValue(key, &stored_value) && stored_value->GetAsString(value); |
| 101 | } |
| 102 | |
| 103 | void PrefValueMap::SetString(const std::string& key, |
| 104 | const std::string& value) { |
Jinho Bang | 84b58bd | 2018-01-01 21:44:48 | [diff] [blame] | 105 | SetValue(key, std::make_unique<base::Value>(value)); |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 106 | } |
| 107 | |
[email protected] | 4e94ab3 | 2011-08-05 05:28:27 | [diff] [blame] | 108 | bool PrefValueMap::GetInteger(const std::string& key, int* value) const { |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 109 | const base::Value* stored_value = nullptr; |
[email protected] | 4e94ab3 | 2011-08-05 05:28:27 | [diff] [blame] | 110 | return GetValue(key, &stored_value) && stored_value->GetAsInteger(value); |
| 111 | } |
| 112 | |
| 113 | void PrefValueMap::SetInteger(const std::string& key, const int value) { |
Jinho Bang | 84b58bd | 2018-01-01 21:44:48 | [diff] [blame] | 114 | SetValue(key, std::make_unique<base::Value>(value)); |
[email protected] | 4e94ab3 | 2011-08-05 05:28:27 | [diff] [blame] | 115 | } |
| 116 | |
[email protected] | e7518a1 | 2014-07-19 04:40:29 | [diff] [blame] | 117 | void PrefValueMap::SetDouble(const std::string& key, const double value) { |
Jinho Bang | 84b58bd | 2018-01-01 21:44:48 | [diff] [blame] | 118 | SetValue(key, std::make_unique<base::Value>(value)); |
[email protected] | e7518a1 | 2014-07-19 04:40:29 | [diff] [blame] | 119 | } |
| 120 | |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 121 | void PrefValueMap::GetDifferingKeys( |
| 122 | const PrefValueMap* other, |
| 123 | std::vector<std::string>* differing_keys) const { |
| 124 | differing_keys->clear(); |
| 125 | |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 126 | // Put everything into ordered maps. |
avi | ad545a8 | 2017-01-04 20:09:29 | [diff] [blame] | 127 | std::map<std::string, base::Value*> this_prefs; |
| 128 | std::map<std::string, base::Value*> other_prefs; |
| 129 | for (const auto& pair : prefs_) |
| 130 | this_prefs[pair.first] = pair.second.get(); |
| 131 | for (const auto& pair : other->prefs_) |
| 132 | other_prefs[pair.first] = pair.second.get(); |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 133 | |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 134 | // Walk over the maps in lockstep, adding everything that is different. |
avi | ad545a8 | 2017-01-04 20:09:29 | [diff] [blame] | 135 | auto this_pref = this_prefs.begin(); |
| 136 | auto other_pref = other_prefs.begin(); |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 137 | while (this_pref != this_prefs.end() && other_pref != other_prefs.end()) { |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 138 | const int diff = this_pref->first.compare(other_pref->first); |
| 139 | if (diff == 0) { |
| 140 | if (!this_pref->second->Equals(other_pref->second)) |
| 141 | differing_keys->push_back(this_pref->first); |
| 142 | ++this_pref; |
| 143 | ++other_pref; |
| 144 | } else if (diff < 0) { |
| 145 | differing_keys->push_back(this_pref->first); |
| 146 | ++this_pref; |
| 147 | } else if (diff > 0) { |
| 148 | differing_keys->push_back(other_pref->first); |
| 149 | ++other_pref; |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | // Add the remaining entries. |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 154 | for ( ; this_pref != this_prefs.end(); ++this_pref) |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 155 | differing_keys->push_back(this_pref->first); |
bauerb | 67b11bd | 2015-04-23 14:53:05 | [diff] [blame] | 156 | for ( ; other_pref != other_prefs.end(); ++other_pref) |
[email protected] | f00768e | 2010-12-23 12:39:01 | [diff] [blame] | 157 | differing_keys->push_back(other_pref->first); |
| 158 | } |
tibell | e23659b4 | 2017-02-23 01:44:13 | [diff] [blame] | 159 | |
| 160 | std::unique_ptr<base::DictionaryValue> PrefValueMap::AsDictionaryValue() const { |
Jinho Bang | 84b58bd | 2018-01-01 21:44:48 | [diff] [blame] | 161 | auto dictionary = std::make_unique<base::DictionaryValue>(); |
tibell | e23659b4 | 2017-02-23 01:44:13 | [diff] [blame] | 162 | for (const auto& value : prefs_) { |
| 163 | dictionary->Set(value.first, value.second->CreateDeepCopy()); |
| 164 | } |
| 165 | return dictionary; |
| 166 | } |