summaryrefslogtreecommitdiffstats
path: root/third_party/libaddressinput
diff options
context:
space:
mode:
authorrouslan@chromium.org <rouslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-10 02:24:24 +0000
committerrouslan@chromium.org <rouslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-10 02:24:24 +0000
commitb1d6cbf2e9125f7eb874a25056cdf7e036f52c3a (patch)
tree9e13cbbffe3df4018b81472becca9f87a0f5de79 /third_party/libaddressinput
parente9149ab55ec7676aa4813a8b19772fadb4e6cdcb (diff)
downloadchromium_src-b1d6cbf2e9125f7eb874a25056cdf7e036f52c3a.zip
chromium_src-b1d6cbf2e9125f7eb874a25056cdf7e036f52c3a.tar.gz
chromium_src-b1d6cbf2e9125f7eb874a25056cdf7e036f52c3a.tar.bz2
[rac] Validate an address.
BUG=327046 Review URL: https://codereview.chromium.org/116363003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244046 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/libaddressinput')
-rw-r--r--third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h8
-rw-r--r--third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_problem.h3
-rw-r--r--third_party/libaddressinput/chromium/cpp/libaddressinput.gyp1
-rw-r--r--third_party/libaddressinput/chromium/cpp/src/address_data.cc50
-rw-r--r--third_party/libaddressinput/chromium/cpp/src/address_problem.cc8
-rw-r--r--third_party/libaddressinput/chromium/cpp/src/address_validator.cc120
-rw-r--r--third_party/libaddressinput/chromium/cpp/src/country_rules_aggregator.cc4
-rw-r--r--third_party/libaddressinput/chromium/cpp/src/rule.cc66
-rw-r--r--third_party/libaddressinput/chromium/cpp/src/rule.h17
-rw-r--r--third_party/libaddressinput/chromium/cpp/src/ruleset.cc25
-rw-r--r--third_party/libaddressinput/chromium/cpp/src/ruleset.h40
-rw-r--r--third_party/libaddressinput/chromium/cpp/test/rule_test.cc114
-rw-r--r--third_party/libaddressinput/libaddressinput.gyp1
13 files changed, 388 insertions, 69 deletions
diff --git a/third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h b/third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h
index d6ae6c0..8c8b75e 100644
--- a/third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h
+++ b/third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h
@@ -19,6 +19,8 @@
#ifndef I18N_ADDRESSINPUT_ADDRESS_DATA_H_
#define I18N_ADDRESSINPUT_ADDRESS_DATA_H_
+#include <libaddressinput/address_field.h>
+
#include <string>
#include <vector>
@@ -31,14 +33,16 @@ namespace addressinput {
// address.address_lines.push_back("1098 Alta Ave");
// address.administrative_area = "CA";
// address.locality = "Mountain View";
-// address.dependent_locality = "";
// address.postal_code = "94043";
-// address.sorting_code = "";
// address.organization = "Google";
// address.recipient = "Chen-Kang Yang";
// address.language_code = "en";
// Process(address);
struct AddressData {
+ // Returns the value of the |field|. The parameter should not be
+ // STREET_ADDRESS, which comprises multiple fields.
+ const std::string& GetField(AddressField field) const;
+
// The BCP 47 language code used to guide how the address is formatted for
// display. The same address may have different representations in different
// languages.
diff --git a/third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_problem.h b/third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_problem.h
index 559fcfd..841f8d1 100644
--- a/third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_problem.h
+++ b/third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_problem.h
@@ -59,6 +59,9 @@ struct AddressProblem {
MISMATCHING_VALUE
};
+ AddressProblem(AddressField field, Type type, const std::string& description);
+ ~AddressProblem();
+
// The address field that has the problem.
AddressField field;
diff --git a/third_party/libaddressinput/chromium/cpp/libaddressinput.gyp b/third_party/libaddressinput/chromium/cpp/libaddressinput.gyp
index 0cac4cb..0c59994 100644
--- a/third_party/libaddressinput/chromium/cpp/libaddressinput.gyp
+++ b/third_party/libaddressinput/chromium/cpp/libaddressinput.gyp
@@ -31,6 +31,7 @@
'target_name': 'libaddressinput',
'type': '<(component)',
'sources': [
+ 'src/address_data.cc',
'src/address_field.cc',
'src/address_problem.cc',
'src/address_ui.cc',
diff --git a/third_party/libaddressinput/chromium/cpp/src/address_data.cc b/third_party/libaddressinput/chromium/cpp/src/address_data.cc
new file mode 100644
index 0000000..9b86cc8
--- /dev/null
+++ b/third_party/libaddressinput/chromium/cpp/src/address_data.cc
@@ -0,0 +1,50 @@
+// Copyright (C) 2013 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <libaddressinput/address_data.h>
+
+#include <libaddressinput/address_field.h>
+
+#include <cassert>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+const std::string& AddressData::GetField(AddressField field) const {
+ switch (field) {
+ case COUNTRY:
+ return country_code;
+ case ADMIN_AREA:
+ return administrative_area;
+ case LOCALITY:
+ return locality;
+ case DEPENDENT_LOCALITY:
+ return dependent_locality;
+ case SORTING_CODE:
+ return sorting_code;
+ case POSTAL_CODE:
+ return postal_code;
+ case ORGANIZATION:
+ return organization;
+ case RECIPIENT:
+ return recipient;
+ default:
+ assert(false);
+ return recipient;
+ }
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/third_party/libaddressinput/chromium/cpp/src/address_problem.cc b/third_party/libaddressinput/chromium/cpp/src/address_problem.cc
index 14a0030..d823e11 100644
--- a/third_party/libaddressinput/chromium/cpp/src/address_problem.cc
+++ b/third_party/libaddressinput/chromium/cpp/src/address_problem.cc
@@ -15,10 +15,18 @@
#include <libaddressinput/address_problem.h>
#include <ostream>
+#include <string>
namespace i18n {
namespace addressinput {
+AddressProblem::AddressProblem(AddressField field,
+ Type type,
+ const std::string& description)
+ : field(field), type(type), description(description) {}
+
+AddressProblem::~AddressProblem() {}
+
std::ostream& operator<<(std::ostream& o, AddressProblem::Type problem_type) {
switch (problem_type) {
case AddressProblem::MISSING_REQUIRED_FIELD:
diff --git a/third_party/libaddressinput/chromium/cpp/src/address_validator.cc b/third_party/libaddressinput/chromium/cpp/src/address_validator.cc
index 04163a6..fdb4113 100644
--- a/third_party/libaddressinput/chromium/cpp/src/address_validator.cc
+++ b/third_party/libaddressinput/chromium/cpp/src/address_validator.cc
@@ -14,6 +14,7 @@
#include <libaddressinput/address_validator.h>
+#include <libaddressinput/address_data.h>
#include <libaddressinput/downloader.h>
#include <libaddressinput/load_rules_delegate.h>
#include <libaddressinput/localization.h>
@@ -21,14 +22,19 @@
#include <libaddressinput/util/basictypes.h>
#include <libaddressinput/util/scoped_ptr.h>
+#include <algorithm>
#include <cassert>
#include <cstddef>
#include <map>
#include <set>
#include <string>
+#include <re2/re2.h>
+
#include "country_rules_aggregator.h"
+#include "messages.h"
#include "retriever.h"
+#include "rule.h"
#include "ruleset.h"
#include "util/stl_util.h"
@@ -37,6 +43,25 @@ namespace addressinput {
namespace {
+// Returns true if the filter is empty (all problems allowed) or contains the
+// |field|->|problem| mapping (explicitly allowed).
+bool FilterAllows(const AddressProblemFilter& filter,
+ AddressField field,
+ AddressProblem::Type problem) {
+ if (filter.empty()) {
+ return true;
+ }
+
+ for (AddressProblemFilter::const_iterator it = filter.begin();
+ it != filter.end(); ++it) {
+ if (it->first == field && it->second == problem) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
// Validates AddressData structure.
class AddressValidatorImpl : public AddressValidator {
public:
@@ -74,8 +99,95 @@ class AddressValidatorImpl : public AddressValidator {
const AddressProblemFilter& filter,
const Localization& localization,
AddressProblems* problems) const {
- // TODO(rouslan): Validate the address.
- return RULES_UNAVAILABLE;
+ std::map<std::string, const Ruleset*>::const_iterator ruleset_it =
+ rules_.find(address.country_code);
+ if (ruleset_it == rules_.end()) {
+ return loading_rules_.find(address.country_code) != loading_rules_.end()
+ ? RULES_NOT_READY
+ : RULES_UNAVAILABLE;
+ }
+
+ const Ruleset* ruleset = ruleset_it->second;
+ assert(ruleset != NULL);
+ const Rule& country_rule =
+ ruleset->GetLanguageCodeRule(address.language_code);
+
+ // Validate required fields.
+ for (std::vector<AddressField>::const_iterator
+ field_it = country_rule.GetRequired().begin();
+ field_it != country_rule.GetRequired().end();
+ ++field_it) {
+ if (address.GetField(*field_it).empty() &&
+ FilterAllows(
+ filter, *field_it, AddressProblem::MISSING_REQUIRED_FIELD)) {
+ problems->push_back(AddressProblem(
+ *field_it,
+ AddressProblem::MISSING_REQUIRED_FIELD,
+ localization.GetString(
+ IDS_LIBADDRESSINPUT_I18N_MISSING_REQUIRED_FIELD)));
+ }
+ }
+
+ // Validate general postal code format. A country-level rule specifies the
+ // regular expression for the whole postal code.
+ if (!address.postal_code.empty() &&
+ !country_rule.GetPostalCodeFormat().empty() &&
+ FilterAllows(filter,
+ POSTAL_CODE,
+ AddressProblem::UNRECOGNIZED_FORMAT) &&
+ !RE2::FullMatch(
+ address.postal_code, country_rule.GetPostalCodeFormat())) {
+ problems->push_back(AddressProblem(
+ POSTAL_CODE,
+ AddressProblem::UNRECOGNIZED_FORMAT,
+ localization.GetString(
+ country_rule.GetInvalidPostalCodeMessageId())));
+ }
+
+ while (ruleset != NULL) {
+ const Rule& rule = ruleset->GetLanguageCodeRule(address.language_code);
+
+ // Validate the field values, e.g. state names in US.
+ AddressField sub_field_type =
+ static_cast<AddressField>(ruleset->field() + 1);
+ const std::string& sub_field = address.GetField(sub_field_type);
+ const std::vector<std::string>& sub_keys = rule.GetSubKeys();
+ if (!sub_field.empty() &&
+ !sub_keys.empty() &&
+ FilterAllows(filter, sub_field_type, AddressProblem::UNKNOWN_VALUE) &&
+ std::find(sub_keys.begin(), sub_keys.end(), sub_field) ==
+ sub_keys.end()) {
+ problems->push_back(AddressProblem(
+ sub_field_type,
+ AddressProblem::UNKNOWN_VALUE,
+ localization.GetString(
+ country_rule.GetInvalidFieldMessageId(sub_field_type))));
+ }
+
+ // Validate sub-region specific postal code format. A sub-region specifies
+ // the regular expression for a prefix of the postal code.
+ int match_position = -1;
+ if (ruleset->field() > COUNTRY &&
+ !address.postal_code.empty() &&
+ !rule.GetPostalCodeFormat().empty() &&
+ FilterAllows(filter,
+ POSTAL_CODE,
+ AddressProblem::MISMATCHING_VALUE) &&
+ (!RE2::PartialMatch(address.postal_code,
+ rule.GetPostalCodeFormat(),
+ &match_position) ||
+ match_position != 0)) {
+ problems->push_back(AddressProblem(
+ POSTAL_CODE,
+ AddressProblem::MISMATCHING_VALUE,
+ localization.GetString(
+ country_rule.GetInvalidPostalCodeMessageId())));
+ }
+
+ ruleset = ruleset->GetSubRegionRuleset(sub_field);
+ }
+
+ return SUCCESS;
}
private:
@@ -87,6 +199,8 @@ class AddressValidatorImpl : public AddressValidator {
assert(rules_.find(country_code) == rules_.end());
loading_rules_.erase(country_code);
if (success) {
+ assert(ruleset != NULL);
+ assert(ruleset->field() == COUNTRY);
rules_[country_code] = ruleset.release();
}
if (load_rules_delegate_ != NULL) {
@@ -105,7 +219,7 @@ class AddressValidatorImpl : public AddressValidator {
std::set<std::string> loading_rules_;
// A mapping of a country code to the owned ruleset for that country code.
- std::map<std::string, Ruleset*> rules_;
+ std::map<std::string, const Ruleset*> rules_;
DISALLOW_COPY_AND_ASSIGN(AddressValidatorImpl);
};
diff --git a/third_party/libaddressinput/chromium/cpp/src/country_rules_aggregator.cc b/third_party/libaddressinput/chromium/cpp/src/country_rules_aggregator.cc
index 991a6e0..e268f86 100644
--- a/third_party/libaddressinput/chromium/cpp/src/country_rules_aggregator.cc
+++ b/third_party/libaddressinput/chromium/cpp/src/country_rules_aggregator.cc
@@ -143,11 +143,11 @@ void CountryRulesAggregator::OnDataReady(bool success,
default_language_ = rule->GetLanguage();
languages_ = rule->GetLanguages();
- root_.reset(new Ruleset(rule.Pass()));
+ root_.reset(new Ruleset(request.level, rule.Pass()));
ruleset = root_.get();
} else {
assert(request.parent != NULL);
- ruleset = new Ruleset(rule.Pass());
+ ruleset = new Ruleset(request.level, rule.Pass());
request.parent->AddSubRegionRuleset(
request.id, scoped_ptr<Ruleset>(ruleset));
}
diff --git a/third_party/libaddressinput/chromium/cpp/src/rule.cc b/third_party/libaddressinput/chromium/cpp/src/rule.cc
index 43d5c43..006ea58 100644
--- a/third_party/libaddressinput/chromium/cpp/src/rule.cc
+++ b/third_party/libaddressinput/chromium/cpp/src/rule.cc
@@ -111,49 +111,62 @@ void ParseAddressFieldsRequired(const std::string& required,
}
}
-int GetAdminAreaMessageId(const std::string& admin_area_type) {
+int GetAdminAreaMessageId(const std::string& admin_area_type, bool error) {
if (admin_area_type == "area") {
- return IDS_LIBADDRESSINPUT_I18N_AREA;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_AREA
+ : IDS_LIBADDRESSINPUT_I18N_AREA;
}
if (admin_area_type == "county") {
- return IDS_LIBADDRESSINPUT_I18N_COUNTY_LABEL;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_COUNTY_LABEL
+ : IDS_LIBADDRESSINPUT_I18N_COUNTY_LABEL;
}
if (admin_area_type == "department") {
- return IDS_LIBADDRESSINPUT_I18N_DEPARTMENT;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_DEPARTMENT
+ : IDS_LIBADDRESSINPUT_I18N_DEPARTMENT;
}
if (admin_area_type == "district") {
- return IDS_LIBADDRESSINPUT_I18N_DEPENDENT_LOCALITY_LABEL;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_DEPENDENT_LOCALITY_LABEL
+ : IDS_LIBADDRESSINPUT_I18N_DEPENDENT_LOCALITY_LABEL;
}
if (admin_area_type == "do_si") {
- return IDS_LIBADDRESSINPUT_I18N_DO_SI;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_DO_SI
+ : IDS_LIBADDRESSINPUT_I18N_DO_SI;
}
if (admin_area_type == "emirate") {
- return IDS_LIBADDRESSINPUT_I18N_EMIRATE;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_EMIRATE
+ : IDS_LIBADDRESSINPUT_I18N_EMIRATE;
}
if (admin_area_type == "island") {
- return IDS_LIBADDRESSINPUT_I18N_ISLAND;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_ISLAND
+ : IDS_LIBADDRESSINPUT_I18N_ISLAND;
}
if (admin_area_type == "parish") {
- return IDS_LIBADDRESSINPUT_I18N_PARISH;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_PARISH
+ : IDS_LIBADDRESSINPUT_I18N_PARISH;
}
if (admin_area_type == "prefecture") {
- return IDS_LIBADDRESSINPUT_I18N_PREFECTURE;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_PREFECTURE
+ : IDS_LIBADDRESSINPUT_I18N_PREFECTURE;
}
if (admin_area_type == "province") {
- return IDS_LIBADDRESSINPUT_I18N_PROVINCE;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_PROVINCE
+ : IDS_LIBADDRESSINPUT_I18N_PROVINCE;
}
if (admin_area_type == "state") {
- return IDS_LIBADDRESSINPUT_I18N_STATE_LABEL;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_STATE_LABEL
+ : IDS_LIBADDRESSINPUT_I18N_STATE_LABEL;
}
return INVALID_MESSAGE_ID;
}
-int GetPostalCodeMessageId(const std::string& postal_code_type) {
+int GetPostalCodeMessageId(const std::string& postal_code_type, bool error) {
if (postal_code_type == "postal") {
- return IDS_LIBADDRESSINPUT_I18N_POSTAL_CODE_LABEL;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_POSTAL_CODE_LABEL
+ : IDS_LIBADDRESSINPUT_I18N_POSTAL_CODE_LABEL;
}
if (postal_code_type == "zip") {
- return IDS_LIBADDRESSINPUT_I18N_ZIP_CODE_LABEL;
+ return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_ZIP_CODE_LABEL
+ : IDS_LIBADDRESSINPUT_I18N_ZIP_CODE_LABEL;
}
return INVALID_MESSAGE_ID;
}
@@ -192,7 +205,9 @@ void Rule::CopyFrom(const Rule& rule) {
language_ = rule.language_;
postal_code_format_ = rule.postal_code_format_;
admin_area_name_message_id_ = rule.admin_area_name_message_id_;
+ invalid_admin_area_message_id_ = rule.invalid_admin_area_message_id_;
postal_code_name_message_id_ = rule.postal_code_name_message_id_;
+ invalid_postal_code_message_id_ = rule.invalid_postal_code_message_id_;
}
bool Rule::ParseSerializedRule(const std::string& serialized_rule) {
@@ -230,15 +245,32 @@ bool Rule::ParseSerializedRule(const std::string& serialized_rule) {
}
if (json->GetStringValueForKey("state_name_type", &value)) {
- admin_area_name_message_id_ = GetAdminAreaMessageId(value);
+ admin_area_name_message_id_ = GetAdminAreaMessageId(value, false);
+ invalid_admin_area_message_id_ = GetAdminAreaMessageId(value, true);
}
if (json->GetStringValueForKey("zip_name_type", &value)) {
- postal_code_name_message_id_ = GetPostalCodeMessageId(value);
+ postal_code_name_message_id_ = GetPostalCodeMessageId(value, false);
+ invalid_postal_code_message_id_ = GetPostalCodeMessageId(value, true);
}
return true;
}
+int Rule::GetInvalidFieldMessageId(AddressField field) const {
+ switch (field) {
+ case ADMIN_AREA:
+ return invalid_admin_area_message_id_;
+ case LOCALITY:
+ return IDS_LIBADDRESSINPUT_I18N_INVALID_LOCALITY_LABEL;
+ case DEPENDENT_LOCALITY:
+ return IDS_LIBADDRESSINPUT_I18N_INVALID_DEPENDENT_LOCALITY_LABEL;
+ case POSTAL_CODE:
+ return invalid_postal_code_message_id_;
+ default:
+ return IDS_LIBADDRESSINPUT_I18N_INVALID_ENTRY;
+ }
+}
+
} // namespace addressinput
} // namespace i18n
diff --git a/third_party/libaddressinput/chromium/cpp/src/rule.h b/third_party/libaddressinput/chromium/cpp/src/rule.h
index eab1de7..9e6fa09 100644
--- a/third_party/libaddressinput/chromium/cpp/src/rule.h
+++ b/third_party/libaddressinput/chromium/cpp/src/rule.h
@@ -76,12 +76,27 @@ class Rule {
// INVALID_MESSAGE_ID.
int GetAdminAreaNameMessageId() const { return admin_area_name_message_id_; }
+ // The error message string identifier for an invalid admin area. If not set,
+ // then INVALID_MESSAGE_ID.
+ int GetInvalidAdminAreaMessageId() const {
+ return invalid_admin_area_message_id_;
+ }
+
// The message string identifier for postal code name. If not set, then
// INVALID_MESSAGE_ID.
int GetPostalCodeNameMessageId() const {
return postal_code_name_message_id_;
}
+ // The error message string identifier for an invalid postal code. If not set,
+ // then INVALID_MESSAGE_ID.
+ int GetInvalidPostalCodeMessageId() const {
+ return invalid_postal_code_message_id_;
+ }
+
+ // Returns the error message string identifier for an invalid |field|.
+ int GetInvalidFieldMessageId(AddressField field) const;
+
private:
std::vector<std::vector<AddressField> > format_;
std::vector<AddressField> required_;
@@ -90,7 +105,9 @@ class Rule {
std::string language_;
std::string postal_code_format_;
int admin_area_name_message_id_;
+ int invalid_admin_area_message_id_;
int postal_code_name_message_id_;
+ int invalid_postal_code_message_id_;
DISALLOW_COPY_AND_ASSIGN(Rule);
};
diff --git a/third_party/libaddressinput/chromium/cpp/src/ruleset.cc b/third_party/libaddressinput/chromium/cpp/src/ruleset.cc
index 3201750..a3eca96 100644
--- a/third_party/libaddressinput/chromium/cpp/src/ruleset.cc
+++ b/third_party/libaddressinput/chromium/cpp/src/ruleset.cc
@@ -14,13 +14,13 @@
#include "ruleset.h"
+#include <libaddressinput/address_field.h>
#include <libaddressinput/util/scoped_ptr.h>
#include <cassert>
#include <cstddef>
#include <map>
#include <string>
-#include <utility>
#include "rule.h"
#include "util/stl_util.h"
@@ -28,10 +28,13 @@
namespace i18n {
namespace addressinput {
-Ruleset::Ruleset(scoped_ptr<Rule> rule)
- : rule_(rule.Pass()),
+Ruleset::Ruleset(AddressField field, scoped_ptr<Rule> rule)
+ : field_(field),
+ rule_(rule.Pass()),
sub_regions_(),
language_codes_() {
+ assert(field_ >= COUNTRY);
+ assert(field_ <= DEPENDENT_LOCALITY);
assert(rule_ != NULL);
}
@@ -43,14 +46,30 @@ Ruleset::~Ruleset() {
void Ruleset::AddSubRegionRuleset(const std::string& sub_region,
scoped_ptr<Ruleset> ruleset) {
assert(sub_regions_.find(sub_region) == sub_regions_.end());
+ assert(ruleset != NULL);
+ assert(ruleset->field() == static_cast<AddressField>(field() + 1));
sub_regions_[sub_region] = ruleset.release();
}
void Ruleset::AddLanguageCodeRule(const std::string& language_code,
scoped_ptr<Rule> rule) {
assert(language_codes_.find(language_code) == language_codes_.end());
+ assert(rule != NULL);
language_codes_[language_code] = rule.release();
}
+Ruleset* Ruleset::GetSubRegionRuleset(const std::string& sub_region) const {
+ std::map<std::string, Ruleset*>::const_iterator it =
+ sub_regions_.find(sub_region);
+ return it != sub_regions_.end() ? it->second : NULL;
+}
+
+const Rule& Ruleset::GetLanguageCodeRule(
+ const std::string& language_code) const {
+ std::map<std::string, const Rule*>::const_iterator it =
+ language_codes_.find(language_code);
+ return it != language_codes_.end() ? *it->second : *rule_;
+}
+
} // namespace addressinput
} // namespace i18n
diff --git a/third_party/libaddressinput/chromium/cpp/src/ruleset.h b/third_party/libaddressinput/chromium/cpp/src/ruleset.h
index 224d8e9..2e5dbbe 100644
--- a/third_party/libaddressinput/chromium/cpp/src/ruleset.h
+++ b/third_party/libaddressinput/chromium/cpp/src/ruleset.h
@@ -15,6 +15,7 @@
#ifndef I18N_ADDRESSINPUT_RULESET_H_
#define I18N_ADDRESSINPUT_RULESET_H_
+#include <libaddressinput/address_field.h>
#include <libaddressinput/util/basictypes.h>
#include <libaddressinput/util/scoped_ptr.h>
@@ -42,26 +43,49 @@ class Rule;
// language version.
class Ruleset {
public:
- // Builds a ruleset with a region-wide |rule| in the default language of the
- // country. The |rule| should not be NULL.
- explicit Ruleset(scoped_ptr<Rule> rule);
+ // Builds a ruleset for |field| with a region-wide |rule| in the default
+ // language of the country. The |field| should be between COUNTRY and
+ // DEPENDENT_LOCALITY (inclusively). The |rule| should not be NULL.
+ Ruleset(AddressField field, scoped_ptr<Rule> rule);
~Ruleset();
- // Returns the region-wide rule in the default language of the country.
- const Rule& rule() const { return *rule_.get(); }
+ // Returns the field type for this ruleset.
+ AddressField field() const { return field_; }
- // Adds and the |ruleset| for |sub_region|.
+ // Returns the region-wide rule for this ruleset in the default language of
+ // the country.
+ const Rule& rule() const { return *rule_; }
+
+ // Adds the |ruleset| for |sub_region|. A |sub_region| should be added at most
+ // once. The |ruleset| should not be NULL.
+ //
+ // The field of the |ruleset| parameter must be exactly one smaller than the
+ // field of this ruleset. For example, a COUNTRY ruleset can contain
+ // ADMIN_AREA rulesets, but should not contain COUNTRY or LOCALITY rulesets.
void AddSubRegionRuleset(const std::string& sub_region,
scoped_ptr<Ruleset> ruleset);
- // Adds a language-specific |rule| for |language_code| for this region.
+ // Adds a language-specific |rule| for |language_code| for this region. A
+ // |language_code| should be added at most once. The |rule| should not be
+ // NULL.
void AddLanguageCodeRule(const std::string& language_code,
scoped_ptr<Rule> rule);
+ // Returns the set of rules for |sub_region|. The result is NULL if there's no
+ // such |sub_region|. The caller does not own the result.
+ Ruleset* GetSubRegionRuleset(const std::string& sub_region) const;
+
+ // If there's a language-specific rule for |language_code|, then returns this
+ // rule. Otherwise returns the rule in the default language of the country.
+ const Rule& GetLanguageCodeRule(const std::string& language_code) const;
+
private:
+ // The field of this ruleset.
+ const AddressField field_;
+
// The region-wide rule in the default language of the country.
- scoped_ptr<const Rule> rule_;
+ const scoped_ptr<const Rule> rule_;
// Owned rulesets for sub-regions.
std::map<std::string, Ruleset*> sub_regions_;
diff --git a/third_party/libaddressinput/chromium/cpp/test/rule_test.cc b/third_party/libaddressinput/chromium/cpp/test/rule_test.cc
index b484555..da10680 100644
--- a/third_party/libaddressinput/chromium/cpp/test/rule_test.cc
+++ b/third_party/libaddressinput/chromium/cpp/test/rule_test.cc
@@ -71,8 +71,12 @@ TEST(RuleTest, CopyOverwritesRule) {
EXPECT_NE(rule.GetPostalCodeFormat(), copy.GetPostalCodeFormat());
EXPECT_NE(rule.GetAdminAreaNameMessageId(),
copy.GetAdminAreaNameMessageId());
+ EXPECT_NE(rule.GetInvalidAdminAreaMessageId(),
+ copy.GetInvalidAdminAreaMessageId());
EXPECT_NE(rule.GetPostalCodeNameMessageId(),
copy.GetPostalCodeNameMessageId());
+ EXPECT_NE(rule.GetInvalidPostalCodeMessageId(),
+ copy.GetInvalidPostalCodeMessageId());
copy.CopyFrom(rule);
EXPECT_EQ(rule.GetFormat(), copy.GetFormat());
@@ -83,8 +87,12 @@ TEST(RuleTest, CopyOverwritesRule) {
EXPECT_EQ(rule.GetPostalCodeFormat(), copy.GetPostalCodeFormat());
EXPECT_EQ(rule.GetAdminAreaNameMessageId(),
copy.GetAdminAreaNameMessageId());
+ EXPECT_EQ(rule.GetInvalidAdminAreaMessageId(),
+ copy.GetInvalidAdminAreaMessageId());
EXPECT_EQ(rule.GetPostalCodeNameMessageId(),
copy.GetPostalCodeNameMessageId());
+ EXPECT_EQ(rule.GetInvalidPostalCodeMessageId(),
+ copy.GetInvalidPostalCodeMessageId());
}
TEST(RuleTest, ParseOverwritesRule) {
@@ -108,8 +116,12 @@ TEST(RuleTest, ParseOverwritesRule) {
EXPECT_FALSE(rule.GetPostalCodeFormat().empty());
EXPECT_EQ(IDS_LIBADDRESSINPUT_I18N_AREA,
rule.GetAdminAreaNameMessageId());
+ EXPECT_EQ(IDS_LIBADDRESSINPUT_I18N_INVALID_AREA,
+ rule.GetInvalidAdminAreaMessageId());
EXPECT_EQ(IDS_LIBADDRESSINPUT_I18N_POSTAL_CODE_LABEL,
rule.GetPostalCodeNameMessageId());
+ EXPECT_EQ(IDS_LIBADDRESSINPUT_I18N_INVALID_POSTAL_CODE_LABEL,
+ rule.GetInvalidPostalCodeMessageId());
ASSERT_TRUE(rule.ParseSerializedRule(
"{"
@@ -130,8 +142,12 @@ TEST(RuleTest, ParseOverwritesRule) {
EXPECT_TRUE(rule.GetPostalCodeFormat().empty());
EXPECT_EQ(IDS_LIBADDRESSINPUT_I18N_DO_SI,
rule.GetAdminAreaNameMessageId());
+ EXPECT_EQ(IDS_LIBADDRESSINPUT_I18N_INVALID_DO_SI,
+ rule.GetInvalidAdminAreaMessageId());
EXPECT_EQ(IDS_LIBADDRESSINPUT_I18N_ZIP_CODE_LABEL,
rule.GetPostalCodeNameMessageId());
+ EXPECT_EQ(IDS_LIBADDRESSINPUT_I18N_INVALID_ZIP_CODE_LABEL,
+ rule.GetInvalidPostalCodeMessageId());
}
TEST(RuleTest, ParseEmptyDataDoesNotOverwriteRule) {
@@ -160,8 +176,12 @@ TEST(RuleTest, ParseEmptyDataDoesNotOverwriteRule) {
EXPECT_EQ(rule.GetPostalCodeFormat(), copy.GetPostalCodeFormat());
EXPECT_EQ(rule.GetAdminAreaNameMessageId(),
copy.GetAdminAreaNameMessageId());
+ EXPECT_EQ(rule.GetInvalidAdminAreaMessageId(),
+ copy.GetInvalidAdminAreaMessageId());
EXPECT_EQ(rule.GetPostalCodeNameMessageId(),
copy.GetPostalCodeNameMessageId());
+ EXPECT_EQ(rule.GetInvalidPostalCodeMessageId(),
+ copy.GetInvalidPostalCodeMessageId());
}
TEST(RuleTest, ParseFormatWithNewLines) {
@@ -288,67 +308,93 @@ TEST(RuleTest, EmptyDictionaryIsValid) {
EXPECT_TRUE(rule.ParseSerializedRule("{}"));
}
+struct LabelData {
+ LabelData(const std::string& data, int name_id, int error_id)
+ : data(data), name_id(name_id), error_id(error_id) {}
+
+ ~LabelData() {}
+
+ std::string data;
+ int name_id;
+ int error_id;
+};
+
// Tests for parsing the postal code name.
-class PostalCodeNameParseTest
- : public testing::TestWithParam<std::pair<std::string, int> > {
+class PostalCodeNameParseTest : public testing::TestWithParam<LabelData> {
protected:
Rule rule_;
};
// Verifies that a postal code name is parsed correctly.
TEST_P(PostalCodeNameParseTest, ParsedCorrectly) {
- ASSERT_TRUE(rule_.ParseSerializedRule(GetParam().first));
- EXPECT_EQ(GetParam().second, rule_.GetPostalCodeNameMessageId());
+ ASSERT_TRUE(rule_.ParseSerializedRule(GetParam().data));
+ EXPECT_EQ(GetParam().name_id, rule_.GetPostalCodeNameMessageId());
+ EXPECT_EQ(GetParam().error_id, rule_.GetInvalidPostalCodeMessageId());
+ EXPECT_EQ(GetParam().error_id, rule_.GetInvalidFieldMessageId(POSTAL_CODE));
}
// Test parsing all postal code names.
INSTANTIATE_TEST_CASE_P(
AllPostalCodeNames, PostalCodeNameParseTest,
testing::Values(
- std::make_pair("{\"zip_name_type\":\"postal\"}",
- IDS_LIBADDRESSINPUT_I18N_POSTAL_CODE_LABEL),
- std::make_pair("{\"zip_name_type\":\"zip\"}",
- IDS_LIBADDRESSINPUT_I18N_ZIP_CODE_LABEL)));
+ LabelData("{\"zip_name_type\":\"postal\"}",
+ IDS_LIBADDRESSINPUT_I18N_POSTAL_CODE_LABEL,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_POSTAL_CODE_LABEL),
+ LabelData("{\"zip_name_type\":\"zip\"}",
+ IDS_LIBADDRESSINPUT_I18N_ZIP_CODE_LABEL,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_ZIP_CODE_LABEL)));
// Tests for parsing the administrative area name.
-class AdminAreaNameParseTest
- : public testing::TestWithParam<std::pair<std::string, int> > {
+class AdminAreaNameParseTest : public testing::TestWithParam<LabelData> {
protected:
Rule rule_;
};
// Verifies that an administrative area name is parsed correctly.
TEST_P(AdminAreaNameParseTest, ParsedCorrectly) {
- ASSERT_TRUE(rule_.ParseSerializedRule(GetParam().first));
- EXPECT_EQ(GetParam().second, rule_.GetAdminAreaNameMessageId());
+ ASSERT_TRUE(rule_.ParseSerializedRule(GetParam().data));
+ EXPECT_EQ(GetParam().name_id, rule_.GetAdminAreaNameMessageId());
+ EXPECT_EQ(GetParam().error_id, rule_.GetInvalidAdminAreaMessageId());
+ EXPECT_EQ(GetParam().error_id, rule_.GetInvalidFieldMessageId(ADMIN_AREA));
}
// Test parsing all administrative area names.
INSTANTIATE_TEST_CASE_P(
AllAdminAreaNames, AdminAreaNameParseTest,
testing::Values(
- std::make_pair("{\"state_name_type\":\"area\"}",
- IDS_LIBADDRESSINPUT_I18N_AREA),
- std::make_pair("{\"state_name_type\":\"county\"}",
- IDS_LIBADDRESSINPUT_I18N_COUNTY_LABEL),
- std::make_pair("{\"state_name_type\":\"department\"}",
- IDS_LIBADDRESSINPUT_I18N_DEPARTMENT),
- std::make_pair("{\"state_name_type\":\"district\"}",
- IDS_LIBADDRESSINPUT_I18N_DEPENDENT_LOCALITY_LABEL),
- std::make_pair("{\"state_name_type\":\"do_si\"}",
- IDS_LIBADDRESSINPUT_I18N_DO_SI),
- std::make_pair("{\"state_name_type\":\"emirate\"}",
- IDS_LIBADDRESSINPUT_I18N_EMIRATE),
- std::make_pair("{\"state_name_type\":\"island\"}",
- IDS_LIBADDRESSINPUT_I18N_ISLAND),
- std::make_pair("{\"state_name_type\":\"parish\"}",
- IDS_LIBADDRESSINPUT_I18N_PARISH),
- std::make_pair("{\"state_name_type\":\"prefecture\"}",
- IDS_LIBADDRESSINPUT_I18N_PREFECTURE),
- std::make_pair("{\"state_name_type\":\"province\"}",
- IDS_LIBADDRESSINPUT_I18N_PROVINCE),
- std::make_pair("{\"state_name_type\":\"state\"}",
- IDS_LIBADDRESSINPUT_I18N_STATE_LABEL)));
+ LabelData("{\"state_name_type\":\"area\"}",
+ IDS_LIBADDRESSINPUT_I18N_AREA,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_AREA),
+ LabelData("{\"state_name_type\":\"county\"}",
+ IDS_LIBADDRESSINPUT_I18N_COUNTY_LABEL,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_COUNTY_LABEL),
+ LabelData("{\"state_name_type\":\"department\"}",
+ IDS_LIBADDRESSINPUT_I18N_DEPARTMENT,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_DEPARTMENT),
+ LabelData("{\"state_name_type\":\"district\"}",
+ IDS_LIBADDRESSINPUT_I18N_DEPENDENT_LOCALITY_LABEL,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_DEPENDENT_LOCALITY_LABEL),
+ LabelData("{\"state_name_type\":\"do_si\"}",
+ IDS_LIBADDRESSINPUT_I18N_DO_SI,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_DO_SI),
+ LabelData("{\"state_name_type\":\"emirate\"}",
+ IDS_LIBADDRESSINPUT_I18N_EMIRATE,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_EMIRATE),
+ LabelData("{\"state_name_type\":\"island\"}",
+ IDS_LIBADDRESSINPUT_I18N_ISLAND,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_ISLAND),
+ LabelData("{\"state_name_type\":\"parish\"}",
+ IDS_LIBADDRESSINPUT_I18N_PARISH,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_PARISH),
+ LabelData("{\"state_name_type\":\"prefecture\"}",
+ IDS_LIBADDRESSINPUT_I18N_PREFECTURE,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_PREFECTURE),
+ LabelData("{\"state_name_type\":\"province\"}",
+ IDS_LIBADDRESSINPUT_I18N_PROVINCE,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_PROVINCE),
+ LabelData("{\"state_name_type\":\"state\"}",
+ IDS_LIBADDRESSINPUT_I18N_STATE_LABEL,
+ IDS_LIBADDRESSINPUT_I18N_INVALID_STATE_LABEL)));
// Tests for rule parsing.
class RuleParseTest : public testing::TestWithParam<std::string> {
diff --git a/third_party/libaddressinput/libaddressinput.gyp b/third_party/libaddressinput/libaddressinput.gyp
index d3f94999..ee1c673 100644
--- a/third_party/libaddressinput/libaddressinput.gyp
+++ b/third_party/libaddressinput/libaddressinput.gyp
@@ -68,6 +68,7 @@
'<(libaddressinput_dir)/cpp/include/libaddressinput/util/internal/scoped_ptr.h',
'<(libaddressinput_dir)/cpp/include/libaddressinput/util/internal/template_util.h',
'<(libaddressinput_dir)/cpp/include/libaddressinput/util/scoped_ptr.h',
+ '<(libaddressinput_dir)/cpp/src/address_data.cc',
'<(libaddressinput_dir)/cpp/src/address_field.cc',
'<(libaddressinput_dir)/cpp/src/address_problem.cc',
'<(libaddressinput_dir)/cpp/src/address_ui.cc',