OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "chrome/browser/policy/policy_map.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/callback.h" | |
10 #include "base/stl_util.h" | |
11 | |
12 namespace policy { | |
13 | |
14 bool PolicyMap::Entry::has_higher_priority_than( | |
15 const PolicyMap::Entry& other) const { | |
16 if (level == other.level) | |
17 return scope > other.scope; | |
18 else | |
19 return level > other.level; | |
20 } | |
21 | |
22 bool PolicyMap::Entry::Equals(const PolicyMap::Entry& other) const { | |
23 return level == other.level && | |
24 scope == other.scope && | |
25 Value::Equals(value, other.value) && | |
26 ExternalDataFetcher::Equals(external_data_fetcher, | |
27 other.external_data_fetcher); | |
28 } | |
29 | |
30 PolicyMap::PolicyMap() { | |
31 } | |
32 | |
33 PolicyMap::~PolicyMap() { | |
34 Clear(); | |
35 } | |
36 | |
37 const PolicyMap::Entry* PolicyMap::Get(const std::string& policy) const { | |
38 PolicyMapType::const_iterator entry = map_.find(policy); | |
39 return entry == map_.end() ? NULL : &entry->second; | |
40 } | |
41 | |
42 const Value* PolicyMap::GetValue(const std::string& policy) const { | |
43 PolicyMapType::const_iterator entry = map_.find(policy); | |
44 return entry == map_.end() ? NULL : entry->second.value; | |
45 } | |
46 | |
47 void PolicyMap::Set(const std::string& policy, | |
48 PolicyLevel level, | |
49 PolicyScope scope, | |
50 Value* value, | |
51 ExternalDataFetcher* external_data_fetcher) { | |
52 Entry& entry = map_[policy]; | |
53 delete entry.value; | |
54 delete entry.external_data_fetcher; | |
55 entry.level = level; | |
56 entry.scope = scope; | |
57 entry.value = value; | |
58 entry.external_data_fetcher = external_data_fetcher; | |
59 } | |
60 | |
61 void PolicyMap::Erase(const std::string& policy) { | |
62 PolicyMapType::iterator it = map_.find(policy); | |
63 if (it != map_.end()) { | |
64 delete it->second.value; | |
65 delete it->second.external_data_fetcher; | |
66 map_.erase(it); | |
67 } | |
68 } | |
69 | |
70 void PolicyMap::Swap(PolicyMap* other) { | |
71 map_.swap(other->map_); | |
72 } | |
73 | |
74 void PolicyMap::CopyFrom(const PolicyMap& other) { | |
75 Clear(); | |
76 for (const_iterator it = other.begin(); it != other.end(); ++it) { | |
77 const Entry& entry = it->second; | |
78 Set(it->first, entry.level, entry.scope, | |
79 entry.value->DeepCopy(), entry.external_data_fetcher ? | |
80 new ExternalDataFetcher(*entry.external_data_fetcher) : NULL); | |
81 } | |
82 } | |
83 | |
84 scoped_ptr<PolicyMap> PolicyMap::DeepCopy() const { | |
85 PolicyMap* copy = new PolicyMap(); | |
86 copy->CopyFrom(*this); | |
87 return make_scoped_ptr(copy); | |
88 } | |
89 | |
90 void PolicyMap::MergeFrom(const PolicyMap& other) { | |
91 for (const_iterator it = other.begin(); it != other.end(); ++it) { | |
92 const Entry* entry = Get(it->first); | |
93 if (!entry || it->second.has_higher_priority_than(*entry)) { | |
94 Set(it->first, it->second.level, it->second.scope, | |
95 it->second.value->DeepCopy(), it->second.external_data_fetcher ? | |
96 new ExternalDataFetcher(*it->second.external_data_fetcher) : | |
97 NULL); | |
98 } | |
99 } | |
100 } | |
101 | |
102 void PolicyMap::LoadFrom( | |
103 const DictionaryValue* policies, | |
104 PolicyLevel level, | |
105 PolicyScope scope) { | |
106 for (DictionaryValue::Iterator it(*policies); !it.IsAtEnd(); it.Advance()) | |
107 Set(it.key(), level, scope, it.value().DeepCopy(), NULL); | |
108 } | |
109 | |
110 void PolicyMap::GetDifferingKeys(const PolicyMap& other, | |
111 std::set<std::string>* differing_keys) const { | |
112 // Walk over the maps in lockstep, adding everything that is different. | |
113 const_iterator iter_this(begin()); | |
114 const_iterator iter_other(other.begin()); | |
115 while (iter_this != end() && iter_other != other.end()) { | |
116 const int diff = iter_this->first.compare(iter_other->first); | |
117 if (diff == 0) { | |
118 if (!iter_this->second.Equals(iter_other->second)) | |
119 differing_keys->insert(iter_this->first); | |
120 ++iter_this; | |
121 ++iter_other; | |
122 } else if (diff < 0) { | |
123 differing_keys->insert(iter_this->first); | |
124 ++iter_this; | |
125 } else { | |
126 differing_keys->insert(iter_other->first); | |
127 ++iter_other; | |
128 } | |
129 } | |
130 | |
131 // Add the remaining entries. | |
132 for ( ; iter_this != end(); ++iter_this) | |
133 differing_keys->insert(iter_this->first); | |
134 for ( ; iter_other != other.end(); ++iter_other) | |
135 differing_keys->insert(iter_other->first); | |
136 } | |
137 | |
138 void PolicyMap::FilterLevel(PolicyLevel level) { | |
139 PolicyMapType::iterator iter(map_.begin()); | |
140 while (iter != map_.end()) { | |
141 if (iter->second.level != level) { | |
142 delete iter->second.value; | |
143 delete iter->second.external_data_fetcher; | |
144 map_.erase(iter++); | |
145 } else { | |
146 ++iter; | |
147 } | |
148 } | |
149 } | |
150 | |
151 bool PolicyMap::Equals(const PolicyMap& other) const { | |
152 return other.size() == size() && | |
153 std::equal(begin(), end(), other.begin(), MapEntryEquals); | |
154 } | |
155 | |
156 bool PolicyMap::empty() const { | |
157 return map_.empty(); | |
158 } | |
159 | |
160 size_t PolicyMap::size() const { | |
161 return map_.size(); | |
162 } | |
163 | |
164 PolicyMap::const_iterator PolicyMap::begin() const { | |
165 return map_.begin(); | |
166 } | |
167 | |
168 PolicyMap::const_iterator PolicyMap::end() const { | |
169 return map_.end(); | |
170 } | |
171 | |
172 void PolicyMap::Clear() { | |
173 for (PolicyMapType::iterator it = map_.begin(); it != map_.end(); ++it) { | |
174 delete it->second.value; | |
175 delete it->second.external_data_fetcher; | |
176 } | |
177 map_.clear(); | |
178 } | |
179 | |
180 // static | |
181 bool PolicyMap::MapEntryEquals(const PolicyMap::PolicyMapType::value_type& a, | |
182 const PolicyMap::PolicyMapType::value_type& b) { | |
183 return a.first == b.first && a.second.Equals(b.second); | |
184 } | |
185 | |
186 } // namespace policy | |
OLD | NEW |