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.
5 #include "chrome/browser/content_settings/content_settings_origin_identifier_value_map.h"
7 #include "base/compiler_specific.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/synchronization/lock.h"
11 #include "base/values.h"
12 #include "chrome/browser/content_settings/content_settings_rule.h"
13 #include "chrome/browser/content_settings/content_settings_utils.h"
14 #include "components/content_settings/core/common/content_settings_types.h"
17 namespace content_settings
{
21 // This iterator is used for iterating the rules for |content_type| and
22 // |resource_identifier| in the precedence order of the rules.
23 class RuleIteratorImpl
: public RuleIterator
{
25 // |RuleIteratorImpl| takes the ownership of |auto_lock|.
27 const OriginIdentifierValueMap::Rules::const_iterator
& current_rule
,
28 const OriginIdentifierValueMap::Rules::const_iterator
& rule_end
,
29 base::AutoLock
* auto_lock
)
30 : current_rule_(current_rule
),
32 auto_lock_(auto_lock
) {
34 virtual ~RuleIteratorImpl() {}
36 virtual bool HasNext() const OVERRIDE
{
37 return (current_rule_
!= rule_end_
);
40 virtual Rule
Next() OVERRIDE
{
41 DCHECK(current_rule_
!= rule_end_
);
42 DCHECK(current_rule_
->second
.get());
43 Rule
to_return(current_rule_
->first
.primary_pattern
,
44 current_rule_
->first
.secondary_pattern
,
45 current_rule_
->second
.get()->DeepCopy());
51 OriginIdentifierValueMap::Rules::const_iterator current_rule_
;
52 OriginIdentifierValueMap::Rules::const_iterator rule_end_
;
53 scoped_ptr
<base::AutoLock
> auto_lock_
;
58 OriginIdentifierValueMap::EntryMapKey::EntryMapKey(
59 ContentSettingsType content_type
,
60 const ResourceIdentifier
& resource_identifier
)
61 : content_type(content_type
),
62 resource_identifier(resource_identifier
) {
65 bool OriginIdentifierValueMap::EntryMapKey::operator<(
66 const OriginIdentifierValueMap::EntryMapKey
& other
) const {
67 if (content_type
!= other
.content_type
)
68 return content_type
< other
.content_type
;
69 return (resource_identifier
< other
.resource_identifier
);
72 OriginIdentifierValueMap::PatternPair::PatternPair(
73 const ContentSettingsPattern
& primary_pattern
,
74 const ContentSettingsPattern
& secondary_pattern
)
75 : primary_pattern(primary_pattern
),
76 secondary_pattern(secondary_pattern
) {
79 bool OriginIdentifierValueMap::PatternPair::operator<(
80 const OriginIdentifierValueMap::PatternPair
& other
) const {
81 // Note that this operator is the other way around than
82 // |ContentSettingsPattern::operator<|. It sorts patterns with higher
84 if (primary_pattern
> other
.primary_pattern
)
86 else if (other
.primary_pattern
> primary_pattern
)
88 return (secondary_pattern
> other
.secondary_pattern
);
91 RuleIterator
* OriginIdentifierValueMap::GetRuleIterator(
92 ContentSettingsType content_type
,
93 const ResourceIdentifier
& resource_identifier
,
94 base::Lock
* lock
) const {
95 EntryMapKey
key(content_type
, resource_identifier
);
96 // We access |entries_| here, so we need to lock |lock_| first. The lock must
97 // be passed to the |RuleIteratorImpl| in a locked state, so that nobody can
98 // access |entries_| after |find()| but before the |RuleIteratorImpl| is
100 scoped_ptr
<base::AutoLock
> auto_lock
;
102 auto_lock
.reset(new base::AutoLock(*lock
));
103 EntryMap::const_iterator it
= entries_
.find(key
);
104 if (it
== entries_
.end())
105 return new EmptyRuleIterator();
106 return new RuleIteratorImpl(it
->second
.begin(),
108 auto_lock
.release());
111 size_t OriginIdentifierValueMap::size() const {
113 EntryMap::const_iterator it
;
114 for (it
= entries_
.begin(); it
!= entries_
.end(); ++it
)
115 size
+= it
->second
.size();
119 OriginIdentifierValueMap::OriginIdentifierValueMap() {}
121 OriginIdentifierValueMap::~OriginIdentifierValueMap() {}
123 base::Value
* OriginIdentifierValueMap::GetValue(
124 const GURL
& primary_url
,
125 const GURL
& secondary_url
,
126 ContentSettingsType content_type
,
127 const ResourceIdentifier
& resource_identifier
) const {
128 EntryMapKey
key(content_type
, resource_identifier
);
129 EntryMap::const_iterator it
= entries_
.find(key
);
130 if (it
== entries_
.end())
133 // Iterate the entries in until a match is found. Since the rules are stored
134 // in the order of decreasing precedence, the most specific match is found
136 Rules::const_iterator entry
;
137 for (entry
= it
->second
.begin(); entry
!= it
->second
.end(); ++entry
) {
138 if (entry
->first
.primary_pattern
.Matches(primary_url
) &&
139 entry
->first
.secondary_pattern
.Matches(secondary_url
)) {
140 return entry
->second
.get();
146 void OriginIdentifierValueMap::SetValue(
147 const ContentSettingsPattern
& primary_pattern
,
148 const ContentSettingsPattern
& secondary_pattern
,
149 ContentSettingsType content_type
,
150 const ResourceIdentifier
& resource_identifier
,
151 base::Value
* value
) {
152 DCHECK(primary_pattern
.IsValid());
153 DCHECK(secondary_pattern
.IsValid());
155 EntryMapKey
key(content_type
, resource_identifier
);
156 PatternPair
patterns(primary_pattern
, secondary_pattern
);
157 // This will create the entry and the linked_ptr if needed.
158 entries_
[key
][patterns
].reset(value
);
161 void OriginIdentifierValueMap::DeleteValue(
162 const ContentSettingsPattern
& primary_pattern
,
163 const ContentSettingsPattern
& secondary_pattern
,
164 ContentSettingsType content_type
,
165 const ResourceIdentifier
& resource_identifier
) {
166 EntryMapKey
key(content_type
, resource_identifier
);
167 PatternPair
patterns(primary_pattern
, secondary_pattern
);
168 entries_
[key
].erase(patterns
);
169 if (entries_
[key
].empty()) {
174 void OriginIdentifierValueMap::DeleteValues(
175 ContentSettingsType content_type
,
176 const ResourceIdentifier
& resource_identifier
) {
177 EntryMapKey
key(content_type
, resource_identifier
);
181 void OriginIdentifierValueMap::clear() {
182 // Delete all owned value objects.
186 } // namespace content_settings