pref_value_map.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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 "base/prefs/pref_value_map.h"
6
7#include "base/logging.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/stl_util.h"
10#include "base/values.h"
11
12PrefValueMap::PrefValueMap() {}
13
14PrefValueMap::~PrefValueMap() {
15  Clear();
16}
17
18bool PrefValueMap::GetValue(const std::string& key,
19                            const base::Value** value) const {
20  const Map::const_iterator entry = prefs_.find(key);
21  if (entry != prefs_.end()) {
22    if (value)
23      *value = entry->second;
24    return true;
25  }
26
27  return false;
28}
29
30bool PrefValueMap::GetValue(const std::string& key, base::Value** value) {
31  const Map::const_iterator entry = prefs_.find(key);
32  if (entry != prefs_.end()) {
33    if (value)
34      *value = entry->second;
35    return true;
36  }
37
38  return false;
39}
40
41bool PrefValueMap::SetValue(const std::string& key, base::Value* value) {
42  DCHECK(value);
43  scoped_ptr<base::Value> value_ptr(value);
44  const Map::iterator entry = prefs_.find(key);
45  if (entry != prefs_.end()) {
46    if (base::Value::Equals(entry->second, value))
47      return false;
48    delete entry->second;
49    entry->second = value_ptr.release();
50  } else {
51    prefs_[key] = value_ptr.release();
52  }
53
54  return true;
55}
56
57bool PrefValueMap::RemoveValue(const std::string& key) {
58  const Map::iterator entry = prefs_.find(key);
59  if (entry != prefs_.end()) {
60    delete entry->second;
61    prefs_.erase(entry);
62    return true;
63  }
64
65  return false;
66}
67
68void PrefValueMap::Clear() {
69  STLDeleteValues(&prefs_);
70  prefs_.clear();
71}
72
73void PrefValueMap::Swap(PrefValueMap* other) {
74  prefs_.swap(other->prefs_);
75}
76
77PrefValueMap::iterator PrefValueMap::begin() {
78  return prefs_.begin();
79}
80
81PrefValueMap::iterator PrefValueMap::end() {
82  return prefs_.end();
83}
84
85PrefValueMap::const_iterator PrefValueMap::begin() const {
86  return prefs_.begin();
87}
88
89PrefValueMap::const_iterator PrefValueMap::end() const {
90  return prefs_.end();
91}
92
93bool PrefValueMap::GetBoolean(const std::string& key,
94                              bool* value) const {
95  const base::Value* stored_value = NULL;
96  return GetValue(key, &stored_value) && stored_value->GetAsBoolean(value);
97}
98
99void PrefValueMap::SetBoolean(const std::string& key, bool value) {
100  SetValue(key, new base::FundamentalValue(value));
101}
102
103bool PrefValueMap::GetString(const std::string& key,
104                             std::string* value) const {
105  const base::Value* stored_value = NULL;
106  return GetValue(key, &stored_value) && stored_value->GetAsString(value);
107}
108
109void PrefValueMap::SetString(const std::string& key,
110                             const std::string& value) {
111  SetValue(key, new base::StringValue(value));
112}
113
114bool PrefValueMap::GetInteger(const std::string& key, int* value) const {
115  const base::Value* stored_value = NULL;
116  return GetValue(key, &stored_value) && stored_value->GetAsInteger(value);
117}
118
119void PrefValueMap::SetInteger(const std::string& key, const int value) {
120  SetValue(key, new base::FundamentalValue(value));
121}
122
123void PrefValueMap::GetDifferingKeys(
124    const PrefValueMap* other,
125    std::vector<std::string>* differing_keys) const {
126  differing_keys->clear();
127
128  // Walk over the maps in lockstep, adding everything that is different.
129  Map::const_iterator this_pref(prefs_.begin());
130  Map::const_iterator other_pref(other->prefs_.begin());
131  while (this_pref != prefs_.end() && other_pref != other->prefs_.end()) {
132    const int diff = this_pref->first.compare(other_pref->first);
133    if (diff == 0) {
134      if (!this_pref->second->Equals(other_pref->second))
135        differing_keys->push_back(this_pref->first);
136      ++this_pref;
137      ++other_pref;
138    } else if (diff < 0) {
139      differing_keys->push_back(this_pref->first);
140      ++this_pref;
141    } else if (diff > 0) {
142      differing_keys->push_back(other_pref->first);
143      ++other_pref;
144    }
145  }
146
147  // Add the remaining entries.
148  for ( ; this_pref != prefs_.end(); ++this_pref)
149      differing_keys->push_back(this_pref->first);
150  for ( ; other_pref != other->prefs_.end(); ++other_pref)
151      differing_keys->push_back(other_pref->first);
152}
153