1 // Copyright 2013 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.
5 #include "components/policy/core/common/policy_bundle.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
12 PolicyBundle::PolicyBundle() {}
14 PolicyBundle::~PolicyBundle() {
18 PolicyMap
& PolicyBundle::Get(const PolicyNamespace
& ns
) {
19 DCHECK(ns
.domain
!= POLICY_DOMAIN_CHROME
|| ns
.component_id
.empty());
20 PolicyMap
*& policy
= policy_bundle_
[ns
];
22 policy
= new PolicyMap();
26 const PolicyMap
& PolicyBundle::Get(const PolicyNamespace
& ns
) const {
27 DCHECK(ns
.domain
!= POLICY_DOMAIN_CHROME
|| ns
.component_id
.empty());
28 const_iterator it
= policy_bundle_
.find(ns
);
29 return it
== end() ? kEmpty_
: *it
->second
;
32 void PolicyBundle::Swap(PolicyBundle
* other
) {
33 policy_bundle_
.swap(other
->policy_bundle_
);
36 void PolicyBundle::CopyFrom(const PolicyBundle
& other
) {
38 for (PolicyBundle::const_iterator it
= other
.begin();
39 it
!= other
.end(); ++it
) {
40 policy_bundle_
[it
->first
] = it
->second
->DeepCopy().release();
44 void PolicyBundle::MergeFrom(const PolicyBundle
& other
) {
45 // Iterate over both |this| and |other| in order; skip what's extra in |this|,
46 // add what's missing, and merge the namespaces in common.
47 MapType::iterator it_this
= policy_bundle_
.begin();
48 MapType::iterator end_this
= policy_bundle_
.end();
49 const_iterator it_other
= other
.begin();
50 const_iterator end_other
= other
.end();
52 while (it_this
!= end_this
&& it_other
!= end_other
) {
53 if (it_this
->first
== it_other
->first
) {
54 // Same namespace: merge existing PolicyMaps.
55 it_this
->second
->MergeFrom(*it_other
->second
);
58 } else if (it_this
->first
< it_other
->first
) {
59 // |this| has a PolicyMap that |other| doesn't; skip it.
61 } else if (it_other
->first
< it_this
->first
) {
62 // |other| has a PolicyMap that |this| doesn't; copy it.
63 PolicyMap
*& policy
= policy_bundle_
[it_other
->first
];
65 policy
= it_other
->second
->DeepCopy().release();
72 // Add extra PolicyMaps at the end.
73 while (it_other
!= end_other
) {
74 PolicyMap
*& policy
= policy_bundle_
[it_other
->first
];
76 policy
= it_other
->second
->DeepCopy().release();
81 bool PolicyBundle::Equals(const PolicyBundle
& other
) const {
82 // Equals() has the peculiarity that an entry with an empty PolicyMap equals
83 // an non-existant entry. This handles usage of non-const Get() that doesn't
84 // insert any policies.
85 const_iterator it_this
= begin();
86 const_iterator it_other
= other
.begin();
89 // Skip empty PolicyMaps.
90 while (it_this
!= end() && it_this
->second
->empty())
92 while (it_other
!= other
.end() && it_other
->second
->empty())
94 if (it_this
== end() || it_other
== other
.end())
96 if (it_this
->first
!= it_other
->first
||
97 !it_this
->second
->Equals(*it_other
->second
)) {
103 return it_this
== end() && it_other
== other
.end();
106 void PolicyBundle::Clear() {
107 STLDeleteValues(&policy_bundle_
);
110 } // namespace policy