OLD | NEW |
---|---|
1 // Copyright (C) 2013 Google Inc. | 1 // Copyright (C) 2013 Google Inc. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include <libaddressinput/address_validator.h> | 15 #include <libaddressinput/address_validator.h> |
16 | 16 |
17 #include <libaddressinput/address_data.h> | |
17 #include <libaddressinput/downloader.h> | 18 #include <libaddressinput/downloader.h> |
18 #include <libaddressinput/load_rules_delegate.h> | 19 #include <libaddressinput/load_rules_delegate.h> |
19 #include <libaddressinput/localization.h> | 20 #include <libaddressinput/localization.h> |
20 #include <libaddressinput/storage.h> | 21 #include <libaddressinput/storage.h> |
21 #include <libaddressinput/util/basictypes.h> | 22 #include <libaddressinput/util/basictypes.h> |
22 #include <libaddressinput/util/scoped_ptr.h> | 23 #include <libaddressinput/util/scoped_ptr.h> |
23 | 24 |
25 #include <algorithm> | |
24 #include <cassert> | 26 #include <cassert> |
27 #include <cstddef> | |
25 #include <map> | 28 #include <map> |
26 #include <string> | 29 #include <string> |
27 #include <utility> | 30 #include <utility> |
28 | 31 |
29 #include "country_rules_retriever.h" | 32 #include "country_rules_retriever.h" |
30 #include "lookup_key.h" | 33 #include "lookup_key.h" |
31 #include "retriever.h" | 34 #include "retriever.h" |
35 #include "rule.h" | |
32 #include "rule_retriever.h" | 36 #include "rule_retriever.h" |
33 #include "util/stl_util.h" | 37 #include "util/stl_util.h" |
34 #include "validating_storage.h" | 38 #include "validating_storage.h" |
35 | 39 |
36 namespace i18n { | 40 namespace i18n { |
37 namespace addressinput { | 41 namespace addressinput { |
38 | 42 |
39 namespace { | 43 namespace { |
40 | 44 |
45 // Returns the next smaller size field type for |field|. For example, returns | |
46 // ADMIN_AREA for COUNTRY. The |field| can only be COUNTRY, ADMIN_AREA, and | |
47 // LOCALITY. | |
48 AddressField GetSubField(AddressField field) { | |
49 switch (field) { | |
50 case COUNTRY: | |
51 return ADMIN_AREA; | |
Evan Stade
2013/12/19 02:12:38
you've now encoded this ordering twice in one CL.
please use gerrit instead
2014/01/08 00:55:52
Fixed.
| |
52 case ADMIN_AREA: | |
53 return LOCALITY; | |
54 case LOCALITY: | |
55 return DEPENDENT_LOCALITY; | |
56 default: | |
57 assert(false); | |
58 return field; | |
59 } | |
60 } | |
61 | |
62 // Returns the |field| value from |address|. The |field| can be only ADMIN_AREA, | |
63 // LOCALITY, and DEPENDENT_LOCALITY. | |
64 const std::string& GetValue(const AddressData& address, AddressField field) { | |
Evan Stade
2013/12/19 02:12:38
didn't I read this function elsewhere in this CL?
please use gerrit instead
2014/01/08 00:55:52
Moved to AddressData.
| |
65 switch (field) { | |
66 case ADMIN_AREA: | |
67 return address.administrative_area; | |
68 case LOCALITY: | |
69 return address.locality; | |
70 case DEPENDENT_LOCALITY: | |
71 return address.dependent_locality; | |
72 default: | |
73 assert(false); | |
74 static const std::string kEmpty; | |
75 return kEmpty; | |
76 } | |
77 } | |
78 | |
79 // Returns true if |filter| allows the |field| to have a |problem_type|. | |
80 bool FilterAllows(const AddressProblemFilter& filter, | |
81 AddressField field, | |
82 AddressProblem::Type problem_type) { | |
83 if (filter.empty()) { | |
84 return true; | |
85 } | |
86 std::pair<AddressProblemFilter::const_iterator, | |
87 AddressProblemFilter::const_iterator> range = | |
88 filter.equal_range(field); | |
Evan Stade
2013/12/19 02:12:38
while this is interesting, I think the following i
please use gerrit instead
2014/01/08 00:55:52
Done.
| |
89 for (AddressProblemFilter::const_iterator it = range.first; | |
90 it != range.second; ++it) { | |
91 if (it->second == problem_type) { | |
92 return true; | |
93 } | |
94 } | |
95 return false; | |
96 } | |
97 | |
41 // Contains all rules loaded for a country code. | 98 // Contains all rules loaded for a country code. |
42 struct CountryRules { | 99 struct CountryRules { |
43 CountryRules(const std::string& country_code, | 100 CountryRules(const std::string& country_code, |
44 scoped_ptr<CountryRulesRetriever::Callback> rules_ready) | 101 scoped_ptr<CountryRulesRetriever::Callback> rules_ready) |
45 : status(AddressValidator::RULES_NOT_READY), | 102 : status(AddressValidator::RULES_NOT_READY), |
46 root(country_code), | 103 root(country_code), |
47 rules_ready(rules_ready.Pass()) {} | 104 rules_ready(rules_ready.Pass()) {} |
48 | 105 |
49 ~CountryRules() {} | 106 ~CountryRules() {} |
50 | 107 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 &country_rules->root); | 157 &country_rules->root); |
101 } | 158 } |
102 } | 159 } |
103 | 160 |
104 // AddressValidator implementation. | 161 // AddressValidator implementation. |
105 virtual Status ValidateAddress( | 162 virtual Status ValidateAddress( |
106 const AddressData& address, | 163 const AddressData& address, |
107 const AddressProblemFilter& filter, | 164 const AddressProblemFilter& filter, |
108 const Localization& localization, | 165 const Localization& localization, |
109 AddressProblems* problems) const { | 166 AddressProblems* problems) const { |
110 return RULES_UNAVAILABLE; | 167 CountryRulesMap::const_iterator country_rule_it = |
168 rules_.find(address.country_code); | |
169 if (country_rule_it == rules_.end()) { | |
170 return RULES_UNAVAILABLE; | |
171 } | |
172 assert(country_rule_it->second != NULL); | |
173 if (country_rule_it->second->status != SUCCESS) { | |
174 return country_rule_it->second->status; | |
175 } | |
176 std::map<AddressField, const Rule*> field_rule_map = | |
Evan Stade
2013/12/19 02:12:38
this function nee4ds some vertical whitespace some
please use gerrit instead
2014/01/08 00:55:52
Done.
| |
177 country_rule_it->second->root.BuildFieldRuleMap(address); | |
178 for (std::map<AddressField, const Rule*>::const_iterator | |
179 field_rule_it = field_rule_map.begin(); | |
Evan Stade
2013/12/19 02:12:38
indent by 4 more
please use gerrit instead
2014/01/08 00:55:52
The rest of libaddressinput uses this format when
Evan Stade
2014/01/08 21:29:34
Why do you think it makes it easier to read? I thi
please use gerrit instead
2014/01/09 19:42:00
Done.
| |
180 field_rule_it != field_rule_map.end(); | |
181 ++field_rule_it) { | |
182 AddressField field = field_rule_it->first; | |
183 const Rule& rule = *field_rule_it->second; | |
184 if (field < DEPENDENT_LOCALITY) { | |
Evan Stade
2013/12/19 02:12:38
nit: invert this check and continue;, that keeps t
please use gerrit instead
2014/01/08 00:55:52
No longer applicable.
| |
185 AddressField sub_field = GetSubField(field); | |
186 const std::string& sub_value = GetValue(address, sub_field); | |
187 if (!rule.GetSubKeys().empty() && !sub_value.empty() && | |
Evan Stade
2013/12/19 02:12:38
nit: easier to read with one condition per line (w
please use gerrit instead
2014/01/08 00:55:52
Done.
| |
188 std::find(rule.GetSubKeys().begin(), | |
189 rule.GetSubKeys().end(), | |
190 sub_value) == rule.GetSubKeys().end() && | |
191 FilterAllows(filter, sub_field, AddressProblem::UNKNOWN_VALUE)) { | |
192 AddressProblem problem = {sub_field, | |
193 AddressProblem::UNKNOWN_VALUE, | |
194 std::string()}; | |
195 problems->push_back(problem); | |
196 } | |
197 } | |
198 } | |
199 return SUCCESS; | |
111 } | 200 } |
112 | 201 |
113 private: | 202 private: |
114 // Called when CountryRulesRetriever::RetrieveRules finishes loading all rules | 203 // Called when CountryRulesRetriever::RetrieveRules finishes loading all rules |
115 // for the |country_code|. | 204 // for the |country_code|. |
116 void OnRulesLoaded(bool success, | 205 void OnRulesLoaded(bool success, |
117 const std::string& country_code, | 206 const std::string& country_code, |
118 const LookupKey& lookup_key) { | 207 const LookupKey& lookup_key) { |
119 CountryRulesMap::const_iterator rules_it = rules_.find(country_code); | 208 CountryRulesMap::const_iterator rules_it = rules_.find(country_code); |
120 assert(rules_it != rules_.end()); | 209 assert(rules_it != rules_.end()); |
(...skipping 30 matching lines...) Expand all Loading... | |
151 scoped_ptr<AddressValidator> AddressValidator::Build( | 240 scoped_ptr<AddressValidator> AddressValidator::Build( |
152 scoped_ptr<const Downloader> downloader, | 241 scoped_ptr<const Downloader> downloader, |
153 scoped_ptr<Storage> storage, | 242 scoped_ptr<Storage> storage, |
154 LoadRulesDelegate* load_rules_delegate) { | 243 LoadRulesDelegate* load_rules_delegate) { |
155 return scoped_ptr<AddressValidator>(new AddressValidatorImpl( | 244 return scoped_ptr<AddressValidator>(new AddressValidatorImpl( |
156 downloader.Pass(), storage.Pass(), load_rules_delegate)); | 245 downloader.Pass(), storage.Pass(), load_rules_delegate)); |
157 } | 246 } |
158 | 247 |
159 } // namespace addressinput | 248 } // namespace addressinput |
160 } // namespace i18n | 249 } // namespace i18n |
OLD | NEW |