Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(619)

Side by Side Diff: third_party/libaddressinput/chromium/cpp/src/country_rules_retriever.cc

Issue 109323011: [rac] Download all rules for a country code in libaddressinput. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix mac build. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (C) 2014 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "country_rules_retriever.h"
16
17 #include <libaddressinput/address_field.h>
18 #include <libaddressinput/callback.h>
19 #include <libaddressinput/util/basictypes.h>
20 #include <libaddressinput/util/scoped_ptr.h>
21
22 #include <cassert>
23 #include <cstddef>
24 #include <map>
25 #include <string>
26 #include <utility>
27
28 #include "retriever.h"
29 #include "rule.h"
30 #include "ruleset.h"
31 #include "util/stl_util.h"
32
33 namespace i18n {
34 namespace addressinput {
35
36 // Information about data requests sent to Retriever. This data is not returned
37 // as part of the ruleset, but is useful in constructing the ruleset
38 // asynchronously.
39 struct CountryRulesRetriever::RequestData {
40 // Does not take ownership of |parent|.
41 RequestData(Ruleset* parent,
42 AddressField level,
43 bool is_language_code,
44 const std::string& id)
45 : parent(parent),
46 level(level),
47 is_language_code(is_language_code),
48 id(id) {}
49
50 ~RequestData() {}
51
52 // The parent ruleset of the data being downloaded. If NULL, then this is the
53 // root ruleset at the COUNTRY level. The language-specific and sub-region
Evan Stade 2014/01/08 21:08:59 add an assert for this in the constructor?
please use gerrit instead 2014/01/09 00:38:11 Done.
54 // rules are added to this ruleset. Owned by |CountryRulesRetriever|.
55 Ruleset* parent;
56
57 // The level of the data being requested. Ranges from COUNTRY to
58 // DEPENDENT_LOCALITY. If COUNTRY, then the rule should use default rules from
59 // Rule::GetDefault().
60 AddressField level;
61
62 // If true, then |id| is a language. The data received for this request should
63 // be placed into a language-specific rule.
64 bool is_language_code;
65
66 // Can be a region name (e.g. "CA") or a language (e.g. "fr"). Used to add a
67 // sub-region or a language-specific rule to |parent|.
68 std::string id;
69 };
70
71 CountryRulesRetriever::CountryRulesRetriever(scoped_ptr<Retriever> retriever)
72 : retriever_(retriever.Pass()),
73 requests_(),
74 country_code_(),
75 rules_ready_(),
76 root_(),
77 success_(true),
78 default_language_(),
79 languages_() {
80 assert(retriever_ != NULL);
81 }
82
83 CountryRulesRetriever::~CountryRulesRetriever() {}
84
85 void CountryRulesRetriever::RetrieveRules(const std::string& country_code,
86 scoped_ptr<Callback> rules_ready) {
87 Reset();
88 country_code_ = country_code;
89 rules_ready_.reset(rules_ready.release());
90
91 // Key construction:
92 // https://code.google.com/p/libaddressinput/wiki/AddressValidationMetadata
93 // Example of a country-level key: "data/CA".
94 std::string key = "data/" + country_code_;
95 requests_.insert(std::make_pair(
96 key, RequestData(NULL, COUNTRY, false, std::string())));
97
98 retriever_->Retrieve(
99 key, BuildCallback(this, &CountryRulesRetriever::OnDataReady));
100 }
101
102 void CountryRulesRetriever::OnDataReady(bool success,
103 const std::string& key,
104 const std::string& data) {
105 std::map<std::string, RequestData>::iterator request_it =
106 requests_.find(key);
107 if (request_it == requests_.end()) {
108 return; // An abandoned request.
109 }
110
111 RequestData request = request_it->second;
112 requests_.erase(request_it);
113
114 success_ &= success;
115 if (!success_) {
116 (*rules_ready_)(success_, country_code_, root_.Pass());
Evan Stade 2014/01/08 21:08:59 why do you pass back partial data?
please use gerrit instead 2014/01/09 00:38:11 Removed.
117 Reset();
118 return;
119 }
120
121 // All country-level rules are based on the default rule.
122 scoped_ptr<Rule> rule(new Rule);
123 if (request.level == COUNTRY) {
124 rule->CopyFrom(Rule::GetDefault());
125 }
126
127 success_ &= rule->ParseSerializedRule(data);
Evan Stade 2014/01/08 21:08:59 I don't get why you do both this and CopyFrom abov
please use gerrit instead 2014/01/09 00:38:11 If a country-level rule is missing some informatio
128 if (!success_) {
129 (*rules_ready_)(success_, country_code_, root_.Pass());
130 Reset();
131 return;
132 }
133
134 // Place the rule in the correct location in the ruleset.
135 Ruleset* ruleset = NULL;
136 if (request.is_language_code) {
137 assert(request.parent != NULL);
138 request.parent->AddLanguageCode(request.id, rule.Pass());
139 ruleset = request.parent;
140 } else if (request.level == COUNTRY) {
141 // The default language and all supported languages for the country code are
142 // in the country-level rule without a language code identifier. For
143 // example: "data/CA".
144 default_language_ = rule->GetLanguage();
145 languages_ = rule->GetLanguages();
146
147 root_.reset(new Ruleset(rule.Pass()));
148 ruleset = root_.get();
149 } else {
150 assert(request.parent != NULL);
151 ruleset = request.parent->AddSubRegion(request.id, rule.Pass());
152 }
153
154 if (!request.is_language_code) {
155 // Retrieve the language-specific rules for this region.
156 for (std::vector<std::string>::const_iterator
157 lang_it = languages_.begin();
Evan Stade 2014/01/08 21:08:59 4 more indent
please use gerrit instead 2014/01/09 00:38:11 Done.
158 lang_it != languages_.end();
159 ++lang_it) {
160 if (*lang_it == default_language_) {
161 continue;
162 }
163 // Example of a language-specific key: "data/CA--fr".
164 std::string language_code_key = key + "--" + *lang_it;
165 requests_.insert(std::make_pair(
166 key, RequestData(ruleset, request.level, true, *lang_it)));
167 retriever_->Retrieve(
168 language_code_key,
169 BuildCallback(this, &CountryRulesRetriever::OnDataReady));
170 }
171
172 if (request.level < DEPENDENT_LOCALITY) {
173 // Retrieve the sub-region rules for this region.
174 for (std::vector<std::string>::const_iterator
175 subkey_it = ruleset->rule().GetSubKeys().begin();
176 subkey_it != ruleset->rule().GetSubKeys().end();
177 ++subkey_it) {
178 // Example of a sub-region key: "data/CA/AB".
179 std::string sub_region_key = key + "/" + *subkey_it;
180 requests_.insert(std::make_pair(
181 key,
182 RequestData(ruleset,
183 static_cast<AddressField>(request.level + 1),
184 false,
185 *subkey_it)));
186 retriever_->Retrieve(
187 sub_region_key,
188 BuildCallback(this, &CountryRulesRetriever::OnDataReady));
189 }
190 }
191 }
192
193 if (requests_.empty()) {
194 (*rules_ready_)(success_, country_code_, root_.Pass());
195 Reset();
196 }
197 }
198
199 void CountryRulesRetriever::Reset() {
200 requests_.clear();
201 country_code_.clear();
202 rules_ready_.reset();
203 root_.reset();
204 success_ = true;
205 default_language_.clear();
206 languages_.clear();
207 }
208
209 } // namespace addressinput
210 } // namespace i18n
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698