OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/common/features/base_feature_provider.h" | 5 #include "extensions/common/features/base_feature_provider.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <stack> | 9 #include <stack> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/values.h" | |
14 #include "extensions/common/extensions_client.h" | 15 #include "extensions/common/extensions_client.h" |
15 #include "extensions/common/features/complex_feature.h" | 16 #include "extensions/common/features/complex_feature.h" |
16 #include "extensions/common/features/simple_feature.h" | 17 #include "extensions/common/features/simple_feature.h" |
17 | 18 |
18 namespace extensions { | 19 namespace extensions { |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 bool IsNocompile(const base::Value& value) { | 23 bool IsNocompile(const base::Value& value) { |
23 bool nocompile = false; | 24 bool nocompile = false; |
(...skipping 21 matching lines...) Expand all Loading... | |
45 BaseFeatureProvider::BaseFeatureProvider(const base::DictionaryValue& root, | 46 BaseFeatureProvider::BaseFeatureProvider(const base::DictionaryValue& root, |
46 FeatureFactory factory) | 47 FeatureFactory factory) |
47 : factory_(factory) { | 48 : factory_(factory) { |
48 for (base::DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); | 49 for (base::DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); |
49 iter.Advance()) { | 50 iter.Advance()) { |
50 if (IsNocompile(iter.value())) { | 51 if (IsNocompile(iter.value())) { |
51 continue; | 52 continue; |
52 } | 53 } |
53 | 54 |
54 if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) { | 55 if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) { |
55 linked_ptr<SimpleFeature> feature((*factory_)()); | 56 scoped_ptr<SimpleFeature> feature((*factory_)()); |
56 | 57 |
57 std::vector<std::string> split = base::SplitString( | 58 std::vector<std::string> split = base::SplitString( |
58 iter.key(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 59 iter.key(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
59 | 60 |
60 // Push parent features on the stack, starting with the current feature. | 61 // Push parent features on the stack, starting with the current feature. |
61 // If one of the features has "noparent" set, stop pushing features on | 62 // If one of the features has "noparent" set, stop pushing features on |
62 // the stack. The features will then be parsed in order, starting with | 63 // the stack. The features will then be parsed in order, starting with |
63 // the farthest parent that is either top level or has "noparent" set. | 64 // the farthest parent that is either top level or has "noparent" set. |
64 std::stack<std::pair<std::string, const base::DictionaryValue*> > | 65 std::stack<std::pair<std::string, const base::DictionaryValue*> > |
65 parse_stack; | 66 parse_stack; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 feature.get())) { | 100 feature.get())) { |
100 parse_error = true; | 101 parse_error = true; |
101 break; | 102 break; |
102 } | 103 } |
103 parse_stack.pop(); | 104 parse_stack.pop(); |
104 } | 105 } |
105 | 106 |
106 if (parse_error) | 107 if (parse_error) |
107 continue; | 108 continue; |
108 | 109 |
109 features_[iter.key()] = feature; | 110 features_[iter.key()] = std::move(feature); |
110 } else if (iter.value().GetType() == base::Value::TYPE_LIST) { | 111 } else if (iter.value().GetType() == base::Value::TYPE_LIST) { |
111 // This is a complex feature. | 112 // This is a complex feature. |
112 const base::ListValue* list = | 113 const base::ListValue* list = |
113 static_cast<const base::ListValue*>(&iter.value()); | 114 static_cast<const base::ListValue*>(&iter.value()); |
114 CHECK_GT(list->GetSize(), 0UL); | 115 CHECK_GT(list->GetSize(), 0UL); |
115 | 116 |
116 scoped_ptr<ComplexFeature::FeatureList> features( | 117 scoped_ptr<ComplexFeature::FeatureList> features( |
117 new ComplexFeature::FeatureList()); | 118 new ComplexFeature::FeatureList()); |
118 | 119 |
119 // Parse and add all SimpleFeatures from the list. | 120 // Parse and add all SimpleFeatures from the list. |
120 for (base::ListValue::const_iterator list_iter = list->begin(); | 121 for (base::ListValue::const_iterator list_iter = list->begin(); |
121 list_iter != list->end(); ++list_iter) { | 122 list_iter != list->end(); ++list_iter) { |
122 if ((*list_iter)->GetType() != base::Value::TYPE_DICTIONARY) { | 123 if ((*list_iter)->GetType() != base::Value::TYPE_DICTIONARY) { |
123 LOG(ERROR) << iter.key() << ": Feature rules must be dictionaries."; | 124 LOG(ERROR) << iter.key() << ": Feature rules must be dictionaries."; |
124 continue; | 125 continue; |
125 } | 126 } |
126 | 127 |
127 scoped_ptr<SimpleFeature> feature((*factory_)()); | 128 scoped_ptr<SimpleFeature> feature((*factory_)()); |
128 if (!ParseFeature(static_cast<const base::DictionaryValue*>(*list_iter), | 129 if (!ParseFeature(static_cast<const base::DictionaryValue*>(*list_iter), |
129 iter.key(), | 130 iter.key(), |
130 feature.get())) | 131 feature.get())) |
131 continue; | 132 continue; |
132 | 133 |
133 features->push_back(std::move(feature)); | 134 features->push_back(std::move(feature)); |
134 } | 135 } |
135 | 136 |
136 linked_ptr<ComplexFeature> feature( | 137 scoped_ptr<ComplexFeature> feature( |
137 new ComplexFeature(std::move(features))); | 138 new ComplexFeature(std::move(features))); |
138 feature->set_name(iter.key()); | 139 feature->set_name(iter.key()); |
139 | 140 |
140 features_[iter.key()] = feature; | 141 features_[iter.key()] = std::move(feature); |
141 } else { | 142 } else { |
142 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or" | 143 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or" |
143 << " list of dictionaries."; | 144 << " list of dictionaries."; |
144 } | 145 } |
145 } | 146 } |
146 } | 147 } |
147 | 148 |
148 BaseFeatureProvider::~BaseFeatureProvider() { | 149 BaseFeatureProvider::~BaseFeatureProvider() { |
149 } | 150 } |
150 | 151 |
151 const std::vector<std::string>& BaseFeatureProvider::GetAllFeatureNames() | 152 const std::vector<std::string>& BaseFeatureProvider::GetAllFeatureNames() |
152 const { | 153 const { |
153 if (feature_names_.empty()) { | 154 if (feature_names_.empty()) { |
154 for (FeatureMap::const_iterator iter = features_.begin(); | 155 for (const auto& feature : features_) |
155 iter != features_.end(); ++iter) { | 156 feature_names_.push_back(feature.first); |
156 feature_names_.push_back(iter->first); | |
157 } | |
158 // A std::map is sorted by its keys, so we don't need to sort feature_names_ | 157 // A std::map is sorted by its keys, so we don't need to sort feature_names_ |
159 // now. | 158 // now. |
160 } | 159 } |
161 return feature_names_; | 160 return feature_names_; |
162 } | 161 } |
163 | 162 |
164 Feature* BaseFeatureProvider::GetFeature(const std::string& name) const { | 163 Feature* BaseFeatureProvider::GetFeature(const std::string& name) const { |
165 FeatureMap::const_iterator iter = features_.find(name); | 164 const auto iter = features_.find(name); |
166 if (iter != features_.end()) | 165 if (iter != features_.end()) |
167 return iter->second.get(); | 166 return iter->second.get(); |
168 else | 167 else |
169 return nullptr; | 168 return nullptr; |
170 } | 169 } |
171 | 170 |
172 Feature* BaseFeatureProvider::GetParent(Feature* feature) const { | 171 Feature* BaseFeatureProvider::GetParent(Feature* feature) const { |
173 CHECK(feature); | 172 CHECK(feature); |
174 if (feature->no_parent()) | 173 if (feature->no_parent()) |
175 return nullptr; | 174 return nullptr; |
176 | 175 |
177 std::vector<std::string> split = base::SplitString( | 176 std::vector<std::string> split = base::SplitString( |
178 feature->name(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 177 feature->name(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
179 if (split.size() < 2) | 178 if (split.size() < 2) |
180 return nullptr; | 179 return nullptr; |
181 split.pop_back(); | 180 split.pop_back(); |
182 return GetFeature(base::JoinString(split, ".")); | 181 return GetFeature(base::JoinString(split, ".")); |
183 } | 182 } |
184 | 183 |
185 // Children of a given API are named starting with parent.name()+".", which | 184 // Children of a given API are named starting with parent.name()+".", which |
186 // means they'll be contiguous in the features_ std::map. | 185 // means they'll be contiguous in the features_ std::map. |
187 std::vector<Feature*> BaseFeatureProvider::GetChildren(const Feature& parent) | 186 std::vector<Feature*> BaseFeatureProvider::GetChildren(const Feature& parent) |
188 const { | 187 const { |
189 std::string prefix = parent.name() + "."; | 188 std::string prefix = parent.name() + "."; |
190 const FeatureMap::const_iterator first_child = features_.lower_bound(prefix); | 189 const auto first_child = features_.lower_bound(prefix); |
Devlin
2016/03/07 15:49:43
This conversion to auto is potentially harmful, be
| |
191 | 190 |
192 // All children have names before (parent.name() + ('.'+1)). | 191 // All children have names before (parent.name() + ('.'+1)). |
193 ++prefix[prefix.size() - 1]; | 192 ++prefix[prefix.size() - 1]; |
194 const FeatureMap::const_iterator after_children = | 193 const auto after_children = features_.lower_bound(prefix); |
195 features_.lower_bound(prefix); | |
196 | 194 |
197 std::vector<Feature*> result; | 195 std::vector<Feature*> result; |
198 result.reserve(std::distance(first_child, after_children)); | 196 result.reserve(std::distance(first_child, after_children)); |
199 for (FeatureMap::const_iterator it = first_child; it != after_children; | 197 for (auto it = first_child; it != after_children; ++it) { |
200 ++it) { | |
201 result.push_back(it->second.get()); | 198 result.push_back(it->second.get()); |
202 } | 199 } |
203 return result; | 200 return result; |
204 } | 201 } |
205 | 202 |
206 } // namespace extensions | 203 } // namespace extensions |
OLD | NEW |