summaryrefslogtreecommitdiff
path: root/chromium/third_party/libaddressinput
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-07-01 12:20:27 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2016-07-01 10:39:40 +0000
commit7366110654eec46f21b6824f302356426f48cd74 (patch)
treef2ff1845183f6117a692bb0c705475c8c13556d5 /chromium/third_party/libaddressinput
parentb92421879c003a0857b2074f7e05b3bbbb326569 (diff)
downloadqtwebengine-chromium-7366110654eec46f21b6824f302356426f48cd74.tar.gz
BASELINE: Update Chromium to 51.0.2704.106
Also add a few extra files we might need for future features. Change-Id: I517c35e43221c610976d347c966d070ad44d4c2b Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'chromium/third_party/libaddressinput')
-rw-r--r--chromium/third_party/libaddressinput/BUILD.gn227
-rw-r--r--chromium/third_party/libaddressinput/LICENSE202
-rw-r--r--chromium/third_party/libaddressinput/OWNERS2
-rw-r--r--chromium/third_party/libaddressinput/README.chromium21
-rw-r--r--chromium/third_party/libaddressinput/chromium/DEPS8
-rw-r--r--chromium/third_party/libaddressinput/chromium/addressinput_util.cc77
-rw-r--r--chromium/third_party/libaddressinput/chromium/addressinput_util.h42
-rw-r--r--chromium/third_party/libaddressinput/chromium/addressinput_util_unittest.cc41
-rw-r--r--chromium/third_party/libaddressinput/chromium/canonicalize_string.cc72
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_address_validator.cc164
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_address_validator.h203
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc892
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_metadata_source.cc112
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_metadata_source.h66
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_metadata_source_unittest.cc100
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_rule_test.cc60
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_storage_impl.cc74
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_storage_impl.h62
-rw-r--r--chromium/third_party/libaddressinput/chromium/chrome_storage_impl_unittest.cc35
-rw-r--r--chromium/third_party/libaddressinput/chromium/fallback_data_store.cc203
-rw-r--r--chromium/third_party/libaddressinput/chromium/fallback_data_store.h22
-rw-r--r--chromium/third_party/libaddressinput/chromium/fallback_data_store_unittest.cc50
-rw-r--r--chromium/third_party/libaddressinput/chromium/input_suggester.cc522
-rw-r--r--chromium/third_party/libaddressinput/chromium/input_suggester.h135
-rw-r--r--chromium/third_party/libaddressinput/chromium/json.cc109
-rw-r--r--chromium/third_party/libaddressinput/chromium/override/basictypes_override.h30
-rw-r--r--chromium/third_party/libaddressinput/chromium/storage_test_runner.cc88
-rw-r--r--chromium/third_party/libaddressinput/chromium/storage_test_runner.h47
-rw-r--r--chromium/third_party/libaddressinput/chromium/string_compare.cc69
-rw-r--r--chromium/third_party/libaddressinput/chromium/string_compare_unittest.cc27
-rwxr-xr-xchromium/third_party/libaddressinput/chromium/tools/require_fields.py51
-rwxr-xr-xchromium/third_party/libaddressinput/chromium/tools/update-strings.py36
-rw-r--r--chromium/third_party/libaddressinput/chromium/trie.cc83
-rw-r--r--chromium/third_party/libaddressinput/chromium/trie.h54
-rw-r--r--chromium/third_party/libaddressinput/chromium/trie_unittest.cc109
-rw-r--r--chromium/third_party/libaddressinput/src/AUTHORS9
-rw-r--r--chromium/third_party/libaddressinput/src/CONTRIBUTORS20
-rw-r--r--chromium/third_party/libaddressinput/src/LICENSE202
-rw-r--r--chromium/third_party/libaddressinput/src/README.md46
-rw-r--r--chromium/third_party/libaddressinput/src/android/README45
-rw-r--r--chromium/third_party/libaddressinput/src/android/build.gradle60
-rw-r--r--chromium/third_party/libaddressinput/src/android/src/androidTest/AndroidManifest.xml26
-rw-r--r--chromium/third_party/libaddressinput/src/android/src/main/AndroidManifest.xml11
-rw-r--r--chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_edittext.xml25
-rw-r--r--chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_layout.xml25
-rw-r--r--chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_spinner.xml24
-rw-r--r--chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_textview.xml26
-rw-r--r--chromium/third_party/libaddressinput/src/android/src/main/res/values/address_strings.xml104
-rw-r--r--chromium/third_party/libaddressinput/src/build.gradle25
-rw-r--r--chromium/third_party/libaddressinput/src/common/README26
-rw-r--r--chromium/third_party/libaddressinput/src/common/build.gradle64
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/LICENSE.chromium27
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/README82
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h96
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h47
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h51
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_input_helper.h67
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h38
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_normalizer.h49
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h68
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h49
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h49
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h113
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h95
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h94
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h48
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/ondemand_supplier.h66
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h103
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h77
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h80
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/source.h56
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h64
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/supplier.h54
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/basictypes.h213
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/scoped_ptr.h444
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/template_util.h111
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/res/messages.grd34
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/res/messages.grdp286
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_data.cc153
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_field.cc47
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_field_util.cc113
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_field_util.h44
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_formatter.cc230
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_input_helper.cc186
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_metadata.cc64
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_normalizer.cc89
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_problem.cc44
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_ui.cc147
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/address_validator.cc49
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/format_element.cc52
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/format_element.h70
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/grit.h36
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/language.cc102
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/language.h49
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/localization.cc190
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/lookup_key.cc153
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/lookup_key.h75
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/null_storage.cc41
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/ondemand_supplier.cc68
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/ondemand_supply_task.cc139
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/ondemand_supply_task.h71
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/post_box_matchers.cc132
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/post_box_matchers.h43
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/preload_supplier.cc373
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/region_data.cc50
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/region_data_builder.cc189
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/region_data_constants.cc1508
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/region_data_constants.h42
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/retriever.cc118
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/retriever.h68
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/rule.cc306
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/rule.h165
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/rule_retriever.cc80
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/rule_retriever.h59
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/cctype_tolower_equal.cc44
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/cctype_tolower_equal.h35
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/json.cc133
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/json.h68
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/lru_cache_using_std.h170
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/md5.cc301
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/md5.h74
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/re2ptr.h46
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/string_compare.cc102
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/string_compare.h52
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/string_split.cc37
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/string_split.h34
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/string_util.cc68
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/util/string_util.h28
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/validating_storage.cc97
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/validating_storage.h64
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/validating_util.cc145
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/validating_util.h60
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/validation_task.cc268
-rw-r--r--chromium/third_party/libaddressinput/src/cpp/src/validation_task.h101
-rw-r--r--chromium/third_party/libaddressinput/src/settings.gradle21
135 files changed, 14687 insertions, 0 deletions
diff --git a/chromium/third_party/libaddressinput/BUILD.gn b/chromium/third_party/libaddressinput/BUILD.gn
new file mode 100644
index 00000000000..864e79003ca
--- /dev/null
+++ b/chromium/third_party/libaddressinput/BUILD.gn
@@ -0,0 +1,227 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//testing/test.gni")
+import("//tools/grit/grit_rule.gni")
+
+libaddressinput_util_files = [
+ "src/cpp/src/address_data.cc",
+ "src/cpp/src/address_field.cc",
+ "src/cpp/src/address_field_util.cc",
+ "src/cpp/src/address_formatter.cc",
+ "src/cpp/src/address_metadata.cc",
+ "src/cpp/src/address_ui.cc",
+ "src/cpp/src/format_element.cc",
+ "src/cpp/src/language.cc",
+ "src/cpp/src/localization.cc",
+ "src/cpp/src/lookup_key.cc",
+ "src/cpp/src/region_data_constants.cc",
+ "src/cpp/src/rule.cc",
+ "src/cpp/src/util/cctype_tolower_equal.cc",
+ "src/cpp/src/util/json.cc",
+ "src/cpp/src/util/string_split.cc",
+ "src/cpp/src/util/string_util.cc",
+]
+
+config("no-newline-eof-warning") {
+ if (is_clang) {
+ cflags = [ "-Wno-newline-eof" ]
+ }
+}
+
+# GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput_strings
+grit("strings") {
+ source = "//chrome/app/address_input_strings.grd"
+ outputs = [
+ "messages.h",
+ "en_messages.cc",
+ "address_input_strings_am.pak",
+ "address_input_strings_ar.pak",
+ "address_input_strings_bg.pak",
+ "address_input_strings_bn.pak",
+ "address_input_strings_ca.pak",
+ "address_input_strings_cs.pak",
+ "address_input_strings_da.pak",
+ "address_input_strings_de.pak",
+ "address_input_strings_el.pak",
+ "address_input_strings_en-GB.pak",
+ "address_input_strings_en-US.pak",
+ "address_input_strings_es.pak",
+ "address_input_strings_es-419.pak",
+ "address_input_strings_et.pak",
+ "address_input_strings_fa.pak",
+ "address_input_strings_fake-bidi.pak",
+ "address_input_strings_fi.pak",
+ "address_input_strings_fil.pak",
+ "address_input_strings_fr.pak",
+ "address_input_strings_gu.pak",
+ "address_input_strings_he.pak",
+ "address_input_strings_hi.pak",
+ "address_input_strings_hr.pak",
+ "address_input_strings_hu.pak",
+ "address_input_strings_id.pak",
+ "address_input_strings_it.pak",
+ "address_input_strings_ja.pak",
+ "address_input_strings_kn.pak",
+ "address_input_strings_ko.pak",
+ "address_input_strings_lt.pak",
+ "address_input_strings_lv.pak",
+ "address_input_strings_ml.pak",
+ "address_input_strings_mr.pak",
+ "address_input_strings_ms.pak",
+ "address_input_strings_nl.pak",
+ "address_input_strings_nb.pak",
+ "address_input_strings_pl.pak",
+ "address_input_strings_pt-BR.pak",
+ "address_input_strings_pt-PT.pak",
+ "address_input_strings_ro.pak",
+ "address_input_strings_ru.pak",
+ "address_input_strings_sk.pak",
+ "address_input_strings_sl.pak",
+ "address_input_strings_sr.pak",
+ "address_input_strings_sv.pak",
+ "address_input_strings_sw.pak",
+ "address_input_strings_ta.pak",
+ "address_input_strings_te.pak",
+ "address_input_strings_th.pak",
+ "address_input_strings_tr.pak",
+ "address_input_strings_uk.pak",
+ "address_input_strings_vi.pak",
+ "address_input_strings_zh-CN.pak",
+ "address_input_strings_zh-TW.pak",
+ ]
+
+ if (is_ios) {
+ # iOS uses "pt" for pt-BR" and "es-MX" for "es-419".
+ outputs -= [
+ "address_input_strings_pt-BR.pak",
+ "address_input_strings_es-419.pak",
+ ]
+ outputs += [
+ "address_input_strings_pt.pak",
+ "address_input_strings_es-MX.pak",
+ ]
+ }
+
+ configs = [ ":no-newline-eof-warning" ]
+}
+
+config("libaddressinput_config") {
+ defines = [
+ "I18N_ADDRESSINPUT_USE_BASICTYPES_OVERRIDE=1",
+ "I18N_ADDRESS_VALIDATION_DATA_URL=\"https://i18napis.appspot.com/ssl-aggregate-address/\"",
+ ]
+ include_dirs = [
+ "src/cpp/include",
+ "chromium/override",
+ ]
+}
+
+# This target provides basic functionality which is cooked into the build.
+# GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput_util
+static_library("util") {
+ sources = libaddressinput_util_files
+ sources += [
+ "chromium/addressinput_util.cc",
+ "chromium/json.cc",
+ ]
+ sources -= [ "src/cpp/src/util/json.cc" ]
+
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [
+ ":no-newline-eof-warning",
+ "//build/config/compiler:no_chromium_code",
+ ]
+
+ public_configs = [ ":libaddressinput_config" ]
+
+ include_dirs = [ "$root_gen_dir/third_party/libaddressinput" ]
+
+ deps = [
+ ":strings",
+ "//base",
+ "//base:i18n",
+ "//third_party/icu",
+ "//third_party/re2",
+ ]
+}
+
+if (!is_android || use_aura) {
+ # The list of files in libaddressinput.gypi.
+ gypi_values = exec_script("//build/gypi_to_gn.py",
+ [ rebase_path("src/cpp/libaddressinput.gypi") ],
+ "scope",
+ [ "src/cpp/libaddressinput.gypi" ])
+
+ # This target provides more complicated functionality like pinging servers
+ # for validation rules.
+ # GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput
+ static_library("libaddressinput") {
+ sources = rebase_path(gypi_values.libaddressinput_files, ".", "src/cpp")
+ sources += [
+ "chromium/chrome_address_validator.cc",
+ "chromium/chrome_metadata_source.cc",
+ "chromium/chrome_storage_impl.cc",
+ "chromium/fallback_data_store.cc",
+ "chromium/input_suggester.cc",
+ "chromium/string_compare.cc",
+ "chromium/trie.cc",
+ ]
+ sources -= libaddressinput_util_files
+ sources -= [ "src/cpp/src/util/string_compare.cc" ]
+
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ "//build/config/compiler:no_chromium_code" ]
+
+ public_configs = [ ":libaddressinput_config" ]
+
+ deps = [
+ ":strings",
+ ":util",
+ "//base",
+ "//base:i18n",
+ "//components/prefs",
+ "//net",
+ "//third_party/icu",
+ "//third_party/re2",
+ ]
+ }
+
+ test("libaddressinput_unittests") {
+ sources =
+ rebase_path(gypi_values.libaddressinput_test_files, ".", "src/cpp")
+ sources += [
+ "chromium/addressinput_util_unittest.cc",
+ "chromium/chrome_address_validator_unittest.cc",
+ "chromium/chrome_metadata_source_unittest.cc",
+ "chromium/chrome_storage_impl_unittest.cc",
+ "chromium/fallback_data_store_unittest.cc",
+ "chromium/storage_test_runner.cc",
+ "chromium/string_compare_unittest.cc",
+ "chromium/trie_unittest.cc",
+ ]
+
+ if (is_ios) {
+ # TODO(rouslan): This tests uses ASSERT_DEATH which is not supported on
+ # iOS. Re-enable once http://crbug.com/595645 is fixed.
+ sources -= [ "src/cpp/test/address_data_test.cc" ]
+ }
+
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ "//build/config/compiler:no_chromium_code" ]
+
+ defines = [ "TEST_DATA_DIR=\"third_party/libaddressinput/src/testdata\"" ]
+
+ include_dirs = [ "src/cpp/src" ]
+
+ deps = [
+ ":libaddressinput",
+ ":strings",
+ "//base/test:run_all_unittests",
+ "//components/prefs",
+ "//net:test_support",
+ "//testing/gtest",
+ ]
+ }
+}
diff --git a/chromium/third_party/libaddressinput/LICENSE b/chromium/third_party/libaddressinput/LICENSE
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/chromium/third_party/libaddressinput/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/chromium/third_party/libaddressinput/OWNERS b/chromium/third_party/libaddressinput/OWNERS
new file mode 100644
index 00000000000..d379e0309a9
--- /dev/null
+++ b/chromium/third_party/libaddressinput/OWNERS
@@ -0,0 +1,2 @@
+rouslan@chromium.org
+estade@chromium.org
diff --git a/chromium/third_party/libaddressinput/README.chromium b/chromium/third_party/libaddressinput/README.chromium
new file mode 100644
index 00000000000..9e7ff6edb91
--- /dev/null
+++ b/chromium/third_party/libaddressinput/README.chromium
@@ -0,0 +1,21 @@
+Name: The library to input, validate, and display addresses.
+Short Name: libaddressinput
+URL: https://github.com/googlei18n/libaddressinput
+Version: 0
+Date: 10 November 2014
+Revision: 678a7f55a2ae7ccf417b4809e602b808b56a8ddb
+License: Apache 2.0
+License File: LICENSE
+Security Critical: no
+
+Description:
+
+This library lets you enter, validate, and display an address with correct
+semantics for many countries around the world. The library uses the serialized
+validation rules from a Google-managed server (without SLA) at
+https://i18napis.appspot.com/ssl-aggregate-address. The library is used in
+requestAutocomplete dialog and autofill.
+
+Local Modifications:
+- Use Chrome's version of JSON reader in chromium/json.cc.
+- Use Chrome's version of loose string comparison in chromium/string_compare.cc.
diff --git a/chromium/third_party/libaddressinput/chromium/DEPS b/chromium/third_party/libaddressinput/chromium/DEPS
new file mode 100644
index 00000000000..b55c0fa48ac
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/DEPS
@@ -0,0 +1,8 @@
+include_rules = [
+ '+base',
+ "+components/prefs",
+ '+net',
+ '+testing',
+ '+third_party/icu',
+ '+url',
+]
diff --git a/chromium/third_party/libaddressinput/chromium/addressinput_util.cc b/chromium/third_party/libaddressinput/chromium/addressinput_util.cc
new file mode 100644
index 00000000000..ca10d41ddef
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/addressinput_util.cc
@@ -0,0 +1,77 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/addressinput_util.h"
+
+#include <stddef.h>
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h"
+
+namespace autofill {
+namespace addressinput {
+
+namespace {
+
+using ::i18n::addressinput::AddressData;
+using ::i18n::addressinput::AddressField;
+using ::i18n::addressinput::AddressProblem;
+using ::i18n::addressinput::IsFieldRequired;
+
+using ::i18n::addressinput::MISSING_REQUIRED_FIELD;
+
+// Returns true if the |problem| should not be reported for the |field| because
+// the |filter| excludes it.
+bool FilterExcludes(const std::multimap<AddressField, AddressProblem>* filter,
+ AddressField field,
+ AddressProblem problem) {
+ return filter != NULL && !filter->empty() &&
+ std::find(filter->begin(),
+ filter->end(),
+ std::multimap<AddressField, AddressProblem>::value_type(
+ field, problem)) == filter->end();
+}
+
+} // namespace
+
+bool HasAllRequiredFields(const AddressData& address_to_check) {
+ std::multimap<AddressField, AddressProblem> problems;
+ ValidateRequiredFields(address_to_check, NULL, &problems);
+ return problems.empty();
+}
+
+void ValidateRequiredFields(
+ const AddressData& address_to_check,
+ const std::multimap<AddressField, AddressProblem>* filter,
+ std::multimap<AddressField, AddressProblem>* problems) {
+ DCHECK(problems);
+
+ static const AddressField kFields[] = {
+ ::i18n::addressinput::COUNTRY,
+ ::i18n::addressinput::ADMIN_AREA,
+ ::i18n::addressinput::LOCALITY,
+ ::i18n::addressinput::DEPENDENT_LOCALITY,
+ ::i18n::addressinput::SORTING_CODE,
+ ::i18n::addressinput::POSTAL_CODE,
+ ::i18n::addressinput::STREET_ADDRESS,
+ // ORGANIZATION is never required.
+ ::i18n::addressinput::RECIPIENT
+ };
+
+ for (size_t i = 0; i < arraysize(kFields); ++i) {
+ AddressField field = kFields[i];
+ if (address_to_check.IsFieldEmpty(field) &&
+ IsFieldRequired(field, address_to_check.region_code) &&
+ !FilterExcludes(filter, field, MISSING_REQUIRED_FIELD)) {
+ problems->insert(std::make_pair(field, MISSING_REQUIRED_FIELD));
+ }
+ }
+}
+
+} // namespace addressinput
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/addressinput_util.h b/chromium/third_party/libaddressinput/chromium/addressinput_util.h
new file mode 100644
index 00000000000..7c888a7b1f2
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/addressinput_util.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_ADDRESSINPUT_UTIL_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_ADDRESSINPUT_UTIL_H_
+
+#include <map>
+
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h"
+
+namespace i18n {
+namespace addressinput {
+struct AddressData;
+}
+}
+
+namespace autofill {
+namespace addressinput {
+
+// Returns true if |address_to_check| has all of its required fields.
+bool HasAllRequiredFields(
+ const ::i18n::addressinput::AddressData& address_to_check);
+
+// Validates required fields in |address_to_check| without loading rules from
+// the server. The |problems| parameter cannot be NULL. Does not take ownership
+// of its parameters.
+//
+// See documentation of ::i18n::addressinput::AddressValidator::Validate() for
+// description of |filter| and |problems|.
+void ValidateRequiredFields(
+ const ::i18n::addressinput::AddressData& address_to_check,
+ const std::multimap< ::i18n::addressinput::AddressField,
+ ::i18n::addressinput::AddressProblem>* filter,
+ std::multimap< ::i18n::addressinput::AddressField,
+ ::i18n::addressinput::AddressProblem>* problems);
+
+} // namespace addressinput
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_ADDRESSINPUT_UTIL_H_
diff --git a/chromium/third_party/libaddressinput/chromium/addressinput_util_unittest.cc b/chromium/third_party/libaddressinput/chromium/addressinput_util_unittest.cc
new file mode 100644
index 00000000000..b68ea81760d
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/addressinput_util_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/addressinput_util.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+
+namespace autofill {
+namespace addressinput {
+
+using ::i18n::addressinput::AddressData;
+
+TEST(AddressinputUtilTest, AddressRequiresRegionCode) {
+ AddressData address;
+ EXPECT_FALSE(HasAllRequiredFields(address));
+}
+
+TEST(AddressinputUtilTest, UsRequiresState) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "90291";
+ // Leave state empty.
+ address.locality = "Los Angeles";
+ address.address_line.push_back("340 Main St.");
+ EXPECT_FALSE(HasAllRequiredFields(address));
+}
+
+TEST(AddressinputUtilTest, CompleteAddressReturnsTrue) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "90291";
+ address.administrative_area = "CA";
+ address.locality = "Los Angeles";
+ address.address_line.push_back("340 Main St.");
+ EXPECT_TRUE(HasAllRequiredFields(address));
+}
+
+} // namespace addressinput
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/canonicalize_string.cc b/chromium/third_party/libaddressinput/chromium/canonicalize_string.cc
new file mode 100644
index 00000000000..d1fc1ce10aa
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/canonicalize_string.cc
@@ -0,0 +1,72 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/src/cpp/src/util/canonicalize_string.h"
+
+#include <stdint.h>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "third_party/icu/source/common/unicode/errorcode.h"
+#include "third_party/icu/source/common/unicode/locid.h"
+#include "third_party/icu/source/common/unicode/unistr.h"
+#include "third_party/icu/source/common/unicode/utypes.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/util/scoped_ptr.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+class ChromeStringCanonicalizer : public StringCanonicalizer {
+ public:
+ ChromeStringCanonicalizer()
+ : error_code_(U_ZERO_ERROR),
+ collator_(
+ icu::Collator::createInstance(
+ icu::Locale::getRoot(), error_code_)) {
+ collator_->setStrength(icu::Collator::PRIMARY);
+ DCHECK(U_SUCCESS(error_code_));
+ }
+
+ virtual ~ChromeStringCanonicalizer() {}
+
+ // StringCanonicalizer implementation.
+ virtual std::string CanonicalizeString(const std::string& original) {
+ // Returns a canonical version of the string that can be used for comparing
+ // strings regardless of diacritics and capitalization.
+ // CanonicalizeString("Texas") == CanonicalizeString("T\u00E9xas");
+ // CanonicalizeString("Texas") == CanonicalizeString("teXas");
+ // CanonicalizeString("Texas") != CanonicalizeString("California");
+ //
+ // The output is not human-readable.
+ // CanonicalizeString("Texas") != "Texas";
+ icu::UnicodeString icu_str(
+ original.c_str(), static_cast<int32_t>(original.length()));
+ int32_t buffer_size = collator_->getSortKey(icu_str, NULL, 0);
+ scoped_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
+ DCHECK(buffer.get());
+ int32_t filled_size =
+ collator_->getSortKey(icu_str, buffer.get(), buffer_size);
+ DCHECK_EQ(buffer_size, filled_size);
+ return std::string(reinterpret_cast<const char*>(buffer.get()));
+ }
+
+ private:
+ UErrorCode error_code_;
+ scoped_ptr<icu::Collator> collator_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeStringCanonicalizer);
+};
+
+} // namespace
+
+// static
+scoped_ptr<StringCanonicalizer> StringCanonicalizer::Build() {
+ return scoped_ptr<StringCanonicalizer>(new ChromeStringCanonicalizer);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_address_validator.cc b/chromium/third_party/libaddressinput/chromium/chrome_address_validator.cc
new file mode 100644
index 00000000000..c55ab49ca47
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_address_validator.cc
@@ -0,0 +1,164 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
+
+#include <cmath>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "third_party/libaddressinput/chromium/addressinput_util.h"
+#include "third_party/libaddressinput/chromium/input_suggester.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_normalizer.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+
+namespace autofill {
+namespace {
+
+using ::i18n::addressinput::AddressData;
+using ::i18n::addressinput::AddressField;
+using ::i18n::addressinput::AddressNormalizer;
+using ::i18n::addressinput::BuildCallback;
+using ::i18n::addressinput::FieldProblemMap;
+using ::i18n::addressinput::PreloadSupplier;
+using ::i18n::addressinput::Source;
+using ::i18n::addressinput::Storage;
+
+using ::i18n::addressinput::ADMIN_AREA;
+using ::i18n::addressinput::DEPENDENT_LOCALITY;
+using ::i18n::addressinput::POSTAL_CODE;
+
+// The maximum number attempts to load rules.
+static const int kMaxAttemptsNumber = 8;
+
+} // namespace
+
+AddressValidator::AddressValidator(scoped_ptr<Source> source,
+ scoped_ptr<Storage> storage,
+ LoadRulesListener* load_rules_listener)
+ : supplier_(new PreloadSupplier(source.release(),
+ storage.release())),
+ input_suggester_(new InputSuggester(supplier_.get())),
+ normalizer_(new AddressNormalizer(supplier_.get())),
+ validator_(new ::i18n::addressinput::AddressValidator(supplier_.get())),
+ validated_(BuildCallback(this, &AddressValidator::Validated)),
+ rules_loaded_(BuildCallback(this, &AddressValidator::RulesLoaded)),
+ load_rules_listener_(load_rules_listener),
+ weak_factory_(this) {}
+
+AddressValidator::~AddressValidator() {}
+
+void AddressValidator::LoadRules(const std::string& region_code) {
+ attempts_number_[region_code] = 0;
+ supplier_->LoadRules(region_code, *rules_loaded_);
+}
+
+AddressValidator::Status AddressValidator::ValidateAddress(
+ const AddressData& address,
+ const FieldProblemMap* filter,
+ FieldProblemMap* problems) const {
+ if (supplier_->IsPending(address.region_code)) {
+ if (problems)
+ addressinput::ValidateRequiredFields(address, filter, problems);
+ return RULES_NOT_READY;
+ }
+
+ if (!supplier_->IsLoaded(address.region_code)) {
+ if (problems)
+ addressinput::ValidateRequiredFields(address, filter, problems);
+ return RULES_UNAVAILABLE;
+ }
+
+ if (!problems)
+ return SUCCESS;
+
+ validator_->Validate(address,
+ true, // Allow postal office boxes.
+ true, // Require recipient name.
+ filter,
+ problems,
+ *validated_);
+
+ return SUCCESS;
+}
+
+AddressValidator::Status AddressValidator::GetSuggestions(
+ const AddressData& user_input,
+ AddressField focused_field,
+ size_t suggestion_limit,
+ std::vector<AddressData>* suggestions) const {
+ if (supplier_->IsPending(user_input.region_code))
+ return RULES_NOT_READY;
+
+ if (!supplier_->IsLoaded(user_input.region_code))
+ return RULES_UNAVAILABLE;
+
+ if (!suggestions)
+ return SUCCESS;
+
+ suggestions->clear();
+
+ if (focused_field == POSTAL_CODE ||
+ (focused_field >= ADMIN_AREA && focused_field <= DEPENDENT_LOCALITY)) {
+ input_suggester_->GetSuggestions(
+ user_input, focused_field, suggestion_limit, suggestions);
+ }
+
+ return SUCCESS;
+}
+
+bool AddressValidator::CanonicalizeAdministrativeArea(
+ AddressData* address) const {
+ if (!supplier_->IsLoaded(address->region_code))
+ return false;
+
+ // TODO: It would probably be beneficial to use the full canonicalization.
+ AddressData tmp(*address);
+ normalizer_->Normalize(&tmp);
+ address->administrative_area = tmp.administrative_area;
+
+ return true;
+}
+
+AddressValidator::AddressValidator()
+ : load_rules_listener_(NULL), weak_factory_(this) {}
+
+base::TimeDelta AddressValidator::GetBaseRetryPeriod() const {
+ return base::TimeDelta::FromSeconds(8);
+}
+
+void AddressValidator::Validated(bool success,
+ const AddressData&,
+ const FieldProblemMap&) {
+ DCHECK(success);
+}
+
+void AddressValidator::RulesLoaded(bool success,
+ const std::string& region_code,
+ int) {
+ if (load_rules_listener_)
+ load_rules_listener_->OnAddressValidationRulesLoaded(region_code, success);
+
+ // Count the first failed attempt to load rules as well.
+ if (success || attempts_number_[region_code] + 1 >= kMaxAttemptsNumber)
+ return;
+
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&AddressValidator::RetryLoadRules,
+ weak_factory_.GetWeakPtr(),
+ region_code),
+ GetBaseRetryPeriod() * pow(2, attempts_number_[region_code]++));
+}
+
+void AddressValidator::RetryLoadRules(const std::string& region_code) {
+ // Do not reset retry count.
+ supplier_->LoadRules(region_code, *rules_loaded_);
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_address_validator.h b/chromium/third_party/libaddressinput/chromium/chrome_address_validator.h
new file mode 100644
index 00000000000..94ae50434e9
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_address_validator.h
@@ -0,0 +1,203 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_
+
+#include <stddef.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h"
+
+namespace i18n {
+namespace addressinput {
+class AddressNormalizer;
+class Source;
+class Storage;
+struct AddressData;
+}
+}
+
+namespace autofill {
+
+class InputSuggester;
+
+// The object to be notified when loading of address validation rules is
+// finished.
+class LoadRulesListener {
+ public:
+ virtual ~LoadRulesListener() {}
+
+ // Called when the validation rules for the |region_code| have been loaded.
+ // The validation rules include the generic rules for the |region_code| and
+ // specific rules for the country's administrative areas, localities, and
+ // dependent localities. If a country has language-specific validation rules,
+ // then these are also loaded.
+ //
+ // The |success| parameter is true when the rules were loaded successfully.
+ virtual void OnAddressValidationRulesLoaded(const std::string& region_code,
+ bool success) = 0;
+};
+
+// Interface to the libaddressinput AddressValidator for Chromium Autofill. The
+// class is named AddressValidator to simplify switching between libaddressinput
+// and this version.
+//
+// It's not possible to name this file address_validator.h because some
+// compilers do not handle multiple files with the same name (although in
+// different directories) gracefully. This class is a shim between upstream
+// libaddressinput API and the API that Chrome expects, hence the file name
+// chrome_address_validator.h.
+class AddressValidator {
+ public:
+ // The status of address validation.
+ enum Status {
+ // Address validation completed successfully. Check |problems| to see if any
+ // problems were found.
+ SUCCESS,
+
+ // The validation rules are not available, because LoadRules() was not
+ // called or failed. Reload the rules.
+ RULES_UNAVAILABLE,
+
+ // The validation rules are being loaded. Try again later.
+ RULES_NOT_READY
+ };
+
+ // Takes ownership of |source| and |storage|.
+ AddressValidator(scoped_ptr< ::i18n::addressinput::Source> source,
+ scoped_ptr< ::i18n::addressinput::Storage> storage,
+ LoadRulesListener* load_rules_listener);
+
+ virtual ~AddressValidator();
+
+ // Loads the generic validation rules for |region_code| and specific rules
+ // for the region's administrative areas, localities, and dependent
+ // localities. A typical data size is 10KB. The largest is 250KB. If a region
+ // has language-specific validation rules, then these are also loaded.
+ //
+ // Example rule:
+ // https://i18napis.appspot.com/ssl-aggregate-address/data/US
+ //
+ // If the rules are already in progress of being loaded, it does nothing.
+ // Invokes |load_rules_listener| when the loading has finished.
+ virtual void LoadRules(const std::string& region_code);
+
+ // Validates the |address| and populates |problems| with the validation
+ // problems, filtered according to the |filter| parameter.
+ //
+ // If the |filter| is empty, then all discovered validation problems are
+ // returned. If the |filter| contains problem elements, then only the problems
+ // in the |filter| may be returned.
+ virtual Status ValidateAddress(
+ const ::i18n::addressinput::AddressData& address,
+ const ::i18n::addressinput::FieldProblemMap* filter,
+ ::i18n::addressinput::FieldProblemMap* problems) const;
+
+ // Fills in |suggestions| for the partially typed in |user_input|, assuming
+ // the user is typing in the |focused_field|. If the number of |suggestions|
+ // is over the |suggestion_limit|, then returns no |suggestions| at all.
+ //
+ // If the |solutions| parameter is NULL, the checks whether the validation
+ // rules are available, but does not fill in suggestions.
+ //
+ // Sample user input 1:
+ // country code = "US"
+ // postal code = "90066"
+ // focused field = POSTAL_CODE
+ // suggestions limit = 1
+ // Suggestion:
+ // [{administrative_area: "CA"}]
+ //
+ // Sample user input 2:
+ // country code = "CN"
+ // dependent locality = "Zongyang"
+ // focused field = DEPENDENT_LOCALITY
+ // suggestions limit = 10
+ // Suggestion:
+ // [{dependent_locality: "Zongyang Xian",
+ // locality: "Anqing Shi",
+ // administrative_area: "Anhui Sheng"}]
+ virtual Status GetSuggestions(
+ const ::i18n::addressinput::AddressData& user_input,
+ ::i18n::addressinput::AddressField focused_field,
+ size_t suggestion_limit,
+ std::vector< ::i18n::addressinput::AddressData>* suggestions) const;
+
+ // Canonicalizes the administrative area in |address_data|. For example,
+ // "texas" changes to "TX". Returns true on success, otherwise leaves
+ // |address_data| alone and returns false.
+ virtual bool CanonicalizeAdministrativeArea(
+ ::i18n::addressinput::AddressData* address) const;
+
+ protected:
+ // Constructor used only for MockAddressValidator.
+ AddressValidator();
+
+ // Returns the period of time to wait between the first attempt's failure and
+ // the second attempt's initiation to load rules. Exposed for testing.
+ virtual base::TimeDelta GetBaseRetryPeriod() const;
+
+ private:
+ // Verifies that |validator_| succeeded. Invoked by |validated_| callback.
+ void Validated(bool success,
+ const ::i18n::addressinput::AddressData&,
+ const ::i18n::addressinput::FieldProblemMap&);
+
+ // Invokes the |load_rules_listener_|, if it's not NULL. Called by
+ // |rules_loaded_| callback.
+ void RulesLoaded(bool success, const std::string& region_code, int);
+
+ // Retries loading rules without resetting the retry counter.
+ void RetryLoadRules(const std::string& region_code);
+
+ // Loads and stores aggregate rules at COUNTRY level.
+ const scoped_ptr< ::i18n::addressinput::PreloadSupplier> supplier_;
+
+ // Suggests addresses based on user input.
+ const scoped_ptr<InputSuggester> input_suggester_;
+
+ // Normalizes addresses into a canonical form.
+ const scoped_ptr< ::i18n::addressinput::AddressNormalizer> normalizer_;
+
+ // Validates addresses.
+ const scoped_ptr<const ::i18n::addressinput::AddressValidator> validator_;
+
+ // The callback that |validator_| invokes when it finished validating an
+ // address.
+ const scoped_ptr<const ::i18n::addressinput::AddressValidator::Callback>
+ validated_;
+
+ // The callback that |supplier_| invokes when it finished loading rules.
+ const scoped_ptr<const ::i18n::addressinput::PreloadSupplier::Callback>
+ rules_loaded_;
+
+ // Not owned delegate to invoke when |suppler_| finished loading rules. Can be
+ // NULL.
+ LoadRulesListener* const load_rules_listener_;
+
+ // A mapping of region codes to the number of attempts to retry loading rules.
+ std::map<std::string, int> attempts_number_;
+
+ // Member variables should appear before the WeakPtrFactory, to ensure that
+ // any WeakPtrs to AddressValidator are invalidated before its members
+ // variable's destructors are executed, rendering them invalid.
+ base::WeakPtrFactory<AddressValidator> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressValidator);
+};
+
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_ADDRESS_VALIDATOR_H_
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc b/chromium/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc
new file mode 100644
index 00000000000..a7f9861247f
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc
@@ -0,0 +1,892 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
+
+#include <stddef.h>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+#include "third_party/libaddressinput/src/cpp/test/testdata_source.h"
+
+namespace autofill {
+
+using ::i18n::addressinput::AddressData;
+using ::i18n::addressinput::AddressField;
+using ::i18n::addressinput::AddressProblem;
+using ::i18n::addressinput::BuildCallback;
+using ::i18n::addressinput::FieldProblemMap;
+using ::i18n::addressinput::GetRegionCodes;
+using ::i18n::addressinput::NullStorage;
+using ::i18n::addressinput::Source;
+using ::i18n::addressinput::Storage;
+using ::i18n::addressinput::TestdataSource;
+
+using ::i18n::addressinput::COUNTRY;
+using ::i18n::addressinput::ADMIN_AREA;
+using ::i18n::addressinput::LOCALITY;
+using ::i18n::addressinput::DEPENDENT_LOCALITY;
+using ::i18n::addressinput::SORTING_CODE;
+using ::i18n::addressinput::POSTAL_CODE;
+using ::i18n::addressinput::STREET_ADDRESS;
+using ::i18n::addressinput::RECIPIENT;
+
+using ::i18n::addressinput::INVALID_FORMAT;
+using ::i18n::addressinput::MISMATCHING_VALUE;
+using ::i18n::addressinput::MISSING_REQUIRED_FIELD;
+using ::i18n::addressinput::UNEXPECTED_FIELD;
+using ::i18n::addressinput::UNKNOWN_VALUE;
+using ::i18n::addressinput::USES_P_O_BOX;
+
+class AddressValidatorTest : public testing::Test, LoadRulesListener {
+ protected:
+ AddressValidatorTest()
+ : validator_(
+ new AddressValidator(scoped_ptr<Source>(new TestdataSource(true)),
+ scoped_ptr<Storage>(new NullStorage),
+ this)) {
+ validator_->LoadRules("US");
+ }
+
+ virtual ~AddressValidatorTest() {}
+
+ const scoped_ptr<AddressValidator> validator_;
+
+ private:
+ // LoadRulesListener implementation.
+ virtual void OnAddressValidationRulesLoaded(const std::string& country_code,
+ bool success) override {
+ AddressData address_data;
+ address_data.region_code = country_code;
+ FieldProblemMap dummy;
+ AddressValidator::Status status =
+ validator_->ValidateAddress(address_data, NULL, &dummy);
+ ASSERT_EQ(success, status == AddressValidator::SUCCESS);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(AddressValidatorTest);
+};
+
+// Use this test fixture if you're going to use a region with a large set of
+// validation rules. All rules should be loaded in SetUpTestCase().
+class LargeAddressValidatorTest : public testing::Test {
+ protected:
+ LargeAddressValidatorTest() {}
+ virtual ~LargeAddressValidatorTest() {}
+
+ static void SetUpTestCase() {
+ validator_ =
+ new AddressValidator(scoped_ptr<Source>(new TestdataSource(true)),
+ scoped_ptr<Storage>(new NullStorage),
+ NULL);
+ validator_->LoadRules("CN");
+ validator_->LoadRules("KR");
+ validator_->LoadRules("TW");
+ }
+
+ static void TearDownTestcase() {
+ delete validator_;
+ validator_ = NULL;
+ }
+
+ // Owned shared instance of validator with large sets validation rules.
+ static AddressValidator* validator_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LargeAddressValidatorTest);
+};
+
+AddressValidator* LargeAddressValidatorTest::validator_ = NULL;
+
+TEST_F(AddressValidatorTest, RegionHasRules) {
+ const std::vector<std::string>& region_codes = GetRegionCodes();
+ AddressData address;
+ for (size_t i = 0; i < region_codes.size(); ++i) {
+ SCOPED_TRACE("For region: " + region_codes[i]);
+ validator_->LoadRules(region_codes[i]);
+ address.region_code = region_codes[i];
+ FieldProblemMap dummy;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &dummy));
+ }
+}
+
+TEST_F(AddressValidatorTest, EmptyAddressNoFatalFailure) {
+ AddressData address;
+ address.region_code = "US";
+
+ FieldProblemMap dummy;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &dummy));
+}
+
+TEST_F(AddressValidatorTest, UsStateNamesAreValidEntries) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "California";
+
+ FieldProblemMap filter;
+ filter.insert(std::make_pair(ADMIN_AREA, UNKNOWN_VALUE));
+ FieldProblemMap problems;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, &filter, &problems));
+ EXPECT_TRUE(problems.empty());
+}
+
+TEST_F(AddressValidatorTest, USZipCode) {
+ AddressData address;
+ address.recipient = "Mr. Smith";
+ address.address_line.push_back("340 Main St.");
+ address.locality = "Venice";
+ address.administrative_area = "CA";
+ address.region_code = "US";
+
+ // Valid Californian zip code.
+ address.postal_code = "90291";
+ FieldProblemMap problems;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ problems.clear();
+
+ // An extended, valid Californian zip code.
+ address.postal_code = "90210-1234";
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ problems.clear();
+
+ // New York zip code (which is invalid for California).
+ address.postal_code = "12345";
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_EQ(1U, problems.size());
+ EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
+ EXPECT_EQ(problems.begin()->second, MISMATCHING_VALUE);
+
+ problems.clear();
+
+ // A zip code with a "90" in the middle.
+ address.postal_code = "12903";
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_EQ(1U, problems.size());
+ EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
+ EXPECT_EQ(problems.begin()->second, MISMATCHING_VALUE);
+
+ problems.clear();
+
+ // Invalid zip code (too many digits).
+ address.postal_code = "902911";
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_EQ(1U, problems.size());
+ EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
+ EXPECT_EQ(problems.begin()->second, INVALID_FORMAT);
+
+ problems.clear();
+
+ // Invalid zip code (too few digits).
+ address.postal_code = "9029";
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_EQ(1U, problems.size());
+ EXPECT_EQ(problems.begin()->first, POSTAL_CODE);
+ EXPECT_EQ(problems.begin()->second, INVALID_FORMAT);
+}
+
+TEST_F(AddressValidatorTest, BasicValidation) {
+ // US rules should always be available, even though this load call fails.
+ validator_->LoadRules("US");
+ AddressData address;
+ address.region_code = "US";
+ address.language_code = "en";
+ address.administrative_area = "TX";
+ address.locality = "Paris";
+ address.postal_code = "75461";
+ address.address_line.push_back("123 Main St");
+ address.recipient = "Mr. Smith";
+ FieldProblemMap problems;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ // The display name works as well as the key.
+ address.administrative_area = "Texas";
+ problems.clear();
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ // Ignore capitalization.
+ address.administrative_area = "tx";
+ problems.clear();
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ // Ignore capitalization.
+ address.administrative_area = "teXas";
+ problems.clear();
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+
+ // Ignore diacriticals.
+ address.administrative_area = base::WideToUTF8(L"T\u00E9xas");
+ problems.clear();
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_TRUE(problems.empty());
+}
+
+TEST_F(AddressValidatorTest, BasicValidationFailure) {
+ // US rules should always be available, even though this load call fails.
+ validator_->LoadRules("US");
+ AddressData address;
+ address.region_code = "US";
+ address.language_code = "en";
+ address.administrative_area = "XT";
+ address.locality = "Paris";
+ address.postal_code = "75461";
+ address.address_line.push_back("123 Main St");
+ address.recipient = "Mr. Smith";
+ FieldProblemMap problems;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(address, NULL, &problems));
+
+ ASSERT_EQ(1U, problems.size());
+ EXPECT_EQ(UNKNOWN_VALUE, problems.begin()->second);
+ EXPECT_EQ(ADMIN_AREA, problems.begin()->first);
+}
+
+TEST_F(AddressValidatorTest, NoNullSuggestionsCrash) {
+ AddressData address;
+ address.region_code = "US";
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, COUNTRY, 1, NULL));
+}
+
+TEST_F(AddressValidatorTest, SuggestAdminAreaForPostalCode) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "90291";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("CA", suggestions[0].administrative_area);
+ EXPECT_EQ("90291", suggestions[0].postal_code);
+}
+
+TEST_F(LargeAddressValidatorTest, SuggestLocalityForPostalCodeWithAdminArea) {
+ AddressData address;
+ address.region_code = "TW";
+ address.postal_code = "515";
+ address.administrative_area = "Changhua";
+ address.language_code = "zh-Latn";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Dacun Township", suggestions[0].locality);
+ EXPECT_EQ("Changhua County", suggestions[0].administrative_area);
+ EXPECT_EQ("515", suggestions[0].postal_code);
+}
+
+TEST_F(LargeAddressValidatorTest, SuggestAdminAreaForPostalCodeWithLocality) {
+ AddressData address;
+ address.region_code = "TW";
+ address.postal_code = "515";
+ address.locality = "Dacun";
+ address.language_code = "zh-Latn";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Dacun Township", suggestions[0].locality);
+ EXPECT_EQ("Changhua County", suggestions[0].administrative_area);
+ EXPECT_EQ("515", suggestions[0].postal_code);
+}
+
+TEST_F(AddressValidatorTest, NoSuggestForPostalCodeWithWrongAdminArea) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "90066";
+ address.postal_code = "TX";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(LargeAddressValidatorTest, SuggestForLocality) {
+ AddressData address;
+ address.region_code = "CN";
+ address.locality = "Anqin";
+ address.language_code = "zh-Latn";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, LOCALITY, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Anqing Shi", suggestions[0].locality);
+ EXPECT_EQ("Anhui Sheng", suggestions[0].administrative_area);
+}
+
+TEST_F(LargeAddressValidatorTest, SuggestForLocalityAndAdminArea) {
+ AddressData address;
+ address.region_code = "CN";
+ address.locality = "Anqing";
+ address.administrative_area = "Anhui";
+ address.language_code = "zh-Latn";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, LOCALITY, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_TRUE(suggestions[0].dependent_locality.empty());
+ EXPECT_EQ("Anqing Shi", suggestions[0].locality);
+ EXPECT_EQ("Anhui Sheng", suggestions[0].administrative_area);
+}
+
+TEST_F(LargeAddressValidatorTest, SuggestForAdminAreaAndLocality) {
+ AddressData address;
+ address.region_code = "CN";
+ address.locality = "Anqing";
+ address.administrative_area = "Anhui";
+ address.language_code = "zh-Latn";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_TRUE(suggestions[0].dependent_locality.empty());
+ EXPECT_TRUE(suggestions[0].locality.empty());
+ EXPECT_EQ("Anhui Sheng", suggestions[0].administrative_area);
+}
+
+TEST_F(LargeAddressValidatorTest, SuggestForDependentLocality) {
+ AddressData address;
+ address.region_code = "CN";
+ address.dependent_locality = "Zongyang";
+ address.language_code = "zh-Latn";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(
+ address, DEPENDENT_LOCALITY, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Zongyang Xian", suggestions[0].dependent_locality);
+ EXPECT_EQ("Anqing Shi", suggestions[0].locality);
+ EXPECT_EQ("Anhui Sheng", suggestions[0].administrative_area);
+}
+
+TEST_F(LargeAddressValidatorTest,
+ NoSuggestForDependentLocalityWithWrongAdminArea) {
+ AddressData address;
+ address.region_code = "CN";
+ address.dependent_locality = "Zongyang";
+ address.administrative_area = "Sichuan Sheng";
+ address.language_code = "zh-Latn";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(
+ address, DEPENDENT_LOCALITY, 10, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(AddressValidatorTest, EmptySuggestionsOverLimit) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "A";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(AddressValidatorTest, PreferShortSuggestions) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "CA";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("CA", suggestions[0].administrative_area);
+}
+
+TEST_F(AddressValidatorTest, SuggestTheSingleMatchForFullMatchName) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "Texas";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Texas", suggestions[0].administrative_area);
+}
+
+TEST_F(AddressValidatorTest, SuggestAdminArea) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "Cali";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("California", suggestions[0].administrative_area);
+}
+
+TEST_F(AddressValidatorTest, MultipleSuggestions) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "MA";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 10, &suggestions));
+ EXPECT_LT(1U, suggestions.size());
+
+ // Massachusetts should not be a suggestion, because it's already covered
+ // under MA.
+ std::set<std::string> expected_suggestions;
+ expected_suggestions.insert("MA");
+ expected_suggestions.insert("Maine");
+ expected_suggestions.insert("Marshall Islands");
+ expected_suggestions.insert("Maryland");
+ for (std::vector<AddressData>::const_iterator it = suggestions.begin();
+ it != suggestions.end();
+ ++it) {
+ expected_suggestions.erase(it->administrative_area);
+ }
+ EXPECT_TRUE(expected_suggestions.empty());
+}
+
+TEST_F(LargeAddressValidatorTest, SuggestNonLatinKeyWhenLanguageMatches) {
+ AddressData address;
+ address.language_code = "ko";
+ address.region_code = "KR";
+ address.postal_code = "210-210";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("강원도", suggestions[0].administrative_area);
+ EXPECT_EQ("210-210", suggestions[0].postal_code);
+}
+
+TEST_F(LargeAddressValidatorTest, SuggestNonLatinKeyWhenUserInputIsNotLatin) {
+ AddressData address;
+ address.language_code = "en";
+ address.region_code = "KR";
+ address.administrative_area = "강원";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("강원도", suggestions[0].administrative_area);
+}
+
+TEST_F(LargeAddressValidatorTest,
+ SuggestLatinNameWhenLanguageDiffersAndLatinNameAvailable) {
+ AddressData address;
+ address.language_code = "ko-Latn";
+ address.region_code = "KR";
+ address.postal_code = "210-210";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("Gangwon", suggestions[0].administrative_area);
+ EXPECT_EQ("210-210", suggestions[0].postal_code);
+}
+
+TEST_F(AddressValidatorTest, NoSuggestionsForEmptyAddress) {
+ AddressData address;
+ address.region_code = "US";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(
+ AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 999, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(AddressValidatorTest, SuggestionIncludesCountry) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "90291";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("US", suggestions[0].region_code);
+}
+
+TEST_F(AddressValidatorTest, InvalidPostalCodeNoSuggestions) {
+ AddressData address;
+ address.region_code = "US";
+ address.postal_code = "0";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(
+ AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 999, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(AddressValidatorTest, MismatchedPostalCodeNoSuggestions) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "TX";
+ address.postal_code = "90291";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(
+ AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 999, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(AddressValidatorTest, SuggestOnlyForAdministrativeAreasAndPostalCode) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "CA";
+ address.locality = "Los Angeles";
+ address.dependent_locality = "Venice";
+ address.postal_code = "90291";
+ address.sorting_code = "123";
+ address.address_line.push_back("123 Main St");
+ address.recipient = "Jon Smith";
+
+ // Fields that should not have suggestions in US.
+ static const AddressField kNoSugestFields[] = {
+ COUNTRY,
+ LOCALITY,
+ DEPENDENT_LOCALITY,
+ SORTING_CODE,
+ STREET_ADDRESS,
+ RECIPIENT
+ };
+
+ static const size_t kNumNoSuggestFields =
+ sizeof kNoSugestFields / sizeof (AddressField);
+
+ for (size_t i = 0; i < kNumNoSuggestFields; ++i) {
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(
+ address, kNoSugestFields[i], 999, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+ }
+}
+
+TEST_F(AddressValidatorTest, SuggestionsAreCleared) {
+ AddressData address;
+ address.region_code = "US";
+
+ std::vector<AddressData> suggestions(1, address);
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, POSTAL_CODE, 1, &suggestions));
+ EXPECT_TRUE(suggestions.empty());
+}
+
+TEST_F(AddressValidatorTest, CanonicalizeUsAdminAreaName) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "cALIFORNIa";
+ EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
+ EXPECT_EQ("CA", address.administrative_area);
+}
+
+TEST_F(AddressValidatorTest, CanonicalizeUsAdminAreaKey) {
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "CA";
+ EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
+ EXPECT_EQ("CA", address.administrative_area);
+}
+
+TEST_F(AddressValidatorTest, CanonicalizeJpAdminAreaKey) {
+ validator_->LoadRules("JP");
+ AddressData address;
+ address.region_code = "JP";
+ address.administrative_area = "東京都";
+ EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
+ EXPECT_EQ("東京都", address.administrative_area);
+}
+
+TEST_F(AddressValidatorTest, CanonicalizeJpAdminAreaLatinName) {
+ validator_->LoadRules("JP");
+ AddressData address;
+ address.region_code = "JP";
+ address.administrative_area = "tOKYo";
+ EXPECT_TRUE(validator_->CanonicalizeAdministrativeArea(&address));
+ EXPECT_EQ("TOKYO", address.administrative_area);
+}
+
+TEST_F(AddressValidatorTest, TokushimaSuggestionIsValid) {
+ validator_->LoadRules("JP");
+ AddressData address;
+ address.region_code = "JP";
+ address.administrative_area = "Toku";
+ address.language_code = "ja-Latn";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 1, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("TOKUSHIMA", suggestions[0].administrative_area);
+
+ FieldProblemMap filter;
+ for (int i = UNEXPECTED_FIELD; i <= USES_P_O_BOX; ++i)
+ filter.insert(std::make_pair(ADMIN_AREA, static_cast<AddressProblem>(i)));
+
+ FieldProblemMap problems;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->ValidateAddress(suggestions[0], &filter, &problems));
+ EXPECT_TRUE(problems.empty());
+}
+
+TEST_F(AddressValidatorTest, ValidPostalCodeInSuggestion) {
+ validator_->LoadRules("US");
+ AddressData address;
+ address.region_code = "US";
+ address.administrative_area = "New";
+ address.postal_code = "13699";
+
+ std::vector<AddressData> suggestions;
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 999, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("New York", suggestions[0].administrative_area);
+
+ address.administrative_area = "New";
+ address.postal_code = "03755";
+
+ EXPECT_EQ(AddressValidator::SUCCESS,
+ validator_->GetSuggestions(address, ADMIN_AREA, 999, &suggestions));
+ ASSERT_EQ(1U, suggestions.size());
+ EXPECT_EQ("New Hampshire", suggestions[0].administrative_area);
+}
+
+TEST_F(AddressValidatorTest, ValidateRequiredFieldsWithoutRules) {
+ // Do not load the rules for JP.
+ AddressData address;
+ address.region_code = "JP";
+
+ FieldProblemMap problems;
+ EXPECT_EQ(AddressValidator::RULES_UNAVAILABLE,
+ validator_->ValidateAddress(address, NULL, &problems));
+ EXPECT_FALSE(problems.empty());
+
+ for (FieldProblemMap::const_iterator it = problems.begin();
+ it != problems.end();
+ ++it) {
+ EXPECT_EQ(MISSING_REQUIRED_FIELD, it->second);
+ }
+}
+
+TEST_F(AddressValidatorTest,
+ DoNotValidateRequiredFieldsWithoutRulesWhenErorrIsFiltered) {
+ // Do not load the rules for JP.
+ AddressData address;
+ address.region_code = "JP";
+
+ FieldProblemMap filter;
+ filter.insert(std::make_pair(COUNTRY, UNKNOWN_VALUE));
+
+ FieldProblemMap problems;
+ EXPECT_EQ(AddressValidator::RULES_UNAVAILABLE,
+ validator_->ValidateAddress(address, &filter, &problems));
+ EXPECT_TRUE(problems.empty());
+}
+
+// Use this test fixture for configuring the number of failed attempts to load
+// rules.
+class FailingAddressValidatorTest : public testing::Test, LoadRulesListener {
+ protected:
+ // A validator that retries loading rules without delay.
+ class TestAddressValidator : public AddressValidator {
+ public:
+ // Takes ownership of |source| and |storage|.
+ TestAddressValidator(scoped_ptr<::i18n::addressinput::Source> source,
+ scoped_ptr<::i18n::addressinput::Storage> storage,
+ LoadRulesListener* load_rules_listener)
+ : AddressValidator(std::move(source),
+ std::move(storage),
+ load_rules_listener) {}
+
+ virtual ~TestAddressValidator() {}
+
+ protected:
+ virtual base::TimeDelta GetBaseRetryPeriod() const override {
+ return base::TimeDelta::FromSeconds(0);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestAddressValidator);
+ };
+
+ // A source that always fails |failures_number| times before downloading
+ // data.
+ class FailingSource : public Source {
+ public:
+ explicit FailingSource()
+ : failures_number_(0), attempts_number_(0), actual_source_(true) {}
+ virtual ~FailingSource() {}
+
+ // Sets the number of times to fail before downloading data.
+ void set_failures_number(int failures_number) {
+ failures_number_ = failures_number;
+ }
+
+ // Source implementation.
+ // Always fails for the first |failures_number| times.
+ virtual void Get(const std::string& url,
+ const Callback& callback) const override {
+ ++attempts_number_;
+ // |callback| takes ownership of the |new std::string|.
+ if (failures_number_-- > 0)
+ callback(false, url, new std::string);
+ else
+ actual_source_.Get(url, callback);
+ }
+
+ // Returns the number of download attempts.
+ int attempts_number() const { return attempts_number_; }
+
+ private:
+ // The number of times to fail before downloading data.
+ mutable int failures_number_;
+
+ // The number of times Get was called.
+ mutable int attempts_number_;
+
+ // The source to use for successful downloads.
+ TestdataSource actual_source_;
+
+ DISALLOW_COPY_AND_ASSIGN(FailingSource);
+ };
+
+ FailingAddressValidatorTest()
+ : source_(new FailingSource),
+ validator_(
+ new TestAddressValidator(scoped_ptr<Source>(source_),
+ scoped_ptr<Storage>(new NullStorage),
+ this)),
+ load_rules_success_(false) {}
+
+ virtual ~FailingAddressValidatorTest() {}
+
+ FailingSource* source_; // Owned by |validator_|.
+ scoped_ptr<AddressValidator> validator_;
+ bool load_rules_success_;
+
+ private:
+ // LoadRulesListener implementation.
+ virtual void OnAddressValidationRulesLoaded(const std::string&,
+ bool success) override {
+ load_rules_success_ = success;
+ }
+
+ base::MessageLoop ui_;
+
+ DISALLOW_COPY_AND_ASSIGN(FailingAddressValidatorTest);
+};
+
+// The validator will attempt to load rules at most 8 times.
+TEST_F(FailingAddressValidatorTest, RetryLoadingRulesHasLimit) {
+ source_->set_failures_number(99);
+ validator_->LoadRules("CH");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(load_rules_success_);
+ EXPECT_EQ(8, source_->attempts_number());
+}
+
+// The validator will load rules successfully if the source returns data
+// before the maximum number of retries.
+TEST_F(FailingAddressValidatorTest, RuleRetryingWillSucceed) {
+ source_->set_failures_number(4);
+ validator_->LoadRules("CH");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(load_rules_success_);
+ EXPECT_EQ(5, source_->attempts_number());
+}
+
+// The delayed task to retry loading rules should stop (instead of crashing) if
+// the validator is destroyed before it fires.
+TEST_F(FailingAddressValidatorTest, DestroyedValidatorStopsRetries) {
+ source_->set_failures_number(4);
+ validator_->LoadRules("CH");
+
+ // Destroy the validator.
+ validator_.reset();
+
+ // Fire the delayed task to retry loading rules.
+ EXPECT_NO_FATAL_FAILURE(base::RunLoop().RunUntilIdle());
+}
+
+// Each call to LoadRules should reset the number of retry attempts. If the
+// first call to LoadRules exceeded the maximum number of retries, the second
+// call to LoadRules should start counting the retries from zero.
+TEST_F(FailingAddressValidatorTest, LoadingRulesSecondTimeSucceeds) {
+ source_->set_failures_number(11);
+ validator_->LoadRules("CH");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(load_rules_success_);
+ EXPECT_EQ(8, source_->attempts_number());
+
+ validator_->LoadRules("CH");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(load_rules_success_);
+ EXPECT_EQ(12, source_->attempts_number());
+}
+
+// Calling LoadRules("CH") and LoadRules("GB") simultaneously should attempt to
+// load both rules up to the maximum number of attempts for each region.
+TEST_F(FailingAddressValidatorTest, RegionsShouldRetryIndividually) {
+ source_->set_failures_number(99);
+ validator_->LoadRules("CH");
+ validator_->LoadRules("GB");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(load_rules_success_);
+ EXPECT_EQ(16, source_->attempts_number());
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_metadata_source.cc b/chromium/third_party/libaddressinput/chromium/chrome_metadata_source.cc
new file mode 100644
index 00000000000..57c5acd4c25
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_metadata_source.cc
@@ -0,0 +1,112 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "net/base/io_buffer.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_response_writer.h"
+#include "url/gurl.h"
+
+namespace autofill {
+
+namespace {
+
+// A URLFetcherResponseWriter that writes into a provided buffer.
+class UnownedStringWriter : public net::URLFetcherResponseWriter {
+ public:
+ UnownedStringWriter(std::string* data) : data_(data) {}
+ virtual ~UnownedStringWriter() {}
+
+ virtual int Initialize(const net::CompletionCallback& callback) override {
+ data_->clear();
+ return net::OK;
+ }
+
+ virtual int Write(net::IOBuffer* buffer,
+ int num_bytes,
+ const net::CompletionCallback& callback) override {
+ data_->append(buffer->data(), num_bytes);
+ return num_bytes;
+ }
+
+ virtual int Finish(const net::CompletionCallback& callback) override {
+ return net::OK;
+ }
+
+ private:
+ std::string* data_; // weak reference.
+
+ DISALLOW_COPY_AND_ASSIGN(UnownedStringWriter);
+};
+
+} // namespace
+
+ChromeMetadataSource::ChromeMetadataSource(
+ const std::string& validation_data_url,
+ net::URLRequestContextGetter* getter)
+ : validation_data_url_(validation_data_url),
+ getter_(getter) {}
+
+ChromeMetadataSource::~ChromeMetadataSource() {
+ STLDeleteValues(&requests_);
+}
+
+void ChromeMetadataSource::Get(const std::string& key,
+ const Callback& downloaded) const {
+ const_cast<ChromeMetadataSource*>(this)->Download(key, downloaded);
+}
+
+void ChromeMetadataSource::OnURLFetchComplete(const net::URLFetcher* source) {
+ std::map<const net::URLFetcher*, Request*>::iterator request =
+ requests_.find(source);
+ DCHECK(request != requests_.end());
+
+ bool ok = source->GetResponseCode() == net::HTTP_OK;
+ scoped_ptr<std::string> data(new std::string());
+ if (ok)
+ data->swap(request->second->data);
+ request->second->callback(ok, request->second->key, data.release());
+
+ delete request->second;
+ requests_.erase(request);
+}
+
+ChromeMetadataSource::Request::Request(const std::string& key,
+ scoped_ptr<net::URLFetcher> fetcher,
+ const Callback& callback)
+ : key(key), fetcher(std::move(fetcher)), callback(callback) {}
+
+void ChromeMetadataSource::Download(const std::string& key,
+ const Callback& downloaded) {
+ GURL resource(validation_data_url_ + key);
+ if (!resource.SchemeIsCryptographic()) {
+ downloaded(false, key, NULL);
+ return;
+ }
+
+ scoped_ptr<net::URLFetcher> fetcher =
+ net::URLFetcher::Create(resource, net::URLFetcher::GET, this);
+ fetcher->SetLoadFlags(
+ net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
+ fetcher->SetRequestContext(getter_);
+
+ Request* request = new Request(key, std::move(fetcher), downloaded);
+ request->fetcher->SaveResponseWithWriter(
+ scoped_ptr<net::URLFetcherResponseWriter>(
+ new UnownedStringWriter(&request->data)));
+ requests_[request->fetcher.get()] = request;
+ request->fetcher->Start();
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_metadata_source.h b/chromium/third_party/libaddressinput/chromium/chrome_metadata_source.h
new file mode 100644
index 00000000000..624e6e4fe5f
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_metadata_source.h
@@ -0,0 +1,66 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_METADATA_SOURCE_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_METADATA_SOURCE_H_
+
+#include <map>
+#include <string>
+
+#include "base/macros.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+
+namespace net {
+class URLFetcher;
+class URLRequestContextGetter;
+}
+
+namespace autofill {
+
+// A class for downloading rules to let libaddressinput validate international
+// addresses.
+class ChromeMetadataSource : public ::i18n::addressinput::Source,
+ public net::URLFetcherDelegate {
+ public:
+ ChromeMetadataSource(const std::string& validation_data_url,
+ net::URLRequestContextGetter* getter);
+ virtual ~ChromeMetadataSource();
+
+ // ::i18n::addressinput::Source:
+ virtual void Get(const std::string& key,
+ const Callback& downloaded) const override;
+
+ // net::URLFetcherDelegate:
+ virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+
+ private:
+ struct Request {
+ Request(const std::string& key,
+ scoped_ptr<net::URLFetcher> fetcher,
+ const Callback& callback);
+
+ std::string key;
+ // The data that's received.
+ std::string data;
+ // The object that manages retrieving the data.
+ scoped_ptr<net::URLFetcher> fetcher;
+ const Callback& callback;
+ };
+
+ // Non-const method actually implementing Get().
+ void Download(const std::string& key, const Callback& downloaded);
+
+ const std::string validation_data_url_;
+ net::URLRequestContextGetter* const getter_; // weak
+
+ // Maps from active URL fetcher to request metadata. The value is owned.
+ std::map<const net::URLFetcher*, Request*> requests_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeMetadataSource);
+};
+
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_METADATA_SOURCE_H_
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_metadata_source_unittest.cc b/chromium/third_party/libaddressinput/chromium/chrome_metadata_source_unittest.cc
new file mode 100644
index 00000000000..ae92a76654b
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_metadata_source_unittest.cc
@@ -0,0 +1,100 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
+
+#include "base/thread_task_runner_handle.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+static const char kFakeUrl[] = "https://example.com";
+static const char kFakeInsecureUrl[] = "http://example.com";
+
+class ChromeMetadataSourceTest : public testing::Test {
+ public:
+ ChromeMetadataSourceTest()
+ : fake_factory_(&factory_),
+ success_(false) {}
+ virtual ~ChromeMetadataSourceTest() {}
+
+ protected:
+ // Sets the response for the download.
+ void SetFakeResponse(const std::string& payload, net::HttpStatusCode code) {
+ fake_factory_.SetFakeResponse(url_,
+ payload,
+ code,
+ net::URLRequestStatus::SUCCESS);
+ }
+
+ // Kicks off the download.
+ void Get() {
+ scoped_refptr<net::TestURLRequestContextGetter> getter(
+ new net::TestURLRequestContextGetter(
+ base::ThreadTaskRunnerHandle::Get()));
+ ChromeMetadataSource impl(std::string(), getter.get());
+ scoped_ptr< ::i18n::addressinput::Source::Callback> callback(
+ ::i18n::addressinput::BuildCallback(
+ this, &ChromeMetadataSourceTest::OnDownloaded));
+ impl.Get(url_.spec(), *callback);
+ base::MessageLoop::current()->RunUntilIdle();
+ }
+
+ void set_url(const GURL& url) { url_ = url; }
+ bool success() const { return success_; }
+ bool has_data() const { return !!data_; }
+
+ const std::string& data() const {
+ DCHECK(data_);
+ return *data_;
+ }
+
+ private:
+ // Callback for when download is finished.
+ void OnDownloaded(bool success,
+ const std::string& url,
+ std::string* data) {
+ ASSERT_FALSE(success && data == NULL);
+ success_ = success;
+ data_.reset(data);
+ }
+
+ base::MessageLoop loop_;
+ net::URLFetcherImplFactory factory_;
+ net::FakeURLFetcherFactory fake_factory_;
+ GURL url_;
+ scoped_ptr<std::string> data_;
+ bool success_;
+};
+
+TEST_F(ChromeMetadataSourceTest, Success) {
+ const char kFakePayload[] = "ham hock";
+ set_url(GURL(kFakeUrl));
+ SetFakeResponse(kFakePayload, net::HTTP_OK);
+ Get();
+ EXPECT_TRUE(success());
+ EXPECT_EQ(kFakePayload, data());
+}
+
+TEST_F(ChromeMetadataSourceTest, Failure) {
+ const char kFakePayload[] = "ham hock";
+ set_url(GURL(kFakeUrl));
+ SetFakeResponse(kFakePayload, net::HTTP_INTERNAL_SERVER_ERROR);
+ Get();
+ EXPECT_FALSE(success());
+ EXPECT_TRUE(!has_data() || data().empty());
+}
+
+TEST_F(ChromeMetadataSourceTest, RejectsInsecureScheme) {
+ const char kFakePayload[] = "ham hock";
+ set_url(GURL(kFakeInsecureUrl));
+ SetFakeResponse(kFakePayload, net::HTTP_OK);
+ Get();
+ EXPECT_FALSE(success());
+ EXPECT_TRUE(!has_data() || data().empty());
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_rule_test.cc b/chromium/third_party/libaddressinput/chromium/chrome_rule_test.cc
new file mode 100644
index 00000000000..e0d5c2f16bc
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_rule_test.cc
@@ -0,0 +1,60 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/src/cpp/src/rule.h"
+
+#include <stddef.h>
+
+#include <string>
+
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(RuleTest, CanonicalizeSubKeyTest) {
+ i18n::addressinput::Rule rule;
+ ASSERT_TRUE(rule.ParseSerializedRule(base::WideToUTF8(
+ L"{ \"sub_keys\": \"FOO~BAR~B\u00C4Z~\u0415\u0416\","
+ L" \"sub_names\": \"Foolandia~Bartopolis~B\u00E4zmonia~"
+ L"\u0415\u0436ville\" }")));
+ EXPECT_EQ(4U, rule.GetSubKeys().size());
+
+ static const struct {
+ const wchar_t* input;
+ // If empty, expect failure.
+ const wchar_t* output;
+ } expectations[] = {
+ { L"foo", L"FOO" },
+ { L"Foo", L"FOO" },
+ { L"FOO", L"FOO" },
+ { L"F", L"" },
+ { L"FOO2", L"" },
+ { L"", L"" },
+ { L"Bar", L"BAR" },
+ { L"Bartopolis", L"BAR" },
+ { L"BARTOPOLIS", L"BAR" },
+ { L"BaRToPoLiS", L"BAR" },
+ // Diacriticals.
+ { L"B\u00C4Z", L"B\u00C4Z" },
+ { L"BAZ", L"B\u00C4Z" },
+ { L"B\u00E4zmonia", L"B\u00C4Z" },
+ { L"bazmonia", L"B\u00C4Z" },
+ // Non-ascii (Cyrillic) case sensitivity.
+ { L"\u0415\u0416", L"\u0415\u0416" },
+ { L"\u0415\u0416VILLE", L"\u0415\u0416" },
+ { L"\u0435\u0436", L"\u0415\u0416" },
+ { L"\u0435\u0436VILLE", L"\u0415\u0416" },
+ { L"\u0435\u0436VILL", L"" },
+ };
+
+ const size_t num_cases = sizeof(expectations) / sizeof(expectations[0]);
+ for (size_t i = 0; i < num_cases; ++i) {
+ const std::string input(base::WideToUTF8(expectations[i].input));
+ const std::string expected_output(base::WideToUTF8(expectations[i].output));
+ std::string output;
+ EXPECT_EQ(!expected_output.empty(),
+ rule.CanonicalizeSubKey(input, true, &output))
+ << "Failed for input " << input;
+ EXPECT_EQ(expected_output, output);
+ }
+}
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_storage_impl.cc b/chromium/third_party/libaddressinput/chromium/chrome_storage_impl.cc
new file mode 100644
index 00000000000..918d3f2ee01
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_storage_impl.cc
@@ -0,0 +1,74 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/chrome_storage_impl.h"
+
+#include <utility>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "components/prefs/writeable_pref_store.h"
+#include "third_party/libaddressinput/chromium/fallback_data_store.h"
+
+namespace autofill {
+
+ChromeStorageImpl::ChromeStorageImpl(WriteablePrefStore* store)
+ : backing_store_(store),
+ scoped_observer_(this) {
+ scoped_observer_.Add(backing_store_);
+}
+
+ChromeStorageImpl::~ChromeStorageImpl() {}
+
+void ChromeStorageImpl::Put(const std::string& key, std::string* data) {
+ DCHECK(data);
+ scoped_ptr<std::string> owned_data(data);
+ scoped_ptr<base::StringValue> string_value(
+ new base::StringValue(std::string()));
+ string_value->GetString()->swap(*owned_data);
+ backing_store_->SetValue(key, std::move(string_value),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+}
+
+void ChromeStorageImpl::Get(const std::string& key,
+ const Storage::Callback& data_ready) const {
+ // |Get()| should not be const, so this is just a thunk that fixes that.
+ const_cast<ChromeStorageImpl*>(this)->DoGet(key, data_ready);
+}
+
+void ChromeStorageImpl::OnPrefValueChanged(const std::string& key) {}
+
+void ChromeStorageImpl::OnInitializationCompleted(bool succeeded) {
+ for (std::vector<Request*>::iterator iter = outstanding_requests_.begin();
+ iter != outstanding_requests_.end(); ++iter) {
+ DoGet((*iter)->key, (*iter)->callback);
+ }
+
+ outstanding_requests_.clear();
+}
+
+void ChromeStorageImpl::DoGet(const std::string& key,
+ const Storage::Callback& data_ready) {
+ if (!backing_store_->IsInitializationComplete()) {
+ outstanding_requests_.push_back(new Request(key, data_ready));
+ return;
+ }
+
+ const base::Value* value = NULL;
+ scoped_ptr<std::string> data(new std::string);
+ if (backing_store_->GetValue(key, &value) && value->GetAsString(data.get())) {
+ data_ready(true, key, data.release());
+ } else if (FallbackDataStore::Get(key, data.get())) {
+ data_ready(true, key, data.release());
+ } else {
+ data_ready(false, key, NULL);
+ }
+}
+
+ChromeStorageImpl::Request::Request(const std::string& key,
+ const Callback& callback)
+ : key(key),
+ callback(callback) {}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_storage_impl.h b/chromium/third_party/libaddressinput/chromium/chrome_storage_impl.h
new file mode 100644
index 00000000000..6a08adc59e2
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_storage_impl.h
@@ -0,0 +1,62 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_STORAGE_IMPL_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_STORAGE_IMPL_H_
+
+#include <list>
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/scoped_vector.h"
+#include "base/scoped_observer.h"
+#include "components/prefs/pref_store.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+
+class WriteablePrefStore;
+
+namespace autofill {
+
+// An implementation of the Storage interface which passes through to an
+// underlying WriteablePrefStore.
+class ChromeStorageImpl : public ::i18n::addressinput::Storage,
+ public PrefStore::Observer {
+ public:
+ // |store| must outlive |this|.
+ explicit ChromeStorageImpl(WriteablePrefStore* store);
+ virtual ~ChromeStorageImpl();
+
+ // ::i18n::addressinput::Storage implementation.
+ virtual void Put(const std::string& key, std::string* data) override;
+ virtual void Get(const std::string& key, const Callback& data_ready)
+ const override;
+
+ // PrefStore::Observer implementation.
+ virtual void OnPrefValueChanged(const std::string& key) override;
+ virtual void OnInitializationCompleted(bool succeeded) override;
+
+ private:
+ struct Request {
+ Request(const std::string& key, const Callback& callback);
+
+ std::string key;
+ const Callback& callback;
+ };
+
+ // Non-const version of Get().
+ void DoGet(const std::string& key, const Callback& data_ready);
+
+ WriteablePrefStore* backing_store_; // weak
+
+ // Get requests that haven't yet been serviced.
+ ScopedVector<Request> outstanding_requests_;
+
+ ScopedObserver<PrefStore, ChromeStorageImpl> scoped_observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeStorageImpl);
+};
+
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_CHROME_STORAGE_IMPL_H_
diff --git a/chromium/third_party/libaddressinput/chromium/chrome_storage_impl_unittest.cc b/chromium/third_party/libaddressinput/chromium/chrome_storage_impl_unittest.cc
new file mode 100644
index 00000000000..629b8ffc345
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/chrome_storage_impl_unittest.cc
@@ -0,0 +1,35 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/chrome_storage_impl.h"
+
+#include <string>
+
+#include "components/prefs/value_map_pref_store.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libaddressinput/chromium/storage_test_runner.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
+
+namespace autofill {
+
+// Tests for ChromeStorageImpl object.
+class ChromeStorageImplTest : public testing::Test {
+ protected:
+ ChromeStorageImplTest()
+ : store_(new ValueMapPrefStore()),
+ storage_(store_.get()),
+ runner_(&storage_) {}
+
+ virtual ~ChromeStorageImplTest() {}
+
+ scoped_refptr<ValueMapPrefStore> store_;
+ ChromeStorageImpl storage_;
+ StorageTestRunner runner_;
+};
+
+TEST_F(ChromeStorageImplTest, StandardStorageTests) {
+ EXPECT_NO_FATAL_FAILURE(runner_.RunAllTests());
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/fallback_data_store.cc b/chromium/third_party/libaddressinput/chromium/fallback_data_store.cc
new file mode 100644
index 00000000000..4c20aa10d27
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/fallback_data_store.cc
@@ -0,0 +1,203 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fallback_data_store.h"
+
+#include <string>
+
+namespace autofill {
+
+bool FallbackDataStore::Get(const std::string& key, std::string* data) {
+ if (key != "data/US")
+ return false;
+
+ // Available at https://i18napis.appspot.com/ssl-aggregate-address/data/US.
+ // The appended checksum is valid, but the timestamp is old.
+ data->assign(
+ "timestamp=0\n"
+ "checksum=38d4bcdadfe494ffe062a7ad668d66d6\n"
+ "{\"data/US/LA\": {\"lang\": \"en\", \"zipex\": \"70000,71599\", \"nam"
+ "e\": \"Louisiana\", \"zip\": \"70|71[0-5]\", \"key\": \"LA\", \"id\":"
+ " \"data/US/LA\"}, \"data/US/VT\": {\"lang\": \"en\", \"zipex\": \"0500"
+ "0,05999\", \"name\": \"Vermont\", \"zip\": \"05\", \"key\": \"VT\", \""
+ "id\": \"data/US/VT\"}, \"data/US/NM\": {\"lang\": \"en\", \"zipex\": \""
+ "87000,88499\", \"name\": \"New Mexico\", \"zip\": \"87|88[0-4]\", \"k"
+ "ey\": \"NM\", \"id\": \"data/US/NM\"}, \"data/US/NJ\": {\"lang\": \"e"
+ "n\", \"zipex\": \"07000,08999\", \"name\": \"New Jersey\", \"zip\": \""
+ "0[78]\", \"key\": \"NJ\", \"id\": \"data/US/NJ\"}, \"data/US/NH\": {\""
+ "lang\": \"en\", \"zipex\": \"03000,03899\", \"name\": \"New Hampshire\""
+ ", \"zip\": \"03[0-8]\", \"key\": \"NH\", \"id\": \"data/US/NH\"}, \"d"
+ "ata/US/ND\": {\"lang\": \"en\", \"zipex\": \"58000,58999\", \"name\":"
+ " \"North Dakota\", \"zip\": \"58\", \"key\": \"ND\", \"id\": \"data/US"
+ "/ND\"}, \"data/US/NE\": {\"lang\": \"en\", \"zipex\": \"68000,69999\","
+ " \"name\": \"Nebraska\", \"zip\": \"6[89]\", \"key\": \"NE\", \"id\":"
+ " \"data/US/NE\"}, \"data/US/NC\": {\"lang\": \"en\", \"zipex\": \"2700"
+ "0,28999\", \"name\": \"North Carolina\", \"zip\": \"2[78]\", \"key\":"
+ " \"NC\", \"id\": \"data/US/NC\"}, \"data/US/PR\": {\"lang\": \"en\", \""
+ "zipex\": \"00600,00799:00900,00999\", \"name\": \"Puerto Rico\", \"zi"
+ "p\": \"00[679]\", \"key\": \"PR\", \"id\": \"data/US/PR\"}, \"data/US/"
+ "RI\": {\"lang\": \"en\", \"zipex\": \"02800,02999\", \"name\": \"Rhode"
+ " Island\", \"zip\": \"02[89]\", \"key\": \"RI\", \"id\": \"data/US/RI\""
+ "}, \"data/US/NY\": {\"lang\": \"en\", \"zipex\": \"10000,14999:06390:"
+ "00501:00544\", \"name\": \"New York\", \"zip\": \"1[0-4]|06390|00501|0"
+ "0544\", \"key\": \"NY\", \"id\": \"data/US/NY\"}, \"data/US/NV\": {\"l"
+ "ang\": \"en\", \"zipex\": \"88900,89999\", \"name\": \"Nevada\", \"zi"
+ "p\": \"889|89\", \"key\": \"NV\", \"id\": \"data/US/NV\"}, \"data/US/K"
+ "Y\": {\"lang\": \"en\", \"zipex\": \"40000,42799\", \"name\": \"Kentuc"
+ "ky\", \"zip\": \"4[01]|42[0-7]\", \"key\": \"KY\", \"id\": \"data/US/K"
+ "Y\"}, \"data/US/PA\": {\"lang\": \"en\", \"zipex\": \"15000,19699\", \""
+ "name\": \"Pennsylvania\", \"zip\": \"1[5-8]|19[0-6]\", \"key\": \"PA\""
+ ", \"id\": \"data/US/PA\"}, \"data/US/OH\": {\"lang\": \"en\", \"zipe"
+ "x\": \"43000,45999\", \"name\": \"Ohio\", \"zip\": \"4[3-5]\", \"key\""
+ ": \"OH\", \"id\": \"data/US/OH\"}, \"data/US/AS\": {\"lang\": \"en\","
+ " \"zipex\": \"96799\", \"name\": \"American Samoa\", \"zip\": \"96799\""
+ ", \"key\": \"AS\", \"id\": \"data/US/AS\"}, \"data/US/AA\": {\"lang\""
+ ": \"en\", \"zipex\": \"34000,34099\", \"name\": \"Armed Forces (AA)\","
+ " \"zip\": \"340\", \"key\": \"AA\", \"id\": \"data/US/AA\"}, \"data/US"
+ "/GA\": {\"lang\": \"en\", \"zipex\": \"30000,31999:39800,39899:39901\""
+ ", \"name\": \"Georgia\", \"zip\": \"3[01]|398|39901\", \"key\": \"GA\""
+ ", \"id\": \"data/US/GA\"}, \"data/US/OK\": {\"lang\": \"en\", \"zipex\""
+ ": \"73000,74999\", \"name\": \"Oklahoma\", \"zip\": \"7[34]\", \"key\""
+ ": \"OK\", \"id\": \"data/US/OK\"}, \"data/US/CO\": {\"lang\": \"en\","
+ " \"zipex\": \"80000,81999\", \"name\": \"Colorado\", \"zip\": \"8[01]\""
+ ", \"key\": \"CO\", \"id\": \"data/US/CO\"}, \"data/US/AK\": {\"lang\""
+ ": \"en\", \"zipex\": \"99500,99999\", \"name\": \"Alaska\", \"zip\": \""
+ "99[5-9]\", \"key\": \"AK\", \"id\": \"data/US/AK\"}, \"data/US/WV\": "
+ "{\"lang\": \"en\", \"zipex\": \"24700,26999\", \"name\": \"West Virgin"
+ "ia\", \"zip\": \"24[7-9]|2[56]\", \"key\": \"WV\", \"id\": \"data/US/W"
+ "V\"}, \"data/US/AL\": {\"lang\": \"en\", \"zipex\": \"35000,36999\", \""
+ "name\": \"Alabama\", \"zip\": \"3[56]\", \"key\": \"AL\", \"id\": \"d"
+ "ata/US/AL\"}, \"data/US/GU\": {\"lang\": \"en\", \"zipex\": \"96910,96"
+ "932\", \"name\": \"Guam\", \"zip\": \"969([1-2]\\\\d|3[12])\", \"key\":"
+ " \"GU\", \"id\": \"data/US/GU\"}, \"data/US/AR\": {\"lang\": \"en\", \""
+ "zipex\": \"71600,72999\", \"name\": \"Arkansas\", \"zip\": \"71[6-9]|"
+ "72\", \"key\": \"AR\", \"id\": \"data/US/AR\"}, \"data/US/AP\": {\"lan"
+ "g\": \"en\", \"zipex\": \"96200,96699\", \"name\": \"Armed Forces (AP"
+ ")\", \"zip\": \"96[2-6]\", \"key\": \"AP\", \"id\": \"data/US/AP\"}, \""
+ "data/US/AZ\": {\"lang\": \"en\", \"zipex\": \"85000,86999\", \"name\""
+ ": \"Arizona\", \"zip\": \"8[56]\", \"key\": \"AZ\", \"id\": \"data/US/"
+ "AZ\"}, \"data/US/VI\": {\"lang\": \"en\", \"zipex\": \"00800,00899\","
+ " \"name\": \"Virgin Islands\", \"zip\": \"008\", \"key\": \"VI\", \"i"
+ "d\": \"data/US/VI\"}, \"data/US/CT\": {\"lang\": \"en\", \"zipex\": \""
+ "06000,06999\", \"name\": \"Connecticut\", \"zip\": \"06\", \"key\": \""
+ "CT\", \"id\": \"data/US/CT\"}, \"data/US/ME\": {\"lang\": \"en\", \"zi"
+ "pex\": \"03900,04999\", \"name\": \"Maine\", \"zip\": \"039|04\", \"ke"
+ "y\": \"ME\", \"id\": \"data/US/ME\"}, \"data/US/MD\": {\"lang\": \"en\""
+ ", \"zipex\": \"20600,21999\", \"name\": \"Maryland\", \"zip\": \"20[6"
+ "-9]|21\", \"key\": \"MD\", \"id\": \"data/US/MD\"}, \"data/US/IN\": {\""
+ "lang\": \"en\", \"zipex\": \"46000,47999\", \"name\": \"Indiana\", \""
+ "zip\": \"4[67]\", \"key\": \"IN\", \"id\": \"data/US/IN\"}, \"data/US/"
+ "MA\": {\"lang\": \"en\", \"zipex\": \"01000,02799:05501:05544\", \"nam"
+ "e\": \"Massachusetts\", \"zip\": \"01|02[0-7]|05501|05544\", \"key\":"
+ " \"MA\", \"id\": \"data/US/MA\"}, \"data/US/IL\": {\"lang\": \"en\", \""
+ "zipex\": \"60000,62999\", \"name\": \"Illinois\", \"zip\": \"6[0-2]\""
+ ", \"key\": \"IL\", \"id\": \"data/US/IL\"}, \"data/US/MO\": {\"lang\":"
+ " \"en\", \"zipex\": \"63000,65999\", \"name\": \"Missouri\", \"zip\":"
+ " \"6[3-5]\", \"key\": \"MO\", \"id\": \"data/US/MO\"}, \"data/US/MN\":"
+ " {\"lang\": \"en\", \"zipex\": \"55000,56799\", \"name\": \"Minnesota\""
+ ", \"zip\": \"55|56[0-7]\", \"key\": \"MN\", \"id\": \"data/US/MN\"},"
+ " \"data/US/IA\": {\"lang\": \"en\", \"zipex\": \"50000,52999\", \"nam"
+ "e\": \"Iowa\", \"zip\": \"5[0-2]\", \"key\": \"IA\", \"id\": \"data/US"
+ "/IA\"}, \"data/US/TN\": {\"lang\": \"en\", \"zipex\": \"37000,38599\","
+ " \"name\": \"Tennessee\", \"zip\": \"37|38[0-5]\", \"key\": \"TN\", \""
+ "id\": \"data/US/TN\"}, \"data/US/WY\": {\"lang\": \"en\", \"zipex\": \""
+ "82000,83199:83414\", \"name\": \"Wyoming\", \"zip\": \"82|83[01]|8341"
+ "4\", \"key\": \"WY\", \"id\": \"data/US/WY\"}, \"data/US/KS\": {\"lan"
+ "g\": \"en\", \"zipex\": \"66000,67999\", \"name\": \"Kansas\", \"zip\""
+ ": \"6[67]\", \"key\": \"KS\", \"id\": \"data/US/KS\"}, \"data/US/MI\":"
+ " {\"lang\": \"en\", \"zipex\": \"48000,49999\", \"name\": \"Michigan\""
+ ", \"zip\": \"4[89]\", \"key\": \"MI\", \"id\": \"data/US/MI\"}, \"data"
+ "/US/ID\": {\"lang\": \"en\", \"zipex\": \"83200,83999\", \"name\": \"I"
+ "daho\", \"zip\": \"83[2-9]\", \"key\": \"ID\", \"id\": \"data/US/ID\"}"
+ ", \"data/US/MT\": {\"lang\": \"en\", \"zipex\": \"59000,59999\", \"nam"
+ "e\": \"Montana\", \"zip\": \"59\", \"key\": \"MT\", \"id\": \"data/US/"
+ "MT\"}, \"data/US/MS\": {\"lang\": \"en\", \"zipex\": \"38600,39799\","
+ " \"name\": \"Mississippi\", \"zip\": \"38[6-9]|39[0-7]\", \"key\": \"M"
+ "S\", \"id\": \"data/US/MS\"}, \"data/US/MP\": {\"lang\": \"en\", \"zip"
+ "ex\": \"96950,96952\", \"name\": \"Northern Mariana Islands\", \"zip\""
+ ": \"9695[0-2]\", \"key\": \"MP\", \"id\": \"data/US/MP\"}, \"data/US/P"
+ "W\": {\"lang\": \"en\", \"zipex\": \"96940\", \"name\": \"Palau\", \"z"
+ "ip\": \"969(39|40)\", \"key\": \"PW\", \"id\": \"data/US/PW\"}, \"data"
+ "/US/SC\": {\"lang\": \"en\", \"zipex\": \"29000,29999\", \"name\": \"S"
+ "outh Carolina\", \"zip\": \"29\", \"key\": \"SC\", \"id\": \"data/US/S"
+ "C\"}, \"data/US/MH\": {\"lang\": \"en\", \"zipex\": \"96960,96979\", \""
+ "name\": \"Marshall Islands\", \"zip\": \"969[67]\", \"key\": \"MH\","
+ " \"id\": \"data/US/MH\"}, \"data/US/WI\": {\"lang\": \"en\", \"zipex\""
+ ": \"53000,54999\", \"name\": \"Wisconsin\", \"zip\": \"5[34]\", \"key\""
+ ": \"WI\", \"id\": \"data/US/WI\"}, \"data/US/SD\": {\"lang\": \"en\","
+ " \"zipex\": \"57000,57999\", \"name\": \"South Dakota\", \"zip\": \"5"
+ "7\", \"key\": \"SD\", \"id\": \"data/US/SD\"}, \"data/US/OR\": {\"lan"
+ "g\": \"en\", \"zipex\": \"97000,97999\", \"name\": \"Oregon\", \"zip\""
+ ": \"97\", \"key\": \"OR\", \"id\": \"data/US/OR\"}, \"data/US/UT\": {\""
+ "lang\": \"en\", \"zipex\": \"84000,84999\", \"name\": \"Utah\", \"zi"
+ "p\": \"84\", \"key\": \"UT\", \"id\": \"data/US/UT\"}, \"data/US/VA\":"
+ " {\"lang\": \"en\", \"zipex\": \"20100,20199:22000,24699\", \"name\":"
+ " \"Virginia\", \"zip\": \"201|2[23]|24[0-6]\", \"key\": \"VA\", \"id\""
+ ": \"data/US/VA\"}, \"data/US/AE\": {\"lang\": \"en\", \"zipex\": \"090"
+ "00,09999\", \"name\": \"Armed Forces (AE)\", \"zip\": \"09\", \"key\":"
+ " \"AE\", \"id\": \"data/US/AE\"}, \"data/US/FL\": {\"lang\": \"en\", \""
+ "zipex\": \"32000,33999:34100,34999\", \"name\": \"Florida\", \"zip\":"
+ " \"3[23]|34[1-9]\", \"key\": \"FL\", \"id\": \"data/US/FL\"}, \"data/U"
+ "S/FM\": {\"lang\": \"en\", \"zipex\": \"96941,96944\", \"name\": \"Mic"
+ "ronesia\", \"zip\": \"9694[1-4]\", \"key\": \"FM\", \"id\": \"data/US/"
+ "FM\"}, \"data/US/DE\": {\"lang\": \"en\", \"zipex\": \"19700,19999\","
+ " \"name\": \"Delaware\", \"zip\": \"19[7-9]\", \"key\": \"DE\", \"id\""
+ ": \"data/US/DE\"}, \"data/US/CA\": {\"lang\": \"en\", \"zipex\": \"900"
+ "00,96199\", \"name\": \"California\", \"zip\": \"9[0-5]|96[01]\", \"ke"
+ "y\": \"CA\", \"id\": \"data/US/CA\"}, \"data/US\": {\"lang\": \"en\","
+ " \"upper\": \"CS\", \"sub_zipexs\": \"35000,36999~99500,99999~96799~85"
+ "000,86999~71600,72999~34000,34099~09000,09999~96200,96699~90000,96199~"
+ "80000,81999~06000,06999~19700,19999~20000,20099:20200,20599:56900,5699"
+ "9~32000,33999:34100,34999~30000,31999:39800,39899:39901~96910,96932~96"
+ "700,96798:96800,96899~83200,83999~60000,62999~46000,47999~50000,52999~"
+ "66000,67999~40000,42799~70000,71599~03900,04999~96960,96979~20600,2199"
+ "9~01000,02799:05501:05544~48000,49999~96941,96944~55000,56799~38600,39"
+ "799~63000,65999~59000,59999~68000,69999~88900,89999~03000,03899~07000,"
+ "08999~87000,88499~10000,14999:06390:00501:00544~27000,28999~58000,5899"
+ "9~96950,96952~43000,45999~73000,74999~97000,97999~96940~15000,19699~00"
+ "600,00799:00900,00999~02800,02999~29000,29999~57000,57999~37000,38599~"
+ "75000,79999:88500,88599:73301:73344~84000,84999~05000,05999~00800,0089"
+ "9~20100,20199:22000,24699~98000,99499~24700,26999~53000,54999~82000,83"
+ "199:83414\", \"zipex\": \"95014,22162-1010\", \"name\": \"UNITED STATE"
+ "S\", \"zip\": \"\\\\d{5}([ \\\\-]\\\\d{4})?\", \"zip_name_type\": \"zi"
+ "p\", \"fmt\": \"%N%n%O%n%A%n%C %S %Z\", \"state_name_type\": \"state\""
+ ", \"languages\": \"en\", \"sub_keys\": \"AL~AK~AS~AZ~AR~AA~AE~AP~CA~CO"
+ "~CT~DE~DC~FL~GA~GU~HI~ID~IL~IN~IA~KS~KY~LA~ME~MH~MD~MA~MI~FM~MN~MS~MO~"
+ "MT~NE~NV~NH~NJ~NM~NY~NC~ND~MP~OH~OK~OR~PW~PA~PR~RI~SC~SD~TN~TX~UT~VT~V"
+ "I~VA~WA~WV~WI~WY\","
+ " \"key\": \"US\", \"require\": \"ACSZ\", \"posturl\": \"https://tools."
+ "usps.com/go/ZipLookupAction!input.action\", \"id\": \"dat"
+ "a/US\", \"sub_names\": \"Alabama~Alaska~American Samoa~Arizona~Arkansa"
+ "s~Armed Forces (AA)~Armed Forces (AE)~Armed Forces (AP)~California~Col"
+ "orado~Connecticut~Delaware~District of Columbia~Florida~Georgia~Guam~H"
+ "awaii~Idaho~Illinois~Indiana~Iowa~Kansas~Kentucky~Louisiana~Maine~Mars"
+ "hall Islands~Maryland~Massachusetts~Michigan~Micronesia~Minnesota~Miss"
+ "issippi~Missouri~Montana~Nebraska~Nevada~New Hampshire~New Jersey~New "
+ "Mexico~New York~North Carolina~North Dakota~Northern Mariana Islands~O"
+ "hio~Oklahoma~Oregon~Palau~Pennsylvania~Puerto Rico~Rhode Island~South "
+ "Carolina~South Dakota~Tennessee~Texas~Utah~Vermont~Virgin Islands~Virg"
+ "inia~Washington~West Virginia~Wisconsin~Wyoming\", \"sub_zips\": \"3[5"
+ "6]~99[5-9]~96799~8[56]~71[6-9]|72~340~09~96[2-6]~9[0-5]|96[01]~8[01]~0"
+ "6~19[7-9]~20[02-5]|569~3[23]|34[1-9]~3[01]|398|39901~969([1-2]\\\\d|3[12"
+ "])~967[0-8]|9679[0-8]|968~83[2-9]~6[0-2]~4[67]~5[0-2]~6[67]~4[01]|42[0"
+ "-7]~70|71[0-5]~039|04~969[67]~20[6-9]|21~01|02[0-7]|05501|05544~4[89]~"
+ "9694[1-4]~55|56[0-7]~38[6-9]|39[0-7]~6[3-5]~59~6[89]~889|89~03[0-8]~0["
+ "78]~87|88[0-4]~1[0-4]|06390|00501|00544~2[78]~58~9695[0-2]~4[3-5]~7[34"
+ "]~97~969(39|40)~1[5-8]|19[0-6]~00[679]~02[89]~29~57~37|38[0-5]~7[5-9]|"
+ "885|73301|73344~84~05~008~201|2[23]|24[0-6]~98|99[0-4]~24[7-9]|2[56]~5"
+ "[34]~82|83[01]|83414\"}, \"data/US/TX\": {\"lang\": \"en\", \"zipex\":"
+ " \"75000,79999:88500,88599:73301:73344\", \"name\": \"Texas\", \"zip\""
+ ": \"7[5-9]|885|73301|73344\", \"key\": \"TX\", \"id\": \"data/US/TX\"}"
+ ", \"data/US/WA\": {\"lang\": \"en\", \"zipex\": \"98000,99499\", \"nam"
+ "e\": \"Washington\", \"zip\": \"98|99[0-4]\", \"key\": \"WA\", \"id\":"
+ " \"data/US/WA\"}, \"data/US/DC\": {\"lang\": \"en\", \"zipex\": \"2000"
+ "0,20099:20200,20599:56900,56999\", \"name\": \"District of Columbia\","
+ " \"zip\": \"20[02-5]|569\", \"key\": \"DC\", \"id\": \"data/US/DC\"},"
+ " \"data/US/HI\": {\"lang\": \"en\", \"zipex\": \"96700,96798:96800,968"
+ "99\", \"name\": \"Hawaii\", \"zip\": \"967[0-8]|9679[0-8]|968\", \"key"
+ "\": \"HI\", \"id\": \"data/US/HI\"}}");
+ return true;
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/fallback_data_store.h b/chromium/third_party/libaddressinput/chromium/fallback_data_store.h
new file mode 100644
index 00000000000..fd8d680576c
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/fallback_data_store.h
@@ -0,0 +1,22 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_FALLBACK_DATA_STORE_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_FALLBACK_DATA_STORE_H_
+
+#include <string>
+
+namespace autofill {
+
+class FallbackDataStore {
+ public:
+ // Gets stale, but valid static data for |key|. Should only be used as a last
+ // resort after attempts to check the local cache or the webserver have
+ // failed.
+ static bool Get(const std::string& key, std::string* data);
+};
+
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_FALLBACK_DATA_STORE_H_
diff --git a/chromium/third_party/libaddressinput/chromium/fallback_data_store_unittest.cc b/chromium/third_party/libaddressinput/chromium/fallback_data_store_unittest.cc
new file mode 100644
index 00000000000..558a0a6896d
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/fallback_data_store_unittest.cc
@@ -0,0 +1,50 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/fallback_data_store.h"
+
+#include <cstddef>
+#include <ctime>
+#include <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libaddressinput/src/cpp/src/util/json.h"
+#include "third_party/libaddressinput/src/cpp/src/validating_util.h"
+
+namespace autofill {
+
+using i18n::addressinput::Json;
+using i18n::addressinput::ValidatingUtil;
+
+TEST(FallbackDataStore, Parsability) {
+ std::string data;
+ ASSERT_TRUE(FallbackDataStore::Get("data/US", &data));
+
+ // Should be stale.
+ EXPECT_FALSE(ValidatingUtil::UnwrapTimestamp(&data, time(NULL)));
+
+ // Should be uncorrupted.
+ EXPECT_TRUE(ValidatingUtil::UnwrapChecksum(&data));
+
+ // Should be valid JSON.
+ Json json;
+ ASSERT_TRUE(json.ParseObject(data));
+
+ // Should not have a string for "data/US", because "data/US" is a dictionary.
+ std::string value;
+ EXPECT_FALSE(json.GetStringValueForKey("data/US", &value));
+
+ // Should have a dictionary with "data/US" identifier.
+ const std::vector<const Json*>& sub_dicts = json.GetSubDictionaries();
+ bool key_found = false;
+ for (std::vector<const Json*>::const_iterator it = sub_dicts.begin();
+ it != sub_dicts.end(); ++it) {
+ const Json* sub_dict = *it;
+ EXPECT_TRUE(sub_dict->GetStringValueForKey("id", &value));
+ key_found |= value == "data/US";
+ }
+ EXPECT_TRUE(key_found);
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/input_suggester.cc b/chromium/third_party/libaddressinput/chromium/input_suggester.cc
new file mode 100644
index 00000000000..9b890f11171
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/input_suggester.cc
@@ -0,0 +1,522 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/input_suggester.h"
+
+#include <cstddef>
+#include <set>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "third_party/libaddressinput/chromium/trie.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h"
+
+namespace autofill {
+
+using ::i18n::addressinput::AddressData;
+using ::i18n::addressinput::AddressField;
+using ::i18n::addressinput::BuildCallback;
+using ::i18n::addressinput::FieldProblemMap;
+using ::i18n::addressinput::PreloadSupplier;
+using ::i18n::addressinput::RegionData;
+using ::i18n::addressinput::RegionDataBuilder;
+
+using ::i18n::addressinput::ADMIN_AREA;
+using ::i18n::addressinput::COUNTRY;
+using ::i18n::addressinput::DEPENDENT_LOCALITY;
+using ::i18n::addressinput::LOCALITY;
+using ::i18n::addressinput::POSTAL_CODE;
+
+using ::i18n::addressinput::INVALID_FORMAT;
+using ::i18n::addressinput::MISMATCHING_VALUE;
+
+namespace {
+
+// Initial size for the buffer used in the canonicalizer.
+static const size_t kInitialBufferSize = 32;
+
+// A region and its metadata useful for constructing a suggestion.
+struct Suggestion {
+ public:
+ // Builds a suggestion of |region_to_suggest|. Does not take ownership of
+ // |region_to_suggest|, which should not be NULL.
+ Suggestion(const RegionData* region_to_suggest,
+ AddressField matching_address_field,
+ bool region_key_matches)
+ : region_to_suggest(region_to_suggest),
+ matching_address_field(matching_address_field),
+ region_key_matches(region_key_matches) {
+ DCHECK(region_to_suggest);
+ }
+
+ ~Suggestion() {}
+
+ // The region that should be suggested. For example, if the region is ("CA",
+ // "California"), then either "CA" or "California" should be suggested.
+ const RegionData* region_to_suggest;
+
+ // The field in the address for which the suggestion should be made. For
+ // example, ADMIN_AREA in US means the suggestion should be made for the field
+ // labeled "State".
+ AddressField matching_address_field;
+
+ // True if the key of the region matches user input (the name may or may not
+ // match). "CA" should be suggested for a ("CA", "California") region.
+ //
+ // False if only the name of the region matches user input (the key does not
+ // match). "California" should be suggested for a ("CA", "California") region.
+ bool region_key_matches;
+};
+
+// Suggestions for an address. Contains lists of suggestions for administrative
+// area, locality, and dependent locality fields of an address.
+class AddressSuggestions {
+ public:
+ AddressSuggestions() {}
+ ~AddressSuggestions() {}
+
+ // Marks all regions at |address_field| level as matching user input.
+ void AllRegionsMatchForField(AddressField address_field) {
+ all_regions_match_input_.insert(address_field);
+ }
+
+ // Marks given regions at |address_field| level as matching user input. The
+ // |regions_match_key| parameter contains the regions that match user input by
+ // their keys. The |regions_match_name| parameter contains the regions that
+ // match user input by their names.
+ //
+ // The |address_field| parameter should be either ADMIN_AREA, LOCALITY, or
+ // DEPENDENT_LOCALITY.
+ bool AddRegions(AddressField address_field,
+ const std::set<const RegionData*>& regions_match_key,
+ const std::set<const RegionData*>& regions_match_name) {
+ DCHECK(address_field >= ADMIN_AREA);
+ DCHECK(address_field <= DEPENDENT_LOCALITY);
+
+ AddressField parent_address_field =
+ static_cast<AddressField>(address_field - 1);
+
+ bool all_parents_match =
+ parent_address_field == COUNTRY ||
+ all_regions_match_input_.find(parent_address_field) !=
+ all_regions_match_input_.end();
+
+ // Cannot build |address_field| level suggestions if there are no matches in
+ // |parent_address_field| level regions.
+ const RegionsMatchInput* parents = NULL;
+ if (address_field > ADMIN_AREA && !all_parents_match) {
+ parents = &regions_match_input_[parent_address_field];
+ if (parents->keys.empty() && parents->names.empty())
+ return false;
+ }
+
+ RegionsMatchInput* regions = NULL;
+ if (address_field < DEPENDENT_LOCALITY)
+ regions = &regions_match_input_[address_field];
+
+ std::vector<Suggestion>* suggestions = &suggestions_[address_field];
+ bool added_suggestions = false;
+
+ // Iterate over both |regions_match_key| and |regions_match_name| and build
+ // Suggestion objects based on the given RegionData objects. Advance either
+ // one iterator at a time (if they point to different data) or both
+ // iterators at once (if they point to the same data).
+ for (std::set<const RegionData*>::const_iterator
+ key_it = regions_match_key.begin(),
+ name_it = regions_match_name.begin();
+ key_it != regions_match_key.end() ||
+ name_it != regions_match_name.end();) {
+ const RegionData* key_region =
+ key_it != regions_match_key.end() ? *key_it : NULL;
+ const RegionData* name_region =
+ name_it != regions_match_name.end() ? *name_it : NULL;
+
+ // Regions that do not have a parent that also matches input will not
+ // become suggestions.
+ bool key_region_has_parent =
+ all_parents_match ||
+ (parents && !parents->keys.empty() && key_region &&
+ parents->keys.find(&key_region->parent()) != parents->keys.end());
+ bool name_region_has_parent =
+ all_parents_match ||
+ (parents && !parents->names.empty() && name_region &&
+ parents->names.find(&name_region->parent()) != parents->names.end());
+
+ if (name_region && (!key_region || name_region < key_region)) {
+ if (name_region_has_parent) {
+ suggestions->push_back(Suggestion(name_region, address_field, false));
+ added_suggestions = true;
+ if (regions)
+ regions->names.insert(name_region);
+ }
+
+ ++name_it;
+ } else if (key_region && (!name_region || key_region < name_region)) {
+ if (key_region_has_parent) {
+ suggestions->push_back(Suggestion(key_region, address_field, true));
+ added_suggestions = true;
+ if (regions)
+ regions->keys.insert(key_region);
+ }
+
+ ++key_it;
+ } else {
+ if (key_region_has_parent) {
+ suggestions->push_back(Suggestion(key_region, address_field, true));
+ added_suggestions = true;
+ if (regions) {
+ regions->keys.insert(key_region);
+ regions->names.insert(name_region);
+ }
+ }
+
+ ++key_it;
+ ++name_it;
+ }
+ }
+
+ return added_suggestions;
+ }
+
+ // Swaps the suggestions for the smallest sub-region into |suggestions|.
+ // |this| is not usable after this call due to using the swap() operation.
+ //
+ // The |suggestions| parameter should not be NULL.
+ void SwapSmallestSubRegionSuggestions(std::vector<Suggestion>* suggestions) {
+ DCHECK(suggestions);
+ for (int i = DEPENDENT_LOCALITY; i >= ADMIN_AREA; --i) {
+ std::vector<Suggestion>* result =
+ &suggestions_[static_cast<AddressField>(i)];
+ if (!result->empty()) {
+ suggestions->swap(*result);
+ return;
+ }
+ }
+ }
+
+ private:
+ // The sets of non-owned regions used for looking up regions that match user
+ // input by keys and names.
+ struct RegionsMatchInput {
+ std::set<const RegionData*> keys;
+ std::set<const RegionData*> names;
+ };
+
+ // The regions that match user input at ADMIN_AREA and LOCALITY levels.
+ std::map<AddressField, RegionsMatchInput> regions_match_input_;
+
+ // The set of fields for which all regions match user input. Used to avoid
+ // storing a long list in |regions_match_input_| and later looking it up
+ // there.
+ std::set<AddressField> all_regions_match_input_;
+
+ // Suggestions at ADMIN_AREA, LOCALITY, and DEPENDENT_LOCALITY levels.
+ std::map<AddressField, std::vector<Suggestion> > suggestions_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressSuggestions);
+};
+
+} // namespace
+
+InputSuggester::StringCanonicalizer::StringCanonicalizer()
+ : buffer_(kInitialBufferSize, 0) {
+ UErrorCode error_code = U_ZERO_ERROR;
+ collator_.reset(
+ icu::Collator::createInstance(icu::Locale::getRoot(), error_code));
+ DCHECK(U_SUCCESS(error_code));
+ collator_->setStrength(icu::Collator::PRIMARY);
+}
+
+InputSuggester::StringCanonicalizer::~StringCanonicalizer() {}
+
+const std::vector<uint8_t>& InputSuggester::StringCanonicalizer::Canonicalize(
+ const std::string& original) const {
+ DCHECK(!original.empty());
+
+ icu::UnicodeString icu_str(original.c_str(),
+ static_cast<int32_t>(original.length()));
+ int32_t sort_key_size =
+ collator_->getSortKey(icu_str, &buffer_[0], buffer_size());
+ DCHECK_LT(0, sort_key_size);
+
+ if (sort_key_size > buffer_size()) {
+ buffer_.resize(sort_key_size * 2, 0);
+ sort_key_size = collator_->getSortKey(icu_str, &buffer_[0], buffer_size());
+ DCHECK_LT(0, sort_key_size);
+ DCHECK_GT(buffer_size(), sort_key_size);
+ }
+
+ return buffer_;
+}
+
+int32_t InputSuggester::StringCanonicalizer::buffer_size() const {
+ return static_cast<int32_t>(buffer_.size());
+}
+
+// All sub-regions of a COUNTRY level region, organized into tries for lookup by
+// region name or key.
+class InputSuggester::SubRegionData {
+ public:
+ SubRegionData()
+ : initialized_(false),
+ smallest_region_size_(COUNTRY),
+ canonicalizer_(NULL) {}
+
+ ~SubRegionData() {}
+
+ bool is_initialized() const { return initialized_; }
+
+ // Adds the sub-regions of |country_region| into tries. Uses
+ // |shared_canonicalizer| for case and diacritic insensitive lookup of the
+ // sub-regions. Should be called at most once.
+ void Initialize(const RegionData& country_region,
+ const StringCanonicalizer& shared_canonicalizer) {
+ DCHECK(!initialized_);
+ DCHECK(!country_region.has_parent());
+
+ initialized_ = true;
+ canonicalizer_ = &shared_canonicalizer;
+
+ if (!country_region.sub_regions().empty())
+ AddSubRegionsOf(country_region, COUNTRY);
+ }
+
+ // Adds the suggestions for |user_input| into |suggestions| when user is
+ // typing in |focused_field|.
+ void BuildSuggestions(const AddressData& user_input,
+ AddressField focused_field,
+ std::vector<Suggestion>* suggestions) {
+ DCHECK(initialized_);
+
+ // Do not suggest anything if there's no suggestion data for the focused
+ // field.
+ if (focused_field != POSTAL_CODE && smallest_region_size_ < focused_field)
+ return;
+
+ // Non-owned regions that match a field value by region key.
+ std::set<const RegionData*> regions_match_key;
+
+ // Non-owned regions that match a field value by region name.
+ std::set<const RegionData*> regions_match_name;
+
+ AddressSuggestions address_suggestions;
+ for (int i = ADMIN_AREA; i <= focused_field && i <= DEPENDENT_LOCALITY;
+ ++i) {
+ AddressField address_field = static_cast<AddressField>(i);
+ AddressField parent_address_field = static_cast<AddressField>(i - 1);
+
+ const std::string& field_value = user_input.GetFieldValue(address_field);
+ const std::string& parent_field_value =
+ user_input.GetFieldValue(parent_address_field);
+
+ if (field_value.empty() &&
+ (address_field == ADMIN_AREA || parent_field_value.empty())) {
+ address_suggestions.AllRegionsMatchForField(address_field);
+ continue;
+ }
+
+ if (field_value.empty()) {
+ DCHECK_NE(address_field, focused_field);
+ continue;
+ }
+
+ regions_match_key.clear();
+ regions_match_name.clear();
+
+ const FieldTries& field_tries = field_tries_[address_field];
+
+ const std::vector<uint8_t>& canonicalized_value =
+ canonicalizer_->Canonicalize(field_value);
+
+ field_tries.keys.FindDataForKeyPrefix(canonicalized_value,
+ &regions_match_key);
+ field_tries.names.FindDataForKeyPrefix(canonicalized_value,
+ &regions_match_name);
+
+ bool added_suggestions = address_suggestions.AddRegions(
+ address_field, regions_match_key, regions_match_name);
+
+ // Do not suggest anything if the focused field does not have suggestions.
+ if (address_field == focused_field && !added_suggestions)
+ return;
+ }
+
+ address_suggestions.SwapSmallestSubRegionSuggestions(suggestions);
+ }
+
+ private:
+ // The tries to lookup regions for a specific field by keys and names. For
+ // example, the FieldTries for ADMIN_AREA in US will have keys for "AL", "AK",
+ // "AS", etc and names for "Alabama", "Alaska", "American Samoa", etc. The
+ // struct is uncopyable due to Trie objects being uncopyable.
+ struct FieldTries {
+ Trie<const RegionData*> keys;
+ Trie<const RegionData*> names;
+ };
+
+ // Adds the sub-regions of |parent_region| into tries.
+ void AddSubRegionsOf(const RegionData& parent_region,
+ AddressField parent_field) {
+ DCHECK(!parent_region.sub_regions().empty());
+
+ AddressField address_field = static_cast<AddressField>(parent_field + 1);
+ DCHECK(address_field >= ADMIN_AREA);
+ DCHECK(address_field <= DEPENDENT_LOCALITY);
+
+ FieldTries* field_tries = &field_tries_[address_field];
+ for (std::vector<const RegionData*>::const_iterator it =
+ parent_region.sub_regions().begin();
+ it != parent_region.sub_regions().end();
+ ++it) {
+ const RegionData* region = *it;
+ DCHECK(region);
+ DCHECK(!region->key().empty());
+ DCHECK(!region->name().empty());
+
+ field_tries->keys.AddDataForKey(
+ canonicalizer_->Canonicalize(region->key()), region);
+
+ field_tries->names.AddDataForKey(
+ canonicalizer_->Canonicalize(region->name()), region);
+
+ if (smallest_region_size_ < address_field)
+ smallest_region_size_ = address_field;
+
+ if (!region->sub_regions().empty())
+ AddSubRegionsOf(*region, address_field);
+ }
+ }
+
+ // True after Initialize() has been called.
+ bool initialized_;
+
+ // The tries to lookup regions for ADMIN_AREA, LOCALITY, and
+ // DEPENDENT_LOCALITY.
+ std::map<AddressField, FieldTries> field_tries_;
+
+ // The smallest size of a sub-region that has data. For example, this is
+ // ADMIN_AREA in US, but DEPENDENT_LOCALITY in CN.
+ AddressField smallest_region_size_;
+
+ // A shared instance of string canonicalizer for case and diacritic comparison
+ // of region keys and names.
+ const StringCanonicalizer* canonicalizer_;
+};
+
+InputSuggester::InputSuggester(PreloadSupplier* supplier)
+ : region_data_builder_(supplier),
+ input_helper_(supplier),
+ validator_(supplier),
+ validated_(BuildCallback(this, &InputSuggester::Validated)) {}
+
+InputSuggester::~InputSuggester() {}
+
+void InputSuggester::GetSuggestions(const AddressData& user_input,
+ AddressField focused_field,
+ size_t suggestions_limit,
+ std::vector<AddressData>* suggestions) {
+ DCHECK(suggestions);
+ DCHECK(focused_field == POSTAL_CODE ||
+ (focused_field >= ADMIN_AREA && focused_field <= DEPENDENT_LOCALITY));
+
+ AddressData address_copy = user_input;
+
+ // Do not suggest anything if the user input is empty.
+ if (address_copy.IsFieldEmpty(focused_field))
+ return;
+
+ if (focused_field == POSTAL_CODE) {
+ // Do not suggest anything if the user is typing an invalid postal code.
+ FieldProblemMap problems;
+ FieldProblemMap filter;
+ filter.insert(std::make_pair(POSTAL_CODE, INVALID_FORMAT));
+ validator_.Validate(address_copy,
+ true, // Allow postal office boxes.
+ false, // Do not require recipient name.
+ &filter,
+ &problems,
+ *validated_);
+ if (!problems.empty())
+ return;
+
+ // Fill in the sub-regions based on the postal code.
+ input_helper_.FillAddress(&address_copy);
+ }
+
+ // Lazily initialize the mapping from COUNTRY level regions to all of their
+ // sub-regions with metadata for generating suggestions.
+ std::string unused_best_language;
+ const RegionData& region_data =
+ region_data_builder_.Build(address_copy.region_code,
+ address_copy.language_code,
+ &unused_best_language);
+ SubRegionData* sub_region_data = &sub_regions_[&region_data];
+ if (!sub_region_data->is_initialized())
+ sub_region_data->Initialize(region_data, canonicalizer_);
+
+ // Build the list of regions that match |address_copy| when the user is typing
+ // in the |focused_field|.
+ std::vector<Suggestion> suggested_regions;
+ sub_region_data->BuildSuggestions(
+ address_copy, focused_field, &suggested_regions);
+
+ FieldProblemMap problems;
+ FieldProblemMap filter;
+ filter.insert(std::make_pair(POSTAL_CODE, MISMATCHING_VALUE));
+
+ // Generate suggestions based on the regions.
+ for (std::vector<Suggestion>::const_iterator suggested_region_it =
+ suggested_regions.begin();
+ suggested_region_it != suggested_regions.end();
+ ++suggested_region_it) {
+ AddressData address;
+ address.region_code = address_copy.region_code;
+ address.postal_code = address_copy.postal_code;
+
+ // Traverse the tree of regions from the smallest |region_to_suggest| to the
+ // country-wide "root" of the tree. Use the region names or keys found at
+ // each of the levels of the tree to build the |address| to suggest.
+ AddressField address_field = suggested_region_it->matching_address_field;
+ for (const RegionData* region = suggested_region_it->region_to_suggest;
+ region->has_parent();
+ region = &region->parent()) {
+ address.SetFieldValue(address_field,
+ suggested_region_it->region_key_matches
+ ? region->key()
+ : region->name());
+ address_field = static_cast<AddressField>(address_field - 1);
+ }
+
+ // Do not suggest an address with a mismatching postal code.
+ problems.clear();
+ validator_.Validate(address,
+ true, // Allow postal office boxes.
+ false, // Do not require recipient name.
+ &filter,
+ &problems,
+ *validated_);
+ if (!problems.empty())
+ continue;
+
+ // Do not add more suggestions than |suggestions_limit|.
+ if (suggestions->size() >= suggestions_limit) {
+ suggestions->clear();
+ return;
+ }
+
+ suggestions->push_back(address);
+ }
+}
+
+void InputSuggester::Validated(bool success,
+ const AddressData&,
+ const FieldProblemMap&) {
+ DCHECK(success);
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/input_suggester.h b/chromium/third_party/libaddressinput/chromium/input_suggester.h
new file mode 100644
index 00000000000..9d5fbcd4fcd
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/input_suggester.h
@@ -0,0 +1,135 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_INPUT_SUGGESTER_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_INPUT_SUGGESTER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <map>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_input_helper.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h"
+
+namespace i18n {
+namespace addressinput {
+class PreloadSupplier;
+class RegionData;
+struct AddressData;
+}
+}
+
+namespace autofill {
+
+// Suggests address completions for a partially entered address from the user.
+class InputSuggester {
+ public:
+ // Does not take ownership of |supplier|, which should not be NULL.
+ explicit InputSuggester(::i18n::addressinput::PreloadSupplier* supplier);
+ ~InputSuggester();
+
+ // Fills in |suggestions| for the partially typed in |user_input|, assuming
+ // the user is typing in the |focused_field|. If the number of |suggestions|
+ // is over the |suggestion_limit|, then returns no |suggestions| at all.
+ //
+ // Sample user input 1:
+ // country code = "US"
+ // postal code = "90066"
+ // focused field = POSTAL_CODE
+ // suggestions limit = 1
+ // Suggestion:
+ // [{administrative_area: "CA"}]
+ //
+ // Sample user input 2:
+ // country code = "CN"
+ // dependent locality = "Zongyang"
+ // focused field = DEPENDENT_LOCALITY
+ // suggestions limit = 10
+ // Suggestion:
+ // [{dependent_locality: "Zongyang Xian",
+ // locality: "Anqing Shi",
+ // administrative_area: "Anhui Sheng"}]
+ //
+ // Builds the index for generating suggestions lazily.
+ //
+ // The |suggestions| parameter should not be NULL. The |focused_field|
+ // parameter should be either POSTAL_CODE or between ADMIN_AREA and
+ // DEPENDENT_LOCALITY inclusively.
+ void GetSuggestions(
+ const ::i18n::addressinput::AddressData& user_input,
+ ::i18n::addressinput::AddressField focused_field,
+ size_t suggestion_limit,
+ std::vector< ::i18n::addressinput::AddressData>* suggestions);
+
+ private:
+ class SubRegionData;
+
+ // Canonicalizes strings for case and diacritic insensitive comparison.
+ class StringCanonicalizer {
+ public:
+ // Initializes the canonicalizer. This is slow, so avoid calling it more
+ // often than necessary.
+ StringCanonicalizer();
+ ~StringCanonicalizer();
+
+ // Returns a 0-terminated canonical version of the string that can be used
+ // for comparing strings regardless of diacritics and capitalization.
+ // Canonicalize("Texas") == Canonicalize("T\u00E9xas");
+ // Canonicalize("Texas") == Canonicalize("teXas");
+ // Canonicalize("Texas") != Canonicalize("California");
+ //
+ // The output is not human-readable.
+ // Canonicalize("Texas") != "Texas";
+ //
+ // The |original| parameter should not be empty.
+ const std::vector<uint8_t>& Canonicalize(const std::string& original) const;
+
+ private:
+ int32_t buffer_size() const;
+
+ mutable std::vector<uint8_t> buffer_;
+ scoped_ptr<icu::Collator> collator_;
+
+ DISALLOW_COPY_AND_ASSIGN(StringCanonicalizer);
+ };
+
+ // The method to be invoked by |validated_| callback.
+ void Validated(bool success,
+ const ::i18n::addressinput::AddressData&,
+ const ::i18n::addressinput::FieldProblemMap&);
+
+ // Data source for region data.
+ ::i18n::addressinput::RegionDataBuilder region_data_builder_;
+
+ // Suggests sub-regions based on postal code.
+ const ::i18n::addressinput::AddressInputHelper input_helper_;
+
+ // Verifies that suggested sub-regions match the postal code.
+ ::i18n::addressinput::AddressValidator validator_;
+
+ // The callback for |validator_| to invoke when validation finishes.
+ const scoped_ptr<const ::i18n::addressinput::AddressValidator::Callback>
+ validated_;
+
+ // A mapping from a COUNTRY level region to a collection of all of its
+ // sub-regions along with metadata used to construct suggestions.
+ std::map<const ::i18n::addressinput::RegionData*, SubRegionData> sub_regions_;
+
+ // Canonicalizes strings for case and diacritic insensitive search of
+ // sub-region names.
+ StringCanonicalizer canonicalizer_;
+
+ DISALLOW_COPY_AND_ASSIGN(InputSuggester);
+};
+
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_INPUT_SUGGESTER_H_
diff --git a/chromium/third_party/libaddressinput/chromium/json.cc b/chromium/third_party/libaddressinput/chromium/json.cc
new file mode 100644
index 00000000000..89c65bc1704
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/json.cc
@@ -0,0 +1,109 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/src/cpp/src/util/json.h"
+
+#include <map>
+
+#include "base/json/json_reader.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+// Returns |json| parsed into a JSON dictionary. Sets |parser_error| to true if
+// parsing failed.
+::scoped_ptr<const base::DictionaryValue> Parse(const std::string& json,
+ bool* parser_error) {
+ DCHECK(parser_error);
+ ::scoped_ptr<const base::DictionaryValue> result;
+
+ // |json| is converted to a |c_str()| here because rapidjson and other parts
+ // of the standalone library use char* rather than std::string.
+ ::scoped_ptr<const base::Value> parsed(base::JSONReader::Read(json.c_str()));
+ *parser_error = !parsed || !parsed->IsType(base::Value::TYPE_DICTIONARY);
+
+ if (*parser_error)
+ result.reset(new base::DictionaryValue);
+ else
+ result.reset(static_cast<const base::DictionaryValue*>(parsed.release()));
+
+ return result;
+}
+
+} // namespace
+
+// Implementation of JSON parser for libaddressinput using JSON parser in
+// Chrome.
+class Json::JsonImpl {
+ public:
+ explicit JsonImpl(const std::string& json)
+ : owned_(Parse(json, &parser_error_)),
+ dict_(*owned_) {}
+
+ ~JsonImpl() { STLDeleteElements(&sub_dicts_); }
+
+ bool parser_error() const { return parser_error_; }
+
+ const std::vector<const Json*>& GetSubDictionaries() {
+ if (sub_dicts_.empty()) {
+ for (base::DictionaryValue::Iterator it(dict_); !it.IsAtEnd();
+ it.Advance()) {
+ if (it.value().IsType(base::Value::TYPE_DICTIONARY)) {
+ const base::DictionaryValue* sub_dict = NULL;
+ it.value().GetAsDictionary(&sub_dict);
+ sub_dicts_.push_back(new Json(new JsonImpl(*sub_dict)));
+ }
+ }
+ }
+ return sub_dicts_;
+ }
+
+ bool GetStringValueForKey(const std::string& key, std::string* value) const {
+ return dict_.GetStringWithoutPathExpansion(key, value);
+ }
+
+ private:
+ explicit JsonImpl(const base::DictionaryValue& dict)
+ : parser_error_(false), dict_(dict) {}
+
+ const ::scoped_ptr<const base::DictionaryValue> owned_;
+ bool parser_error_;
+ const base::DictionaryValue& dict_;
+ std::vector<const Json*> sub_dicts_;
+
+ DISALLOW_COPY_AND_ASSIGN(JsonImpl);
+};
+
+Json::Json() {}
+
+Json::~Json() {}
+
+bool Json::ParseObject(const std::string& json) {
+ DCHECK(!impl_);
+ impl_.reset(new JsonImpl(json));
+ if (impl_->parser_error())
+ impl_.reset();
+ return !!impl_;
+}
+
+const std::vector<const Json*>& Json::GetSubDictionaries() const {
+ return impl_->GetSubDictionaries();
+}
+
+bool Json::GetStringValueForKey(const std::string& key,
+ std::string* value) const {
+ return impl_->GetStringValueForKey(key, value);
+}
+
+Json::Json(JsonImpl* impl) : impl_(impl) {}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/chromium/override/basictypes_override.h b/chromium/third_party/libaddressinput/chromium/override/basictypes_override.h
new file mode 100644
index 00000000000..651f506c790
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/override/basictypes_override.h
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_BASICTYPES_OVERRIDE_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_BASICTYPES_OVERRIDE_H_
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+
+// There is no more base/basictypes.h in Chromium. Even though libaddressinput
+// has its own "basictypes.h" that defines a whole host of custom integers of
+// specific lengths, the only one actually used is |uint32| in util/md5.cc. So
+// here you go:
+
+typedef uint32_t uint32;
+
+// TODO: Switch libaddressinput to |uint32_t|.
+
+// Also, Chromium uses the C++11 |static_assert|, so here's a definition for the
+// old COMPILE_ASSERT:
+
+#define COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
+
+// TODO: Switch libaddressinput to |static_assert|.
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_BASICTYPES_OVERRIDE_H_
diff --git a/chromium/third_party/libaddressinput/chromium/storage_test_runner.cc b/chromium/third_party/libaddressinput/chromium/storage_test_runner.cc
new file mode 100644
index 00000000000..453f0f29289
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/storage_test_runner.cc
@@ -0,0 +1,88 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/storage_test_runner.h"
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h"
+
+namespace autofill {
+
+using ::i18n::addressinput::Storage;
+
+StorageTestRunner::StorageTestRunner(Storage* storage)
+ : storage_(storage),
+ success_(false),
+ key_(),
+ data_() {}
+
+StorageTestRunner::~StorageTestRunner() {}
+
+void StorageTestRunner::RunAllTests() {
+ EXPECT_NO_FATAL_FAILURE(GetWithoutPutReturnsEmptyData());
+ EXPECT_NO_FATAL_FAILURE(GetReturnsWhatWasPut());
+ EXPECT_NO_FATAL_FAILURE(SecondPutOverwritesData());
+}
+
+void StorageTestRunner::ClearValues() {
+ success_ = false;
+ key_.clear();
+ data_.clear();
+}
+
+scoped_ptr<Storage::Callback> StorageTestRunner::BuildCallback() {
+ return scoped_ptr<Storage::Callback>(::i18n::addressinput::BuildCallback(
+ this, &StorageTestRunner::OnDataReady));
+}
+
+void StorageTestRunner::OnDataReady(bool success,
+ const std::string& key,
+ std::string* data) {
+ assert(!success || data != NULL);
+ success_ = success;
+ key_ = key;
+ if (data != NULL) {
+ data_ = *data;
+ delete data;
+ }
+}
+
+void StorageTestRunner::GetWithoutPutReturnsEmptyData() {
+ ClearValues();
+ scoped_ptr<Storage::Callback> callback(BuildCallback());
+ storage_->Get("key", *callback);
+
+ EXPECT_FALSE(success_);
+ EXPECT_EQ("key", key_);
+ EXPECT_TRUE(data_.empty());
+}
+
+void StorageTestRunner::GetReturnsWhatWasPut() {
+ ClearValues();
+ storage_->Put("key", new std::string("value"));
+ scoped_ptr<Storage::Callback> callback(BuildCallback());
+ storage_->Get("key", *callback);
+
+ EXPECT_TRUE(success_);
+ EXPECT_EQ("key", key_);
+ EXPECT_EQ("value", data_);
+}
+
+void StorageTestRunner::SecondPutOverwritesData() {
+ ClearValues();
+ storage_->Put("key", new std::string("bad-value"));
+ storage_->Put("key", new std::string("good-value"));
+ scoped_ptr<Storage::Callback> callback(BuildCallback());
+ storage_->Get("key", *callback);
+
+ EXPECT_TRUE(success_);
+ EXPECT_EQ("key", key_);
+ EXPECT_EQ("good-value", data_);
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/storage_test_runner.h b/chromium/third_party/libaddressinput/chromium/storage_test_runner.h
new file mode 100644
index 00000000000..afbb8858edc
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/storage_test_runner.h
@@ -0,0 +1,47 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_STORAGE_TEST_RUNNER_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_STORAGE_TEST_RUNNER_H_
+
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace autofill {
+
+// A test sutie for ::i18n::addressinput::Storage.
+class StorageTestRunner {
+ public:
+ // Does not take ownership of |storage|.
+ explicit StorageTestRunner(::i18n::addressinput::Storage* storage);
+ ~StorageTestRunner();
+
+ // Runs all the tests from the standard test suite.
+ void RunAllTests();
+
+ private:
+ void ClearValues();
+ scoped_ptr< ::i18n::addressinput::Storage::Callback> BuildCallback();
+ void OnDataReady(bool success, const std::string& key, std::string* data);
+
+ // Test suite.
+ void GetWithoutPutReturnsEmptyData();
+ void GetReturnsWhatWasPut();
+ void SecondPutOverwritesData();
+
+ ::i18n::addressinput::Storage* storage_; // weak
+ bool success_;
+ std::string key_;
+ std::string data_;
+
+ DISALLOW_COPY_AND_ASSIGN(StorageTestRunner);
+};
+
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_STORAGE_TEST_RUNNER_H_
diff --git a/chromium/third_party/libaddressinput/chromium/string_compare.cc b/chromium/third_party/libaddressinput/chromium/string_compare.cc
new file mode 100644
index 00000000000..8996cd8fadd
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/string_compare.cc
@@ -0,0 +1,69 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/src/cpp/src/util/string_compare.h"
+
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+class IcuStringComparer {
+ public:
+ IcuStringComparer() {
+ UErrorCode error_code = U_ZERO_ERROR;
+ collator_.reset(
+ icu::Collator::createInstance(icu::Locale::getRoot(), error_code));
+ DCHECK(U_SUCCESS(error_code));
+ collator_->setStrength(icu::Collator::PRIMARY);
+ }
+
+ ~IcuStringComparer() {}
+
+ int Compare(const std::string& a, const std::string& b) const {
+ UErrorCode error_code = U_ZERO_ERROR;
+ int result = collator_->compareUTF8(a, b, error_code);
+ DCHECK(U_SUCCESS(error_code));
+ return result;
+ }
+
+ private:
+ // ::scoped_ptr is from "base/memory/scoped_ptr.h", which does not interfere
+ // with ::i18n::addressinput::scoped_ptr from
+ // <libaddressinput/util/scoped_ptr.h>.
+ ::scoped_ptr<icu::Collator> collator_;
+
+ DISALLOW_COPY_AND_ASSIGN(IcuStringComparer);
+};
+
+static base::LazyInstance<IcuStringComparer> g_comparer =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+// Dummy required for scoped_ptr<Impl>.
+class StringCompare::Impl {};
+
+StringCompare::StringCompare() {}
+
+StringCompare::~StringCompare() {}
+
+bool StringCompare::NaturalEquals(const std::string& a,
+ const std::string& b) const {
+ return g_comparer.Get().Compare(a, b) == 0;
+}
+
+bool StringCompare::NaturalLess(const std::string& a,
+ const std::string& b) const {
+ return g_comparer.Get().Compare(a, b) < 0;
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/chromium/string_compare_unittest.cc b/chromium/third_party/libaddressinput/chromium/string_compare_unittest.cc
new file mode 100644
index 00000000000..a10e55ad727
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/string_compare_unittest.cc
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/src/cpp/src/util/string_compare.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+TEST(ChromeStringCompareTest, IgnoreDiacritics) {
+ i18n::addressinput::StringCompare sc;
+ EXPECT_TRUE(sc.NaturalEquals("Texas", base::WideToUTF8(L"T\u00E9xas")));
+}
+
+TEST(ChromeStringCompareTest, IgnoreCapitalization) {
+ i18n::addressinput::StringCompare sc;
+ EXPECT_TRUE(sc.NaturalEquals("Texas", "teXas"));
+}
+
+TEST(ChromeStringCompareTest, DifferentStringAreDifferent) {
+ i18n::addressinput::StringCompare sc;
+ EXPECT_FALSE(sc.NaturalEquals("Texas", "California"));
+}
+
+} // namespace
diff --git a/chromium/third_party/libaddressinput/chromium/tools/require_fields.py b/chromium/third_party/libaddressinput/chromium/tools/require_fields.py
new file mode 100755
index 00000000000..b82afa2475d
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/tools/require_fields.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import json
+import urllib
+from sys import exit as sys_exit
+
+
+# Derived from region_data_constants.cc.
+_COUNTRIES = [
+ 'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO', 'AQ', 'AR', 'AS',
+ 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH',
+ 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY',
+ 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN',
+ 'CO', 'CR', 'CS', 'CV', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO',
+ 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM',
+ 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL', 'GM',
+ 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN',
+ 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IS', 'IT',
+ 'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KR', 'KW',
+ 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV',
+ 'LY', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'ML', 'MN', 'MO',
+ 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA',
+ 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM',
+ 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT',
+ 'PW', 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SE',
+ 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'ST', 'SV',
+ 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO',
+ 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA',
+ 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW'
+]
+_I18N_URL = 'https://i18napis.appspot.com/address/data/%s'
+
+
+def main():
+ for country in _COUNTRIES:
+ url = _I18N_URL % country
+ try:
+ data = json.load(urllib.urlopen(url))
+ except Exception as e:
+ print 'Error: could not load %s' % url
+ return 1
+ if 'require' in data:
+ print '%s: %s' % (country, data['require'])
+ return 0
+
+
+if __name__ == '__main__':
+ sys_exit(main())
diff --git a/chromium/third_party/libaddressinput/chromium/tools/update-strings.py b/chromium/third_party/libaddressinput/chromium/tools/update-strings.py
new file mode 100755
index 00000000000..44e8351087f
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/tools/update-strings.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This script updates the address_input_strings.grdp file based on the strings
+# in libaddressinput.
+
+import os
+import sys
+
+HEADER = """<!--
+
+DO NOT MODIFY.
+
+This file is generated by
+third_party/libaddressinput/chromium/tools/update-strings.py from
+src/third_party/libaddressinput/src/cpp/res/messages.grdp. Submit modifications
+to the upstream library at https://github.com/googlei18n/libaddressinput.
+
+-->
+"""
+
+script_dir = os.path.dirname(os.path.realpath(__file__))
+from_file = os.path.abspath(os.path.join(
+ script_dir, os.pardir, os.pardir, 'src', 'cpp', 'res', 'messages.grdp'))
+to_file = os.path.abspath(os.path.join(
+ script_dir, os.pardir, os.pardir, os.pardir, os.pardir, 'chrome', 'app',
+ 'address_input_strings.grdp'))
+
+with open(from_file, 'r') as source:
+ with open(to_file, 'w') as destination:
+ destination.write(source.readline()) # XML declaration.
+ destination.write(HEADER)
+ destination.write(source.read())
diff --git a/chromium/third_party/libaddressinput/chromium/trie.cc b/chromium/third_party/libaddressinput/chromium/trie.cc
new file mode 100644
index 00000000000..ccaf46e887b
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/trie.cc
@@ -0,0 +1,83 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/trie.h"
+
+#include <stddef.h>
+
+#include <queue>
+#include <string>
+
+#include "base/logging.h"
+
+// Separating template definitions and declarations requires defining all
+// possible template parameters to avoid linking errors.
+namespace i18n {
+namespace addressinput {
+class RegionData;
+}
+}
+
+namespace autofill {
+
+template <typename T>
+Trie<T>::Trie() {}
+
+template <typename T>
+Trie<T>::~Trie() {}
+
+template <typename T>
+void Trie<T>::AddDataForKey(const std::vector<uint8_t>& key,
+ const T& data_item) {
+ Trie<T>* current_node = this;
+ for (std::vector<uint8_t>::size_type i = 0; i < key.size(); ++i) {
+ if (!key[i])
+ break;
+ current_node = &current_node->sub_nodes_[key[i]];
+ }
+ current_node->data_list_.insert(data_item);
+}
+
+template <typename T>
+void Trie<T>::FindDataForKeyPrefix(const std::vector<uint8_t>& key_prefix,
+ std::set<T>* results) const {
+ DCHECK(results);
+
+ // Find the sub-trie for the key prefix.
+ const Trie<T>* current_node = this;
+ for (std::vector<uint8_t>::size_type i = 0; i < key_prefix.size(); ++i) {
+ if (!key_prefix[i])
+ break;
+
+ typename std::map<uint8_t, Trie<T> >::const_iterator sub_node_it =
+ current_node->sub_nodes_.find(key_prefix[i]);
+ if (sub_node_it == current_node->sub_nodes_.end())
+ return;
+
+ current_node = &sub_node_it->second;
+ }
+
+ // Collect data from all sub-tries.
+ std::queue<const Trie<T>*> node_queue;
+ node_queue.push(current_node);
+ while (!node_queue.empty()) {
+ const Trie<T>* queue_front = node_queue.front();
+ node_queue.pop();
+
+ results->insert(queue_front->data_list_.begin(),
+ queue_front->data_list_.end());
+
+ for (typename std::map<uint8_t, Trie<T> >::const_iterator sub_node_it =
+ queue_front->sub_nodes_.begin();
+ sub_node_it != queue_front->sub_nodes_.end();
+ ++sub_node_it) {
+ node_queue.push(&sub_node_it->second);
+ }
+ }
+}
+
+template class Trie<const ::i18n::addressinput::RegionData*>;
+template class Trie<std::string>;
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/chromium/trie.h b/chromium/third_party/libaddressinput/chromium/trie.h
new file mode 100644
index 00000000000..914897e9b53
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/trie.h
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_TRIE_H_
+#define THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_TRIE_H_
+
+#include <stdint.h>
+#include <map>
+#include <set>
+#include <vector>
+
+namespace autofill {
+
+// A prefix search tree. Can return all objects whose keys start with a prefix
+// byte sequence.
+//
+// Maps keys to multiple objects. This property is useful when mapping region
+// names to region objects. For example, there's a "St. Petersburg" in Florida,
+// and there's a "St. Petersburg" in Russia. A lookup for "St. Petersburg" key
+// should return two distinct objects.
+template <typename T>
+class Trie {
+ public:
+ Trie();
+ ~Trie();
+
+ // Returns true if no data was added in AddDataForKey().
+ bool empty() const { return data_list_.empty() && sub_nodes_.empty(); }
+
+ // Adds a mapping from the 0 terminated |key| to |data_item|. Can be called
+ // with the same |key| multiple times.
+ void AddDataForKey(const std::vector<uint8_t>& key, const T& data_item);
+
+ // Adds all objects whose keys start with the 0 terminated |key_prefix| to the
+ // |results| parameter. The |results| parameter should not be NULL.
+ void FindDataForKeyPrefix(const std::vector<uint8_t>& key_prefix,
+ std::set<T>* results) const;
+
+ private:
+ // All objects for this node in the Trie. This field is a collection to enable
+ // mapping the same key to multiple objects.
+ std::set<T> data_list_;
+
+ // Trie sub nodes. The root Trie stores the objects for the empty key. The
+ // children of the root Trie store the objects for the one-byte keys. The
+ // grand-children of the root Trie store the objects for the two-byte keys,
+ // and so on.
+ std::map<uint8_t, Trie<T> > sub_nodes_;
+};
+
+} // namespace autofill
+
+#endif // THIRD_PARTY_LIBADDRESSINPUT_CHROMIUM_TRIE_H_
diff --git a/chromium/third_party/libaddressinput/chromium/trie_unittest.cc b/chromium/third_party/libaddressinput/chromium/trie_unittest.cc
new file mode 100644
index 00000000000..32b0bb1d3ab
--- /dev/null
+++ b/chromium/third_party/libaddressinput/chromium/trie_unittest.cc
@@ -0,0 +1,109 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/libaddressinput/chromium/trie.h"
+
+#include <stdint.h>
+#include <set>
+#include <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+namespace {
+
+std::vector<uint8_t> ToByteArray(const std::string& text) {
+ std::vector<uint8_t> result(text.length() + 1, 0);
+ result.assign(text.begin(), text.end());
+ return result;
+}
+
+} // namespace
+
+TEST(TrieTest, EmptyTrieHasNoData) {
+ Trie<std::string> trie;
+ std::set<std::string> result;
+ trie.FindDataForKeyPrefix(ToByteArray("key"), &result);
+ EXPECT_TRUE(result.empty());
+}
+
+TEST(TrieTest, CanGetDataByExactKey) {
+ Trie<std::string> trie;
+ trie.AddDataForKey(ToByteArray("hello"), "world");
+ std::set<std::string> result;
+ trie.FindDataForKeyPrefix(ToByteArray("hello"), &result);
+ std::set<std::string> expected;
+ expected.insert("world");
+ EXPECT_EQ(expected, result);
+}
+
+TEST(TrieTest, CanGetDataByPrefix) {
+ Trie<std::string> trie;
+ trie.AddDataForKey(ToByteArray("hello"), "world");
+ std::set<std::string> result;
+ trie.FindDataForKeyPrefix(ToByteArray("he"), &result);
+ std::set<std::string> expected;
+ expected.insert("world");
+ EXPECT_EQ(expected, result);
+}
+
+TEST(TrieTest, KeyTooLongNoData) {
+ Trie<std::string> trie;
+ trie.AddDataForKey(ToByteArray("hello"), "world");
+ std::set<std::string> result;
+ trie.FindDataForKeyPrefix(ToByteArray("helloo"), &result);
+ EXPECT_TRUE(result.empty());
+}
+
+TEST(TrieTest, CommonPrefixFindsMultipleData) {
+ Trie<std::string> trie;
+ trie.AddDataForKey(ToByteArray("hello"), "world");
+ trie.AddDataForKey(ToByteArray("howdy"), "buddy");
+ trie.AddDataForKey(ToByteArray("foo"), "bar");
+ std::set<std::string> results;
+ trie.FindDataForKeyPrefix(ToByteArray("h"), &results);
+ std::set<std::string> expected;
+ expected.insert("world");
+ expected.insert("buddy");
+ EXPECT_EQ(expected, results);
+}
+
+TEST(TrieTest, KeyCanBePrefixOfOtherKey) {
+ Trie<std::string> trie;
+ trie.AddDataForKey(ToByteArray("hello"), "world");
+ trie.AddDataForKey(ToByteArray("helloo"), "woorld");
+ trie.AddDataForKey(ToByteArray("hella"), "warld");
+ std::set<std::string> results;
+ trie.FindDataForKeyPrefix(ToByteArray("hello"), &results);
+ std::set<std::string> expected;
+ expected.insert("world");
+ expected.insert("woorld");
+ EXPECT_EQ(expected, results);
+}
+
+TEST(TrieTest, AllowMutlipleKeys) {
+ Trie<std::string> trie;
+ trie.AddDataForKey(ToByteArray("hello"), "world");
+ trie.AddDataForKey(ToByteArray("hello"), "woorld");
+ std::set<std::string> results;
+ trie.FindDataForKeyPrefix(ToByteArray("hello"), &results);
+ std::set<std::string> expected;
+ expected.insert("world");
+ expected.insert("woorld");
+ EXPECT_EQ(expected, results);
+}
+
+TEST(TrieTest, CanFindVeryLongKey) {
+ Trie<std::string> trie;
+ static const char kVeryLongKey[] = "1234567890qwertyuioasdfghj";
+ trie.AddDataForKey(ToByteArray(kVeryLongKey), "world");
+ std::set<std::string> result;
+ trie.FindDataForKeyPrefix(ToByteArray(kVeryLongKey), &result);
+ std::set<std::string> expected;
+ expected.insert("world");
+ EXPECT_EQ(expected, result);
+}
+
+} // namespace autofill
diff --git a/chromium/third_party/libaddressinput/src/AUTHORS b/chromium/third_party/libaddressinput/src/AUTHORS
new file mode 100644
index 00000000000..c42ee90e455
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/AUTHORS
@@ -0,0 +1,9 @@
+# This is the official list of libaddressinput authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+
+# Names should be added to this file as:
+# Name or Organization <email address>
+# The email address is not required for organizations.
+
+Google Inc.
diff --git a/chromium/third_party/libaddressinput/src/CONTRIBUTORS b/chromium/third_party/libaddressinput/src/CONTRIBUTORS
new file mode 100644
index 00000000000..f8840a56506
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/CONTRIBUTORS
@@ -0,0 +1,20 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people. For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# Names should be added to this file as:
+# Name <email address>
+
+David Beaumont <dbeaumont@google.com>
+David Yonge-Mallo <davinci@google.com>
+Dong Zhou <dongzhou@google.com>
+Fredrik Roubert <roubert@google.com>
+Jeanine Lilleng <jeanine@google.com>
+Keghani Kouzoujian <keghani@google.com>
+Lara Scheidegger <lararennie@google.com>
+Rouslan Solomakhin <rouslan@chromium.org>
+Shaopeng Jia <shaopengjia@google.com>
diff --git a/chromium/third_party/libaddressinput/src/LICENSE b/chromium/third_party/libaddressinput/src/LICENSE
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/chromium/third_party/libaddressinput/src/README.md b/chromium/third_party/libaddressinput/src/README.md
new file mode 100644
index 00000000000..0e67ff9240d
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/README.md
@@ -0,0 +1,46 @@
+# ![](https://github.com/googlei18n/libaddressinput/wiki/libaddressinput-icon-70x55.png) libaddressinput
+
+[![Build Status](https://drone.io/github.com/googlei18n/libaddressinput/status.png)](https://drone.io/github.com/googlei18n/libaddressinput/latest)
+
+The _libaddressinput_ project consists of two different libraries (one
+implemented in C++, one implemented in Java for Android) that use
+[address metadata](https://github.com/googlei18n/libaddressinput/wiki/AddressValidationMetadata)
+from
+[Google](https://developers.google.com/)'s
+[I18n Services](https://i18napis.appspot.com/)
+[Address Data Service](https://i18napis.appspot.com/address)
+to assist application developers in collecting and handling _postal addresses_
+from all over the world.
+
+These libraries can provide information about what input fields are required for
+a correct address input form for any country in the world and can validate an
+address to highlight input errors like missing required fields or invalid
+values.
+
+## C++
+
+The C++ library (in very portable C++03) of _libaddressinput_ is the backend for
+[requestAutocomplete()](http://www.html5rocks.com/en/tutorials/forms/requestautocomplete/)
+in [Chromium](http://www.chromium.org/Home). The source code for that is a good
+example of how to use this library to implement a complex feature in a real
+application:
+
+https://src.chromium.org/viewvc/chrome/trunk/src/third_party/libaddressinput/
+https://chromium.googlesource.com/chromium/src/+/master/third_party/libaddressinput/
+
+Video: [Easy International Checkout with Chrome](https://www.youtube.com/watch?v=ljYeHwGgzQk)
+
+## Java
+
+The Java library of _libaddressinput_ is written for use in
+[Android](https://developer.android.com/) and includes an Android UI address
+input widget ready for use, but only the UI parts are tied to Android.
+
+Non-UI code and tests can be run in Java SE, and the rest of the library could
+easily be adapted to run in any Java environment.
+
+## Mailing List
+
+Using and developing libaddressinput is discussed on this mailing list:
+
+https://groups.google.com/forum/#!forum/libaddressinput-discuss
diff --git a/chromium/third_party/libaddressinput/src/android/README b/chromium/third_party/libaddressinput/src/android/README
new file mode 100644
index 00000000000..dada471f3e0
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/README
@@ -0,0 +1,45 @@
+Building and running tests with Android
+=======================================
+
+The easiest way to build libaddressinput for Android and run all the tests is
+using the Gradle project automation tool:
+
+http://tools.android.com/tech-docs/new-build-system
+http://www.gradle.org/
+
+
+Prerequisite dependencies for using Gradle with Android
+-------------------------------------------------------
+Android Studio: https://developer.android.com/sdk/index.html
+or
+Android SDK Tools: https://developer.android.com/sdk/index.html#Other
+
+Set the ANDROID_HOME environment variable to the root of the SDK.
+
+Install the following packages:
+* Tools/Android SDK Build-tools (Rev. 21.1.2)
+* Android 5.1 (API 22)
+* Extras/Android Support Library
+
+Gradle (latest version):
+ https://services.gradle.org/distributions/gradle-2.3-bin.zip
+
+Note: Additionally you must take care to avoid having multiple versions of
+Gradle on your path, as this can cause problems.
+
+
+Building and Running
+--------------------
+After installing all the prerequisites, check that everything is working by
+running:
+
+$ gradle build
+
+With an Android emulator running or an Android device connected, the following
+command line then builds the library and runs the tests:
+
+$ gradle connectedInstrumentTest
+
+The test runner logs to the system log, which can be viewed using logcat:
+
+$ adb logcat
diff --git a/chromium/third_party/libaddressinput/src/android/build.gradle b/chromium/third_party/libaddressinput/src/android/build.gradle
new file mode 100644
index 00000000000..0d48fc8c6d8
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/build.gradle
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+buildscript {
+ repositories {
+ mavenCentral()
+ mavenLocal()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.1.0'
+ }
+}
+
+apply plugin: 'com.android.library'
+
+tasks.withType(JavaCompile) {
+ options.encoding = 'UTF-8'
+}
+
+dependencies {
+ compile project(':common')
+}
+
+android {
+ /*
+ * If these are modified, update the README to reflect the new versions and
+ * update any related settings in the AdroidManifest.xml file.
+ *
+ * NOTE: Because the 'buildToolsVersion' directive only matches an exact
+ * release (rather than allowing wildcards) and Android remove older
+ * versions of the build tools very soon after a new revision is made
+ * available, we must never use the lastest major version of the build
+ * tools here (because it will quickly be superceded and become unavailable
+ * to anyone using a fresh install of the SDK). The "final" release of the
+ * previous major version remains available for much longer however, so as
+ * a workaround we always use that.
+ *
+ * So when the build tools version 23.0.0 is released, the buildToolsVersion
+ * below should be bumped to the last released version of the 22.x.x series.
+ *
+ * The obvious way to fix this would be allow wildcards (ie, "22.+") but
+ * Android have explicitly said that they won't do this.
+ */
+ compileSdkVersion 22
+ buildToolsVersion '21.1.2'
+}
+
diff --git a/chromium/third_party/libaddressinput/src/android/src/androidTest/AndroidManifest.xml b/chromium/third_party/libaddressinput/src/android/src/androidTest/AndroidManifest.xml
new file mode 100644
index 00000000000..d16ab0d834f
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.i18n.addressinput"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="9"
+ android:targetSdkVersion="22" />
+
+<!--
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.i18n.addressinput" />
+-->
+
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application
+ android:allowBackup="false"
+ android:icon="@android:drawable/sym_def_app_icon" >
+ <uses-library android:name="android.test.runner" />
+ <activity android:name=".testing.TestActivity" />
+ </application>
+
+</manifest>
diff --git a/chromium/third_party/libaddressinput/src/android/src/main/AndroidManifest.xml b/chromium/third_party/libaddressinput/src/android/src/main/AndroidManifest.xml
new file mode 100644
index 00000000000..e4b72013c16
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/src/main/AndroidManifest.xml
@@ -0,0 +1,11 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.i18n.addressinput"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="9"
+ android:targetSdkVersion="22" />
+ <application/>
+
+</manifest>
diff --git a/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_edittext.xml b/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_edittext.xml
new file mode 100644
index 00000000000..e36c330c767
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_edittext.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2010 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.
+ */
+-->
+<EditText
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/address_edit_text"
+ android:singleLine="true"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:inputType = "textPostalAddress|textCapWords" />
diff --git a/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_layout.xml b/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_layout.xml
new file mode 100644
index 00000000000..1256968e967
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_layout.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2010 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.
+ */
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/address_layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
diff --git a/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_spinner.xml b/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_spinner.xml
new file mode 100644
index 00000000000..9f2bf3068c4
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_spinner.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2010 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.
+ */
+-->
+<Spinner
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/address_spinner"
+ android:drawSelectorOnTop="true"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
diff --git a/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_textview.xml b/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_textview.xml
new file mode 100644
index 00000000000..f112a5a03e3
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/src/main/res/layout/address_textview.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (C) 2010 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.
+ */
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/address_text_view"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dip"
+ android:layout_marginLeft="3dip"
+ android:textColor="?android:attr/textColorPrimary"
+ android:focusableInTouchMode="true" />
diff --git a/chromium/third_party/libaddressinput/src/android/src/main/res/values/address_strings.xml b/chromium/third_party/libaddressinput/src/android/src/main/res/values/address_strings.xml
new file mode 100644
index 00000000000..7a6d2bd74e4
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/android/src/main/res/values/address_strings.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (C) 2010 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.
+ */
+
+/*
+ * Strings used in the AddressInput widget. The first section contains strings
+ * that may need to be changed for consistency with the client application, the
+ * second section contains widget-specific labels and error messages.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- The first section of strings are for strings that may need to be changed
+ to be consistent with other parts of the client application. -->
+
+ <string name="address_data_loading" translation_description="Message displayed to the user when data is being loaded from the server. The u2026 is the unicode character for the ellipses (...)">Loading\u2026</string>
+
+ <string name="please_select" translation_description="Message shown for a dropdown menu in which nothing is yet selected.">Please select</string>
+
+ <!-- Strings below this point are address-specific and relate either to
+ labels for input fields or to error messages that the widget may report. -->
+
+ <string name="i18n_country_or_region_label" translation_description="A country or a political region (Countries like the United States or regions like Hong Kong or Macao, or places like Taiwan, where whether it is a country or not is a politically sensitive question). [CHAR LIMIT=30]">Country / Region</string>
+
+ <string name="i18n_locality_label" translation_description="A city or town, such as New York City [CHAR LIMIT=30]">City</string>
+
+ <string name="i18n_post_town" translation_description="The name of a town through which postal deliveries are routed, present in UK addresses. See: http://en.wikipedia.org/wiki/Post_town [CHAR LIMIT=30]">Post Town</string>
+
+ <string name="i18n_suburb" translation_description="Smaller part of a city used in some addresses in countries like New Zealand to give a more specific location in a postal address. [CHAR LIMIT=30]">Suburb</string>
+
+ <string name="i18n_village_township" translation_description="A unit used in postal addresses in Malaysia, which is smaller than the city/town, and represents a village, township, or precinct. [CHAR LIMIT=30]">Village / Township</string>
+
+ <string name="i18n_address_line1_label" translation_description="Street-level part of an address, e.g. &quot;18th Street, Unit 3&quot;. [CHAR LIMIT=30]">Street address</string>
+
+ <string name="i18n_pin_code_label" translation_description="PIN (Postal Index Number) Code. Values are numeric. Used in India. [CHAR LIMIT=30]">PIN code</string>
+
+ <string name="i18n_postal_code_label" translation_description="Postal Code. Values are frequently alphanumeric. Used in countries such as Switzerland. [CHAR LIMIT=30]">Postal code</string>
+
+ <string name="i18n_zip_code_label" translation_description="ZIP code. Used in countries like the US. [CHAR LIMIT=30]">ZIP code</string>
+
+ <string name="i18n_area" translation_description="Administrative Area for Hong Kong (e.g. Kowloon). [CHAR LIMIT=30]">Area</string>
+
+ <string name="i18n_county" translation_description="Administrative Area for the United Kingdom (e.g. Yorkshire). [CHAR LIMIT=30]">County</string>
+
+ <string name="i18n_department" translation_description="Administrative Area, as used for countries like Nicaragua (e.g. Boaco). [CHAR LIMIT=30]">Department</string>
+
+ <string name="i18n_district" translation_description="Administrative Area for Nauru Central Pacific (e.g. Aiwo district), or area of a town (a neighborhood/suburb) used for addresses in Korea and China. [CHAR LIMIT=30]">District</string>
+
+ <string name="i18n_do_si" translation_description="Administrative Area for Korea (e.g. Gyeonggi-do or Busan-si). [CHAR LIMIT=30]">Do/Si</string>
+
+ <string name="i18n_emirate" translation_description="Administrative Area for United Arab Emirates (e.g. Abu Dhabi). [CHAR LIMIT=30]">Emirate</string>
+
+ <string name="i18n_island" translation_description="Administrative Area for certain countries (e.g. Bahama's Cat Island). [CHAR LIMIT=30]">Island</string>
+
+ <string name="i18n_oblast" translation_description="Administrative Area for certain countries (e.g. Russia's Leningrad). [CHAR LIMIT=30]">Oblast</string>
+
+ <string name="i18n_parish" translation_description="Administrative Area for certain countries (e.g. Andorra's Canillo). [CHAR LIMIT=30]">Parish</string>
+
+ <string name="i18n_prefecture" translation_description="Administrative Area for Japan (e.g. Hokkaido). [CHAR LIMIT=30]">Prefecture</string>
+
+ <string name="i18n_province" translation_description="Administrative Area for certain countries (e.g. Canada's Ontario). [CHAR LIMIT=30]">Province</string>
+
+ <string name="i18n_state" translation_description="Administrative Area for certain countries (e.g. California in the USA). [CHAR LIMIT=30]">State</string>
+
+ <string name="i18n_recipient_label" translation_description="Label indicating the person to be contacted as part of this address, to be used for example as &quot;Name: John Doe&quot;. [CHAR LIMIT=30]">Name</string>
+
+ <string name="i18n_neighborhood" translation_description="Label for a neighborhood, shown as part of an address input form. [CHAR LIMIT=30]">Neighborhood</string>
+
+ <string name="i18n_organization_label" translation_description="Label for the field of organization, firm, company, or institution in an address. Examples of values in this field: Google, Department of Transportation, University of Cambridge. [CHAR LIMIT=30]">Organization</string>
+
+ <string name="i18n_missing_required_field" translation_description="Error message shown with a UI field when it is a required field and the user has not filled it out. [CHAR LIMIT=30]">You can\u0027t leave this empty.</string>
+
+ <string name="unknown_entry" translation_description="Occurs when the user fills out the wrong value for an address field. For example, this would be shown when putting 'Cupertino' in United States' State field. [CHAR LIMIT=60]">%1$s is not recognized as a known value for this field.</string>
+
+ <string name="unrecognized_format_pin_code" translation_description="Occurs when the user fills out a PIN code that does not conform to the country's PIN code format. For example, this would be shown when using '123' as an Indian PIN code, which is normally 6 digits long. [CHAR LIMIT=60]">This PIN code format is not recognized.</string>
+
+ <string name="unrecognized_format_postal_code" translation_description="Occurs when the user fills out a postal code that does not conform to the country's postal code format. For example, this would be shown when using '80' as a Swiss postal code, which is normally 4 digits long. [CHAR LIMIT=60]">This postal code format is not recognized.</string>
+
+ <string name="unrecognized_format_zip_code" translation_description="Occurs when the user fills out a ZIP code that does not conform to the country's ZIP code format. For example, this would be shown when using '901' as a ZIP code for the United States. [CHAR LIMIT=60]">This ZIP code format is not recognized.</string>
+
+ <string name="mismatching_value_pin_code" translation_description="Occurs when the user fills out the wrong PIN code for a certain location. For example, this would be shown when using 456001 for New Delhi, India. [CHAR LIMIT=70]">This PIN code does not appear to match the rest of this address.</string>
+
+ <string name="mismatching_value_postal_code" translation_description="Occurs when the user fills out the wrong postal code for a certain location. For example, this would be shown when using Z3Z 2Y7 for Alberta, Canada. [CHAR LIMIT=70]">This postal code does not appear to match the rest of this address.</string>
+
+ <string name="mismatching_value_zip_code" translation_description="Occurs when the user fills out the wrong ZIP code for a certain location. For example, this would be shown when using 10001 for Arizona state. [CHAR LIMIT=70]">This ZIP code does not appear to match the rest of this address.</string>
+
+ <string name="i18n_address_line1_accessibility_label" translation_description="Accessibility label for the text field of the first street address line. [CHAR LIMIT=50]">Street address: line 1</string>
+
+ <string name="i18n_address_line2_accessibility_label" translation_description="Accessibility label for the text field of the second street address line. [CHAR LIMIT=50]">Street address: line 2</string>
+</resources>
diff --git a/chromium/third_party/libaddressinput/src/build.gradle b/chromium/third_party/libaddressinput/src/build.gradle
new file mode 100644
index 00000000000..b63b0b7286a
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/build.gradle
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/*
+ * Root Gradle file for Java address input widget (under "common" and "android")
+ */
+allprojects {
+ repositories {
+ mavenCentral()
+ mavenLocal()
+ }
+}
diff --git a/chromium/third_party/libaddressinput/src/common/README b/chromium/third_party/libaddressinput/src/common/README
new file mode 100644
index 00000000000..fdec1bdcec6
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/common/README
@@ -0,0 +1,26 @@
+Building and running tests
+==========================
+
+The common (non-UI) parts of libaddressinput are built and run using the Gradle
+project automation tool:
+
+http://tools.android.com/tech-docs/new-build-system
+http://www.gradle.org/
+
+
+Prerequisite dependencies for using Gradle
+------------------------------------------
+Gradle (latest version):
+ https://services.gradle.org/distributions/gradle-2.3-bin.zip
+
+Note: Additionally you must take care to avoid having multiple versions of
+Gradle on your path, as this can cause problems.
+
+
+Building and Running
+--------------------
+After installing all the prerequisites, check that everything is working by
+running:
+
+$ gradle build
+$ gradle test
diff --git a/chromium/third_party/libaddressinput/src/common/build.gradle b/chromium/third_party/libaddressinput/src/common/build.gradle
new file mode 100644
index 00000000000..a03c619c4d1
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/common/build.gradle
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+buildscript {
+ repositories {
+ mavenCentral()
+ mavenLocal()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.1.0'
+ }
+}
+
+apply plugin: 'java'
+
+tasks.withType(JavaCompile) {
+ options.encoding = 'UTF-8'
+}
+
+sourceSets {
+ /* It's simpler if the test resources are next to the java sources. */
+ test {
+ resources {
+ srcDir 'src/test/java'
+ }
+ }
+}
+
+test {
+ /* Listen to events in the test execution lifecycle. */
+ beforeTest { descriptor -> logger.lifecycle("Running test: " + descriptor) }
+
+ /* Show standard out and standard error of the test JVM(s) on the console. */
+ // testLogging.showStandardStreams = true
+
+ /* Listen to standard out and standard error of the test JVM(s). */
+ // onOutput { descriptor, event ->
+ // logger.lifecycle("Test: " + descriptor + " produced standard out/err: " + event.message )
+ // }
+}
+
+dependencies {
+ compile 'com.google.guava:guava-gwt:18.0'
+ /* Note that gradle will warn about this not being the same version as *
+ * the Android JSON library (but will not compile if it's removed). */
+ compile 'org.json:json:20090211'
+ testCompile 'junit:junit:4.11'
+ testCompile 'com.google.truth:truth:0.25'
+ testCompile 'org.mockito:mockito-core:1.9.5'
+}
+
diff --git a/chromium/third_party/libaddressinput/src/cpp/LICENSE.chromium b/chromium/third_party/libaddressinput/src/cpp/LICENSE.chromium
new file mode 100644
index 00000000000..3d0f7d3edfd
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/LICENSE.chromium
@@ -0,0 +1,27 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/chromium/third_party/libaddressinput/src/cpp/README b/chromium/third_party/libaddressinput/src/cpp/README
new file mode 100644
index 00000000000..d6fbf447545
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/README
@@ -0,0 +1,82 @@
+Intro
+=====
+
+The C++ version of libaddressinput library provides UI layout information and
+validation for address input forms.
+
+The library does not provide a UI. The user of the library must provide the user
+interface that uses libaddressinput. The user of the library must also provide a
+way to store data on disk and download data from the internet.
+
+The first client of the library is Chrome web browser. This motivates not
+providing UI or networking capabilities. Chrome will provide those.
+
+When including the library in your project, you can override the dependencies
+and include directories in libaddressinput.gypi to link with your own
+third-party libraries.
+
+Dependencies
+============
+
+The library depends on these tools and libraries:
+
+GYP: Generates the build files.
+Ninja: Executes the build files.
+GTest: Used for unit tests.
+Python: Used by GRIT, which generates localization files.
+RE2: Used for validating postal code format.
+
+Most of these packages are available on Debian-like distributions. You can
+install them with this command:
+
+$ sudo apt-get install gyp ninja-build libgtest-dev python libre2-dev
+
+Make sure that your version of GYP is at least 0.1~svn1395. Older versions of
+GYP do not generate the Ninja build files correctly. You can download a
+new-enough version from http://packages.ubuntu.com/saucy/gyp.
+
+Make sure that your version of RE2 is at least 20140111+dfsg-1. Older versions
+of RE2 don't support set_never_capture() and the packages don't provide shared
+libraries.
+
+If your distribution does not include the binary packages for the dependencies,
+you can download them from these locations:
+
+http://packages.ubuntu.com/saucy/gyp
+http://packages.ubuntu.com/saucy/ninja-build
+http://packages.ubuntu.com/saucy/libgtest-dev
+http://packages.ubuntu.com/saucy/python
+http://packages.ubuntu.com/utopic/libre2-1
+http://packages.ubuntu.com/utopic/libre2-dev
+
+Alternatively, you can download, build, and install these tools and libraries
+from source code. Their home pages contain information on how to accomplish
+that.
+
+https://code.google.com/p/gyp/
+http://martine.github.io/ninja/
+https://code.google.com/p/googletest/
+http://python.org/
+https://code.google.com/p/re2/
+
+Build
+=====
+
+Building the library involves generating an out/Default/build.ninja file and
+running ninja:
+
+$ export GYP_GENERATORS='ninja'
+$ gyp --depth .
+$ ninja -C out/Default
+
+Overriding paths defined in the *.gyp files can be done by setting the
+GYP_DEFINES environment variable before running gyp:
+
+$ export GYP_DEFINES="gtest_dir='/xxx/include' gtest_src_dir='/xxx'"
+
+Test
+====
+
+This command will execute the unit tests for the library:
+
+$ out/Default/unit_tests
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h
new file mode 100644
index 00000000000..89d32737235
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h
@@ -0,0 +1,96 @@
+// Copyright (C) 2014 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.
+//
+// A struct for storing address data: country code, administrative area,
+// locality, etc. The field names correspond to the OASIS xAL standard:
+// https://www.oasis-open.org/committees/ciq/download.shtml
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_DATA_H_
+#define I18N_ADDRESSINPUT_ADDRESS_DATA_H_
+
+#include <libaddressinput/address_field.h>
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+struct AddressData {
+ // CLDR (Common Locale Data Repository) region code.
+ std::string region_code;
+
+ // The address lines represent the most specific part of any address.
+ std::vector<std::string> address_line;
+
+ // Top-level administrative subdivision of this country.
+ std::string administrative_area;
+
+ // Generally refers to the city/town portion of an address.
+ std::string locality;
+
+ // Dependent locality or sublocality. Used for UK dependent localities, or
+ // neighborhoods or boroughs in other locations.
+ std::string dependent_locality;
+
+ // Values are frequently alphanumeric.
+ std::string postal_code;
+
+ // This corresponds to the SortingCode sub-element of the xAL
+ // PostalServiceElements element. Use is very country-specific.
+ std::string sorting_code;
+
+ // Language code of the address. Should be in BCP-47 format.
+ std::string language_code;
+
+ // The organization, firm, company, or institution at this address. This
+ // corresponds to the FirmName sub-element of the xAL FirmType element.
+ std::string organization;
+
+ // Name of recipient or contact person. Not present in xAL.
+ std::string recipient;
+
+ // Returns whether the |field| is empty.
+ bool IsFieldEmpty(AddressField field) const;
+
+ // Returns the value of the |field|. The parameter must not be STREET_ADDRESS,
+ // which comprises multiple fields (will crash otherwise).
+ const std::string& GetFieldValue(AddressField field) const;
+
+ // Copies |value| into the |field|. The parameter must not be STREET_ADDRESS,
+ // which comprises multiple fields (will crash otherwise).
+ void SetFieldValue(AddressField field, const std::string& value);
+
+ // Returns the value of the |field|. The parameter must be STREET_ADDRESS,
+ // which comprises multiple fields (will crash otherwise).
+ const std::vector<std::string>& GetRepeatedFieldValue(
+ AddressField field) const;
+
+ bool operator==(const AddressData& other) const;
+
+ // Returns true if the parameter comprises multiple fields, false otherwise.
+ // Use it to determine whether to call |GetFieldValue| or
+ // |GetRepeatedFieldValue|.
+ static bool IsRepeatedFieldValue(AddressField field);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+// Produces human-readable output in logging, for example in unit tests.
+std::ostream& operator<<(std::ostream& o,
+ const i18n::addressinput::AddressData& address);
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_DATA_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h
new file mode 100644
index 00000000000..8f2ee05e4c9
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h
@@ -0,0 +1,47 @@
+// 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.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_FIELD_H_
+#define I18N_ADDRESSINPUT_ADDRESS_FIELD_H_
+
+#include <iosfwd>
+
+namespace i18n {
+namespace addressinput {
+
+// Address field types, ordered by size, from largest to smallest.
+enum AddressField {
+ COUNTRY, // Country code.
+ ADMIN_AREA, // Administrative area such as a state, province,
+ // island, etc.
+ LOCALITY, // City or locality.
+ DEPENDENT_LOCALITY, // Dependent locality (may be an inner-city district or
+ // a suburb).
+ SORTING_CODE, // Sorting code.
+ POSTAL_CODE, // Zip or postal code.
+ STREET_ADDRESS, // Street address lines.
+ ORGANIZATION, // Organization, company, firm, institution, etc.
+ RECIPIENT // Name.
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+// Produces human-readable output in logging, for example in unit tests. Prints
+// what you would expect for valid fields, e.g. "COUNTRY" for COUNTRY. For
+// invalid values, prints "[INVALID ENUM VALUE x]".
+std::ostream& operator<<(std::ostream& o,
+ i18n::addressinput::AddressField field);
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_FIELD_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h
new file mode 100644
index 00000000000..e267884bf67
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h
@@ -0,0 +1,51 @@
+// Copyright (C) 2014 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.
+//
+// Utility functions for formatting the addresses represented as AddressData.
+//
+// Note these work best if the address has a language code specified - this can
+// be obtained when building the UI components (calling BuildComponents on
+// address_ui.h).
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_FORMATTER_H_
+#define I18N_ADDRESSINPUT_ADDRESS_FORMATTER_H_
+
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+struct AddressData;
+
+// Formats the address onto multiple lines. This formats the address in national
+// format; without the country.
+void GetFormattedNationalAddress(
+ const AddressData& address_data, std::vector<std::string>* lines);
+
+// Formats the address as a single line. This formats the address in national
+// format; without the country.
+void GetFormattedNationalAddressLine(
+ const AddressData& address_data, std::string* line);
+
+// Formats the street-level part of an address as a single line. For example,
+// two lines of "Apt 1", "10 Red St." will be concatenated in a
+// language-appropriate way, to give something like "Apt 1, 10 Red St".
+void GetStreetAddressLinesAsSingleLine(
+ const AddressData& address_data, std::string* line);
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_FORMATTER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_input_helper.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_input_helper.h
new file mode 100644
index 00000000000..feb04d7ae83
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_input_helper.h
@@ -0,0 +1,67 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_INPUT_HELPER_H_
+#define I18N_ADDRESSINPUT_ADDRESS_INPUT_HELPER_H_
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+class LookupKey;
+class PreloadSupplier;
+struct AddressData;
+struct Node;
+
+class AddressInputHelper {
+ public:
+ // Creates an input helper that uses the supplier provided to get metadata to
+ // help a user complete or fix an address. Doesn't take ownership of
+ // |supplier|. Since latency is important for these kinds of tasks, we expect
+ // the supplier to have the data already.
+ AddressInputHelper(PreloadSupplier* supplier);
+
+ ~AddressInputHelper();
+
+ // Fill in missing components of an address as best as we can based on
+ // existing data. For example, for some countries only one postal code is
+ // valid; this would enter that one. For others, the postal code indicates
+ // what state should be selected. Existing data will never be overwritten.
+ //
+ // Note that the preload supplier must have had the rules for the country
+ // represented by this address loaded before this method is called - otherwise
+ // an assertion failure will result.
+ //
+ // The address should have the best language tag as returned from
+ // BuildComponents().
+ void FillAddress(AddressData* address) const;
+
+ private:
+ void CheckChildrenForPostCodeMatches(
+ const AddressData& address, const LookupKey& lookup_key,
+ const Node* parent, std::vector<Node>* hierarchy) const;
+
+ // We don't own the supplier_.
+ PreloadSupplier* const supplier_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressInputHelper);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_INPUT_HELPER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h
new file mode 100644
index 00000000000..cbe72db52b3
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_METADATA_H_
+#define I18N_ADDRESSINPUT_ADDRESS_METADATA_H_
+
+#include <libaddressinput/address_field.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+// Checks whether |field| is a required field for |region_code|. Returns false
+// also if no data could be found for region_code. Note: COUNTRY is always
+// required.
+bool IsFieldRequired(AddressField field, const std::string& region_code);
+
+// Checks whether |field| is a field that is used for |region_code|. Returns
+// false also if no data could be found for region_code. Note: COUNTRY is always
+// used.
+bool IsFieldUsed(AddressField field, const std::string& region_code);
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_METADATA_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_normalizer.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_normalizer.h
new file mode 100644
index 00000000000..06b7eb2b3fd
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_normalizer.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_NORMALIZER_H_
+#define I18N_ADDRESSINPUT_ADDRESS_NORMALIZER_H_
+
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+namespace i18n {
+namespace addressinput {
+
+class PreloadSupplier;
+class StringCompare;
+struct AddressData;
+
+class AddressNormalizer {
+ public:
+ // Does not take ownership of |supplier|.
+ explicit AddressNormalizer(const PreloadSupplier* supplier);
+ ~AddressNormalizer();
+
+ // Converts the names of different fields in the address into their canonical
+ // form. Should be called only when supplier->IsLoaded() returns true for
+ // the region code of the |address|.
+ void Normalize(AddressData* address) const;
+
+ private:
+ const PreloadSupplier* const supplier_; // Not owned.
+ const scoped_ptr<const StringCompare> compare_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressNormalizer);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_NORMALIZER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h
new file mode 100644
index 00000000000..743b9e86aa4
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_problem.h
@@ -0,0 +1,68 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_PROBLEM_H_
+#define I18N_ADDRESSINPUT_ADDRESS_PROBLEM_H_
+
+#include <iosfwd>
+
+namespace i18n {
+namespace addressinput {
+
+// Address problem types, in no particular order.
+enum AddressProblem {
+ // The field is not null and not whitespace, and the field should not be used
+ // by addresses in this country. For example, in the U.S. the SORTING_CODE
+ // field is unused, so its presence is an error.
+ UNEXPECTED_FIELD,
+
+ // The field is null or whitespace, and the field is required. For example,
+ // in the U.S. ADMIN_AREA is a required field.
+ MISSING_REQUIRED_FIELD,
+
+ // A list of values for the field is defined and the value does not occur in
+ // the list. Applies to hierarchical elements like REGION, ADMIN_AREA,
+ // LOCALITY, and DEPENDENT_LOCALITY. For example, in the US, the values for
+ // ADMIN_AREA include "CA" but not "XX".
+ UNKNOWN_VALUE,
+
+ // A format for the field is defined and the value does not match. This is
+ // used to match POSTAL_CODE against the the format pattern generally. Formats
+ // indicate how many digits/letters should be present, and what punctuation is
+ // allowed. For example, in the U.S. postal codes are five digits with an
+ // optional hyphen followed by four digits.
+ INVALID_FORMAT,
+
+ // A specific pattern for the field is defined based on a specific sub-region
+ // (an ADMIN_AREA for example) and the value does not match. This is used to
+ // match POSTAL_CODE against a regular expression. For example, in the U.S.
+ // postal codes in the state of California start with '9'.
+ MISMATCHING_VALUE,
+
+ // The value contains a P.O. box and the widget options have acceptPostal set
+ // to false. For example, a street address line that contained "P.O. Box 3456"
+ // would fire this error.
+ USES_P_O_BOX
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+// Produces human-readable output in logging, for example in unit tests. Prints
+// what you would expect for valid values, e.g. "UNEXPECTED_FIELD" for
+// UNEXPECTED_FIELD. For invalid values, prints "[INVALID ENUM VALUE x]".
+std::ostream& operator<<(std::ostream& o,
+ i18n::addressinput::AddressProblem problem);
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_PROBLEM_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h
new file mode 100644
index 00000000000..cc39f6a1204
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_UI_H_
+#define I18N_ADDRESSINPUT_ADDRESS_UI_H_
+
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+class Localization;
+struct AddressUiComponent;
+
+// Returns the list of supported CLDR region codes.
+const std::vector<std::string>& GetRegionCodes();
+
+// Returns the UI components for the CLDR |region_code|. Uses the strings from
+// |localization|. The components can be in default or Latin order, depending on
+// the BCP 47 |ui_language_tag|.
+//
+// Sets the |best_address_language_tag| to the BCP 47 language tag that should
+// be saved with this address. This language will be used to get drop-downs to
+// help users fill in their address, and to format the address that the user
+// entered. The parameter should not be NULL.
+//
+// Returns an empty vector on error.
+std::vector<AddressUiComponent> BuildComponents(
+ const std::string& region_code,
+ const Localization& localization,
+ const std::string& ui_language_tag,
+ std::string* best_address_language_tag);
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_UI_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h
new file mode 100644
index 00000000000..5982a29f003
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_UI_COMPONENT_H_
+#define I18N_ADDRESSINPUT_ADDRESS_UI_COMPONENT_H_
+
+#include <libaddressinput/address_field.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+// A description of an input field in an address form. The user of the library
+// will use a list of these elements to layout the address form input fields.
+struct AddressUiComponent {
+ // The types of hints for how large the field should be in a multiline address
+ // form.
+ enum LengthHint {
+ HINT_LONG, // The field should take up the whole line.
+ HINT_SHORT // The field does not need to take up the whole line.
+ };
+
+ // The address field type for this UI component, for example LOCALITY.
+ AddressField field;
+
+ // The name of the field, for example "City".
+ std::string name;
+
+ // The hint for how large the input field should be in a multiline address
+ // form.
+ LengthHint length_hint;
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_UI_COMPONENT_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h
new file mode 100644
index 00000000000..cdb1edf1286
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h
@@ -0,0 +1,113 @@
+// Copyright (C) 2014 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.
+//
+// The public interface to the address validation features of libaddressinput.
+// The AddressValidator will examine an AddressData struct and return a map of
+// the problems found with the different fields of this struct.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_VALIDATOR_H_
+#define I18N_ADDRESSINPUT_ADDRESS_VALIDATOR_H_
+
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/address_problem.h>
+#include <libaddressinput/callback.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <map>
+
+namespace i18n {
+namespace addressinput {
+
+class Supplier;
+struct AddressData;
+
+typedef std::multimap<AddressField, AddressProblem> FieldProblemMap;
+
+// Validates an AddressData struct. Sample usage:
+// class MyClass {
+// public:
+// MyClass()
+// : supplier_(new MySupplier),
+// validator_(new AddressValidator(supplier_.get())),
+// validated_(BuildCallback(this, &MyClass::Validated)) {}
+//
+// virtual ~MyClass() {}
+//
+// void ValidateAddress() const {
+// address_.region_code = "US";
+// address_.administrative_area = "CA";
+// validator_.Validate(address_, filter_, &problems_, *validated_);
+// }
+//
+// void Validated(bool success,
+// const AddressData& address,
+// const FieldProblemMap& problems) {
+// if (success && problems.empty()) {
+// ...
+// }
+// }
+//
+// private:
+// AddressData address_;
+// FieldProblemMap filter_;
+// FieldProblemMap problems_;
+// const scoped_ptr<Supplier> supplier_;
+// const scoped_ptr<AddressValidator> validator_;
+// const scoped_ptr<const AddressValidator::Callback> validated_;
+// };
+class AddressValidator {
+ public:
+ typedef i18n::addressinput::Callback<const AddressData&,
+ const FieldProblemMap&> Callback;
+
+ // Does not take ownership of |supplier|.
+ AddressValidator(Supplier* supplier);
+
+ ~AddressValidator();
+
+ // Validates the |address| and populates |problems| with the validation
+ // problems, filtered according to the |filter| parameter.
+ //
+ // Set |allow_postal| to allow postal addresses, rather than only addresses
+ // describing physical locations.
+ //
+ // Set |require_name| if recipient should be considered a required field.
+ //
+ // If the |filter| is NULL or empty, then all discovered validation problems
+ // are returned. If the |filter| contains problem elements, then only those
+ // field-problem pairs present in the |filter| will be returned.
+ //
+ // Calls the |validated| callback when validation is done. All objects passed
+ // as parameters must be kept available until the callback has been called.
+ //
+ // The |success| parameter of the callback indicates whether it was possible
+ // to perform validation. If |success| is true, then |problems| will contain
+ // information about any problems found with the |address|.
+ void Validate(const AddressData& address,
+ bool allow_postal,
+ bool require_name,
+ const FieldProblemMap* filter,
+ FieldProblemMap* problems,
+ const Callback& validated) const;
+
+ private:
+ Supplier* const supplier_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressValidator);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_VALIDATOR_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h
new file mode 100644
index 00000000000..d8c4ea65efb
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/callback.h
@@ -0,0 +1,95 @@
+// 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.
+//
+// An object to store a pointer to a method in an object with the following
+// signature:
+//
+// void Observer::ObserveEvent(bool success, Key key, Data data);
+
+#ifndef I18N_ADDRESSINPUT_CALLBACK_H_
+#define I18N_ADDRESSINPUT_CALLBACK_H_
+
+#include <cassert>
+#include <cstddef>
+
+namespace i18n {
+namespace addressinput {
+
+// Stores a pointer to a method in an object. Sample usage:
+// class MyClass {
+// public:
+// typedef Callback<const MyType&, const MyDataType&> MyCallback;
+//
+// void GetDataAsynchronously() {
+// scoped_ptr<MyCallback> callback(BuildCallback(
+// this, &MyClass::OnDataReady));
+// bool success = ...
+// MyKeyType key = ...
+// MyDataType data = ...
+// (*callback)(success, key, data);
+// }
+//
+// void OnDataReady(bool success,
+// const MyKeyType& key,
+// const MyDataType& data) {
+// ...
+// }
+// };
+template <typename Key, typename Data>
+class Callback {
+ public:
+ virtual ~Callback() {}
+ virtual void operator()(bool success, Key key, Data data) const = 0;
+};
+
+namespace {
+
+template <typename Observer, typename Key, typename Data>
+class CallbackImpl : public Callback<Key, Data> {
+ public:
+ typedef void (Observer::*ObserveEvent)(bool, Key, Data);
+
+ CallbackImpl(Observer* observer, ObserveEvent observe_event)
+ : observer_(observer),
+ observe_event_(observe_event) {
+ assert(observer_ != NULL);
+ assert(observe_event_ != NULL);
+ }
+
+ virtual ~CallbackImpl() {}
+
+ virtual void operator()(bool success, Key key, Data data) const {
+ (observer_->*observe_event_)(success, key, data);
+ }
+
+ private:
+ Observer* observer_;
+ ObserveEvent observe_event_;
+};
+
+} // namespace
+
+// Returns a callback to |observer->observe_event| method. The caller owns the
+// result.
+template <typename Observer, typename Key, typename Data>
+Callback<Key, Data>* BuildCallback(
+ Observer* observer,
+ void (Observer::*observe_event)(bool, Key, Data)) {
+ return new CallbackImpl<Observer, Key, Data>(observer, observe_event);
+}
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_CALLBACK_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h
new file mode 100644
index 00000000000..5e7896d9f10
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h
@@ -0,0 +1,94 @@
+// 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.
+
+#ifndef I18N_ADDRESSINPUT_LOCALIZATION_H_
+#define I18N_ADDRESSINPUT_LOCALIZATION_H_
+
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/address_problem.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+struct AddressData;
+
+// The object to retrieve localized strings based on message IDs. It returns
+// English by default. Sample usage:
+// Localization localization;
+// std::string best_language_tag;
+// Process(BuildComponents("CA", localization, "en-US", &best_language_tag));
+//
+// Alternative usage:
+// Localization localization;
+// localization.SetGetter(&MyStringGetter);
+// std::string best_language_tag;
+// Process(BuildComponents("CA", localization, "fr-CA", &best_language_tag));
+class Localization {
+ public:
+ // Initializes with English messages by default.
+ Localization();
+ ~Localization();
+
+ // Returns the localized string for |message_id|. Returns an empty string if
+ // there's no message with this identifier.
+ std::string GetString(int message_id) const;
+
+ // Returns the error message. If |enable_examples| is false, then the error
+ // message will not contain examples of valid input. If |enable_links| is
+ // false, then the error message will not contain HTML links. (Some error
+ // messages contain postal code examples or link to post office websites to
+ // look up the postal code for an address). Vector field values (e.g. for
+ // street address) should not be empty if problem is UNKNOWN_VALUE. The
+ // POSTAL_CODE field should only be used with MISSING_REQUIRED_FIELD,
+ // INVALID_FORMAT, and MISMATCHING_VALUE problem codes. All other fields
+ // should only be used with MISSING_REQUIRED_FIELD, UNKNOWN_VALUE, and
+ // USES_P_O_BOX problem codes.
+ std::string GetErrorMessage(const AddressData& address,
+ AddressField field,
+ AddressProblem problem,
+ bool enable_examples,
+ bool enable_links) const;
+
+ // Sets the string getter that takes a message identifier and returns the
+ // corresponding localized string. For example, in Chromium there is
+ // l10n_util::GetStringUTF8 which always returns strings in the current
+ // application locale.
+ void SetGetter(std::string (*getter)(int));
+
+ private:
+ // Returns the error message where the address field is a postal code. Helper
+ // to |GetErrorMessage|. If |postal_code_example| is empty, then the error
+ // message will not contain examples of valid postal codes. If
+ // |post_service_url| is empty, then the error message will not contain a post
+ // service URL. The problem should only be one of MISSING_REQUIRED_FIELD,
+ // INVALID_FORMAT, or MISMATCHING_VALUE.
+ std::string GetErrorMessageForPostalCode(const AddressData& address,
+ AddressProblem problem,
+ bool uses_postal_code_as_label,
+ std::string postal_code_example,
+ std::string post_service_url) const;
+
+ // The string getter.
+ std::string (*get_string_)(int);
+
+ DISALLOW_COPY_AND_ASSIGN(Localization);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_LOCALIZATION_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h
new file mode 100644
index 00000000000..66d9ab5216e
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 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.
+//
+// It is not always desirable to cache libaddressinput data. Sometimes it might
+// give better performance characteristics to not cache. This implementation of
+// the Storage interface therefore doesn't actually store anything.
+
+#ifndef I18N_ADDRESSINPUT_NULL_STORAGE_H_
+#define I18N_ADDRESSINPUT_NULL_STORAGE_H_
+
+#include <libaddressinput/storage.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class NullStorage : public Storage {
+ public:
+ NullStorage();
+ virtual ~NullStorage();
+
+ // No-op.
+ virtual void Put(const std::string& key, std::string* data);
+
+ // Always calls the |data_ready| callback function signalling failure.
+ virtual void Get(const std::string& key, const Callback& data_ready) const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NullStorage);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_NULL_STORAGE_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/ondemand_supplier.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/ondemand_supplier.h
new file mode 100644
index 00000000000..6212d34b6e3
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/ondemand_supplier.h
@@ -0,0 +1,66 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_ONDEMAND_SUPPLIER_H_
+#define I18N_ADDRESSINPUT_ONDEMAND_SUPPLIER_H_
+
+#include <libaddressinput/callback.h>
+#include <libaddressinput/supplier.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <map>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class LookupKey;
+class Retriever;
+class Rule;
+class Source;
+class Storage;
+
+// An implementation of the Supplier interface that owns a Retriever object,
+// through which it loads address metadata as needed, creating Rule objects and
+// caching these.
+//
+// When using an OndemandSupplier, address validation will benefit from address
+// metadata server synonym resolution, because the server will be contacted for
+// every new LookupKey (ie. every LookupKey that isn't on canonical form and
+// isn't already cached).
+//
+// The maximum size of this cache is naturally limited to the amount of data
+// available from the data server. (Currently this is less than 12,000 items of
+// in total less than 2 MB of JSON data.)
+class OndemandSupplier : public Supplier {
+ public:
+ // Takes ownership of |source| and |storage|.
+ OndemandSupplier(const Source* source, Storage* storage);
+ virtual ~OndemandSupplier();
+
+ // Loads the metadata needed for |lookup_key|, then calls |supplied|.
+ virtual void Supply(const LookupKey& lookup_key, const Callback& supplied);
+
+ private:
+ const scoped_ptr<const Retriever> retriever_;
+ std::map<std::string, const Rule*> rule_cache_;
+
+ DISALLOW_COPY_AND_ASSIGN(OndemandSupplier);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ONDEMAND_SUPPLIER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h
new file mode 100644
index 00000000000..5987c7980da
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h
@@ -0,0 +1,103 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_PRELOAD_SUPPLIER_H_
+#define I18N_ADDRESSINPUT_PRELOAD_SUPPLIER_H_
+
+#include <libaddressinput/callback.h>
+#include <libaddressinput/supplier.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+class IndexMap;
+class LookupKey;
+class Retriever;
+class Rule;
+class Source;
+class Storage;
+
+// An implementation of the Supplier interface that owns a Retriever object,
+// through which it can load aggregated address metadata for a region when
+// instructed to, creating Rule objects and caching these. It also provides
+// methods to check whether metadata for a particular region is already loaded
+// or in progress of being loaded.
+//
+// When using a PreloadSupplier, it becomes possible to do synchronous address
+// validation using an asynchronous Source, and to have full control over when
+// network access is being done.
+//
+// The maximum size of this cache is naturally limited to the amount of data
+// available from the data server. (Currently this is less than 12,000 items of
+// in total less than 2 MB of JSON data.)
+class PreloadSupplier : public Supplier {
+ public:
+ typedef i18n::addressinput::Callback<const std::string&, int> Callback;
+
+ // Takes ownership of |source| and |storage|.
+ PreloadSupplier(const Source* source, Storage* storage);
+ virtual ~PreloadSupplier();
+
+ // Collects the metadata needed for |lookup_key| from the cache, then calls
+ // |supplied|. If the metadata needed isn't found in the cache, it will call
+ // the callback with status false.
+ virtual void Supply(const LookupKey& lookup_key,
+ const Supplier::Callback& supplied);
+
+ // Should be called only when IsLoaded() returns true for the region code of
+ // the |lookup_key|. Can return NULL if the |lookup_key| does not correspond
+ // to any rule data. The caller does not own the result.
+ const Rule* GetRule(const LookupKey& lookup_key) const;
+
+ // Loads all address metadata available for |region_code|. (A typical data
+ // size is 10 kB. The largest is 250 kB.)
+ //
+ // If the rules are already in progress of being loaded, it does nothing.
+ // Calls |loaded| when the loading has finished.
+ void LoadRules(const std::string& region_code, const Callback& loaded);
+
+ // Returns a mapping of lookup keys to rules. Should be called only when
+ // IsLoaded() returns true for the |region_code|.
+ const std::map<std::string, const Rule*>& GetRulesForRegion(
+ const std::string& region_code) const;
+
+ bool IsLoaded(const std::string& region_code) const;
+ bool IsPending(const std::string& region_code) const;
+
+ private:
+ bool GetRuleHierarchy(const LookupKey& lookup_key,
+ RuleHierarchy* hierarchy) const;
+ bool IsLoadedKey(const std::string& key) const;
+ bool IsPendingKey(const std::string& key) const;
+
+ const scoped_ptr<const Retriever> retriever_;
+ std::set<std::string> pending_;
+ const scoped_ptr<IndexMap> rule_index_;
+ std::vector<const Rule*> rule_storage_;
+ std::map<std::string, std::map<std::string, const Rule*> > region_rules_;
+
+ DISALLOW_COPY_AND_ASSIGN(PreloadSupplier);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_PRELOAD_SUPPLIER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h
new file mode 100644
index 00000000000..92438dc6787
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h
@@ -0,0 +1,77 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_REGION_DATA_H_
+#define I18N_ADDRESSINPUT_REGION_DATA_H_
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+// The key and name of a region that can be used as one of the items in a
+// dropdown UI element.
+class RegionData {
+ public:
+ // Creates a top-level RegionData object. Use AddSubRegion() to add data below
+ // it. Does not make a copy of data in |region_code|.
+ explicit RegionData(const std::string& region_code);
+
+ ~RegionData();
+
+ // Creates a sub-level RegionData object, with this object as its parent and
+ // owner. Does not make copies of the data in |key| or |name|.
+ RegionData* AddSubRegion(const std::string& key, const std::string& name);
+
+ const std::string& key() const { return key_; }
+
+ const std::string& name() const { return name_; }
+
+ bool has_parent() const { return parent_ != NULL; }
+
+ // Should be called only if has_parent() returns true.
+ const RegionData& parent() const {
+ assert(parent_ != NULL);
+ return *parent_;
+ }
+
+ // The caller does not own the results. The results are not NULL and have a
+ // parent.
+ const std::vector<const RegionData*>& sub_regions() const {
+ return sub_regions_;
+ }
+
+ private:
+ // Private constructor used by AddSubRegion().
+ RegionData(const std::string& key,
+ const std::string& name,
+ RegionData* parent);
+
+ const std::string& key_;
+ const std::string& name_;
+ const RegionData* const parent_; // Not owned.
+ std::vector<const RegionData*> sub_regions_; // Owned.
+
+ DISALLOW_COPY_AND_ASSIGN(RegionData);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_REGION_DATA_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h
new file mode 100644
index 00000000000..906ca36fa3a
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h
@@ -0,0 +1,80 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_REGION_DATA_BUILDER_H_
+#define I18N_ADDRESSINPUT_REGION_DATA_BUILDER_H_
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <map>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class PreloadSupplier;
+class RegionData;
+
+class RegionDataBuilder {
+ public:
+ // Does not take ownership of |supplier|, which should not be NULL.
+ explicit RegionDataBuilder(PreloadSupplier* supplier);
+ ~RegionDataBuilder();
+
+ // Returns a tree of administrative subdivisions for the |region_code|.
+ // Examples:
+ // US with en-US UI language.
+ // |______________________
+ // | | |
+ // v v v
+ // AL:Alabama AK:Alaska AS:American Samoa ...
+ //
+ // KR with ko-Latn UI language.
+ // |______________________________________
+ // | | |
+ // v v v
+ // 강원도:Gangwon 경기도:Gyeonggi 경상남도:Gyeongnam ...
+ //
+ // KR with ko-KR UI language.
+ // |_______________________________
+ // | | |
+ // v v v
+ // 강원도:강원 경기도:경기 경상남도:경남 ...
+ //
+ // The BCP 47 |ui_language_tag| is used to choose the best supported language
+ // tag for this region (assigned to |best_region_tree_language_tag|). For
+ // example, Canada has both English and French names for its administrative
+ // subdivisions. If the UI language is French, then the French names are used.
+ // The |best_region_tree_language_tag| value may be an empty string.
+ //
+ // Should be called only if supplier->IsLoaded(region_code) returns true. The
+ // |best_region_tree_language_tag| parameter should not be NULL.
+ const RegionData& Build(const std::string& region_code,
+ const std::string& ui_language_tag,
+ std::string* best_region_tree_language_tag);
+
+ private:
+ typedef std::map<std::string, const RegionData*> LanguageRegionMap;
+ typedef std::map<std::string, LanguageRegionMap*> RegionCodeDataMap;
+
+ PreloadSupplier* const supplier_; // Not owned.
+ RegionCodeDataMap cache_;
+
+ DISALLOW_COPY_AND_ASSIGN(RegionDataBuilder);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_REGION_DATA_BUILDER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/source.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/source.h
new file mode 100644
index 00000000000..4d91b68565b
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/source.h
@@ -0,0 +1,56 @@
+// 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.
+//
+// The interface to be implemented by the user of the library to access address
+// metadata, typically by downloading this from the address metadata server or
+// by linking the metadata into the binary.
+
+#ifndef I18N_ADDRESSINPUT_SOURCE_H_
+#define I18N_ADDRESSINPUT_SOURCE_H_
+
+#include <libaddressinput/callback.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+// Gets address metadata. The callback data must be allocated on the heap,
+// passing ownership to the callback. Sample usage:
+//
+// class MySource : public Source {
+// public:
+// virtual void Get(const std::string& key,
+// const Callback& data_ready) const {
+// bool success = ...
+// std::string* data = new ...
+// data_ready(success, key, data);
+// }
+// };
+class Source {
+ public:
+ typedef i18n::addressinput::Callback<const std::string&,
+ std::string*> Callback;
+
+ virtual ~Source() {}
+
+ // Gets metadata for |key| and invokes the |data_ready| callback.
+ virtual void Get(const std::string& key,
+ const Callback& data_ready) const = 0;
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_SOURCE_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h
new file mode 100644
index 00000000000..94ad13bdd20
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h
@@ -0,0 +1,64 @@
+// 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.
+//
+// The interface to be implemented by the user of the library to enable storing
+// address metadata (e.g. on disk).
+
+#ifndef I18N_ADDRESSINPUT_STORAGE_H_
+#define I18N_ADDRESSINPUT_STORAGE_H_
+
+#include <libaddressinput/callback.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+// Stores address metadata. The data must be allocated on the heap, passing
+// ownership to the called function. Sample usage:
+//
+// class MyStorage : public Storage {
+// public:
+// virtual void Put(const std::string& key, std::string* data) {
+// ...
+// delete data;
+// }
+//
+// virtual void Get(const std::string& key,
+// const Callback& data_ready) const {
+// bool success = ...
+// std::string* data = new ...
+// data_ready(success, key, data);
+// }
+// };
+class Storage {
+ public:
+ typedef i18n::addressinput::Callback<const std::string&,
+ std::string*> Callback;
+
+ virtual ~Storage() {}
+
+ // Stores |data| for |key|, where |data| is an object allocated on the heap,
+ // which Storage takes ownership of.
+ virtual void Put(const std::string& key, std::string* data) = 0;
+
+ // Retrieves the data for |key| and invokes the |data_ready| callback.
+ virtual void Get(const std::string& key,
+ const Callback& data_ready) const = 0;
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_STORAGE_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/supplier.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/supplier.h
new file mode 100644
index 00000000000..7d079cff450
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/supplier.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_SUPPLIER_H_
+#define I18N_ADDRESSINPUT_SUPPLIER_H_
+
+#include <libaddressinput/callback.h>
+
+namespace i18n {
+namespace addressinput {
+
+class LookupKey;
+class Rule;
+
+// Interface for objects that are able to supply the AddressValidator with the
+// metadata needed to validate an address, as described by a LookupKey.
+class Supplier {
+ public:
+ struct RuleHierarchy;
+ typedef i18n::addressinput::Callback<const LookupKey&,
+ const RuleHierarchy&> Callback;
+
+ virtual ~Supplier() {}
+
+ // Aggregates the metadata needed for |lookup_key| into a RuleHierarchy
+ // object, then calls |supplied|. Implementations of this interface may
+ // either load the necessary data on demand, or fail if the necessary data
+ // hasn't already been loaded.
+ virtual void Supply(const LookupKey& lookup_key,
+ const Callback& supplied) = 0;
+
+ // A RuleHierarchy object encapsulates the hierarchical list of Rule objects
+ // that corresponds to a particular LookupKey.
+ struct RuleHierarchy {
+ RuleHierarchy() : rule() {}
+ const Rule* rule[4]; // Cf. LookupKey::kHierarchy.
+ };
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_SUPPLIER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/basictypes.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/basictypes.h
new file mode 100644
index 00000000000..663133fc0a9
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/basictypes.h
@@ -0,0 +1,213 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The original source code is from:
+// https://code.google.com/p/libphonenumber/source/browse/trunk/cpp/src/phonenumbers/base/basictypes.h?r=621
+
+#if I18N_ADDRESSINPUT_USE_BASICTYPES_OVERRIDE
+
+// If building libaddressinput in an environment where there already is another
+// implementation of the basictypes.h header file (like in Chromium), then pass
+// the command line flag -DI18N_ADDRESSINPUT_USE_BASICTYPES_OVERRIDE=1 to the
+// compiler and provide a file named basictypes_override.h, in a location where
+// the compiler will look for it, which provides the desired implementation.
+
+#include "basictypes_override.h"
+
+#else
+
+#ifndef I18N_ADDRESSINPUT_UTIL_BASICTYPES_H_
+#define I18N_ADDRESSINPUT_UTIL_BASICTYPES_H_
+
+#include <climits> // So we can set the bounds of our types
+#include <cstddef> // For size_t
+
+#if !defined(_WIN32)
+// stdint.h is part of C99 but MSVC doesn't have it.
+#include <stdint.h> // For intptr_t.
+#endif
+
+#ifdef INT64_MAX
+
+// INT64_MAX is defined if C99 stdint.h is included; use the
+// native types if available.
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
+
+const uint8 kuint8max = UINT8_MAX;
+const uint16 kuint16max = UINT16_MAX;
+const uint32 kuint32max = UINT32_MAX;
+const uint64 kuint64max = UINT64_MAX;
+const int8 kint8min = INT8_MIN;
+const int8 kint8max = INT8_MAX;
+const int16 kint16min = INT16_MIN;
+const int16 kint16max = INT16_MAX;
+const int32 kint32min = INT32_MIN;
+const int32 kint32max = INT32_MAX;
+const int64 kint64min = INT64_MIN;
+const int64 kint64max = INT64_MAX;
+
+#else // !INT64_MAX
+
+typedef signed char int8;
+typedef short int16;
+// TODO: Remove these type guards. These are to avoid conflicts with
+// obsolete/protypes.h in the Gecko SDK.
+#ifndef _INT32
+#define _INT32
+typedef int int32;
+#endif
+
+// The NSPR system headers define 64-bit as |long| when possible. In order to
+// not have typedef mismatches, we do the same on LP64.
+#if __LP64__
+typedef long int64;
+#else
+typedef long long int64;
+#endif
+
+// NOTE: unsigned types are DANGEROUS in loops and other arithmetical
+// places. Use the signed types unless your variable represents a bit
+// pattern (eg a hash value) or you really need the extra bit. Do NOT
+// use 'unsigned' to express "this value should always be positive";
+// use assertions for this.
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+// TODO: Remove these type guards. These are to avoid conflicts with
+// obsolete/protypes.h in the Gecko SDK.
+#ifndef _UINT32
+#define _UINT32
+typedef unsigned int uint32;
+#endif
+
+// See the comment above about NSPR and 64-bit.
+#if __LP64__
+typedef unsigned long uint64;
+#else
+typedef unsigned long long uint64;
+#endif
+
+#endif // !INT64_MAX
+
+typedef signed char schar;
+
+// A type to represent a Unicode code-point value. As of Unicode 4.0,
+// such values require up to 21 bits.
+// (For type-checking on pointers, make this explicitly signed,
+// and it should always be the signed version of whatever int32 is.)
+typedef signed int char32;
+
+// A macro to disallow the copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+#if !defined(DISALLOW_COPY_AND_ASSIGN)
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+#endif
+
+// The arraysize(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example. If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+//
+// One caveat is that arraysize() doesn't accept any array of an
+// anonymous type or a type defined inside a function. In these rare
+// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is
+// due to a limitation in C++'s template system. The limitation might
+// eventually be removed, but it hasn't happened yet.
+
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template <typename T, size_t N>
+char (&ArraySizeHelper(T (&array)[N]))[N];
+
+// That gcc wants both of these prototypes seems mysterious. VC, for
+// its part, can't decide which to use (another mystery). Matching of
+// template overloads: the final frontier.
+#ifndef _MSC_VER
+template <typename T, size_t N>
+char (&ArraySizeHelper(const T (&array)[N]))[N];
+#endif
+
+#if !defined(arraysize)
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+#endif
+
+// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
+// but can be used on anonymous types or types defined inside
+// functions. It's less safe than arraysize as it accepts some
+// (although not all) pointers. Therefore, you should use arraysize
+// whenever possible.
+//
+// The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type
+// size_t.
+//
+// ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error
+//
+// "warning: division by zero in ..."
+//
+// when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer.
+// You should only use ARRAYSIZE_UNSAFE on statically allocated arrays.
+//
+// The following comments are on the implementation details, and can
+// be ignored by the users.
+//
+// ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in
+// the array) and sizeof(*(arr)) (the # of bytes in one array
+// element). If the former is divisible by the latter, perhaps arr is
+// indeed an array, in which case the division result is the # of
+// elements in the array. Otherwise, arr cannot possibly be an array,
+// and we generate a compiler error to prevent the code from
+// compiling.
+//
+// Since the size of bool is implementation-defined, we need to cast
+// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
+// result has type size_t.
+//
+// This macro is not perfect as it wrongfully accepts certain
+// pointers, namely where the pointer size is divisible by the pointee
+// size. Since all our code has to go through a 32-bit compiler,
+// where a pointer is 4 bytes, this means all pointers to a type whose
+// size is 3 or greater than 4 will be (righteously) rejected.
+
+#if !defined(ARRAYSIZE_UNSAFE)
+#define ARRAYSIZE_UNSAFE(a) \
+ ((sizeof(a) / sizeof(*(a))) / \
+ static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+#endif
+
+// The COMPILE_ASSERT macro can be used to verify that a compile time
+// expression is true. For example, you could use it to verify the
+// size of a static array:
+//
+// COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES,
+// content_type_names_incorrect_size);
+//
+// or to make sure a struct is smaller than a certain size:
+//
+// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
+//
+// The second argument to the macro is the name of the variable. If
+// the expression is false, most compilers will issue a warning/error
+// containing the name of the variable.
+
+template <bool>
+struct CompileAssert {
+};
+
+#if !defined(COMPILE_ASSERT)
+#define COMPILE_ASSERT(expr, msg) \
+ typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
+#endif
+
+#endif // I18N_ADDRESSINPUT_UTIL_BASICTYPES_H_
+#endif // I18N_ADDRESSINPUT_USE_BASICTYPES_OVERRIDE
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/scoped_ptr.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/scoped_ptr.h
new file mode 100644
index 00000000000..a88c2a9f6ab
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/scoped_ptr.h
@@ -0,0 +1,444 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The original source code is from:
+// https://code.google.com/p/libphonenumber/source/browse/trunk/cpp/src/phonenumbers/base/memory/scoped_ptr.h?r=621
+
+#ifndef I18N_ADDRESSINPUT_UTIL_SCOPED_PTR_H_
+#define I18N_ADDRESSINPUT_UTIL_SCOPED_PTR_H_
+
+// This is an implementation designed to match the anticipated future TR2
+// implementation of the scoped_ptr class and scoped_ptr_malloc (deprecated).
+
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/template_util.h>
+
+#include <algorithm> // For std::swap().
+#include <cassert>
+#include <cstddef>
+#include <cstdlib>
+
+namespace i18n {
+namespace addressinput {
+
+// Function object which deletes its parameter, which must be a pointer.
+// If C is an array type, invokes 'delete[]' on the parameter; otherwise,
+// invokes 'delete'. The default deleter for scoped_ptr<T>.
+template <class T>
+struct DefaultDeleter {
+ DefaultDeleter() {}
+ template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) {
+ // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor
+ // if U* is implicitly convertible to T* and U is not an array type.
+ //
+ // Correct implementation should use SFINAE to disable this
+ // constructor. However, since there are no other 1-argument constructors,
+ // using a COMPILE_ASSERT() based on is_convertible<> and requiring
+ // complete types is simpler and will cause compile failures for equivalent
+ // misuses.
+ //
+ // Note, the is_convertible<U*, T*> check also ensures that U is not an
+ // array. T is guaranteed to be a non-array, so any U* where U is an array
+ // cannot convert to T*.
+ enum { T_must_be_complete = sizeof(T) };
+ enum { U_must_be_complete = sizeof(U) };
+ COMPILE_ASSERT((is_convertible<U*, T*>::value),
+ U_ptr_must_implicitly_convert_to_T_ptr);
+ }
+ inline void operator()(T* ptr) const {
+ enum { type_must_be_complete = sizeof(T) };
+ delete ptr;
+ }
+};
+
+// Specialization of DefaultDeleter for array types.
+template <class T>
+struct DefaultDeleter<T[]> {
+ inline void operator()(T* ptr) const {
+ enum { type_must_be_complete = sizeof(T) };
+ delete[] ptr;
+ }
+
+ private:
+ // Disable this operator for any U != T because it is undefined to execute
+ // an array delete when the static type of the array mismatches the dynamic
+ // type.
+ //
+ // References:
+ // C++98 [expr.delete]p3
+ // http://cplusplus.github.com/LWG/lwg-defects.html#938
+ template <typename U> void operator()(U* array) const;
+};
+
+template <class T, int n>
+struct DefaultDeleter<T[n]> {
+ // Never allow someone to declare something like scoped_ptr<int[10]>.
+ COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type);
+};
+
+// Function object which invokes 'free' on its parameter, which must be
+// a pointer. Can be used to store malloc-allocated pointers in scoped_ptr:
+//
+// scoped_ptr<int, base::FreeDeleter> foo_ptr(
+// static_cast<int*>(malloc(sizeof(int))));
+struct FreeDeleter {
+ inline void operator()(void* ptr) const {
+ free(ptr);
+ }
+};
+
+// Minimal implementation of the core logic of scoped_ptr, suitable for
+// reuse in both scoped_ptr and its specializations.
+template <class T, class D>
+class scoped_ptr_impl {
+ public:
+ explicit scoped_ptr_impl(T* p) : data_(p) { }
+
+ // Initializer for deleters that have data parameters.
+ scoped_ptr_impl(T* p, const D& d) : data_(p, d) {}
+
+ // Templated constructor that destructively takes the value from another
+ // scoped_ptr_impl.
+ template <typename U, typename V>
+ scoped_ptr_impl(scoped_ptr_impl<U, V>* other)
+ : data_(other->release(), other->get_deleter()) {
+ // We do not support move-only deleters. We could modify our move
+ // emulation to have base::subtle::move() and base::subtle::forward()
+ // functions that are imperfect emulations of their C++11 equivalents,
+ // but until there's a requirement, just assume deleters are copyable.
+ }
+
+ template <typename U, typename V>
+ void TakeState(scoped_ptr_impl<U, V>* other) {
+ // See comment in templated constructor above regarding lack of support
+ // for move-only deleters.
+ reset(other->release());
+ get_deleter() = other->get_deleter();
+ }
+
+ ~scoped_ptr_impl() {
+ if (data_.ptr != NULL) {
+ // Not using get_deleter() saves one function call in non-optimized
+ // builds.
+ static_cast<D&>(data_)(data_.ptr);
+ }
+ }
+
+ void reset(T* p) {
+ // This is a self-reset, which is no longer allowed: http://crbug.com/162971
+ if (p != NULL && p == data_.ptr)
+ abort();
+
+ // Note that running data_.ptr = p can lead to undefined behavior if
+ // get_deleter()(get()) deletes this. In order to pevent this, reset()
+ // should update the stored pointer before deleting its old value.
+ //
+ // However, changing reset() to use that behavior may cause current code to
+ // break in unexpected ways. If the destruction of the owned object
+ // dereferences the scoped_ptr when it is destroyed by a call to reset(),
+ // then it will incorrectly dispatch calls to |p| rather than the original
+ // value of |data_.ptr|.
+ //
+ // During the transition period, set the stored pointer to NULL while
+ // deleting the object. Eventually, this safety check will be removed to
+ // prevent the scenario initially described from occuring and
+ // http://crbug.com/176091 can be closed.
+ T* old = data_.ptr;
+ data_.ptr = NULL;
+ if (old != NULL)
+ static_cast<D&>(data_)(old);
+ data_.ptr = p;
+ }
+
+ T* get() const { return data_.ptr; }
+
+ D& get_deleter() { return data_; }
+ const D& get_deleter() const { return data_; }
+
+ void swap(scoped_ptr_impl& p2) {
+ // Standard swap idiom: 'using std::swap' ensures that std::swap is
+ // present in the overload set, but we call swap unqualified so that
+ // any more-specific overloads can be used, if available.
+ using std::swap;
+ swap(static_cast<D&>(data_), static_cast<D&>(p2.data_));
+ swap(data_.ptr, p2.data_.ptr);
+ }
+
+ T* release() {
+ T* old_ptr = data_.ptr;
+ data_.ptr = NULL;
+ return old_ptr;
+ }
+
+ private:
+ // Needed to allow type-converting constructor.
+ template <typename U, typename V> friend class scoped_ptr_impl;
+
+ // Use the empty base class optimization to allow us to have a D
+ // member, while avoiding any space overhead for it when D is an
+ // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good
+ // discussion of this technique.
+ struct Data : public D {
+ explicit Data(T* ptr_in) : ptr(ptr_in) {}
+ Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {}
+ T* ptr;
+ };
+
+ Data data_;
+
+ DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl);
+};
+
+// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any).
+// That is, scoped_ptr<T> owns the T object that it points to.
+// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
+// Also like T*, scoped_ptr<T> is thread-compatible, and once you
+// dereference it, you get the thread safety guarantees of T.
+//
+// The size of scoped_ptr is small. On most compilers, when using the
+// DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will
+// increase the size proportional to whatever state they need to have. See
+// comments inside scoped_ptr_impl<> for details.
+//
+// Current implementation targets having a strict subset of C++11's
+// unique_ptr<> features. Known deficiencies include not supporting move-only
+// deleteres, function pointers as deleters, and deleters with reference
+// types.
+template <class T, class D = DefaultDeleter<T> >
+class scoped_ptr {
+ public:
+ // The element and deleter types.
+ typedef T element_type;
+ typedef D deleter_type;
+
+ // Constructor. Defaults to initializing with NULL.
+ scoped_ptr() : impl_(NULL) { }
+
+ // Constructor. Takes ownership of p.
+ explicit scoped_ptr(element_type* p) : impl_(p) { }
+
+ // Constructor. Allows initialization of a stateful deleter.
+ scoped_ptr(element_type* p, const D& d) : impl_(p, d) { }
+
+ // Constructor. Allows construction from a scoped_ptr rvalue for a
+ // convertible type and deleter.
+ //
+ // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct
+ // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor
+ // has different post-conditions if D is a reference type. Since this
+ // implementation does not support deleters with reference type,
+ // we do not need a separate move constructor allowing us to avoid one
+ // use of SFINAE. You only need to care about this if you modify the
+ // implementation of scoped_ptr.
+ template <typename U, typename V>
+ scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) {
+ COMPILE_ASSERT(!is_array<U>::value, U_cannot_be_an_array);
+ }
+
+ // operator=. Allows assignment from a scoped_ptr rvalue for a convertible
+ // type and deleter.
+ //
+ // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from
+ // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated
+ // form has different requirements on for move-only Deleters. Since this
+ // implementation does not support move-only Deleters, we do not need a
+ // separate move assignment operator allowing us to avoid one use of SFINAE.
+ // You only need to care about this if you modify the implementation of
+ // scoped_ptr.
+ template <typename U, typename V>
+ scoped_ptr& operator=(scoped_ptr<U, V> rhs) {
+ COMPILE_ASSERT(!is_array<U>::value, U_cannot_be_an_array);
+ impl_.TakeState(&rhs.impl_);
+ return *this;
+ }
+
+ // Reset. Deletes the currently owned object, if any.
+ // Then takes ownership of a new object, if given.
+ void reset(element_type* p = NULL) { impl_.reset(p); }
+
+ // Accessors to get the owned object.
+ // operator* and operator-> will assert() if there is no current object.
+ element_type& operator*() const {
+ assert(impl_.get() != NULL);
+ return *impl_.get();
+ }
+ element_type* operator->() const {
+ assert(impl_.get() != NULL);
+ return impl_.get();
+ }
+ element_type* get() const { return impl_.get(); }
+
+ // Access to the deleter.
+ deleter_type& get_deleter() { return impl_.get_deleter(); }
+ const deleter_type& get_deleter() const { return impl_.get_deleter(); }
+
+ // Allow scoped_ptr<element_type> to be used in boolean expressions, but not
+ // implicitly convertible to a real bool (which is dangerous).
+ private:
+ typedef scoped_ptr_impl<element_type, deleter_type> scoped_ptr::*Testable;
+
+ public:
+ operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
+
+ // Comparison operators.
+ // These return whether two scoped_ptr refer to the same object, not just to
+ // two different but equal objects.
+ bool operator==(const element_type* p) const { return impl_.get() == p; }
+ bool operator!=(const element_type* p) const { return impl_.get() != p; }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr& p2) {
+ impl_.swap(p2.impl_);
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ element_type* release() {
+ return impl_.release();
+ }
+
+ private:
+ // Needed to reach into |impl_| in the constructor.
+ template <typename U, typename V> friend class scoped_ptr;
+ scoped_ptr_impl<element_type, deleter_type> impl_;
+
+ // Forbid comparison of scoped_ptr types. If U != T, it totally
+ // doesn't make sense, and if U == T, it still doesn't make sense
+ // because you should never have the same object owned by two different
+ // scoped_ptrs.
+ template <class U> bool operator==(scoped_ptr<U> const& p2) const;
+ template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
+};
+
+template <class T, class D>
+class scoped_ptr<T[], D> {
+ public:
+ // The element and deleter types.
+ typedef T element_type;
+ typedef D deleter_type;
+
+ // Constructor. Defaults to initializing with NULL.
+ scoped_ptr() : impl_(NULL) { }
+
+ // Constructor. Stores the given array. Note that the argument's type
+ // must exactly match T*. In particular:
+ // - it cannot be a pointer to a type derived from T, because it is
+ // inherently unsafe in the general case to access an array through a
+ // pointer whose dynamic type does not match its static type (eg., if
+ // T and the derived types had different sizes access would be
+ // incorrectly calculated). Deletion is also always undefined
+ // (C++98 [expr.delete]p3). If you're doing this, fix your code.
+ // - it cannot be NULL, because NULL is an integral expression, not a
+ // pointer to T. Use the no-argument version instead of explicitly
+ // passing NULL.
+ // - it cannot be const-qualified differently from T per unique_ptr spec
+ // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
+ // to work around this may use implicit_cast<const T*>().
+ // However, because of the first bullet in this comment, users MUST
+ // NOT use implicit_cast<Base*>() to upcast the static type of the array.
+ explicit scoped_ptr(element_type* array) : impl_(array) { }
+
+ // Reset. Deletes the currently owned array, if any.
+ // Then takes ownership of a new object, if given.
+ void reset(element_type* array = NULL) { impl_.reset(array); }
+
+ // Accessors to get the owned array.
+ element_type& operator[](size_t i) const {
+ assert(impl_.get() != NULL);
+ return impl_.get()[i];
+ }
+ element_type* get() const { return impl_.get(); }
+
+ // Access to the deleter.
+ deleter_type& get_deleter() { return impl_.get_deleter(); }
+ const deleter_type& get_deleter() const { return impl_.get_deleter(); }
+
+ // Allow scoped_ptr<element_type> to be used in boolean expressions, but not
+ // implicitly convertible to a real bool (which is dangerous).
+ private:
+ typedef scoped_ptr_impl<element_type, deleter_type> scoped_ptr::*Testable;
+
+ public:
+ operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
+
+ // Comparison operators.
+ // These return whether two scoped_ptr refer to the same object, not just to
+ // two different but equal objects.
+ bool operator==(element_type* array) const { return impl_.get() == array; }
+ bool operator!=(element_type* array) const { return impl_.get() != array; }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr& p2) {
+ impl_.swap(p2.impl_);
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ element_type* release() {
+ return impl_.release();
+ }
+
+ private:
+ // Force element_type to be a complete type.
+ enum { type_must_be_complete = sizeof(element_type) };
+
+ // Actually hold the data.
+ scoped_ptr_impl<element_type, deleter_type> impl_;
+
+ // Disable initialization from any type other than element_type*, by
+ // providing a constructor that matches such an initialization, but is
+ // private and has no definition. This is disabled because it is not safe to
+ // call delete[] on an array whose static type does not match its dynamic
+ // type.
+ template <typename U> explicit scoped_ptr(U* array);
+ explicit scoped_ptr(int disallow_construction_from_null);
+
+ // Disable reset() from any type other than element_type*, for the same
+ // reasons as the constructor above.
+ template <typename U> void reset(U* array);
+ void reset(int disallow_reset_from_null);
+
+ // Forbid comparison of scoped_ptr types. If U != T, it totally
+ // doesn't make sense, and if U == T, it still doesn't make sense
+ // because you should never have the same object owned by two different
+ // scoped_ptrs.
+ template <class U> bool operator==(scoped_ptr<U> const& p2) const;
+ template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
+};
+
+// Free functions
+template <class T, class D>
+void swap(scoped_ptr<T, D>& p1, scoped_ptr<T, D>& p2) {
+ p1.swap(p2);
+}
+
+template <class T, class D>
+bool operator==(T* p1, const scoped_ptr<T, D>& p2) {
+ return p1 == p2.get();
+}
+
+template <class T, class D>
+bool operator!=(T* p1, const scoped_ptr<T, D>& p2) {
+ return p1 != p2.get();
+}
+
+// A function to convert T* into scoped_ptr<T>
+// Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+scoped_ptr<T> make_scoped_ptr(T* ptr) {
+ return scoped_ptr<T>(ptr);
+}
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_SCOPED_PTR_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/template_util.h b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/template_util.h
new file mode 100644
index 00000000000..35125e12d0b
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/include/libaddressinput/util/template_util.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The original source code is from:
+// https://code.google.com/p/libphonenumber/source/browse/trunk/cpp/src/phonenumbers/base/template_util.h?r=621
+
+#ifndef I18N_ADDRESSINPUT_UTIL_TEMPLATE_UTIL_H_
+#define I18N_ADDRESSINPUT_UTIL_TEMPLATE_UTIL_H_
+
+#include <cstddef> // For size_t.
+
+namespace i18n {
+namespace addressinput {
+
+// template definitions from tr1
+
+template<class T, T v>
+struct integral_constant {
+ static const T value = v;
+ typedef T value_type;
+ typedef integral_constant<T, v> type;
+};
+
+template <class T, T v> const T integral_constant<T, v>::value;
+
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+
+template <class T> struct is_pointer : false_type {};
+template <class T> struct is_pointer<T*> : true_type {};
+
+template <class T, class U> struct is_same : public false_type {};
+template <class T> struct is_same<T,T> : true_type {};
+
+template<class> struct is_array : public false_type {};
+template<class T, size_t n> struct is_array<T[n]> : public true_type {};
+template<class T> struct is_array<T[]> : public true_type {};
+
+template <class T> struct is_non_const_reference : false_type {};
+template <class T> struct is_non_const_reference<T&> : true_type {};
+template <class T> struct is_non_const_reference<const T&> : false_type {};
+
+template <class T> struct is_void : false_type {};
+template <> struct is_void<void> : true_type {};
+
+namespace internal {
+
+// Types YesType and NoType are guaranteed such that sizeof(YesType) <
+// sizeof(NoType).
+typedef char YesType;
+
+struct NoType {
+ YesType dummy[2];
+};
+
+// This class is an implementation detail for is_convertible, and you
+// don't need to know how it works to use is_convertible. For those
+// who care: we declare two different functions, one whose argument is
+// of type To and one with a variadic argument list. We give them
+// return types of different size, so we can use sizeof to trick the
+// compiler into telling us which function it would have chosen if we
+// had called it with an argument of type From. See Alexandrescu's
+// _Modern C++ Design_ for more details on this sort of trick.
+
+struct ConvertHelper {
+ template <typename To>
+ static YesType Test(To);
+
+ template <typename To>
+ static NoType Test(...);
+
+ template <typename From>
+ static From& Create();
+};
+
+// Used to determine if a type is a struct/union/class. Inspired by Boost's
+// is_class type_trait implementation.
+struct IsClassHelper {
+ template <typename C>
+ static YesType Test(void(C::*)(void));
+
+ template <typename C>
+ static NoType Test(...);
+};
+
+} // namespace internal
+
+// Inherits from true_type if From is convertible to To, false_type otherwise.
+//
+// Note that if the type is convertible, this will be a true_type REGARDLESS
+// of whether or not the conversion would emit a warning.
+template <typename From, typename To>
+struct is_convertible
+ : integral_constant<bool,
+ sizeof(internal::ConvertHelper::Test<To>(
+ internal::ConvertHelper::Create<From>())) ==
+ sizeof(internal::YesType)> {
+};
+
+template <typename T>
+struct is_class
+ : integral_constant<bool,
+ sizeof(internal::IsClassHelper::Test<T>(0)) ==
+ sizeof(internal::YesType)> {
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_TEMPLATE_UTIL_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/res/messages.grd b/chromium/third_party/libaddressinput/src/cpp/res/messages.grd
new file mode 100644
index 00000000000..dd3aa64e8f1
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/res/messages.grd
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<grit base_dir="." latest_public_release="0" current_release="1"
+ source_lang_id="en" enc_check="möl">
+ <outputs>
+ <output filename="messages.h" type="rc_header" lang="en">
+ <emit>
+ <!-- If the emit element is not specified, then the generated
+ messages.h includes an atlres.h file from Windows Template
+ Library (WTL). -->
+ </emit>
+ </output>
+ <output filename="en_messages.cc" lang="en" type="c_format" />
+ </outputs>
+ <release seq="1" allow_pseudo="false">
+ <messages fallback_to_english="true">
+ <part file="messages.grdp" />
+ </messages>
+ </release>
+</grit>
diff --git a/chromium/third_party/libaddressinput/src/cpp/res/messages.grdp b/chromium/third_party/libaddressinput/src/cpp/res/messages.grdp
new file mode 100644
index 00000000000..ca893542bc6
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/res/messages.grdp
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<grit-part>
+ <message
+ name="IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL"
+ desc="A country or a political region (Countries like the United States or
+ regions like Hong Kong or Macao, or places like Taiwan, where
+ whether it is a country or not is a politically sensitive
+ question).">
+ Country / Region
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_LOCALITY_LABEL"
+ desc="E.g., New York City.">
+ City
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_POST_TOWN"
+ desc="The name of a town through
+ which postal deliveries are routed, present in UK addresses.
+ See: http://en.wikipedia.org/wiki/Post_town">
+ Post Town
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_SUBURB"
+ desc="Smaller part of a city used in some addresses in countries like New
+ Zealand to give a more specific location in a postal address.">
+ Suburb
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_VILLAGE_TOWNSHIP"
+ desc="A unit used in postal addresses in Malaysia, which is smaller than the
+ city/town, and represents a village, township, or precinct.">
+ Village / Township
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_ADDRESS_LINE_1_LABEL"
+ desc="E.g., 18th Street, Unit 3.">
+ Street address
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_PIN_CODE_LABEL"
+ desc="PIN (Postal Index Number) Code. Values are numeric. Used in India.">
+ PIN code
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_POSTAL_CODE_LABEL"
+ desc="Postal Code. Values are frequently alphanumeric. Used in countries
+ such as Switzerland.">
+ Postal code
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_ZIP_CODE_LABEL"
+ desc="ZIP code. Values are frequently alphanumeric. Used in countries such
+ as the US.">
+ ZIP code
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_AREA"
+ desc="Administrative Area for Hong Kong (e.g., Kowloon).">
+ Area
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_COUNTY"
+ desc="Administrative Area for United Kingdoms (e.g. York) or for the
+ United States (e.g. Orange County).">
+ County
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_DEPARTMENT"
+ desc="Administrative Area for Nicaragua (e.g., Boaco) or France.">
+ Department
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_DISTRICT"
+ desc="Administrative Area for Nauru Central Pacific (e.g., Aiwo district),
+ or area of a town (a neighbourhood/suburb) used for addresses in
+ Korea and China.">
+ District
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_DO_SI"
+ desc="Administrative Area for Korea (e.g., Gyeonggi-do or Busan-si).">
+ Do/Si
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_EMIRATE"
+ desc="Administrative Area for United Arab Emirates (e.g., Abu Dhabi).">
+ Emirate
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_ISLAND"
+ desc="Administrative Area for certain countries (e.g., Bahama's Cat
+ Island).">
+ Island
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_OBLAST"
+ desc="Administrative Area for certain countries (e.g., Russia's
+ Leningrad).">
+ Oblast
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_PARISH"
+ desc="Administrative Area for certain countries (e.g., Andorra's
+ Canillo).">
+ Parish
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_PREFECTURE"
+ desc="Administrative Area for Japan (e.g., Hokkaido).">
+ Prefecture
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_PROVINCE"
+ desc="Administrative Area for certain countries (e.g., France's
+ Champagne).">
+ Province
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_STATE"
+ desc="Administrative Area for certain countries (e.g., US' California).">
+ State
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_ORGANIZATION_LABEL"
+ desc="Label for the field of organization, firm, company, or institution
+ in an address. Examples of values in this field: Google,
+ Department of Transportation, University of Cambridge.">
+ Organization
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_RECIPIENT_LABEL"
+ desc="Label for the field for a person's name in an address.">
+ Name
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_NEIGHBORHOOD"
+ desc="Label for a neighborhood, shown as part of an address input form.">
+ Neighborhood
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISSING_REQUIRED_FIELD"
+ desc="Error message shown with a UI field when it is a required field and
+ the user has not filled it out.">
+ You can't leave this empty.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISSING_REQUIRED_POSTAL_CODE_EXAMPLE_AND_URL"
+ desc="Error message shown with the postal code field when it is a required
+ field and the user has not filled it out, providing an example
+ postal code and a link to this country's postal service that a user
+ can use to look up their postal code.">
+ You must provide a postal code, for example <ph name="EXAMPLE">$1<ex>90291</ex></ph>. Don't know your postal code? Find it out <ph name="BEGIN_LINK">$2</ph>here<ph name="END_LINK">$3</ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISSING_REQUIRED_POSTAL_CODE_EXAMPLE"
+ desc="Error message shown with the postal code field when it is a required
+ field and the user has not filled it out, providing an example
+ postal code.">
+ You must provide a postal code, for example <ph name="EXAMPLE">$1<ex>90291</ex></ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISSING_REQUIRED_ZIP_CODE_EXAMPLE_AND_URL"
+ desc="Error message shown with the ZIP code field when it is a required
+ field and the user has not filled it out, providing an example ZIP
+ code and a link to this country's postal service that a user can use
+ to look up their ZIP code. This is specifically for countries using
+ ZIP codes instead of Postal codes, such as America.">
+ You must provide a ZIP code, for example <ph name="EXAMPLE">$1<ex>90291</ex></ph>. Don't know your ZIP code? Find it out <ph name="BEGIN_LINK">$2</ph>here<ph name="END_LINK">$3</ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISSING_REQUIRED_ZIP_CODE_EXAMPLE"
+ desc="Error message shown with the ZIP code field when it is a required
+ field and the user has not filled it out, providing an example ZIP
+ code.">
+ You must provide a ZIP code, for example <ph name="EXAMPLE">$1<ex>90291</ex></ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_UNKNOWN_VALUE"
+ desc="Occurs when the user fills out the wrong value for an address field.
+ For example, this would be shown when putting 'Cupertino' in United
+ States' State field.">
+ <ph name="FIELD_VALUE">$1<ex>Cupertino</ex></ph> is not recognized as a known value for this field.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE_EXAMPLE_AND_URL"
+ desc="Occurs when the user fills out a postal code that does not conform
+ to the country's postal code format. For example, this would be
+ shown when using '80' as a Swiss postal code, which is normally 4
+ digits long. Provides an example postal code and a link to this
+ country's postal service that a user can use to look up their postal
+ code.">
+ This postal code format is not recognized. Example of a valid postal code: <ph name="EXAMPLE">$1<ex>90291</ex></ph>. Don't know your postal code? Find it out <ph name="BEGIN_LINK">$2</ph>here<ph name="END_LINK">$3</ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE_EXAMPLE"
+ desc="Occurs when the user fills out a postal code that does not conform
+ to the country's postal code format. For example, this would be
+ shown when using '80' as a Swiss postal code, which is normally 4
+ digits long. Provides an example postal code.">
+ This postal code format is not recognized. Example of a valid postal code: <ph name="EXAMPLE">$1<ex>90291</ex></ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE"
+ desc="Occurs when the user fills out a postal code that does not conform
+ to the country's postal code format. For example, this would be
+ shown when using '80' as a Swiss postal code, which is normally 4
+ digits long.">
+ This postal code format is not recognized.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP_CODE_EXAMPLE_AND_URL"
+ desc="Occurs when the user fills out a ZIP code that does not conform to
+ the country's ZIP code format. For example, this would be shown when
+ using '901' as a ZIP code for the United States. Provides an example
+ ZIP code and a link to this country's postal service that a user can
+ use to look up their ZIP code.">
+ This ZIP code format is not recognized. Example of a valid ZIP code: <ph name="EXAMPLE">$1<ex>90291</ex></ph>. Don't know your ZIP code? Find it out <ph name="BEGIN_LINK">$2</ph>here<ph name="END_LINK">$3</ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP_CODE_EXAMPLE"
+ desc="Occurs when the user fills out a ZIP code that does not conform to
+ the country's ZIP code format. For example, this would be shown when
+ using '901' as a ZIP code for the United States. Provides an example
+ ZIP code.">
+ This ZIP code format is not recognized. Example of a valid ZIP code: <ph name="EXAMPLE">$1<ex>90291</ex></ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP"
+ desc="Occurs when the user fills out a ZIP code that does not conform to
+ the country's ZIP code format. For example, this would be shown when
+ using '901' as a ZIP code for the United States.">
+ This ZIP code format is not recognized.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_POSTAL_CODE_URL"
+ desc="Occurs when the user fills out the wrong postal code for a certain
+ location. For example, this would be shown when using Z3Z 2Y7 for
+ Alberta, Canada. Provides a link to this country's postal service
+ that a user can use to look up their postal code.">
+ This postal code does not appear to match the rest of this address. Don't know your postal code? Find it out <ph name="BEGIN_LINK">$1</ph>here<ph name="END_LINK">$2</ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_POSTAL_CODE"
+ desc="Occurs when the user fills out the wrong postal code for a certain
+ location. For example, this would be shown when using Z3Z 2Y7 for
+ Alberta, Canada.">
+ This postal code does not appear to match the rest of this address.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_ZIP_URL"
+ desc="Occurs when the user fills out the wrong ZIP code for a certain
+ location. For example, this would be shown when using 10001 for
+ Arizona state. Provides a link to this country's postal service that
+ a user can use to look up their ZIP code.">
+ This ZIP code does not appear to match the rest of this address. Don't know your ZIP code? Find it out <ph name="BEGIN_LINK">$1</ph>here<ph name="END_LINK">$2</ph>.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_ZIP"
+ desc="Occurs when the user fills out the wrong ZIP code for a certain
+ location. For example, this would be shown when using 10001 for
+ Arizona state.">
+ This ZIP code does not appear to match the rest of this address.
+ </message>
+ <message
+ name="IDS_LIBADDRESSINPUT_PO_BOX_FORBIDDEN_VALUE"
+ desc="Occurs when the user fills out a P.O. box as part of a physical
+ address.">
+ This address line appears to contain a post office box. Please use a street or building address.
+ </message>
+</grit-part>
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_data.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_data.cc
new file mode 100644
index 00000000000..40d3ee76535
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_data.cc
@@ -0,0 +1,153 @@
+// Copyright (C) 2014 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 <libaddressinput/util/basictypes.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include <re2/re2.h>
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+// Mapping from AddressField value to pointer to AddressData member.
+std::string AddressData::*kStringField[] = {
+ &AddressData::region_code,
+ &AddressData::administrative_area,
+ &AddressData::locality,
+ &AddressData::dependent_locality,
+ &AddressData::sorting_code,
+ &AddressData::postal_code,
+ NULL,
+ &AddressData::organization,
+ &AddressData::recipient
+};
+
+// Mapping from AddressField value to pointer to AddressData member.
+const std::vector<std::string> AddressData::*kVectorStringField[] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &AddressData::address_line,
+ NULL,
+ NULL
+};
+
+COMPILE_ASSERT(arraysize(kStringField) == arraysize(kVectorStringField),
+ field_mapping_array_size_mismatch);
+
+// A string is considered to be "empty" not only if it actually is empty, but
+// also if it contains nothing but whitespace.
+bool IsStringEmpty(const std::string& str) {
+ static const RE2 kMatcher("\\S");
+ return str.empty() || !RE2::PartialMatch(str, kMatcher);
+}
+
+} // namespace
+
+bool AddressData::IsFieldEmpty(AddressField field) const {
+ assert(field >= 0);
+ assert(static_cast<size_t>(field) < arraysize(kStringField));
+ if (kStringField[field] != NULL) {
+ const std::string& value = GetFieldValue(field);
+ return IsStringEmpty(value);
+ } else {
+ const std::vector<std::string>& value = GetRepeatedFieldValue(field);
+ return std::find_if(value.begin(),
+ value.end(),
+ std::not1(std::ptr_fun(&IsStringEmpty))) == value.end();
+ }
+}
+
+const std::string& AddressData::GetFieldValue(
+ AddressField field) const {
+ assert(field >= 0);
+ assert(static_cast<size_t>(field) < arraysize(kStringField));
+ assert(kStringField[field] != NULL);
+ return this->*kStringField[field];
+}
+
+void AddressData::SetFieldValue(AddressField field, const std::string& value) {
+ assert(field >= 0);
+ assert(static_cast<size_t>(field) < arraysize(kStringField));
+ assert(kStringField[field] != NULL);
+ (this->*kStringField[field]).assign(value);
+}
+
+const std::vector<std::string>& AddressData::GetRepeatedFieldValue(
+ AddressField field) const {
+ assert(IsRepeatedFieldValue(field));
+ return this->*kVectorStringField[field];
+}
+
+bool AddressData::operator==(const AddressData& other) const {
+ return region_code == other.region_code &&
+ address_line == other.address_line &&
+ administrative_area == other.administrative_area &&
+ locality == other.locality &&
+ dependent_locality == other.dependent_locality &&
+ postal_code == other.postal_code &&
+ sorting_code == other.sorting_code &&
+ language_code == other.language_code &&
+ organization == other.organization &&
+ recipient == other.recipient;
+}
+
+// static
+bool AddressData::IsRepeatedFieldValue(AddressField field) {
+ assert(field >= 0);
+ assert(static_cast<size_t>(field) < arraysize(kVectorStringField));
+ return kVectorStringField[field] != NULL;
+}
+
+} // namespace addressinput
+} // namespace i18n
+
+std::ostream& operator<<(std::ostream& o,
+ const i18n::addressinput::AddressData& address) {
+ o << "region_code: \"" << address.region_code << "\"\n"
+ "administrative_area: \"" << address.administrative_area << "\"\n"
+ "locality: \"" << address.locality << "\"\n"
+ "dependent_locality: \"" << address.dependent_locality << "\"\n"
+ "postal_code: \"" << address.postal_code << "\"\n"
+ "sorting_code: \"" << address.sorting_code << "\"\n";
+
+ // TODO: Update the field order in the .h file to match the order they are
+ // printed out here, for consistency.
+ for (std::vector<std::string>::const_iterator it =
+ address.address_line.begin();
+ it != address.address_line.end(); ++it) {
+ o << "address_line: \"" << *it << "\"\n";
+ }
+
+ o << "language_code: \"" << address.language_code << "\"\n"
+ "organization: \"" << address.organization << "\"\n"
+ "recipient: \"" << address.recipient << "\"\n";
+
+ return o;
+}
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_field.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_field.cc
new file mode 100644
index 00000000000..c5c96d86896
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_field.cc
@@ -0,0 +1,47 @@
+// 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_field.h>
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <cstddef>
+#include <ostream>
+
+using i18n::addressinput::AddressField;
+using i18n::addressinput::COUNTRY;
+using i18n::addressinput::RECIPIENT;
+
+std::ostream& operator<<(std::ostream& o, AddressField field) {
+ static const char* const kFieldNames[] = {
+ "COUNTRY",
+ "ADMIN_AREA",
+ "LOCALITY",
+ "DEPENDENT_LOCALITY",
+ "SORTING_CODE",
+ "POSTAL_CODE",
+ "STREET_ADDRESS",
+ "ORGANIZATION",
+ "RECIPIENT"
+ };
+ COMPILE_ASSERT(COUNTRY == 0, bad_base);
+ COMPILE_ASSERT(RECIPIENT == arraysize(kFieldNames) - 1, bad_length);
+
+ if (field < 0 || static_cast<size_t>(field) >= arraysize(kFieldNames)) {
+ o << "[INVALID ENUM VALUE " << static_cast<int>(field) << "]";
+ } else {
+ o << kFieldNames[field];
+ }
+ return o;
+}
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_field_util.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_field_util.cc
new file mode 100644
index 00000000000..26de3c04859
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_field_util.cc
@@ -0,0 +1,113 @@
+// 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 "address_field_util.h"
+
+#include <libaddressinput/address_field.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "format_element.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+std::map<char, AddressField> InitFields() {
+ std::map<char, AddressField> fields;
+ fields.insert(std::make_pair('R', COUNTRY));
+ fields.insert(std::make_pair('S', ADMIN_AREA));
+ fields.insert(std::make_pair('C', LOCALITY));
+ fields.insert(std::make_pair('D', DEPENDENT_LOCALITY));
+ fields.insert(std::make_pair('X', SORTING_CODE));
+ fields.insert(std::make_pair('Z', POSTAL_CODE));
+ fields.insert(std::make_pair('A', STREET_ADDRESS));
+ fields.insert(std::make_pair('O', ORGANIZATION));
+ fields.insert(std::make_pair('N', RECIPIENT));
+ return fields;
+}
+
+const std::map<char, AddressField>& GetFields() {
+ static const std::map<char, AddressField> kFields(InitFields());
+ return kFields;
+}
+
+bool IsFieldToken(char c) {
+ return GetFields().find(c) != GetFields().end();
+}
+
+AddressField ParseFieldToken(char c) {
+ std::map<char, AddressField>::const_iterator it = GetFields().find(c);
+ assert(it != GetFields().end());
+ return it->second;
+}
+
+} // namespace
+
+void ParseFormatRule(const std::string& format,
+ std::vector<FormatElement>* elements) {
+ assert(elements != NULL);
+ elements->clear();
+
+ std::string::const_iterator prev = format.begin();
+ for (std::string::const_iterator next = format.begin();
+ next != format.end(); prev = ++next) {
+ // Find the next field element or newline (indicated by %<TOKEN>).
+ if ((next = std::find(next, format.end(), '%')) == format.end()) {
+ // No more tokens in the format string.
+ break;
+ }
+ if (prev < next) {
+ // Push back preceding literal.
+ elements->push_back(FormatElement(std::string(prev, next)));
+ }
+ if ((prev = ++next) == format.end()) {
+ // Move forward and check we haven't reached the end of the string
+ // (unlikely, it shouldn't end with %).
+ break;
+ }
+ // Process the token after the %.
+ if (*next == 'n') {
+ elements->push_back(FormatElement());
+ } else if (IsFieldToken(*next)) {
+ elements->push_back(FormatElement(ParseFieldToken(*next)));
+ } // Else it's an unknown token, we ignore it.
+ }
+ // Push back any trailing literal.
+ if (prev != format.end()) {
+ elements->push_back(FormatElement(std::string(prev, format.end())));
+ }
+}
+
+void ParseAddressFieldsRequired(const std::string& required,
+ std::vector<AddressField>* fields) {
+ assert(fields != NULL);
+ fields->clear();
+ for (std::string::const_iterator it = required.begin();
+ it != required.end(); ++it) {
+ if (IsFieldToken(*it)) {
+ fields->push_back(ParseFieldToken(*it));
+ }
+ }
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_field_util.h b/chromium/third_party/libaddressinput/src/cpp/src/address_field_util.h
new file mode 100644
index 00000000000..123672b0ac5
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_field_util.h
@@ -0,0 +1,44 @@
+// 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.
+
+#ifndef I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_
+#define I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_
+
+#include <libaddressinput/address_field.h>
+
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+class FormatElement;
+
+// Clears |fields|, parses |format|, and adds the format address fields to
+// |fields|. The |fields| may also contain NEWLINE elements. For example, parses
+// "%S%C%n%D%X" into {ADMIN_AREA, LOCALITY, NEWLINE, DEPENDENT_LOCALITY,
+// SORTING_CODE}.
+void ParseFormatRule(const std::string& format,
+ std::vector<FormatElement>* fields);
+
+// Clears |fields|, parses |required|, and adds the required fields to |fields|.
+// For example, parses "SCDX" into {ADMIN_AREA, LOCALITY, DEPENDENT_LOCALITY,
+// SORTING_CODE}.
+void ParseAddressFieldsRequired(const std::string& required,
+ std::vector<AddressField>* fields);
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_formatter.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_formatter.cc
new file mode 100644
index 00000000000..b54cbac122c
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_formatter.cc
@@ -0,0 +1,230 @@
+// Copyright (C) 2014 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_formatter.h>
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <string>
+#include <vector>
+
+#include "format_element.h"
+#include "language.h"
+#include "region_data_constants.h"
+#include "rule.h"
+#include "util/cctype_tolower_equal.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+const char kCommaSeparator[] = ", ";
+const char kSpaceSeparator[] = " ";
+const char kArabicCommaSeparator[] = "\xD8\x8C" " "; /* "، " */
+
+const char* kLanguagesThatUseSpace[] = {
+ "th",
+ "ko"
+};
+
+const char* kLanguagesThatHaveNoSeparator[] = {
+ "ja",
+ "zh" // All Chinese variants.
+};
+
+// This data is based on CLDR, for languages that are in official use in some
+// country, where Arabic is the most likely script tag.
+// TODO: Consider supporting variants such as tr-Arab by detecting the script
+// code.
+const char* kLanguagesThatUseAnArabicComma[] = {
+ "ar",
+ "az",
+ "fa",
+ "kk",
+ "ku",
+ "ky",
+ "ps",
+ "tg",
+ "tk",
+ "ur",
+ "uz"
+};
+
+std::string GetLineSeparatorForLanguage(const std::string& language_tag) {
+ Language address_language(language_tag);
+
+ // First deal with explicit script tags.
+ if (address_language.has_latin_script) {
+ return kCommaSeparator;
+ }
+
+ // Now guess something appropriate based on the base language.
+ const std::string& base_language = address_language.base;
+ if (std::find_if(kLanguagesThatUseSpace,
+ kLanguagesThatUseSpace + arraysize(kLanguagesThatUseSpace),
+ std::bind2nd(EqualToTolowerString(), base_language)) !=
+ kLanguagesThatUseSpace + arraysize(kLanguagesThatUseSpace)) {
+ return kSpaceSeparator;
+ } else if (std::find_if(
+ kLanguagesThatHaveNoSeparator,
+ kLanguagesThatHaveNoSeparator +
+ arraysize(kLanguagesThatHaveNoSeparator),
+ std::bind2nd(EqualToTolowerString(), base_language)) !=
+ kLanguagesThatHaveNoSeparator +
+ arraysize(kLanguagesThatHaveNoSeparator)) {
+ return "";
+ } else if (std::find_if(
+ kLanguagesThatUseAnArabicComma,
+ kLanguagesThatUseAnArabicComma +
+ arraysize(kLanguagesThatUseAnArabicComma),
+ std::bind2nd(EqualToTolowerString(), base_language)) !=
+ kLanguagesThatUseAnArabicComma +
+ arraysize(kLanguagesThatUseAnArabicComma)) {
+ return kArabicCommaSeparator;
+ }
+ // Either the language is a Latin-script language, or no language was
+ // specified. In the latter case we still return ", " as the most common
+ // separator in use. In countries that don't use this, e.g. Thailand,
+ // addresses are often written in Latin script where this would still be
+ // appropriate, so this is a reasonable default in the absence of information.
+ return kCommaSeparator;
+}
+
+void CombineLinesForLanguage(const std::vector<std::string>& lines,
+ const std::string& language_tag,
+ std::string* line) {
+ line->clear();
+ std::string separator = GetLineSeparatorForLanguage(language_tag);
+ for (std::vector<std::string>::const_iterator it = lines.begin();
+ it != lines.end();
+ ++it) {
+ if (it != lines.begin()) {
+ line->append(separator);
+ }
+ line->append(*it);
+ }
+}
+
+} // namespace
+
+void GetFormattedNationalAddress(
+ const AddressData& address_data, std::vector<std::string>* lines) {
+ assert(lines != NULL);
+ lines->clear();
+
+ Rule rule;
+ rule.CopyFrom(Rule::GetDefault());
+ // TODO: Eventually, we should get the best rule for this country and
+ // language, rather than just for the country.
+ rule.ParseSerializedRule(RegionDataConstants::GetRegionData(
+ address_data.region_code));
+
+ Language language(address_data.language_code);
+
+ // If Latin-script rules are available and the |language_code| of this address
+ // is explicitly tagged as being Latin, then use the Latin-script formatting
+ // rules.
+ const std::vector<FormatElement>& format =
+ language.has_latin_script && !rule.GetLatinFormat().empty()
+ ? rule.GetLatinFormat()
+ : rule.GetFormat();
+
+ // Address format without the unnecessary elements (based on which address
+ // fields are empty). We assume all literal strings that are not at the start
+ // or end of a line are separators, and therefore only relevant if the
+ // surrounding fields are filled in. This works with the data we have
+ // currently.
+ std::vector<FormatElement> pruned_format;
+ for (std::vector<FormatElement>::const_iterator
+ element_it = format.begin();
+ element_it != format.end();
+ ++element_it) {
+ // Always keep the newlines.
+ if (element_it->IsNewline() ||
+ // Always keep the non-empty address fields.
+ (element_it->IsField() &&
+ !address_data.IsFieldEmpty(element_it->GetField())) ||
+ // Only keep literals that satisfy these 2 conditions:
+ (!element_it->IsField() &&
+ // (1) Not preceding an empty field.
+ (element_it + 1 == format.end() ||
+ !(element_it + 1)->IsField() ||
+ !address_data.IsFieldEmpty((element_it + 1)->GetField())) &&
+ // (2) Not following a removed field.
+ (element_it == format.begin() ||
+ !(element_it - 1)->IsField() ||
+ (!pruned_format.empty() && pruned_format.back().IsField())))) {
+ pruned_format.push_back(*element_it);
+ }
+ }
+
+ std::string line;
+ for (std::vector<FormatElement>::const_iterator
+ element_it = pruned_format.begin();
+ element_it != pruned_format.end();
+ ++element_it) {
+ if (element_it->IsNewline()) {
+ if (!line.empty()) {
+ lines->push_back(line);
+ line.clear();
+ }
+ } else if (element_it->IsField()) {
+ AddressField field = element_it->GetField();
+ if (field == STREET_ADDRESS) {
+ // The field "street address" represents the street address lines of an
+ // address, so there can be multiple values.
+ if (!address_data.IsFieldEmpty(field)) {
+ line.append(address_data.address_line.front());
+ if (address_data.address_line.size() > 1U) {
+ lines->push_back(line);
+ line.clear();
+ lines->insert(lines->end(),
+ address_data.address_line.begin() + 1,
+ address_data.address_line.end());
+ }
+ }
+ } else {
+ line.append(address_data.GetFieldValue(field));
+ }
+ } else {
+ line.append(element_it->GetLiteral());
+ }
+ }
+ if (!line.empty()) {
+ lines->push_back(line);
+ }
+}
+
+void GetFormattedNationalAddressLine(
+ const AddressData& address_data, std::string* line) {
+ std::vector<std::string> address_lines;
+ GetFormattedNationalAddress(address_data, &address_lines);
+ CombineLinesForLanguage(address_lines, address_data.language_code, line);
+}
+
+void GetStreetAddressLinesAsSingleLine(
+ const AddressData& address_data, std::string* line) {
+ CombineLinesForLanguage(
+ address_data.address_line, address_data.language_code, line);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_input_helper.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_input_helper.cc
new file mode 100644
index 00000000000..82ea6fc2bbd
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_input_helper.cc
@@ -0,0 +1,186 @@
+// Copyright (C) 2014 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_input_helper.h>
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/address_metadata.h>
+#include <libaddressinput/preload_supplier.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include <re2/re2.h>
+
+#include "language.h"
+#include "lookup_key.h"
+#include "region_data_constants.h"
+#include "rule.h"
+#include "util/re2ptr.h"
+
+namespace i18n {
+namespace addressinput {
+
+// Used for building a hierarchy of rules, each one connected to its parent.
+struct Node {
+ const Node* parent;
+ const Rule* rule;
+};
+
+namespace {
+
+const char kLookupKeySeparator = '/';
+
+const size_t kHierarchyDepth = arraysize(LookupKey::kHierarchy);
+
+// Gets the best name for the entity represented by the current rule, using the
+// language provided. The language is currently used to distinguish whether a
+// Latin-script name should be fetched; if it is not explicitly Latin-script, we
+// prefer IDs over names (so return CA instead of California for an English
+// user.) If there is no Latin-script name, we fall back to the ID.
+std::string GetBestName(const Language& language, const Rule& rule) {
+ if (language.has_latin_script) {
+ const std::string& name = rule.GetLatinName();
+ if (!name.empty()) {
+ return name;
+ }
+ }
+ // The ID is stored as data/US/CA for "CA", for example, and we only want the
+ // last part.
+ const std::string& id = rule.GetId();
+ std::string::size_type pos = id.rfind(kLookupKeySeparator);
+ assert(pos != std::string::npos);
+ return id.substr(pos + 1);
+}
+
+void FillAddressFromMatchedRules(
+ const std::vector<Node>* hierarchy,
+ AddressData* address) {
+ assert(hierarchy != NULL);
+ assert(address != NULL);
+ // We skip region code, because we never try and fill that in if it isn't
+ // already set.
+ Language language(address->language_code);
+ for (size_t depth = kHierarchyDepth - 1; depth > 0; --depth) {
+ // If there is only one match at this depth, then we should populate the
+ // address, using this rule and its parents.
+ if (hierarchy[depth].size() == 1) {
+ for (const Node* node = &hierarchy[depth].front();
+ node != NULL; node = node->parent, --depth) {
+ const Rule* rule = node->rule;
+ assert(rule != NULL);
+
+ AddressField field = LookupKey::kHierarchy[depth];
+ // Note only empty fields are permitted to be overwritten.
+ if (address->IsFieldEmpty(field)) {
+ address->SetFieldValue(field, GetBestName(language, *rule));
+ }
+ }
+ break;
+ }
+ }
+}
+
+} // namespace;
+
+AddressInputHelper::AddressInputHelper(PreloadSupplier* supplier)
+ : supplier_(supplier) {
+ assert(supplier_ != NULL);
+}
+
+AddressInputHelper::~AddressInputHelper() {
+}
+
+void AddressInputHelper::FillAddress(AddressData* address) const {
+ assert(address != NULL);
+ const std::string& region_code = address->region_code;
+ if (!RegionDataConstants::IsSupported(region_code)) {
+ // If we don't have a region code, we can't do anything reliably to fill
+ // this address.
+ return;
+ }
+
+ AddressData lookup_key_address;
+ lookup_key_address.region_code = region_code;
+ // First try and fill in the postal code if it is missing.
+ LookupKey lookup_key;
+ lookup_key.FromAddress(lookup_key_address);
+ const Rule* region_rule = supplier_->GetRule(lookup_key);
+ // We have already checked that the region is supported; and users of this
+ // method must have called LoadRules() first, so we check this here.
+ assert(region_rule != NULL);
+
+ const RE2ptr* postal_code_reg_exp = region_rule->GetPostalCodeMatcher();
+ if (postal_code_reg_exp != NULL) {
+ if (address->postal_code.empty()) {
+ address->postal_code = region_rule->GetSolePostalCode();
+ }
+
+ // If we have a valid postal code, try and work out the most specific
+ // hierarchy that matches the postal code. Note that the postal code might
+ // have been added in the previous check.
+ if (!address->postal_code.empty() &&
+ RE2::FullMatch(address->postal_code, *postal_code_reg_exp->ptr)) {
+
+ // This hierarchy is used to store rules that represent possible matches
+ // at each level of the hierarchy.
+ std::vector<Node> hierarchy[kHierarchyDepth];
+ CheckChildrenForPostCodeMatches(*address, lookup_key, NULL, hierarchy);
+
+ FillAddressFromMatchedRules(hierarchy, address);
+ }
+ }
+
+ // TODO: When we have the data, we should fill in the state for countries with
+ // state required and only one possible value, e.g. American Samoa.
+}
+
+void AddressInputHelper::CheckChildrenForPostCodeMatches(
+ const AddressData& address,
+ const LookupKey& lookup_key,
+ const Node* parent,
+ // An array of vectors.
+ std::vector<Node>* hierarchy) const {
+ const Rule* rule = supplier_->GetRule(lookup_key);
+ assert(rule != NULL);
+
+ const RE2ptr* postal_code_prefix = rule->GetPostalCodeMatcher();
+ if (postal_code_prefix == NULL ||
+ RE2::PartialMatch(address.postal_code, *postal_code_prefix->ptr)) {
+ // This was a match, so store it and its parent in the hierarchy.
+ hierarchy[lookup_key.GetDepth()].push_back(Node());
+ Node* node = &hierarchy[lookup_key.GetDepth()].back();
+ node->parent = parent;
+ node->rule = rule;
+
+ if (IsFieldUsed(LookupKey::kHierarchy[lookup_key.GetDepth() + 1],
+ address.region_code)) {
+ // If children are used and present, check them too.
+ for (std::vector<std::string>::const_iterator child_it =
+ rule->GetSubKeys().begin();
+ child_it != rule->GetSubKeys().end(); ++child_it) {
+ LookupKey child_key;
+ child_key.FromLookupKey(lookup_key, *child_it);
+ CheckChildrenForPostCodeMatches(address, child_key, node, hierarchy);
+ }
+ }
+ }
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_metadata.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_metadata.cc
new file mode 100644
index 00000000000..c088e0d600d
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_metadata.cc
@@ -0,0 +1,64 @@
+// Copyright (C) 2014 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_metadata.h>
+
+#include <libaddressinput/address_field.h>
+
+#include <algorithm>
+#include <string>
+
+#include "format_element.h"
+#include "region_data_constants.h"
+#include "rule.h"
+
+namespace i18n {
+namespace addressinput {
+
+bool IsFieldRequired(AddressField field, const std::string& region_code) {
+ if (field == COUNTRY) {
+ return true;
+ }
+
+ Rule rule;
+ rule.CopyFrom(Rule::GetDefault());
+ if (!rule.ParseSerializedRule(
+ RegionDataConstants::GetRegionData(region_code))) {
+ return false;
+ }
+
+ return std::find(rule.GetRequired().begin(),
+ rule.GetRequired().end(),
+ field) != rule.GetRequired().end();
+}
+
+bool IsFieldUsed(AddressField field, const std::string& region_code) {
+ if (field == COUNTRY) {
+ return true;
+ }
+
+ Rule rule;
+ rule.CopyFrom(Rule::GetDefault());
+ if (!rule.ParseSerializedRule(
+ RegionDataConstants::GetRegionData(region_code))) {
+ return false;
+ }
+
+ return std::find(rule.GetFormat().begin(),
+ rule.GetFormat().end(),
+ FormatElement(field)) != rule.GetFormat().end();
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_normalizer.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_normalizer.cc
new file mode 100644
index 00000000000..562203e2ae5
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_normalizer.cc
@@ -0,0 +1,89 @@
+// Copyright (C) 2014 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_normalizer.h>
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/preload_supplier.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "lookup_key.h"
+#include "rule.h"
+#include "util/string_compare.h"
+
+namespace i18n {
+namespace addressinput {
+
+AddressNormalizer::AddressNormalizer(const PreloadSupplier* supplier)
+ : supplier_(supplier),
+ compare_(new StringCompare) {
+ assert(supplier_ != NULL);
+}
+
+AddressNormalizer::~AddressNormalizer() {}
+
+void AddressNormalizer::Normalize(AddressData* address) const {
+ assert(address != NULL);
+ assert(supplier_->IsLoaded(address->region_code));
+
+ AddressData region_address;
+ region_address.region_code = address->region_code;
+ LookupKey parent_key;
+ parent_key.FromAddress(region_address);
+ const Rule* parent_rule = supplier_->GetRule(parent_key);
+ assert(parent_rule != NULL);
+
+ LookupKey lookup_key;
+ for (size_t depth = 1; depth < arraysize(LookupKey::kHierarchy); ++depth) {
+ AddressField field = LookupKey::kHierarchy[depth];
+ if (address->IsFieldEmpty(field)) {
+ return;
+ }
+ const std::string& field_value = address->GetFieldValue(field);
+ bool no_match_found_yet = true;
+ for (std::vector<std::string>::const_iterator
+ key_it = parent_rule->GetSubKeys().begin();
+ key_it != parent_rule->GetSubKeys().end(); ++key_it) {
+ lookup_key.FromLookupKey(parent_key, *key_it);
+ const Rule* rule = supplier_->GetRule(lookup_key);
+ assert(rule != NULL);
+
+ bool matches_latin_name =
+ compare_->NaturalEquals(field_value, rule->GetLatinName());
+ bool matches_local_name_id =
+ compare_->NaturalEquals(field_value, *key_it) ||
+ compare_->NaturalEquals(field_value, rule->GetName());
+ if (matches_latin_name || matches_local_name_id) {
+ address->SetFieldValue(
+ field, matches_latin_name ? rule->GetLatinName() : *key_it);
+ no_match_found_yet = false;
+ parent_key.FromLookupKey(parent_key, *key_it);
+ parent_rule = supplier_->GetRule(parent_key);
+ assert(parent_rule != NULL);
+ break;
+ }
+ }
+ if (no_match_found_yet) {
+ return; // Abort search.
+ }
+ }
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_problem.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_problem.cc
new file mode 100644
index 00000000000..0fade172adb
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_problem.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2014 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_problem.h>
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <cstddef>
+#include <ostream>
+
+using i18n::addressinput::AddressProblem;
+using i18n::addressinput::UNEXPECTED_FIELD;
+using i18n::addressinput::USES_P_O_BOX;
+
+std::ostream& operator<<(std::ostream& o, AddressProblem problem) {
+ static const char* const kProblemNames[] = {
+ "UNEXPECTED_FIELD",
+ "MISSING_REQUIRED_FIELD",
+ "UNKNOWN_VALUE",
+ "INVALID_FORMAT",
+ "MISMATCHING_VALUE",
+ "USES_P_O_BOX"
+ };
+ COMPILE_ASSERT(UNEXPECTED_FIELD == 0, bad_base);
+ COMPILE_ASSERT(USES_P_O_BOX == arraysize(kProblemNames) - 1, bad_length);
+
+ if (problem < 0 || static_cast<size_t>(problem) >= arraysize(kProblemNames)) {
+ o << "[INVALID ENUM VALUE " << static_cast<int>(problem) << "]";
+ } else {
+ o << kProblemNames[problem];
+ }
+ return o;
+}
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_ui.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_ui.cc
new file mode 100644
index 00000000000..5df8b3d0438
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_ui.cc
@@ -0,0 +1,147 @@
+// 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_ui.h>
+
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/address_ui_component.h>
+#include <libaddressinput/localization.h>
+
+#include <cassert>
+#include <cstddef>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "format_element.h"
+#include "grit.h"
+#include "language.h"
+#include "messages.h"
+#include "region_data_constants.h"
+#include "rule.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+std::string GetLabelForField(const Localization& localization,
+ AddressField field,
+ int admin_area_name_message_id,
+ int postal_code_name_message_id,
+ int locality_name_message_id,
+ int sublocality_name_message_id) {
+ int messageId;
+ switch (field) {
+ case SORTING_CODE:
+ // This needs no translation as it's used only in one locale.
+ return "CEDEX";
+ case COUNTRY:
+ messageId = IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL;
+ break;
+ case ADMIN_AREA:
+ messageId = admin_area_name_message_id;
+ break;
+ case LOCALITY:
+ messageId = locality_name_message_id;
+ break;
+ case DEPENDENT_LOCALITY:
+ messageId = sublocality_name_message_id;
+ break;
+ case POSTAL_CODE:
+ messageId = postal_code_name_message_id;
+ break;
+ case STREET_ADDRESS:
+ messageId = IDS_LIBADDRESSINPUT_ADDRESS_LINE_1_LABEL;
+ break;
+ case ORGANIZATION:
+ messageId = IDS_LIBADDRESSINPUT_ORGANIZATION_LABEL;
+ break;
+ case RECIPIENT:
+ messageId = IDS_LIBADDRESSINPUT_RECIPIENT_LABEL;
+ break;
+ default:
+ messageId = INVALID_MESSAGE_ID;
+ }
+ return localization.GetString(messageId);
+}
+
+} // namespace
+
+const std::vector<std::string>& GetRegionCodes() {
+ return RegionDataConstants::GetRegionCodes();
+}
+
+std::vector<AddressUiComponent> BuildComponents(
+ const std::string& region_code,
+ const Localization& localization,
+ const std::string& ui_language_tag,
+ std::string* best_address_language_tag) {
+ assert(best_address_language_tag != NULL);
+ std::vector<AddressUiComponent> result;
+
+ Rule rule;
+ rule.CopyFrom(Rule::GetDefault());
+ if (!rule.ParseSerializedRule(
+ RegionDataConstants::GetRegionData(region_code))) {
+ return result;
+ }
+
+ const Language& best_address_language =
+ ChooseBestAddressLanguage(rule, Language(ui_language_tag));
+ *best_address_language_tag = best_address_language.tag;
+
+ const std::vector<FormatElement>& format =
+ !rule.GetLatinFormat().empty() && best_address_language.has_latin_script
+ ? rule.GetLatinFormat()
+ : rule.GetFormat();
+
+ // For avoiding showing an input field twice, when the field is displayed
+ // twice on an envelope.
+ std::set<AddressField> fields;
+
+ bool preceded_by_newline = true;
+ bool followed_by_newline = true;
+ for (std::vector<FormatElement>::const_iterator format_it = format.begin();
+ format_it != format.end(); ++format_it) {
+ if (format_it->IsNewline()) {
+ preceded_by_newline = true;
+ continue;
+ } else if (!format_it->IsField() ||
+ !fields.insert(format_it->GetField()).second) {
+ continue;
+ }
+ AddressUiComponent component;
+ std::vector<FormatElement>::const_iterator next_format_it = format_it + 1;
+ followed_by_newline =
+ next_format_it == format.end() || next_format_it->IsNewline();
+ component.length_hint = preceded_by_newline && followed_by_newline
+ ? AddressUiComponent::HINT_LONG
+ : AddressUiComponent::HINT_SHORT;
+ preceded_by_newline = false;
+ component.field = format_it->GetField();
+ component.name = GetLabelForField(localization,
+ format_it->GetField(),
+ rule.GetAdminAreaNameMessageId(),
+ rule.GetPostalCodeNameMessageId(),
+ rule.GetLocalityNameMessageId(),
+ rule.GetSublocalityNameMessageId());
+ result.push_back(component);
+ }
+
+ return result;
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/address_validator.cc b/chromium/third_party/libaddressinput/src/cpp/src/address_validator.cc
new file mode 100644
index 00000000000..8f0c33cf38f
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/address_validator.cc
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 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_validator.h>
+
+#include <cassert>
+#include <cstddef>
+
+#include "validation_task.h"
+
+namespace i18n {
+namespace addressinput {
+
+AddressValidator::AddressValidator(Supplier* supplier) : supplier_(supplier) {
+ assert(supplier_ != NULL);
+}
+
+AddressValidator::~AddressValidator() {
+}
+
+void AddressValidator::Validate(const AddressData& address,
+ bool allow_postal,
+ bool require_name,
+ const FieldProblemMap* filter,
+ FieldProblemMap* problems,
+ const Callback& validated) const {
+ // The ValidationTask object will delete itself after Run() has finished.
+ (new ValidationTask(
+ address,
+ allow_postal,
+ require_name,
+ filter,
+ problems,
+ validated))->Run(supplier_);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/format_element.cc b/chromium/third_party/libaddressinput/src/cpp/src/format_element.cc
new file mode 100644
index 00000000000..8f9669c8845
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/format_element.cc
@@ -0,0 +1,52 @@
+// Copyright (C) 2014 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 "format_element.h"
+
+#include <libaddressinput/address_field.h>
+
+#include <cassert>
+#include <ostream>
+
+namespace i18n {
+namespace addressinput {
+
+FormatElement::FormatElement(AddressField field) : field_(field), literal_() {}
+
+FormatElement::FormatElement(const std::string& literal)
+ : field_(static_cast<AddressField>(-1)), literal_(literal) {
+ assert(!literal.empty());
+}
+
+FormatElement::FormatElement()
+ : field_(static_cast<AddressField>(-1)), literal_("\n") {}
+
+bool FormatElement::operator==(const FormatElement& other) const {
+ return field_ == other.field_ && literal_ == other.literal_;
+}
+
+} // namespace addressinput
+} // namespace i18n
+
+std::ostream& operator<<(std::ostream& o,
+ const i18n::addressinput::FormatElement& element) {
+ if (element.IsField()) {
+ o << "Field: " << element.GetField();
+ } else if (element.IsNewline()) {
+ o << "Newline";
+ } else {
+ o << "Literal: " << element.GetLiteral();
+ }
+ return o;
+}
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/format_element.h b/chromium/third_party/libaddressinput/src/cpp/src/format_element.h
new file mode 100644
index 00000000000..e37a1883856
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/format_element.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2014 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.
+//
+// An object representing a token in a formatting string. This may be a
+// placeholder for a field in the address data such as ADMIN_AREA, a literal
+// string such as " ", or a newline.
+
+#ifndef I18N_ADDRESSINPUT_FORMAT_ELEMENT_H_
+#define I18N_ADDRESSINPUT_FORMAT_ELEMENT_H_
+
+#include <libaddressinput/address_field.h>
+
+#include <iosfwd>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class FormatElement {
+ public:
+ // Builds a format element to represent |field|.
+ explicit FormatElement(AddressField field);
+
+ // Builds an element representing a literal string |literal|.
+ explicit FormatElement(const std::string& literal);
+
+ // Builds a newline element.
+ FormatElement();
+
+ // Returns true if this element represents a field element.
+ bool IsField() const { return literal_.empty(); }
+
+ // Returns true if this element represents a new line.
+ bool IsNewline() const { return literal_ == "\n"; }
+
+ AddressField GetField() const { return field_; }
+ const std::string& GetLiteral() const { return literal_; }
+
+ bool operator==(const FormatElement& other) const;
+
+ private:
+ // The field this element represents. Should only be used if |literal| is an
+ // empty string.
+ AddressField field_;
+
+ // The literal string for this element. This will be "\n" if this is a
+ // newline - but IsNewline() is preferred to determine this. If empty, then
+ // this FormatElement represents an address field.
+ std::string literal_;
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+// Produces human-readable output in logging, for example in unit tests.
+std::ostream& operator<<(std::ostream& o,
+ const i18n::addressinput::FormatElement& field);
+
+#endif // I18N_ADDRESSINPUT_FORMAT_ELEMENT_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/grit.h b/chromium/third_party/libaddressinput/src/cpp/src/grit.h
new file mode 100644
index 00000000000..c4c23f3116d
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/grit.h
@@ -0,0 +1,36 @@
+// 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.
+
+#ifndef I18N_ADDRESSINPUT_GRIT_H_
+#define I18N_ADDRESSINPUT_GRIT_H_
+
+namespace i18n {
+namespace addressinput {
+
+// A message identifier that is guaranteed to not clash with any
+// IDS_ADDRESSINPUT_I18N_* identifiers that are generated by GRIT. GRIT
+// generates messages in the range from decimal 101 to 0x7FFF in order to work
+// with Windows.
+// https://code.google.com/p/grit-i18n/source/browse/trunk/grit/format/rc_header.py?r=94#169
+// http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx
+//
+// The enum must be named to enable using it in gtest templates, e.g.
+// EXPECT_EQ(INVALID_MESSAGE_ID, my_id) will not compile on some platforms when
+// the enum is unnamed.
+enum MessageIdentifier { INVALID_MESSAGE_ID = 0 };
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_GRIT_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/language.cc b/chromium/third_party/libaddressinput/src/cpp/src/language.cc
new file mode 100644
index 00000000000..28817dc12d2
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/language.cc
@@ -0,0 +1,102 @@
+// Copyright (C) 2014 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 "language.h"
+
+#include <algorithm>
+#include <cctype>
+#include <string>
+#include <vector>
+
+#include "rule.h"
+#include "util/string_split.h"
+
+namespace i18n {
+namespace addressinput {
+
+Language::Language(const std::string& language_tag) : tag(language_tag),
+ base(),
+ has_latin_script(false) {
+ // Character '-' is the separator for subtags in the BCP 47. However, some
+ // legacy code generates tags with '_' instead of '-'.
+ static const char kSubtagsSeparator = '-';
+ static const char kAlternativeSubtagsSeparator = '_';
+ std::replace(
+ tag.begin(), tag.end(), kAlternativeSubtagsSeparator, kSubtagsSeparator);
+
+ // OK to use 'tolower' because BCP 47 tags are always in ASCII.
+ std::string lowercase = tag;
+ std::transform(
+ lowercase.begin(), lowercase.end(), lowercase.begin(), tolower);
+
+ base = lowercase.substr(0, lowercase.find(kSubtagsSeparator));
+
+ // The lowercase BCP 47 subtag for Latin script.
+ static const char kLowercaseLatinScript[] = "latn";
+ std::vector<std::string> subtags;
+ SplitString(lowercase, kSubtagsSeparator, &subtags);
+
+ // Support only the second and third position for the script.
+ has_latin_script =
+ (subtags.size() > 1 && subtags[1] == kLowercaseLatinScript) ||
+ (subtags.size() > 2 && subtags[2] == kLowercaseLatinScript);
+}
+
+Language::~Language() {}
+
+Language ChooseBestAddressLanguage(const Rule& address_region_rule,
+ const Language& ui_language) {
+ if (address_region_rule.GetLanguages().empty()) {
+ return ui_language;
+ }
+
+ std::vector<Language> available_languages;
+ for (std::vector<std::string>::const_iterator
+ language_tag_it = address_region_rule.GetLanguages().begin();
+ language_tag_it != address_region_rule.GetLanguages().end();
+ ++language_tag_it) {
+ available_languages.push_back(Language(*language_tag_it));
+ }
+
+ if (ui_language.tag.empty()) {
+ return available_languages.front();
+ }
+
+ bool has_latin_format = !address_region_rule.GetLatinFormat().empty();
+
+ // The conventionally formatted BCP 47 Latin script with a preceding subtag
+ // separator.
+ static const char kLatinScriptSuffix[] = "-Latn";
+ Language latin_script_language(
+ available_languages.front().base + kLatinScriptSuffix);
+ if (has_latin_format && ui_language.has_latin_script) {
+ return latin_script_language;
+ }
+
+ for (std::vector<Language>::const_iterator
+ available_lang_it = available_languages.begin();
+ available_lang_it != available_languages.end(); ++available_lang_it) {
+ // Base language comparison works because no region supports the same base
+ // language with different scripts, for now. For example, no region supports
+ // "zh-Hant" and "zh-Hans" at the same time.
+ if (ui_language.base == available_lang_it->base) {
+ return *available_lang_it;
+ }
+ }
+
+ return has_latin_format ? latin_script_language : available_languages.front();
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/language.h b/chromium/third_party/libaddressinput/src/cpp/src/language.h
new file mode 100644
index 00000000000..561c79fa690
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/language.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_LANGUAGE_H_
+#define I18N_ADDRESSINPUT_LANGUAGE_H_
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class Rule;
+
+// Helper for working with a BCP 47 language tag.
+// http://tools.ietf.org/html/bcp47
+struct Language {
+ explicit Language(const std::string& language_tag);
+ ~Language();
+
+ // The language tag (with '_' replaced with '-'), for example "zh-Latn-CN".
+ std::string tag;
+
+ // The base language, for example "zh". Always lowercase.
+ std::string base;
+
+ // True if the language tag explicitly has a Latin script. For example, this
+ // is true for "zh-Latn", but false for "zh". Only the second and third subtag
+ // positions are supported for script.
+ bool has_latin_script;
+};
+
+Language ChooseBestAddressLanguage(const Rule& address_region_rule,
+ const Language& ui_language);
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_LANGUAGE_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/localization.cc b/chromium/third_party/libaddressinput/src/cpp/src/localization.cc
new file mode 100644
index 00000000000..b544cd9f067
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/localization.cc
@@ -0,0 +1,190 @@
+// 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/localization.h>
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/address_problem.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "messages.h"
+#include "region_data_constants.h"
+#include "rule.h"
+#include "util/string_split.h"
+#include "util/string_util.h"
+
+namespace {
+
+void PushBackUrl(const std::string& url, std::vector<std::string>* parameters) {
+ assert(parameters != NULL);
+ // TODO: HTML-escape the "url".
+ parameters->push_back("<a href=\"" + url + "\">");
+ parameters->push_back("</a>");
+}
+
+} // namespace
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+#include "en_messages.cc"
+
+std::string GetEnglishString(int message_id) {
+ const char* str = GetString(message_id);
+ return str != NULL ? std::string(str) : std::string();
+}
+
+} // namespace
+
+Localization::Localization() : get_string_(&GetEnglishString) {}
+
+Localization::~Localization() {}
+
+std::string Localization::GetString(int message_id) const {
+ return get_string_(message_id);
+}
+
+std::string Localization::GetErrorMessage(const AddressData& address,
+ AddressField field,
+ AddressProblem problem,
+ bool enable_examples,
+ bool enable_links) const {
+ if (field == POSTAL_CODE) {
+ Rule rule;
+ rule.CopyFrom(Rule::GetDefault());
+ std::string postal_code_example, post_service_url;
+ if (rule.ParseSerializedRule(
+ RegionDataConstants::GetRegionData(address.region_code))) {
+ if (enable_examples) {
+ std::vector<std::string> examples_list;
+ SplitString(rule.GetPostalCodeExample(), ',', &examples_list);
+ if (!examples_list.empty()) {
+ postal_code_example = examples_list.front();
+ }
+ }
+ if (enable_links) {
+ post_service_url = rule.GetPostServiceUrl();
+ }
+ } else {
+ assert(false);
+ }
+ // If we can't parse the serialized rule |uses_postal_code_as_label| will be
+ // determined from the default rule.
+ bool uses_postal_code_as_label =
+ rule.GetPostalCodeNameMessageId() ==
+ IDS_LIBADDRESSINPUT_POSTAL_CODE_LABEL;
+ return GetErrorMessageForPostalCode(address, problem,
+ uses_postal_code_as_label,
+ postal_code_example, post_service_url);
+ } else {
+ if (problem == MISSING_REQUIRED_FIELD) {
+ return get_string_(IDS_LIBADDRESSINPUT_MISSING_REQUIRED_FIELD);
+ } else if (problem == UNKNOWN_VALUE) {
+ std::vector<std::string> parameters;
+ if (AddressData::IsRepeatedFieldValue(field)) {
+ std::vector<std::string> values = address.GetRepeatedFieldValue(field);
+ assert(!values.empty());
+ parameters.push_back(values.front());
+ } else {
+ parameters.push_back(address.GetFieldValue(field));
+ }
+ return DoReplaceStringPlaceholders(
+ get_string_(IDS_LIBADDRESSINPUT_UNKNOWN_VALUE), parameters);
+ } else if (problem == USES_P_O_BOX) {
+ return get_string_(IDS_LIBADDRESSINPUT_PO_BOX_FORBIDDEN_VALUE);
+ } else {
+ // Keep the default under "else" so the compiler helps us check that all
+ // handled cases return and don't fall through.
+ assert(false);
+ return "";
+ }
+ }
+}
+
+void Localization::SetGetter(std::string (*getter)(int)) {
+ assert(getter != NULL);
+ get_string_ = getter;
+}
+
+std::string Localization::GetErrorMessageForPostalCode(
+ const AddressData& address,
+ AddressProblem problem,
+ bool uses_postal_code_as_label,
+ std::string postal_code_example,
+ std::string post_service_url) const {
+ int message_id;
+ std::vector<std::string> parameters;
+ if (problem == MISSING_REQUIRED_FIELD) {
+ if (!postal_code_example.empty() && !post_service_url.empty()) {
+ message_id = uses_postal_code_as_label ?
+ IDS_LIBADDRESSINPUT_MISSING_REQUIRED_POSTAL_CODE_EXAMPLE_AND_URL :
+ IDS_LIBADDRESSINPUT_MISSING_REQUIRED_ZIP_CODE_EXAMPLE_AND_URL;
+ parameters.push_back(postal_code_example);
+ PushBackUrl(post_service_url, &parameters);
+ } else if (!postal_code_example.empty()) {
+ message_id = uses_postal_code_as_label ?
+ IDS_LIBADDRESSINPUT_MISSING_REQUIRED_POSTAL_CODE_EXAMPLE :
+ IDS_LIBADDRESSINPUT_MISSING_REQUIRED_ZIP_CODE_EXAMPLE ;
+ parameters.push_back(postal_code_example);
+ } else {
+ message_id = IDS_LIBADDRESSINPUT_MISSING_REQUIRED_FIELD;
+ }
+ return DoReplaceStringPlaceholders(get_string_(message_id), parameters);
+ } else if (problem == INVALID_FORMAT) {
+ if (!postal_code_example.empty() && !post_service_url.empty()) {
+ message_id = uses_postal_code_as_label ?
+ IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE_EXAMPLE_AND_URL :
+ IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP_CODE_EXAMPLE_AND_URL;
+ parameters.push_back(postal_code_example);
+ PushBackUrl(post_service_url, &parameters);
+ } else if (!postal_code_example.empty()) {
+ message_id = uses_postal_code_as_label ?
+ IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE_EXAMPLE :
+ IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP_CODE_EXAMPLE;
+ parameters.push_back(postal_code_example);
+ } else {
+ message_id = uses_postal_code_as_label ?
+ IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE :
+ IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP;
+ }
+ return DoReplaceStringPlaceholders(get_string_(message_id), parameters);
+ } else if (problem == MISMATCHING_VALUE) {
+ if (!post_service_url.empty()) {
+ message_id = uses_postal_code_as_label ?
+ IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_POSTAL_CODE_URL :
+ IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_ZIP_URL;
+ PushBackUrl(post_service_url, &parameters);
+ } else {
+ message_id = uses_postal_code_as_label ?
+ IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_POSTAL_CODE :
+ IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_ZIP;
+ }
+ return DoReplaceStringPlaceholders(get_string_(message_id), parameters);
+ } else {
+ // Keep the default under "else" so the compiler helps us check that all
+ // handled cases return and don't fall through.
+ assert(false);
+ return "";
+ }
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/lookup_key.cc b/chromium/third_party/libaddressinput/src/cpp/src/lookup_key.cc
new file mode 100644
index 00000000000..d793a2beae5
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/lookup_key.cc
@@ -0,0 +1,153 @@
+// Copyright (C) 2014 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 "lookup_key.h"
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "language.h"
+#include "region_data_constants.h"
+#include "rule.h"
+#include "util/cctype_tolower_equal.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+const char kSlashDelim[] = "/";
+const char kDashDelim[] = "--";
+const char kData[] = "data";
+const char kUnknown[] = "ZZ";
+
+// Assume the language_tag has had "Latn" script removed when this is called.
+bool ShouldSetLanguageForKey(const std::string& language_tag,
+ const std::string& region_code) {
+ // We only need a language in the key if there is subregion data at all.
+ if (RegionDataConstants::GetMaxLookupKeyDepth(region_code) == 0) {
+ return false;
+ }
+ Rule rule;
+ rule.CopyFrom(Rule::GetDefault());
+ // TODO: Pre-parse the rules and have a map from region code to rule.
+ if (!rule.ParseSerializedRule(
+ RegionDataConstants::GetRegionData(region_code))) {
+ return false;
+ }
+ const std::vector<std::string>& languages = rule.GetLanguages();
+ // Do not add the default language (we want "data/US", not "data/US--en").
+ // (empty should not happen here because we have some sub-region data).
+ if (languages.empty() || languages[0] == language_tag) {
+ return false;
+ }
+ // Finally, only return true if the language is one of the remaining ones.
+ return std::find_if(languages.begin() + 1, languages.end(),
+ std::bind2nd(EqualToTolowerString(), language_tag)) !=
+ languages.end();
+}
+
+} // namespace
+
+const AddressField LookupKey::kHierarchy[] = {
+ COUNTRY,
+ ADMIN_AREA,
+ LOCALITY,
+ DEPENDENT_LOCALITY
+};
+
+LookupKey::LookupKey() {
+}
+
+LookupKey::~LookupKey() {
+}
+
+void LookupKey::FromAddress(const AddressData& address) {
+ nodes_.clear();
+ if (address.region_code.empty()) {
+ nodes_.insert(std::make_pair(COUNTRY, kUnknown));
+ } else {
+ for (size_t i = 0; i < arraysize(kHierarchy); ++i) {
+ AddressField field = kHierarchy[i];
+ const std::string& value = address.GetFieldValue(field);
+ if (value.empty()) {
+ break;
+ }
+ nodes_.insert(std::make_pair(field, value));
+ }
+ }
+ Language address_language(address.language_code);
+ std::string language_tag_no_latn = address_language.has_latin_script
+ ? address_language.base
+ : address_language.tag;
+ if (ShouldSetLanguageForKey(language_tag_no_latn, address.region_code)) {
+ language_ = language_tag_no_latn;
+ }
+}
+
+void LookupKey::FromLookupKey(const LookupKey& parent,
+ const std::string& child_node) {
+ assert(parent.nodes_.size() < arraysize(kHierarchy));
+ assert(!child_node.empty());
+
+ // Copy its nodes if this isn't the parent object.
+ if (this != &parent) nodes_ = parent.nodes_;
+ AddressField child_field = kHierarchy[nodes_.size()];
+ nodes_.insert(std::make_pair(child_field, child_node));
+}
+
+std::string LookupKey::ToKeyString(size_t max_depth) const {
+ assert(max_depth < arraysize(kHierarchy));
+ std::string key_string(kData);
+
+ for (size_t i = 0; i <= max_depth; ++i) {
+ AddressField field = kHierarchy[i];
+ std::map<AddressField, std::string>::const_iterator it = nodes_.find(field);
+ if (it == nodes_.end()) {
+ break;
+ }
+ key_string.append(kSlashDelim);
+ key_string.append(it->second);
+ }
+ if (!language_.empty()) {
+ key_string.append(kDashDelim);
+ key_string.append(language_);
+ }
+ return key_string;
+}
+
+const std::string& LookupKey::GetRegionCode() const {
+ std::map<AddressField, std::string>::const_iterator it = nodes_.find(COUNTRY);
+ assert(it != nodes_.end());
+ return it->second;
+}
+
+size_t LookupKey::GetDepth() const {
+ size_t depth = nodes_.size() - 1;
+ assert(depth < arraysize(kHierarchy));
+ return depth;
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/lookup_key.h b/chromium/third_party/libaddressinput/src/cpp/src/lookup_key.h
new file mode 100644
index 00000000000..0b74cd3d938
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/lookup_key.h
@@ -0,0 +1,75 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_LOOKUP_KEY_H_
+#define I18N_ADDRESSINPUT_LOOKUP_KEY_H_
+
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <cstddef>
+#include <map>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+struct AddressData;
+
+// A LookupKey maps between an AddressData struct and the key string used to
+// request address data from an address data server.
+class LookupKey {
+ public:
+ // The array length is explicitly specified here, to make it possible to get
+ // the length through arraysize(LookupKey::kHierarchy).
+ static const AddressField kHierarchy[4];
+
+ LookupKey();
+ ~LookupKey();
+
+ // Initializes this object by parsing |address|.
+ void FromAddress(const AddressData& address);
+
+ // Initializes this object to be a copy of |parent| key that's one level
+ // deeper with the next level node being |child_node|.
+ //
+ // For example, if |parent| is "data/US" and |child_node| is "CA", then this
+ // key becomes "data/US/CA".
+ //
+ // The |parent| can be at most LOCALITY level. The |child_node| cannot be
+ // empty.
+ void FromLookupKey(const LookupKey& parent, const std::string& child_node);
+
+ // Returns the lookup key string (of |max_depth|).
+ std::string ToKeyString(size_t max_depth) const;
+
+ // Returns the region code. Must not be called on an empty object.
+ const std::string& GetRegionCode() const;
+
+ // Returns the depth. Must not be called on an empty object.
+ size_t GetDepth() const;
+
+ private:
+ std::map<AddressField, std::string> nodes_;
+ // The language of the key, obtained from the address (empty for default
+ // language).
+ std::string language_;
+
+ DISALLOW_COPY_AND_ASSIGN(LookupKey);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_LOOKUP_KEY_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/null_storage.cc b/chromium/third_party/libaddressinput/src/cpp/src/null_storage.cc
new file mode 100644
index 00000000000..7786a0dcd4f
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/null_storage.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2014 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/null_storage.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+NullStorage::NullStorage() {
+}
+
+NullStorage::~NullStorage() {
+}
+
+void NullStorage::Put(const std::string& key, std::string* data) {
+ assert(data != NULL); // Sanity check.
+ delete data;
+}
+
+void NullStorage::Get(const std::string& key,
+ const Callback& data_ready) const {
+ data_ready(false, key, NULL);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supplier.cc b/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supplier.cc
new file mode 100644
index 00000000000..fa3f88e8701
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supplier.cc
@@ -0,0 +1,68 @@
+// Copyright (C) 2014 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/ondemand_supplier.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <map>
+#include <string>
+
+#include "lookup_key.h"
+#include "ondemand_supply_task.h"
+#include "region_data_constants.h"
+#include "retriever.h"
+#include "rule.h"
+
+namespace i18n {
+namespace addressinput {
+
+OndemandSupplier::OndemandSupplier(const Source* source, Storage* storage)
+ : retriever_(new Retriever(source, storage)) {
+}
+
+OndemandSupplier::~OndemandSupplier() {
+ for (std::map<std::string, const Rule*>::const_iterator
+ it = rule_cache_.begin(); it != rule_cache_.end(); ++it) {
+ delete it->second;
+ }
+}
+
+void OndemandSupplier::Supply(const LookupKey& lookup_key,
+ const Callback& supplied) {
+ OndemandSupplyTask* task =
+ new OndemandSupplyTask(lookup_key, &rule_cache_, supplied);
+
+ if (RegionDataConstants::IsSupported(lookup_key.GetRegionCode())) {
+ size_t max_depth = std::min(
+ lookup_key.GetDepth(),
+ RegionDataConstants::GetMaxLookupKeyDepth(lookup_key.GetRegionCode()));
+
+ for (size_t depth = 0; depth <= max_depth; ++depth) {
+ const std::string& key = lookup_key.ToKeyString(depth);
+ std::map<std::string, const Rule*>::const_iterator it =
+ rule_cache_.find(key);
+ if (it != rule_cache_.end()) {
+ task->hierarchy_.rule[depth] = it->second;
+ } else {
+ task->Queue(key); // If not in the cache, it needs to be loaded.
+ }
+ }
+ }
+
+ task->Retrieve(*retriever_);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supply_task.cc b/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supply_task.cc
new file mode 100644
index 00000000000..a4f6a12049a
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supply_task.cc
@@ -0,0 +1,139 @@
+// Copyright (C) 2014 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 "ondemand_supply_task.h"
+
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/callback.h>
+#include <libaddressinput/supplier.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <map>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "lookup_key.h"
+#include "retriever.h"
+#include "rule.h"
+
+namespace i18n {
+namespace addressinput {
+
+OndemandSupplyTask::OndemandSupplyTask(
+ const LookupKey& lookup_key,
+ std::map<std::string, const Rule*>* rules,
+ const Supplier::Callback& supplied)
+ : hierarchy_(),
+ pending_(),
+ lookup_key_(lookup_key),
+ rule_cache_(rules),
+ supplied_(supplied),
+ retrieved_(BuildCallback(this, &OndemandSupplyTask::Load)),
+ success_(true) {
+ assert(rule_cache_ != NULL);
+ assert(retrieved_ != NULL);
+}
+
+OndemandSupplyTask::~OndemandSupplyTask() {
+}
+
+void OndemandSupplyTask::Queue(const std::string& key) {
+ assert(pending_.find(key) == pending_.end());
+ pending_.insert(key);
+}
+
+void OndemandSupplyTask::Retrieve(const Retriever& retriever) {
+ if (pending_.empty()) {
+ Loaded();
+ } else {
+ // When the final pending rule has been retrieved, the retrieved_ callback,
+ // implemented by Load(), will finish by calling Loaded(), which will finish
+ // by delete'ing this OndemandSupplyTask object. So after the final call to
+ // retriever.Retrieve() no attributes of this object can be accessed (as the
+ // object then no longer will exist, if the final callback has finished by
+ // then), and the condition statement of the loop must therefore not use the
+ // otherwise obvious it != pending_.end() but instead test a local variable
+ // that isn't affected by the object being deleted.
+ bool done = false;
+ for (std::set<std::string>::const_iterator it = pending_.begin(); !done; ) {
+ const std::string& key = *it++;
+ done = it == pending_.end();
+ retriever.Retrieve(key, *retrieved_);
+ }
+ }
+}
+
+void OndemandSupplyTask::Load(bool success,
+ const std::string& key,
+ const std::string& data) {
+ size_t depth = std::count(key.begin(), key.end(), '/') - 1;
+ assert(depth < arraysize(LookupKey::kHierarchy));
+
+ // Sanity check: This key should be present in the set of pending requests.
+ size_t status = pending_.erase(key);
+ assert(status == 1); // There will always be one item erased from the set.
+ (void)status; // Prevent unused variable if assert() is optimized away.
+
+ if (success) {
+ // The address metadata server will return the empty JSON "{}" when it
+ // successfully performed a lookup, but didn't find any data for that key.
+ if (data != "{}") {
+ Rule* rule = new Rule;
+ if (LookupKey::kHierarchy[depth] == COUNTRY) {
+ // All rules on the COUNTRY level inherit from the default rule.
+ rule->CopyFrom(Rule::GetDefault());
+ }
+ if (rule->ParseSerializedRule(data)) {
+ // Try inserting the Rule object into the rule_cache_ map, or else find
+ // the already existing Rule object with the same ID already in the map.
+ // It is possible that a key was queued even though the corresponding
+ // Rule object is already in the cache, as the data server is free to do
+ // advanced normalization and aliasing so that the ID of the data
+ // returned is different from the key requested. (It would be possible
+ // to cache such aliases, to increase performance in the case where a
+ // certain alias is requested repeatedly, but such a cache would then
+ // have to be kept to some limited size to not grow indefinitely with
+ // every possible permutation of a name recognized by the data server.)
+ std::pair<std::map<std::string, const Rule*>::iterator, bool> result =
+ rule_cache_->insert(std::make_pair(rule->GetId(), rule));
+ if (!result.second) { // There was already an entry with this ID.
+ delete rule;
+ }
+ // Pointer to object in the map.
+ hierarchy_.rule[depth] = result.first->second;
+ } else {
+ delete rule;
+ success_ = false;
+ }
+ }
+ } else {
+ success_ = false;
+ }
+
+ if (pending_.empty()) {
+ Loaded();
+ }
+}
+
+void OndemandSupplyTask::Loaded() {
+ supplied_(success_, lookup_key_, hierarchy_);
+ delete this;
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supply_task.h b/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supply_task.h
new file mode 100644
index 00000000000..45b33c90508
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/ondemand_supply_task.h
@@ -0,0 +1,71 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_ONDEMAND_SUPPLY_TASK_H_
+#define I18N_ADDRESSINPUT_ONDEMAND_SUPPLY_TASK_H_
+
+#include <libaddressinput/supplier.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "retriever.h"
+
+namespace i18n {
+namespace addressinput {
+
+class LookupKey;
+class Rule;
+
+// An OndemandSupplyTask object encapsulates the information necessary to
+// retrieve the set of Rule objects corresponding to a LookupKey and call a
+// callback when that has been done. Calling the Retrieve() method will load
+// required metadata, then call the callback and delete the OndemandSupplyTask
+// object itself.
+class OndemandSupplyTask {
+ public:
+ OndemandSupplyTask(const LookupKey& lookup_key,
+ std::map<std::string, const Rule*>* rules,
+ const Supplier::Callback& supplied);
+ ~OndemandSupplyTask();
+
+ // Adds lookup key string |key| to the queue of data to be retrieved.
+ void Queue(const std::string& key);
+
+ // Retrieves and parses data for all queued keys, then calls |supplied_|.
+ void Retrieve(const Retriever& retriever);
+
+ Supplier::RuleHierarchy hierarchy_;
+
+ private:
+ void Load(bool success, const std::string& key, const std::string& data);
+ void Loaded();
+
+ std::set<std::string> pending_;
+ const LookupKey& lookup_key_;
+ std::map<std::string, const Rule*>* const rule_cache_;
+ const Supplier::Callback& supplied_;
+ const scoped_ptr<const Retriever::Callback> retrieved_;
+ bool success_;
+
+ DISALLOW_COPY_AND_ASSIGN(OndemandSupplyTask);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_ONDEMAND_SUPPLY_TASK_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/post_box_matchers.cc b/chromium/third_party/libaddressinput/src/cpp/src/post_box_matchers.cc
new file mode 100644
index 00000000000..f1ad6dd6e95
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/post_box_matchers.cc
@@ -0,0 +1,132 @@
+// Copyright (C) 2014 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 "post_box_matchers.h"
+
+#include <cstddef>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <re2/re2.h>
+
+#include "language.h"
+#include "rule.h"
+#include "util/re2ptr.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+std::map<std::string, const RE2ptr*> InitMatchers() {
+ static const struct {
+ const char* const language;
+ const RE2ptr ptr;
+ } kMatchers[] = {
+ { "ar",
+ /* "صندوق بريد|ص[-. ]ب" */
+ new RE2("\xD8\xB5\xD9\x86\xD8\xAF\xD9\x88\xD9\x82 "
+ "\xD8\xA8\xD8\xB1\xD9\x8A\xD8\xAF|\xD8\xB5[-. ]\xD8\xA8") },
+
+ { "cs", new RE2("(?i)p\\.? ?p\\.? \\d") },
+ { "da", new RE2("(?i)Postboks") },
+ { "de", new RE2("(?i)Postfach") },
+
+ { "el",
+ /* "T\\.? ?Θ\\.? \\d{2}" */
+ new RE2("(?i)T\\.? ?\xCE\x98\\.? \\d{2}") },
+
+ { "en", new RE2("Private Bag|Post(?:al)? Box") },
+ { "es", new RE2("(?i)(?:Apartado|Casillas) de correos?") },
+ { "fi", new RE2("(?i)Postilokero|P\\.?L\\.? \\d") },
+ { "hr", new RE2("(?i)p\\.? ?p\\.? \\d") },
+
+ { "hu",
+ /* "Postafi(?:[oó]|ó)k|Pf\\.? \\d" */
+ new RE2("(?i)Postafi(?:[o\xC3\xB3]|o\xCC\x81)k|Pf\\.? \\d") },
+
+ { "fr",
+ /* "Bo(?:[iî]|î)te Postale|BP \\d|CEDEX \\d" */
+ new RE2("(?i)Bo(?:[i\xC3\xAE]|i\xCC\x82)te Postale|BP \\d|CEDEX \\d") },
+
+ { "ja",
+ /* "私書箱\\d{1,5}号" */
+ new RE2("(?i)\xE7\xA7\x81\xE6\x9B\xB8\xE7\xAE\xB1\\d{1,5}\xE5\x8F\xB7") },
+
+ { "nl", new RE2("(?i)Postbus") },
+ { "no", new RE2("(?i)Postboks") },
+ { "pl", new RE2("(?i)Skr(?:\\.?|ytka) poczt(?:\\.?|owa)") },
+ { "pt", new RE2("(?i)Apartado") },
+
+ { "ru",
+ /* "абонентский ящик|[аa]\\\" */
+ new RE2("(?i)\xD0\xB0\xD0\xB1\xD0\xBE\xD0\xBD\xD0\xB5\xD0\xBD\xD1\x82\xD1"
+ "\x81\xD0\xBA\xD0\xB8\xD0\xB9 \xD1\x8F\xD1\x89\xD0\xB8\xD0\xBA|"
+ "[\xD0\xB0""a]\\\"\xD1\x8F (?:(?:\xE2\x84\x96|#|N) ?)?\\d") },
+
+ { "sv", new RE2("(?i)Box \\d") },
+
+ { "zh",
+ /* "郵政信箱.{1,5}號|郵局第.{1,10}號信箱" */
+ new RE2("(?i)\xE9\x83\xB5\xE6\x94\xBF\xE4\xBF\xA1\xE7\xAE\xB1.{1,5}"
+ "\xE8\x99\x9F|\xE9\x83\xB5\xE5\xB1\x80\xE7\xAC\xAC.{1,10}"
+ "\xE8\x99\x9F\xE4\xBF\xA1\xE7\xAE\xB1") },
+
+ { "und", new RE2("P\\.? ?O\\.? Box") }
+ };
+
+ std::map<std::string, const RE2ptr*> matchers;
+
+ for (size_t i = 0; i < sizeof kMatchers / sizeof *kMatchers; ++i) {
+ matchers.insert(std::make_pair(kMatchers[i].language, &kMatchers[i].ptr));
+ }
+
+ return matchers;
+}
+
+} // namespace
+
+// static
+std::vector<const RE2ptr*> PostBoxMatchers::GetMatchers(
+ const Rule& country_rule) {
+ static const std::map<std::string, const RE2ptr*> kMatchers(InitMatchers());
+
+ // Always add any expressions defined for "und" (English-like defaults).
+ std::vector<std::string> languages(1, "und");
+ for (std::vector<std::string>::const_iterator
+ it = country_rule.GetLanguages().begin();
+ it != country_rule.GetLanguages().end(); ++it) {
+ Language language(*it);
+ languages.push_back(language.base);
+ }
+
+ std::vector<const RE2ptr*> result;
+
+ for (std::vector<std::string>::const_iterator
+ it = languages.begin();
+ it != languages.end(); ++it) {
+ std::map<std::string, const RE2ptr*>::const_iterator
+ jt = kMatchers.find(*it);
+ if (jt != kMatchers.end()) {
+ result.push_back(jt->second);
+ }
+ }
+
+ return result;
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/post_box_matchers.h b/chromium/third_party/libaddressinput/src/cpp/src/post_box_matchers.h
new file mode 100644
index 00000000000..9924a2c5133
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/post_box_matchers.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2014 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.
+//
+// Post office box regular expressions.
+
+#ifndef I18N_ADDRESSINPUT_POST_BOX_MATCHERS_H_
+#define I18N_ADDRESSINPUT_POST_BOX_MATCHERS_H_
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+class Rule;
+struct RE2ptr;
+
+class PostBoxMatchers {
+ public:
+ // Returns pointers to RE2 regular expression objects to test address lines
+ // for those languages that are relevant for |country_rule|.
+ static std::vector<const RE2ptr*> GetMatchers(const Rule& country_rule);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PostBoxMatchers);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_POST_BOX_MATCHERS_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/preload_supplier.cc b/chromium/third_party/libaddressinput/src/cpp/src/preload_supplier.cc
new file mode 100644
index 00000000000..79119bdbea1
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/preload_supplier.cc
@@ -0,0 +1,373 @@
+// Copyright (C) 2014 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/preload_supplier.h>
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/callback.h>
+#include <libaddressinput/supplier.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <map>
+#include <set>
+#include <stack>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "lookup_key.h"
+#include "region_data_constants.h"
+#include "retriever.h"
+#include "rule.h"
+#include "util/json.h"
+#include "util/string_compare.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+// STL predicate less<> that uses StringCompare to match strings that a human
+// reader would consider to be "the same". The default implementation just does
+// case insensitive string comparison, but StringCompare can be overriden with
+// more sophisticated implementations.
+class IndexLess : public std::binary_function<std::string, std::string, bool> {
+ public:
+ result_type operator()(const first_argument_type& a,
+ const second_argument_type& b) const {
+ static const StringCompare kStringCompare;
+ return kStringCompare.NaturalLess(a, b);
+ }
+};
+
+} // namespace
+
+class IndexMap : public std::map<std::string, const Rule*, IndexLess> {};
+
+namespace {
+
+class Helper {
+ public:
+ // Does not take ownership of its parameters.
+ Helper(const std::string& region_code,
+ const std::string& key,
+ const PreloadSupplier::Callback& loaded,
+ const Retriever& retriever,
+ std::set<std::string>* pending,
+ IndexMap* rule_index,
+ std::vector<const Rule*>* rule_storage,
+ std::map<std::string, const Rule*>* region_rules)
+ : region_code_(region_code),
+ loaded_(loaded),
+ pending_(pending),
+ rule_index_(rule_index),
+ rule_storage_(rule_storage),
+ region_rules_(region_rules),
+ retrieved_(BuildCallback(this, &Helper::OnRetrieved)) {
+ assert(pending_ != NULL);
+ assert(rule_index_ != NULL);
+ assert(rule_storage_ != NULL);
+ assert(region_rules_ != NULL);
+ assert(retrieved_ != NULL);
+ pending_->insert(key);
+ retriever.Retrieve(key, *retrieved_);
+ }
+
+ private:
+ ~Helper() {}
+
+ void OnRetrieved(bool success,
+ const std::string& key,
+ const std::string& data) {
+ int rule_count = 0;
+
+ size_t status = pending_->erase(key);
+ assert(status == 1); // There will always be one item erased from the set.
+ (void)status; // Prevent unused variable if assert() is optimized away.
+
+ Json json;
+ std::string id;
+ std::vector<const Rule*> sub_rules;
+
+ IndexMap::iterator last_index_it = rule_index_->end();
+ IndexMap::iterator last_latin_it = rule_index_->end();
+ std::map<std::string, const Rule*>::iterator last_region_it =
+ region_rules_->end();
+
+ IndexMap::const_iterator hints[arraysize(LookupKey::kHierarchy) - 1];
+ std::fill(hints, hints + arraysize(hints), rule_index_->end());
+
+ if (!success) {
+ goto callback;
+ }
+
+ if (!json.ParseObject(data)) {
+ success = false;
+ goto callback;
+ }
+
+ for (std::vector<const Json*>::const_iterator
+ it = json.GetSubDictionaries().begin();
+ it != json.GetSubDictionaries().end();
+ ++it) {
+ const Json* value = *it;
+ assert(value != NULL);
+ if (!value->GetStringValueForKey("id", &id)) {
+ success = false;
+ goto callback;
+ }
+ assert(!id.empty());
+
+ size_t depth = std::count(id.begin(), id.end(), '/') - 1;
+ assert(depth < arraysize(LookupKey::kHierarchy));
+ AddressField field = LookupKey::kHierarchy[depth];
+
+ Rule* rule = new Rule;
+ if (field == COUNTRY) {
+ // All rules on the COUNTRY level inherit from the default rule.
+ rule->CopyFrom(Rule::GetDefault());
+ }
+ rule->ParseJsonRule(*value);
+ assert(id == rule->GetId()); // Sanity check.
+
+ rule_storage_->push_back(rule);
+ if (depth > 0) {
+ sub_rules.push_back(rule);
+ }
+
+ // Add the ID of this Rule object to the rule index with natural string
+ // comparison for keys.
+ last_index_it =
+ rule_index_->insert(last_index_it, std::make_pair(id, rule));
+
+ // Add the ID of this Rule object to the region-specific rule index with
+ // exact string comparison for keys.
+ last_region_it =
+ region_rules_->insert(last_region_it, std::make_pair(id, rule));
+
+ ++rule_count;
+ }
+
+ /*
+ * Normally the address metadata server takes care of mapping from natural
+ * language names to metadata IDs (eg. "São Paulo" -> "SP") and from Latin
+ * script names to local script names (eg. "Tokushima" -> "徳島県").
+ *
+ * As the PreloadSupplier doesn't contact the metadata server upon each
+ * Supply() request, it instead has an internal lookup table (rule_index_)
+ * that contains such mappings.
+ *
+ * This lookup table is populated by iterating over all sub rules and for
+ * each of them construct ID strings using human readable names (eg. "São
+ * Paulo") and using Latin script names (eg. "Tokushima").
+ */
+ for (std::vector<const Rule*>::const_iterator
+ it = sub_rules.begin(); it != sub_rules.end(); ++it) {
+ std::stack<const Rule*> hierarchy;
+ hierarchy.push(*it);
+
+ // Push pointers to all parent Rule objects onto the hierarchy stack.
+ for (std::string parent_id((*it)->GetId());;) {
+ // Strip the last part of parent_id. Break if COUNTRY level is reached.
+ std::string::size_type pos = parent_id.rfind('/');
+ if (pos == sizeof "data/ZZ" - 1) {
+ break;
+ }
+ parent_id.resize(pos);
+
+ IndexMap::const_iterator* const hint = &hints[hierarchy.size() - 1];
+ if (*hint == rule_index_->end() || (*hint)->first != parent_id) {
+ *hint = rule_index_->find(parent_id);
+ }
+ assert(*hint != rule_index_->end());
+ hierarchy.push((*hint)->second);
+ }
+
+ std::string human_id((*it)->GetId().substr(0, sizeof "data/ZZ" - 1));
+ std::string latin_id(human_id);
+
+ // Append the names from all Rule objects on the hierarchy stack.
+ for (; !hierarchy.empty(); hierarchy.pop()) {
+ const Rule* rule = hierarchy.top();
+
+ human_id.push_back('/');
+ if (!rule->GetName().empty()) {
+ human_id.append(rule->GetName());
+ } else {
+ // If the "name" field is empty, the name is the last part of the ID.
+ const std::string& id = rule->GetId();
+ std::string::size_type pos = id.rfind('/');
+ assert(pos != std::string::npos);
+ human_id.append(id.substr(pos + 1));
+ }
+
+ if (!rule->GetLatinName().empty()) {
+ latin_id.push_back('/');
+ latin_id.append(rule->GetLatinName());
+ }
+ }
+
+ // If the ID has a language tag, copy it.
+ {
+ const std::string& id = (*it)->GetId();
+ std::string::size_type pos = id.rfind("--");
+ if (pos != std::string::npos) {
+ human_id.append(id, pos, id.size() - pos);
+ }
+ }
+
+ last_index_it =
+ rule_index_->insert(last_index_it, std::make_pair(human_id, *it));
+
+ // Add the Latin script ID, if a Latin script name could be found for
+ // every part of the ID.
+ if (std::count(human_id.begin(), human_id.end(), '/') ==
+ std::count(latin_id.begin(), latin_id.end(), '/')) {
+ last_latin_it =
+ rule_index_->insert(last_latin_it, std::make_pair(latin_id, *it));
+ }
+ }
+
+ callback:
+ loaded_(success, region_code_, rule_count);
+ delete this;
+ }
+
+ const std::string region_code_;
+ const PreloadSupplier::Callback& loaded_;
+ std::set<std::string>* const pending_;
+ IndexMap* const rule_index_;
+ std::vector<const Rule*>* const rule_storage_;
+ std::map<std::string, const Rule*>* const region_rules_;
+ const scoped_ptr<const Retriever::Callback> retrieved_;
+
+ DISALLOW_COPY_AND_ASSIGN(Helper);
+};
+
+std::string KeyFromRegionCode(const std::string& region_code) {
+ AddressData address;
+ address.region_code = region_code;
+ LookupKey lookup_key;
+ lookup_key.FromAddress(address);
+ return lookup_key.ToKeyString(0); // Zero depth = COUNTRY level.
+}
+
+} // namespace
+
+PreloadSupplier::PreloadSupplier(const Source* source, Storage* storage)
+ : retriever_(new Retriever(source, storage)),
+ pending_(),
+ rule_index_(new IndexMap),
+ rule_storage_(),
+ region_rules_() {}
+
+PreloadSupplier::~PreloadSupplier() {
+ for (std::vector<const Rule*>::const_iterator
+ it = rule_storage_.begin(); it != rule_storage_.end(); ++it) {
+ delete *it;
+ }
+}
+
+void PreloadSupplier::Supply(const LookupKey& lookup_key,
+ const Supplier::Callback& supplied) {
+ Supplier::RuleHierarchy hierarchy;
+ bool success = GetRuleHierarchy(lookup_key, &hierarchy);
+ supplied(success, lookup_key, hierarchy);
+}
+
+const Rule* PreloadSupplier::GetRule(const LookupKey& lookup_key) const {
+ assert(IsLoaded(lookup_key.GetRegionCode()));
+ Supplier::RuleHierarchy hierarchy;
+ if (!GetRuleHierarchy(lookup_key, &hierarchy)) {
+ return NULL;
+ }
+ return hierarchy.rule[lookup_key.GetDepth()];
+}
+
+void PreloadSupplier::LoadRules(const std::string& region_code,
+ const Callback& loaded) {
+ const std::string& key = KeyFromRegionCode(region_code);
+
+ if (IsLoadedKey(key)) {
+ loaded(true, region_code, 0);
+ return;
+ }
+
+ if (IsPendingKey(key)) {
+ return;
+ }
+
+ new Helper(
+ region_code,
+ key,
+ loaded,
+ *retriever_,
+ &pending_,
+ rule_index_.get(),
+ &rule_storage_,
+ &region_rules_[region_code]);
+}
+
+const std::map<std::string, const Rule*>& PreloadSupplier::GetRulesForRegion(
+ const std::string& region_code) const {
+ assert(IsLoaded(region_code));
+ return region_rules_.find(region_code)->second;
+}
+
+bool PreloadSupplier::IsLoaded(const std::string& region_code) const {
+ return IsLoadedKey(KeyFromRegionCode(region_code));
+}
+
+bool PreloadSupplier::IsPending(const std::string& region_code) const {
+ return IsPendingKey(KeyFromRegionCode(region_code));
+}
+
+bool PreloadSupplier::GetRuleHierarchy(const LookupKey& lookup_key,
+ RuleHierarchy* hierarchy) const {
+ assert(hierarchy != NULL);
+
+ if (RegionDataConstants::IsSupported(lookup_key.GetRegionCode())) {
+ size_t max_depth = std::min(
+ lookup_key.GetDepth(),
+ RegionDataConstants::GetMaxLookupKeyDepth(lookup_key.GetRegionCode()));
+
+ for (size_t depth = 0; depth <= max_depth; ++depth) {
+ const std::string& key = lookup_key.ToKeyString(depth);
+ IndexMap::const_iterator it = rule_index_->find(key);
+ if (it == rule_index_->end()) {
+ return depth > 0; // No data on COUNTRY level is failure.
+ }
+ hierarchy->rule[depth] = it->second;
+ }
+ }
+
+ return true;
+}
+
+bool PreloadSupplier::IsLoadedKey(const std::string& key) const {
+ return rule_index_->find(key) != rule_index_->end();
+}
+
+bool PreloadSupplier::IsPendingKey(const std::string& key) const {
+ return pending_.find(key) != pending_.end();
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/region_data.cc b/chromium/third_party/libaddressinput/src/cpp/src/region_data.cc
new file mode 100644
index 00000000000..798501edcd9
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/region_data.cc
@@ -0,0 +1,50 @@
+// Copyright (C) 2014 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/region_data.h>
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+RegionData::RegionData(const std::string& region_code)
+ : key_(region_code),
+ name_(region_code),
+ parent_(NULL),
+ sub_regions_() {}
+
+RegionData::~RegionData() {
+ for (std::vector<const RegionData*>::const_iterator it = sub_regions_.begin();
+ it != sub_regions_.end(); ++it) {
+ delete *it;
+ }
+}
+
+RegionData* RegionData::AddSubRegion(const std::string& key,
+ const std::string& name) {
+ RegionData* sub_region = new RegionData(key, name, this);
+ sub_regions_.push_back(sub_region);
+ return sub_region;
+}
+
+RegionData::RegionData(const std::string& key,
+ const std::string& name,
+ RegionData* parent)
+ : key_(key), name_(name), parent_(parent), sub_regions_() {}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/region_data_builder.cc b/chromium/third_party/libaddressinput/src/cpp/src/region_data_builder.cc
new file mode 100644
index 00000000000..b600d09ab06
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/region_data_builder.cc
@@ -0,0 +1,189 @@
+// Copyright (C) 2014 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/region_data_builder.h>
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/preload_supplier.h>
+#include <libaddressinput/region_data.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "language.h"
+#include "lookup_key.h"
+#include "region_data_constants.h"
+#include "rule.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+// The maximum depth of lookup keys.
+static const size_t kLookupKeysMaxDepth = arraysize(LookupKey::kHierarchy) - 1;
+
+// Does not take ownership of |parent_region|, which is not allowed to be NULL.
+void BuildRegionTreeRecursively(
+ const std::map<std::string, const Rule*>& rules,
+ std::map<std::string, const Rule*>::const_iterator hint,
+ const LookupKey& parent_key,
+ RegionData* parent_region,
+ const std::vector<std::string>& keys,
+ bool prefer_latin_name,
+ size_t region_max_depth) {
+ assert(parent_region != NULL);
+
+ LookupKey lookup_key;
+ for (std::vector<std::string>::const_iterator key_it = keys.begin();
+ key_it != keys.end(); ++key_it) {
+ lookup_key.FromLookupKey(parent_key, *key_it);
+ const std::string& lookup_key_string =
+ lookup_key.ToKeyString(kLookupKeysMaxDepth);
+
+ ++hint;
+ if (hint == rules.end() || hint->first != lookup_key_string) {
+ hint = rules.find(lookup_key_string);
+ if (hint == rules.end()) {
+ return;
+ }
+ }
+
+ const Rule* rule = hint->second;
+ assert(rule != NULL);
+
+ const std::string& local_name = rule->GetName().empty()
+ ? *key_it : rule->GetName();
+ const std::string& name =
+ prefer_latin_name && !rule->GetLatinName().empty()
+ ? rule->GetLatinName() : local_name;
+ RegionData* region = parent_region->AddSubRegion(*key_it, name);
+
+ if (!rule->GetSubKeys().empty() &&
+ region_max_depth > parent_key.GetDepth()) {
+ BuildRegionTreeRecursively(rules,
+ hint,
+ lookup_key,
+ region,
+ rule->GetSubKeys(),
+ prefer_latin_name,
+ region_max_depth);
+ }
+ }
+}
+
+// The caller owns the result.
+RegionData* BuildRegion(const std::map<std::string, const Rule*>& rules,
+ const std::string& region_code,
+ const Language& language) {
+ AddressData address;
+ address.region_code = region_code;
+
+ LookupKey lookup_key;
+ lookup_key.FromAddress(address);
+
+ std::map<std::string, const Rule*>::const_iterator hint =
+ rules.find(lookup_key.ToKeyString(kLookupKeysMaxDepth));
+ assert(hint != rules.end());
+
+ const Rule* rule = hint->second;
+ assert(rule != NULL);
+
+ RegionData* region = new RegionData(region_code);
+
+ // If there're sub-keys for field X, but field X is not used in this region
+ // code, then these sub-keys are skipped over. For example, CH has sub-keys
+ // for field ADMIN_AREA, but CH does not use ADMIN_AREA field.
+ size_t region_max_depth =
+ RegionDataConstants::GetMaxLookupKeyDepth(region_code);
+ if (region_max_depth > 0) {
+ BuildRegionTreeRecursively(rules,
+ hint,
+ lookup_key,
+ region,
+ rule->GetSubKeys(),
+ language.has_latin_script,
+ region_max_depth);
+ }
+
+ return region;
+}
+
+} // namespace
+
+RegionDataBuilder::RegionDataBuilder(PreloadSupplier* supplier)
+ : supplier_(supplier),
+ cache_() {
+ assert(supplier_ != NULL);
+}
+
+RegionDataBuilder::~RegionDataBuilder() {
+ for (RegionCodeDataMap::const_iterator region_it = cache_.begin();
+ region_it != cache_.end(); ++region_it) {
+ for (LanguageRegionMap::const_iterator
+ language_it = region_it->second->begin();
+ language_it != region_it->second->end(); ++language_it) {
+ delete language_it->second;
+ }
+ delete region_it->second;
+ }
+}
+
+const RegionData& RegionDataBuilder::Build(
+ const std::string& region_code,
+ const std::string& ui_language_tag,
+ std::string* best_region_tree_language_tag) {
+ assert(supplier_->IsLoaded(region_code));
+ assert(best_region_tree_language_tag != NULL);
+
+ // Look up the region tree in cache first before building it.
+ RegionCodeDataMap::const_iterator region_it = cache_.find(region_code);
+ if (region_it == cache_.end()) {
+ region_it =
+ cache_.insert(std::make_pair(region_code, new LanguageRegionMap)).first;
+ }
+
+ // No need to copy from default rule first, because only languages and Latin
+ // format are going to be used, which do not exist in the default rule.
+ Rule rule;
+ rule.ParseSerializedRule(RegionDataConstants::GetRegionData(region_code));
+ static const Language kUndefinedLanguage("und");
+ const Language& best_language =
+ rule.GetLanguages().empty()
+ ? kUndefinedLanguage
+ : ChooseBestAddressLanguage(rule, Language(ui_language_tag));
+ *best_region_tree_language_tag = best_language.tag;
+
+ LanguageRegionMap::const_iterator language_it =
+ region_it->second->find(best_language.tag);
+ if (language_it == region_it->second->end()) {
+ const std::map<std::string, const Rule*>& rules =
+ supplier_->GetRulesForRegion(region_code);
+ language_it =
+ region_it->second->insert(std::make_pair(best_language.tag,
+ BuildRegion(rules,
+ region_code,
+ best_language)))
+ .first;
+ }
+
+ return *language_it->second;
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/region_data_constants.cc b/chromium/third_party/libaddressinput/src/cpp/src/region_data_constants.cc
new file mode 100644
index 00000000000..a44a310eb3b
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/region_data_constants.cc
@@ -0,0 +1,1508 @@
+// 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.
+//
+// The data in this file is automatically generated.
+
+#include "region_data_constants.h"
+
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <map>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "address_field_util.h"
+#include "format_element.h"
+#include "lookup_key.h"
+
+namespace i18n {
+namespace addressinput {
+
+// ---- BEGIN AUTOGENERATED CODE ----
+namespace {
+
+std::map<std::string, std::string> InitRegionData() {
+ std::map<std::string, std::string> region_data;
+ region_data.insert(std::make_pair("AC", "{"
+ "\"zipex\":\"ASCN 1ZZ\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("AD", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"AD100,AD501,AD700\","
+ "\"posturl\":\"http://www.correos.es/comun/CodigosPostales/1010_s-CodPostal.asp\?Provincia=\","
+ "\"languages\":\"ca\""
+ "}"));
+ region_data.insert(std::make_pair("AE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%S\","
+ "\"lfmt\":\"%N%n%O%n%A%n%S\","
+ "\"require\":\"AS\","
+ "\"state_name_type\":\"emirate\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("AF", "{"
+ "\"zipex\":\"1001,2601,3801\","
+ "\"posturl\":\"http://afghanpost.gov.af/Postal%20Code/\","
+ "\"languages\":\"fa~ps\""
+ "}"));
+ region_data.insert(std::make_pair("AG", "{"
+ "\"require\":\"A\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("AI", "{"
+ "\"zipex\":\"2640\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("AL", "{"
+ "\"zipex\":\"1001,1017,3501\","
+ "\"languages\":\"sq\""
+ "}"));
+ region_data.insert(std::make_pair("AM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z%n%C%n%S\","
+ "\"lfmt\":\"%N%n%O%n%A%n%Z%n%C%n%S\","
+ "\"zipex\":\"375010,0002,0010\","
+ "\"languages\":\"hy\""
+ "}"));
+ region_data.insert(std::make_pair("AO", "{"
+ "\"languages\":\"pt\""
+ "}"));
+ region_data.insert(std::make_pair("AQ", "{"
+ "\"languages\":\"\""
+ "}"));
+ region_data.insert(std::make_pair("AR", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C%n%S\","
+ "\"zipex\":\"C1070AAM,C1000WAM,B1000TBU,X5187XAB\","
+ "\"posturl\":\"http://www.correoargentino.com.ar/formularios/cpa\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("AS", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"96799\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"sm~en\""
+ "}"));
+ region_data.insert(std::make_pair("AT", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"1010,3741\","
+ "\"posturl\":\"http://www.post.at/post_subsite_postleitzahlfinder.php\","
+ "\"languages\":\"de\""
+ "}"));
+ region_data.insert(std::make_pair("AU", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"2060,3171,6430,4000,4006,3001\","
+ "\"posturl\":\"http://www1.auspost.com.au/postcodes/\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("AW", "{"
+ "\"languages\":\"nl~pap\""
+ "}"));
+ region_data.insert(std::make_pair("AX", "{"
+ "\"fmt\":\"%O%n%N%n%A%nAX-%Z %C%n\\u00c5LAND\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"22150,22550,22240,22710,22270,22730,22430\","
+ "\"posturl\":\"http://www.posten.ax/department.con\?iPage=123\","
+ "\"languages\":\"sv\""
+ "}"));
+ region_data.insert(std::make_pair("AZ", "{"
+ "\"fmt\":\"%N%n%O%n%A%nAZ %Z %C\","
+ "\"zipex\":\"1000\","
+ "\"languages\":\"az-Latn~az-Cyrl\""
+ "}"));
+ region_data.insert(std::make_pair("BA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"71000\","
+ "\"posturl\":\"http://www.post.ba/postanski_brojevi.php\","
+ "\"languages\":\"bs-Cyrl~bs-Latn~hr~sr-Cyrl~sr-Latn\""
+ "}"));
+ region_data.insert(std::make_pair("BB", "{"
+ "\"state_name_type\":\"parish\","
+ "\"zipex\":\"BB23026,BB22025\","
+ "\"posturl\":\"http://barbadospostal.com/zipcodes.html\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("BD", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C - %Z\","
+ "\"zipex\":\"1340,1000\","
+ "\"posturl\":\"http://www.bangladeshpost.gov.bd/PostCode.asp\","
+ "\"languages\":\"bn\""
+ "}"));
+ region_data.insert(std::make_pair("BE", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"4000,1000\","
+ "\"posturl\":\"http://www.post.be/site/nl/residential/customerservice/search/postal_codes.html\","
+ "\"languages\":\"nl~fr~de\""
+ "}"));
+ region_data.insert(std::make_pair("BF", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %X\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("BG", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"1000,1700\","
+ "\"posturl\":\"http://www.bgpost.bg/\?cid=5\","
+ "\"languages\":\"bg\""
+ "}"));
+ region_data.insert(std::make_pair("BH", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"317\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("BI", "{"
+ "\"languages\":\"rn~fr\""
+ "}"));
+ region_data.insert(std::make_pair("BJ", "{"
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("BL", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"97100\","
+ "\"posturl\":\"http://www.laposte.fr/Particulier/Utiliser-nos-outils-pratiques/Outils-et-documents/Trouvez-un-code-postal\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("BM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"FL 07,HM GX,HM 12\","
+ "\"posturl\":\"http://www.landvaluation.bm/\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("BN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"BT2328,KA1131,BA1511\","
+ "\"posturl\":\"http://www.post.gov.bn/index.php/extensions/postcode-guide\","
+ "\"languages\":\"ms-Latn~ms-Arab\""
+ "}"));
+ region_data.insert(std::make_pair("BO", "{"
+ "\"languages\":\"es~qu~ay\""
+ "}"));
+ region_data.insert(std::make_pair("BQ", "{"
+ "\"languages\":\"nl\""
+ "}"));
+ region_data.insert(std::make_pair("BR", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%D%n%C-%S%n%Z\","
+ "\"require\":\"ASCZ\","
+ "\"state_name_type\":\"state\","
+ "\"sublocality_name_type\":\"neighborhood\","
+ "\"zipex\":\"40301-110,70002-900\","
+ "\"posturl\":\"http://www.buscacep.correios.com.br/\","
+ "\"languages\":\"pt\""
+ "}"));
+ region_data.insert(std::make_pair("BS", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %S\","
+ "\"state_name_type\":\"island\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("BT", "{"
+ "\"zipex\":\"11001,31101,35003\","
+ "\"posturl\":\"http://www.bhutanpost.com.bt/postcode/postcode.php\","
+ "\"languages\":\"dz\""
+ "}"));
+ region_data.insert(std::make_pair("BV", "{"
+ "\"languages\":\"\""
+ "}"));
+ region_data.insert(std::make_pair("BW", "{"
+ "\"languages\":\"en~tn\""
+ "}"));
+ region_data.insert(std::make_pair("BY", "{"
+ "\"fmt\":\"%S%n%Z %C %X%n%A%n%O%n%N\","
+ "\"zipex\":\"223016,225860,220050\","
+ "\"posturl\":\"http://zip.belpost.by\","
+ "\"languages\":\"be~ru\""
+ "}"));
+ region_data.insert(std::make_pair("BZ", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("CA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zipex\":\"H3Z 2Y7,V8X 3X4,T0L 1K0,T0H 1A0,K1A 0B1\","
+ "\"posturl\":\"http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity\?execution=e2s1\","
+ "\"languages\":\"en~fr\""
+ "}"));
+ region_data.insert(std::make_pair("CC", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%C %S %Z\","
+ "\"zipex\":\"6799\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("CD", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %X\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("CF", "{"
+ "\"languages\":\"fr~sg\""
+ "}"));
+ region_data.insert(std::make_pair("CG", "{"
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("CH", "{"
+ "\"fmt\":\"%O%n%N%n%A%nCH-%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"2544,1211,1556,3030\","
+ "\"posturl\":\"http://www.post.ch/db/owa/pv_plz_pack/pr_main\","
+ "\"languages\":\"de~fr~it\""
+ "}"));
+ region_data.insert(std::make_pair("CI", "{"
+ "\"fmt\":\"%N%n%O%n%X %A %C %X\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("CK", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("CL", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C%n%S\","
+ "\"zipex\":\"8340457,8720019,1230000,8329100\","
+ "\"posturl\":\"http://www.correos.cl/SitePages/home.aspx\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("CM", "{"
+ "\"languages\":\"fr~en\""
+ "}"));
+ region_data.insert(std::make_pair("CN", "{"
+ "\"fmt\":\"%Z%n%S%C%D%n%A%n%O%n%N\","
+ "\"lfmt\":\"%N%n%O%n%A%n%D%n%C%n%S, %Z\","
+ "\"require\":\"ACSZ\","
+ "\"sublocality_name_type\":\"district\","
+ "\"zipex\":\"266033,317204,100096,100808\","
+ "\"posturl\":\"http://www.cpdc.com.cn/postcdQueryAction.do\?reqCode=gotoQueryPostAddr\","
+ "\"languages\":\"zh\""
+ "}"));
+ region_data.insert(std::make_pair("CO", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %S, %Z\","
+ "\"zipex\":\"111221,130001,760011\","
+ "\"posturl\":\"http://www.codigopostal.gov.co/\","
+ "\"state_name_type\":\"department\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("CR", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"1000,2010,1001\","
+ "\"posturl\":\"https://www.correos.go.cr/nosotros/codigopostal/busqueda.html\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("CV", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C%n%S\","
+ "\"state_name_type\":\"island\","
+ "\"zipex\":\"7600\","
+ "\"languages\":\"pt\""
+ "}"));
+ region_data.insert(std::make_pair("CW", "{"
+ "\"languages\":\"pap~nl\""
+ "}"));
+ region_data.insert(std::make_pair("CX", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%C %S %Z\","
+ "\"zipex\":\"6798\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("CY", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"2008,3304,1900\","
+ "\"languages\":\"el~tr\""
+ "}"));
+ region_data.insert(std::make_pair("CZ", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"100 00,251 66,530 87,110 00,225 99\","
+ "\"posturl\":\"http://psc.ceskaposta.cz/CleanForm.action\","
+ "\"languages\":\"cs\""
+ "}"));
+ region_data.insert(std::make_pair("DE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"26133,53225\","
+ "\"posturl\":\"http://www.postdirekt.de/plzserver/\","
+ "\"languages\":\"de\""
+ "}"));
+ region_data.insert(std::make_pair("DJ", "{"
+ "\"languages\":\"ar~fr\""
+ "}"));
+ region_data.insert(std::make_pair("DK", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"8660,1566\","
+ "\"posturl\":\"http://www.postdanmark.dk/da/Privat/Kundeservice/postnummerkort/Sider/Find-postnummer.aspx\","
+ "\"languages\":\"da\""
+ "}"));
+ region_data.insert(std::make_pair("DM", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("DO", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"11903,10101\","
+ "\"posturl\":\"http://inposdom.gob.do/servicios/codigo-postal.html#buscar_codigo\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("DZ", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"40304,16027\","
+ "\"languages\":\"ar~fr\""
+ "}"));
+ region_data.insert(std::make_pair("EC", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z%n%C\","
+ "\"zipex\":\"090105,EC090112,H0103C,P0133B,P0133A,P0133V\","
+ "\"languages\":\"es~qu\""
+ "}"));
+ region_data.insert(std::make_pair("EE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"69501,11212\","
+ "\"posturl\":\"http://www.post.ee/\?op=sihtnumbriotsing\","
+ "\"languages\":\"et\""
+ "}"));
+ region_data.insert(std::make_pair("EG", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S%n%Z\","
+ "\"lfmt\":\"%N%n%O%n%A%n%C%n%S%n%Z\","
+ "\"zipex\":\"12411,11599\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("EH", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"70000,72000\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("ER", "{"
+ "\"languages\":\"ti~en~ar\""
+ "}"));
+ region_data.insert(std::make_pair("ES", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C %S\","
+ "\"require\":\"ACSZ\","
+ "\"zipex\":\"28039,28300,28070\","
+ "\"posturl\":\"http://www.correos.es/contenido/13-MenuRec2/04-MenuRec24/1010_s-CodPostal.asp\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("ET", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"1000\","
+ "\"languages\":\"am\""
+ "}"));
+ region_data.insert(std::make_pair("FI", "{"
+ "\"fmt\":\"%O%n%N%n%A%nFI-%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"00550,00011\","
+ "\"posturl\":\"http://www.verkkoposti.com/e3/postinumeroluettelo\","
+ "\"languages\":\"fi~sv\""
+ "}"));
+ region_data.insert(std::make_pair("FJ", "{"
+ "\"languages\":\"en~hif-Deva~fj\""
+ "}"));
+ region_data.insert(std::make_pair("FK", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"FIQQ 1ZZ\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("FM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"96941,96944\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("FO", "{"
+ "\"fmt\":\"%N%n%O%n%A%nFO%Z %C\","
+ "\"zipex\":\"100\","
+ "\"posturl\":\"http://www.postur.fo/\","
+ "\"languages\":\"fo\""
+ "}"));
+ region_data.insert(std::make_pair("FR", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"33380,34092,33506\","
+ "\"posturl\":\"http://www.laposte.fr/Particulier/Utiliser-nos-outils-pratiques/Outils-et-documents/Trouvez-un-code-postal\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("GA", "{"
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("GB", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"state_name_type\":\"county\","
+ "\"locality_name_type\":\"post_town\","
+ "\"zipex\":\"EC1Y 8SY,GIR 0AA,M2 5BQ,M34 4AB,CR0 2YR,DN16 9AA,W1A 4ZZ,EC1A 1HQ,OX14 4PG,BS18 8HF,NR25 7HG,RH6 0NP,BH23 6AA,B6 5BA,SO23 9AP,PO1 3AX,BFPO 61\","
+ "\"posturl\":\"http://www.royalmail.com/postcode-finder\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("GD", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("GE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"0101\","
+ "\"posturl\":\"http://www.georgianpost.ge/index.php\?page=10\","
+ "\"languages\":\"ka\""
+ "}"));
+ region_data.insert(std::make_pair("GF", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"97300\","
+ "\"posturl\":\"http://www.laposte.fr/Particulier/Utiliser-nos-outils-pratiques/Outils-et-documents/Trouvez-un-code-postal\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("GG", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%nGUERNSEY%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"GY1 1AA,GY2 2BT\","
+ "\"posturl\":\"http://www.guernseypost.com/postcode_finder/\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("GH", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("GI", "{"
+ "\"fmt\":\"%N%n%O%n%A%nGIBRALTAR%n%Z\","
+ "\"require\":\"A\","
+ "\"zipex\":\"GX11 1AA\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("GL", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"3900,3950,3911\","
+ "\"languages\":\"kl\""
+ "}"));
+ region_data.insert(std::make_pair("GM", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("GN", "{"
+ "\"fmt\":\"%N%n%O%n%Z %A %C\","
+ "\"zipex\":\"001,200,100\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("GP", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"97100\","
+ "\"posturl\":\"http://www.laposte.fr/Particulier/Utiliser-nos-outils-pratiques/Outils-et-documents/Trouvez-un-code-postal\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("GQ", "{"
+ "\"languages\":\"es~fr\""
+ "}"));
+ region_data.insert(std::make_pair("GR", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"151 24,151 10,101 88\","
+ "\"posturl\":\"http://www.elta.gr/findapostcode.aspx\","
+ "\"languages\":\"el\""
+ "}"));
+ region_data.insert(std::make_pair("GS", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"SIQQ 1ZZ\","
+ "\"languages\":\"\""
+ "}"));
+ region_data.insert(std::make_pair("GT", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z- %C\","
+ "\"zipex\":\"09001,01501\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("GU", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"96910,96931\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"en~ch\""
+ "}"));
+ region_data.insert(std::make_pair("GW", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"1000,1011\","
+ "\"languages\":\"pt\""
+ "}"));
+ region_data.insert(std::make_pair("GY", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("HK", "{"
+ "\"fmt\":\"%S%n%C%n%A%n%O%n%N\","
+ "\"lfmt\":\"%N%n%O%n%A%n%C%n%S\","
+ "\"require\":\"AS\","
+ "\"state_name_type\":\"area\","
+ "\"locality_name_type\":\"district\","
+ "\"languages\":\"zh-Hant~en\""
+ "}"));
+ region_data.insert(std::make_pair("HM", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%C %S %Z\","
+ "\"zipex\":\"7050\","
+ "\"languages\":\"\""
+ "}"));
+ region_data.insert(std::make_pair("HN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %S%n%Z\","
+ "\"require\":\"ACS\","
+ "\"zipex\":\"31301\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("HR", "{"
+ "\"fmt\":\"%N%n%O%n%A%nHR-%Z %C\","
+ "\"zipex\":\"10000,21001,10002\","
+ "\"posturl\":\"http://www.posta.hr/default.aspx\?pretpum\","
+ "\"languages\":\"hr\""
+ "}"));
+ region_data.insert(std::make_pair("HT", "{"
+ "\"fmt\":\"%N%n%O%n%A%nHT%Z %C %X\","
+ "\"zipex\":\"6120,5310,6110,8510\","
+ "\"languages\":\"ht~fr\""
+ "}"));
+ region_data.insert(std::make_pair("HU", "{"
+ "\"fmt\":\"%N%n%O%n%C%n%A%n%Z\","
+ "\"zipex\":\"1037,2380,1540\","
+ "\"posturl\":\"http://posta.hu/ugyfelszolgalat/iranyitoszam_kereso\","
+ "\"languages\":\"hu\""
+ "}"));
+ region_data.insert(std::make_pair("ID", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S %Z\","
+ "\"state_name_type\":\"district\","
+ "\"zipex\":\"40115\","
+ "\"languages\":\"id\""
+ "}"));
+ region_data.insert(std::make_pair("IE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S\","
+ "\"state_name_type\":\"county\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("IL", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"9614303\","
+ "\"posturl\":\"http://www.israelpost.co.il/zipcode.nsf/demozip\?openform\","
+ "\"languages\":\"iw~ar\""
+ "}"));
+ region_data.insert(std::make_pair("IM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"IM2 1AA,IM99 1PS\","
+ "\"posturl\":\"http://www.gov.im/post/postal/fr_main.asp\","
+ "\"languages\":\"en~gv\""
+ "}"));
+ region_data.insert(std::make_pair("IN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z%n%S\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"pin\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"110034,110001\","
+ "\"posturl\":\"http://www.indiapost.gov.in/pin/pinsearch.aspx\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("IO", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"BBND 1ZZ\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("IQ", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%C, %S%n%Z\","
+ "\"require\":\"ACS\","
+ "\"zipex\":\"31001\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("IR", "{"
+ "\"fmt\":\"%O%n%N%n%S%n%C, %D%n%A%n%Z\","
+ "\"sublocality_name_type\":\"neighborhood\","
+ "\"zipex\":\"11936-12345\","
+ "\"languages\":\"fa\""
+ "}"));
+ region_data.insert(std::make_pair("IS", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"320,121,220,110\","
+ "\"posturl\":\"http://www.postur.is/cgi-bin/hsrun.exe/Distributed/vefur/vefur.htx;start=HS_landakort_postnumer\","
+ "\"languages\":\"is\""
+ "}"));
+ region_data.insert(std::make_pair("IT", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C %S\","
+ "\"require\":\"ACSZ\","
+ "\"zipex\":\"00144,47037,39049\","
+ "\"posturl\":\"http://www.poste.it/online/cercacap/\","
+ "\"languages\":\"it\""
+ "}"));
+ region_data.insert(std::make_pair("JE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%nJERSEY%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"JE1 1AA,JE2 2BT\","
+ "\"posturl\":\"http://www.jerseypost.com/tools/postcode-address-finder/\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("JM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S %X\","
+ "\"require\":\"ACS\","
+ "\"state_name_type\":\"parish\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("JO", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"11937,11190\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("JP", "{"
+ "\"fmt\":\"\\u3012%Z%n%S%C%n%A%n%O%n%N\","
+ "\"lfmt\":\"%N%n%O%n%A%n%C, %S%n%Z\","
+ "\"require\":\"ACSZ\","
+ "\"state_name_type\":\"prefecture\","
+ "\"zipex\":\"154-0023,350-1106,951-8073,112-0001,208-0032,231-0012\","
+ "\"posturl\":\"http://search.post.japanpost.jp/zipcode/\","
+ "\"languages\":\"ja\""
+ "}"));
+ region_data.insert(std::make_pair("KE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%Z\","
+ "\"zipex\":\"20100,00100\","
+ "\"languages\":\"en~sw\""
+ "}"));
+ region_data.insert(std::make_pair("KG", "{"
+ "\"fmt\":\"%Z %C %X%n%A%n%O%n%N\","
+ "\"zipex\":\"720001\","
+ "\"languages\":\"ky-Cyrl~ru\""
+ "}"));
+ region_data.insert(std::make_pair("KH", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"12203,14206,12000\","
+ "\"languages\":\"km\""
+ "}"));
+ region_data.insert(std::make_pair("KI", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%S%n%C\","
+ "\"state_name_type\":\"island\","
+ "\"languages\":\"en~gil\""
+ "}"));
+ region_data.insert(std::make_pair("KM", "{"
+ "\"languages\":\"ar~fr~zdj\""
+ "}"));
+ region_data.insert(std::make_pair("KN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %S\","
+ "\"require\":\"ACS\","
+ "\"state_name_type\":\"island\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("KR", "{"
+ "\"fmt\":\"%S %C%D%n%A%n%O%n%N%n%Z\","
+ "\"lfmt\":\"%N%n%O%n%A%n%D%n%C%n%S%n%Z\","
+ "\"require\":\"ACSZ\","
+ "\"state_name_type\":\"do_si\","
+ "\"sublocality_name_type\":\"district\","
+ "\"zipex\":\"110-110,699-800\","
+ "\"posturl\":\"http://www.epost.go.kr/search/zipcode/search5.jsp\","
+ "\"languages\":\"ko\""
+ "}"));
+ region_data.insert(std::make_pair("KW", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"54541,54551,54404,13009\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("KY", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%S %Z\","
+ "\"require\":\"AS\","
+ "\"state_name_type\":\"island\","
+ "\"zipex\":\"KY1-1100,KY1-1702,KY2-2101\","
+ "\"posturl\":\"http://www.caymanpost.gov.ky/portal/page\?_pageid=3561,1&_dad=portal&_schema=PORTAL\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("KZ", "{"
+ "\"fmt\":\"%Z%n%S%n%C%n%A%n%O%n%N\","
+ "\"zipex\":\"040900,050012\","
+ "\"languages\":\"ru~kk-Cyrl\""
+ "}"));
+ region_data.insert(std::make_pair("LA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"01160,01000\","
+ "\"languages\":\"lo\""
+ "}"));
+ region_data.insert(std::make_pair("LB", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"2038 3054,1107 2810,1000\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("LC", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("LI", "{"
+ "\"fmt\":\"%O%n%N%n%A%nFL-%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"9496,9491,9490,9485\","
+ "\"posturl\":\"http://www.post.ch/db/owa/pv_plz_pack/pr_main\","
+ "\"languages\":\"de~gsw\""
+ "}"));
+ region_data.insert(std::make_pair("LK", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%Z\","
+ "\"zipex\":\"20000,00100\","
+ "\"posturl\":\"http://www.slpost.gov.lk/\","
+ "\"languages\":\"si~ta\""
+ "}"));
+ region_data.insert(std::make_pair("LR", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C %X\","
+ "\"zipex\":\"1000\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("LS", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"100\","
+ "\"languages\":\"st~en\""
+ "}"));
+ region_data.insert(std::make_pair("LT", "{"
+ "\"fmt\":\"%O%n%N%n%A%nLT-%Z %C\","
+ "\"zipex\":\"04340,03500\","
+ "\"posturl\":\"http://www.post.lt/lt/\?id=316\","
+ "\"languages\":\"lt\""
+ "}"));
+ region_data.insert(std::make_pair("LU", "{"
+ "\"fmt\":\"%O%n%N%n%A%nL-%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"4750,2998\","
+ "\"posturl\":\"http://www.pt.lu/portal/services_en_ligne/recherche_codes_postaux\","
+ "\"languages\":\"fr~lb~de\""
+ "}"));
+ region_data.insert(std::make_pair("LV", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %Z\","
+ "\"zipex\":\"LV-1073,LV-1000\","
+ "\"posturl\":\"http://www.pasts.lv/lv/uzzinas/nodalas/\","
+ "\"languages\":\"lv\""
+ "}"));
+ region_data.insert(std::make_pair("LY", "{"
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("MA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"53000,10000,20050,16052\","
+ "\"languages\":\"ar~fr~tzm-Latn\""
+ "}"));
+ region_data.insert(std::make_pair("MC", "{"
+ "\"fmt\":\"%N%n%O%n%A%nMC-%Z %C %X\","
+ "\"zipex\":\"98000,98020,98011,98001\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("MD", "{"
+ "\"fmt\":\"%N%n%O%n%A%nMD-%Z %C\","
+ "\"zipex\":\"2012,2019\","
+ "\"languages\":\"ro\""
+ "}"));
+ region_data.insert(std::make_pair("ME", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"81257,81258,81217,84314,85366\","
+ "\"languages\":\"sr-Latn\""
+ "}"));
+ region_data.insert(std::make_pair("MF", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"97100\","
+ "\"posturl\":\"http://www.laposte.fr/Particulier/Utiliser-nos-outils-pratiques/Outils-et-documents/Trouvez-un-code-postal\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("MG", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"501,101\","
+ "\"languages\":\"mg~fr~en\""
+ "}"));
+ region_data.insert(std::make_pair("MH", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"96960,96970\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"en~mh\""
+ "}"));
+ region_data.insert(std::make_pair("MK", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"1314,1321,1443,1062\","
+ "\"languages\":\"mk\""
+ "}"));
+ region_data.insert(std::make_pair("ML", "{"
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("MM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %Z\","
+ "\"zipex\":\"11181\","
+ "\"languages\":\"my\""
+ "}"));
+ region_data.insert(std::make_pair("MN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%S %C-%X%n%Z\","
+ "\"zipex\":\"65030,65270\","
+ "\"posturl\":\"http://www.zipcode.mn/\","
+ "\"languages\":\"mn-Cyrl\""
+ "}"));
+ region_data.insert(std::make_pair("MO", "{"
+ "\"fmt\":\"%A%n%O%n%N\","
+ "\"lfmt\":\"%N%n%O%n%A\","
+ "\"require\":\"A\","
+ "\"languages\":\"zh-Hant~pt\""
+ "}"));
+ region_data.insert(std::make_pair("MP", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"96950,96951,96952\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("MQ", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"97220\","
+ "\"posturl\":\"http://www.laposte.fr/Particulier/Utiliser-nos-outils-pratiques/Outils-et-documents/Trouvez-un-code-postal\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("MR", "{"
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("MS", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("MT", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"NXR 01,ZTN 05,GPO 01,BZN 1130,SPB 6031,VCT 1753\","
+ "\"posturl\":\"http://postcodes.maltapost.com/\","
+ "\"languages\":\"mt~en\""
+ "}"));
+ region_data.insert(std::make_pair("MU", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z%n%C\","
+ "\"zipex\":\"42602\","
+ "\"languages\":\"en~fr\""
+ "}"));
+ region_data.insert(std::make_pair("MV", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"20026\","
+ "\"posturl\":\"http://www.maldivespost.com/\?lid=10\","
+ "\"languages\":\"dv\""
+ "}"));
+ region_data.insert(std::make_pair("MW", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %X\","
+ "\"languages\":\"en~ny\""
+ "}"));
+ region_data.insert(std::make_pair("MX", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%D%n%Z %C, %S\","
+ "\"require\":\"ACZ\","
+ "\"state_name_type\":\"state\","
+ "\"sublocality_name_type\":\"neighborhood\","
+ "\"zipex\":\"02860,77520,06082\","
+ "\"posturl\":\"http://www.correosdemexico.gob.mx/ServiciosLinea/Paginas/ccpostales.aspx\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("MY", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%D%n%Z %C%n%S\","
+ "\"require\":\"ACZ\","
+ "\"state_name_type\":\"state\","
+ "\"sublocality_name_type\":\"village_township\","
+ "\"zipex\":\"43000,50754,88990,50670\","
+ "\"posturl\":\"http://www.pos.com.my/pos/homepage.aspx\","
+ "\"languages\":\"ms\""
+ "}"));
+ region_data.insert(std::make_pair("MZ", "{"
+ "\"zipex\":\"1102,1119,3212\","
+ "\"languages\":\"pt\""
+ "}"));
+ region_data.insert(std::make_pair("NA", "{"
+ "\"languages\":\"af~en\""
+ "}"));
+ region_data.insert(std::make_pair("NC", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"98814,98800,98810\","
+ "\"posturl\":\"http://poste.opt.nc/index.php\?option=com_content&view=article&id=80&Itemid=131\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("NE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"8001\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("NF", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%C %S %Z\","
+ "\"zipex\":\"2899\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("NG", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z%n%S\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"930283,300001,931104\","
+ "\"posturl\":\"http://www.nigeriapostcodes.com/views/\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("NI", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z%n%C, %S\","
+ "\"state_name_type\":\"department\","
+ "\"zipex\":\"52000\","
+ "\"posturl\":\"http://www.correos.gob.ni/index.php/codigo-postal-2\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("NL", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"1234 AB,2490 AA\","
+ "\"posturl\":\"http://www.postnl.nl/voorthuis/\","
+ "\"languages\":\"nl\""
+ "}"));
+ region_data.insert(std::make_pair("NO", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"0025,0107,6631\","
+ "\"posturl\":\"http://adressesok.posten.no/nb/postal_codes/search\","
+ "\"languages\":\"no~nn\""
+ "}"));
+ region_data.insert(std::make_pair("NP", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"44601\","
+ "\"posturl\":\"http://www.gpo.gov.np/postalcode.aspx\","
+ "\"languages\":\"ne\""
+ "}"));
+ region_data.insert(std::make_pair("NR", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%S\","
+ "\"require\":\"AS\","
+ "\"state_name_type\":\"district\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("NU", "{"
+ "\"languages\":\"en~niu\""
+ "}"));
+ region_data.insert(std::make_pair("NZ", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%D%n%C %Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"6001,6015,6332,8252,1030\","
+ "\"posturl\":\"http://www.nzpost.co.nz/Cultures/en-NZ/OnlineTools/PostCodeFinder/\","
+ "\"languages\":\"en~mi\""
+ "}"));
+ region_data.insert(std::make_pair("OM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z%n%C\","
+ "\"zipex\":\"133,112,111\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("PA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("PE", "{"
+ "\"zipex\":\"LIMA 23,LIMA 42,CALLAO 2,02001\","
+ "\"posturl\":\"http://www.serpost.com.pe/cpostal/codigo\","
+ "\"languages\":\"es~qu\""
+ "}"));
+ region_data.insert(std::make_pair("PF", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C %S\","
+ "\"require\":\"ACSZ\","
+ "\"state_name_type\":\"island\","
+ "\"zipex\":\"98709\","
+ "\"languages\":\"fr~ty\""
+ "}"));
+ region_data.insert(std::make_pair("PG", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z %S\","
+ "\"require\":\"ACS\","
+ "\"zipex\":\"111\","
+ "\"languages\":\"tpi~en~ho\""
+ "}"));
+ region_data.insert(std::make_pair("PH", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%D, %C%n%Z %S\","
+ "\"zipex\":\"1008,1050,1135,1207,2000,1000\","
+ "\"posturl\":\"http://www.philpost.gov.ph/\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("PK", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C-%Z\","
+ "\"zipex\":\"44000\","
+ "\"posturl\":\"http://www.pakpost.gov.pk/postcode/postcode.html\","
+ "\"languages\":\"ur~en\""
+ "}"));
+ region_data.insert(std::make_pair("PL", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"00-950,05-470,48-300,32-015,00-940\","
+ "\"posturl\":\"http://www.poczta-polska.pl/kody.php\","
+ "\"languages\":\"pl\""
+ "}"));
+ region_data.insert(std::make_pair("PM", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"97500\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("PN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"PCRN 1ZZ\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("PR", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C PR %Z\","
+ "\"require\":\"ACZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"zipex\":\"00930\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"es~en\""
+ "}"));
+ region_data.insert(std::make_pair("PS", "{"
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("PT", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"2725-079,1250-096,1201-950,2860-571,1208-148\","
+ "\"posturl\":\"http://www.ctt.pt/feapl_2/app/open/tools.jspx\?tool=1\","
+ "\"languages\":\"pt\""
+ "}"));
+ region_data.insert(std::make_pair("PW", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"96940\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"pau~en\""
+ "}"));
+ region_data.insert(std::make_pair("PY", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"1536,1538,1209\","
+ "\"languages\":\"gn~es\""
+ "}"));
+ region_data.insert(std::make_pair("QA", "{"
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("RE", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"97400\","
+ "\"posturl\":\"http://www.laposte.fr/Particulier/Utiliser-nos-outils-pratiques/Outils-et-documents/Trouvez-un-code-postal\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("RO", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"060274,061357,200716\","
+ "\"posturl\":\"http://www.posta-romana.ro/zip_codes\","
+ "\"languages\":\"ro\""
+ "}"));
+ region_data.insert(std::make_pair("RS", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"106314\","
+ "\"posturl\":\"http://www.posta.rs/struktura/lat/aplikacije/pronadji/nadji-postu.asp\","
+ "\"languages\":\"sr-Cyrl~sr-Latn\""
+ "}"));
+ region_data.insert(std::make_pair("RU", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S%n%Z\","
+ "\"lfmt\":\"%N%n%O%n%A%n%C%n%S%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"state_name_type\":\"oblast\","
+ "\"zipex\":\"247112,103375,188300\","
+ "\"posturl\":\"http://info.russianpost.ru/servlet/department\","
+ "\"languages\":\"ru\""
+ "}"));
+ region_data.insert(std::make_pair("RW", "{"
+ "\"languages\":\"rw~fr~en\""
+ "}"));
+ region_data.insert(std::make_pair("SA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z\","
+ "\"zipex\":\"11564,11187,11142\","
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("SB", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("SC", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S\","
+ "\"state_name_type\":\"island\","
+ "\"languages\":\"fr~en\""
+ "}"));
+ region_data.insert(std::make_pair("SE", "{"
+ "\"fmt\":\"%O%n%N%n%A%nSE-%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"11455,12345,10500\","
+ "\"posturl\":\"http://www.posten.se/sv/Kundservice/Sidor/Sok-postnummer-resultat.aspx\","
+ "\"languages\":\"sv\""
+ "}"));
+ region_data.insert(std::make_pair("SG", "{"
+ "\"fmt\":\"%N%n%O%n%A%nSINGAPORE %Z\","
+ "\"require\":\"AZ\","
+ "\"zipex\":\"546080,308125,408600\","
+ "\"posturl\":\"http://www.singpost.com.sg/quick_services/index.htm\","
+ "\"languages\":\"en~zh-Hans~ms-Latn~ta\""
+ "}"));
+ region_data.insert(std::make_pair("SH", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"STHL 1ZZ\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("SI", "{"
+ "\"fmt\":\"%N%n%O%n%A%nSI- %Z %C\","
+ "\"zipex\":\"4000,1001,2500\","
+ "\"languages\":\"sl\""
+ "}"));
+ region_data.insert(std::make_pair("SJ", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"9170\","
+ "\"posturl\":\"http://epab.posten.no/\","
+ "\"languages\":\"no\""
+ "}"));
+ region_data.insert(std::make_pair("SK", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"010 01,023 14,972 48,921 01,975 99\","
+ "\"posturl\":\"http://psc.posta.sk\","
+ "\"languages\":\"sk\""
+ "}"));
+ region_data.insert(std::make_pair("SL", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("SM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"require\":\"AZ\","
+ "\"zipex\":\"47890,47891,47895,47899\","
+ "\"posturl\":\"http://www.poste.it/online/cercacap/\","
+ "\"languages\":\"it\""
+ "}"));
+ region_data.insert(std::make_pair("SN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"12500,46024,16556,10000\","
+ "\"languages\":\"wo~fr\""
+ "}"));
+ region_data.insert(std::make_pair("SO", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %S %Z\","
+ "\"require\":\"ACS\","
+ "\"zipex\":\"09010,11010\","
+ "\"languages\":\"so\""
+ "}"));
+ region_data.insert(std::make_pair("SR", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %X%n%S\","
+ "\"languages\":\"nl\""
+ "}"));
+ region_data.insert(std::make_pair("SS", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("ST", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %X\","
+ "\"languages\":\"pt\""
+ "}"));
+ region_data.insert(std::make_pair("SV", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z-%C%n%S\","
+ "\"require\":\"ACS\","
+ "\"zipex\":\"CP 1101\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("SX", "{"
+ "\"languages\":\"en~nl\""
+ "}"));
+ region_data.insert(std::make_pair("SZ", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%Z\","
+ "\"zipex\":\"H100\","
+ "\"posturl\":\"http://www.sptc.co.sz/swazipost/codes.php\","
+ "\"languages\":\"en~ss\""
+ "}"));
+ region_data.insert(std::make_pair("TA", "{"
+ "\"zipex\":\"TDCU 1ZZ\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("TC", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"TKCA 1ZZ\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("TD", "{"
+ "\"languages\":\"fr~ar\""
+ "}"));
+ region_data.insert(std::make_pair("TF", "{"
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("TG", "{"
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("TH", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%D %C%n%S %Z\","
+ "\"lfmt\":\"%N%n%O%n%A%n%D, %C%n%S %Z\","
+ "\"zipex\":\"10150,10210\","
+ "\"languages\":\"th\""
+ "}"));
+ region_data.insert(std::make_pair("TJ", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"735450,734025\","
+ "\"languages\":\"tg-Cyrl\""
+ "}"));
+ region_data.insert(std::make_pair("TK", "{"
+ "\"languages\":\"en~tkl\""
+ "}"));
+ region_data.insert(std::make_pair("TL", "{"
+ "\"languages\":\"pt~tet\""
+ "}"));
+ region_data.insert(std::make_pair("TM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"744000\","
+ "\"languages\":\"tk-Latn\""
+ "}"));
+ region_data.insert(std::make_pair("TN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"1002,8129,3100,1030\","
+ "\"posturl\":\"http://www.poste.tn/codes.php\","
+ "\"languages\":\"ar~fr\""
+ "}"));
+ region_data.insert(std::make_pair("TO", "{"
+ "\"languages\":\"to~en\""
+ "}"));
+ region_data.insert(std::make_pair("TR", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C/%S\","
+ "\"require\":\"ACZ\","
+ "\"locality_name_type\":\"district\","
+ "\"zipex\":\"01960,06101\","
+ "\"posturl\":\"http://postakodu.ptt.gov.tr/\","
+ "\"languages\":\"tr\""
+ "}"));
+ region_data.insert(std::make_pair("TT", "{"
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("TV", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%X%n%C%n%S\","
+ "\"state_name_type\":\"island\","
+ "\"languages\":\"tyv\""
+ "}"));
+ region_data.insert(std::make_pair("TW", "{"
+ "\"fmt\":\"%Z%n%S%C%n%A%n%O%n%N\","
+ "\"lfmt\":\"%N%n%O%n%A%n%C, %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"state_name_type\":\"county\","
+ "\"zipex\":\"104,106,10603,40867\","
+ "\"posturl\":\"http://www.post.gov.tw/post/internet/f_searchzone/index.jsp\?ID=190102\","
+ "\"languages\":\"zh-Hant\""
+ "}"));
+ region_data.insert(std::make_pair("TZ", "{"
+ "\"zipex\":\"6090\","
+ "\"languages\":\"sw~en\""
+ "}"));
+ region_data.insert(std::make_pair("UA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S%n%Z\","
+ "\"lfmt\":\"%N%n%O%n%A%n%C%n%S%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"state_name_type\":\"oblast\","
+ "\"zipex\":\"15432,01055,01001\","
+ "\"posturl\":\"http://services.ukrposhta.com/postindex_new/\","
+ "\"languages\":\"uk\""
+ "}"));
+ region_data.insert(std::make_pair("UG", "{"
+ "\"languages\":\"sw~en\""
+ "}"));
+ region_data.insert(std::make_pair("UM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACS\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"96898\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("US", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C, %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"95014,22162-1010\","
+ "\"posturl\":\"https://tools.usps.com/go/ZipLookupAction!input.action\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("UY", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C %S\","
+ "\"zipex\":\"11600\","
+ "\"posturl\":\"http://www.correo.com.uy/index.asp\?codPag=codPost&switchMapa=codPost\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("UZ", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C%n%S\","
+ "\"zipex\":\"702100,700000\","
+ "\"posturl\":\"http://www.pochta.uz/index.php/uz/pochta-indekslari/9\","
+ "\"languages\":\"uz-Latn~uz-Cyrl\""
+ "}"));
+ region_data.insert(std::make_pair("VA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"00120\","
+ "\"languages\":\"it~la\""
+ "}"));
+ region_data.insert(std::make_pair("VC", "{"
+ "\"zipex\":\"VC0100,VC0110,VC0400\","
+ "\"posturl\":\"http://www.svgpost.gov.vc/\?option=com_content&view=article&id=3&Itemid=16\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("VE", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %Z, %S\","
+ "\"require\":\"ACS\","
+ "\"zipex\":\"1010,3001,8011,1020\","
+ "\"posturl\":\"http://www.ipostel.gob.ve/nlinea/codigo_postal.php\","
+ "\"languages\":\"es\""
+ "}"));
+ region_data.insert(std::make_pair("VG", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%Z\","
+ "\"require\":\"A\","
+ "\"zipex\":\"VG1110,VG1150,VG1160\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("VI", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C %S %Z\","
+ "\"require\":\"ACSZ\","
+ "\"zip_name_type\":\"zip\","
+ "\"state_name_type\":\"state\","
+ "\"zipex\":\"00802-1222,00850-9802\","
+ "\"posturl\":\"http://zip4.usps.com/zip4/welcome.jsp\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("VN", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C%n%S %Z\","
+ "\"lfmt\":\"%N%n%O%n%A%n%C%n%S %Z\","
+ "\"zipex\":\"119415,136065,720344\","
+ "\"posturl\":\"http://postcode.vnpost.vn/services/search.aspx\","
+ "\"languages\":\"vi\""
+ "}"));
+ region_data.insert(std::make_pair("VU", "{"
+ "\"languages\":\"bi~en~fr\""
+ "}"));
+ region_data.insert(std::make_pair("WF", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"98600\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("WS", "{"
+ "\"languages\":\"sm~en\""
+ "}"));
+ region_data.insert(std::make_pair("XK", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"10000\","
+ "\"languages\":\"sq~sr-Cyrl~sr-Latn\""
+ "}"));
+ region_data.insert(std::make_pair("YE", "{"
+ "\"languages\":\"ar\""
+ "}"));
+ region_data.insert(std::make_pair("YT", "{"
+ "\"fmt\":\"%O%n%N%n%A%n%Z %C %X\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"97600\","
+ "\"languages\":\"fr\""
+ "}"));
+ region_data.insert(std::make_pair("ZA", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%D%n%C%n%Z\","
+ "\"require\":\"ACZ\","
+ "\"zipex\":\"0083,1451,0001\","
+ "\"posturl\":\"http://www.postoffice.co.za/tools/postalcode.html\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("ZM", "{"
+ "\"fmt\":\"%N%n%O%n%A%n%Z %C\","
+ "\"zipex\":\"50100,50101\","
+ "\"languages\":\"en\""
+ "}"));
+ region_data.insert(std::make_pair("ZW", "{"
+ "\"languages\":\"en~sn~nd\""
+ "}"));
+ return region_data;
+}
+
+} // namespace
+
+// static
+const std::string& RegionDataConstants::GetDefaultRegionData() {
+ static const std::string kDefaultRegionData(
+ "{"
+ "\"fmt\":\"%N%n%O%n%A%n%C\","
+ "\"require\":\"AC\","
+ "\"zip_name_type\":\"postal\","
+ "\"state_name_type\":\"province\","
+ "\"locality_name_type\":\"city\","
+ "\"sublocality_name_type\":\"suburb\""
+ "}");
+ return kDefaultRegionData;
+}
+// ---- END AUTOGENERATED CODE ----
+
+namespace {
+
+const std::map<std::string, std::string>& GetAllRegionData() {
+ static const std::map<std::string, std::string> kRegionData(InitRegionData());
+ return kRegionData;
+}
+
+struct SelectFirst {
+ template <typename Pair>
+ const typename Pair::first_type& operator()(const Pair& pair) const {
+ return pair.first;
+ }
+};
+
+std::vector<std::string> InitRegionCodes() {
+ std::vector<std::string> region_codes(GetAllRegionData().size());
+ std::transform(GetAllRegionData().begin(),
+ GetAllRegionData().end(),
+ region_codes.begin(),
+ SelectFirst());
+ return region_codes;
+}
+
+const std::map<std::string, size_t> InitMaxLookupKeyDepth() {
+ std::map<std::string, size_t> max_depth;
+ for (std::map<std::string, std::string>::const_iterator
+ it = GetAllRegionData().begin(); it != GetAllRegionData().end(); ++it) {
+ std::vector<FormatElement> fields;
+ // Here it->second actually contains the entire JSON blob for this region,
+ // and not only the format field, but it doesn't really matter when just
+ // checking whether a particular formatting code (eg. "%C") is present, as
+ // there isn't anything else in the JSON that erroneously could match a
+ // formatting code.
+ ParseFormatRule(it->second, &fields);
+ size_t depth = 1;
+ for (; depth < arraysize(LookupKey::kHierarchy); ++depth) {
+ AddressField field = LookupKey::kHierarchy[depth];
+ // Check to see if a particular field in the hierarchy is used by
+ // addresses in this country. If not, the maximum depth has been reached.
+ if (std::find(fields.begin(), fields.end(), FormatElement(field)) ==
+ fields.end()) {
+ break;
+ }
+ }
+ max_depth.insert(std::make_pair(it->first, depth - 1));
+ }
+ return max_depth;
+}
+
+} // namespace
+
+// static
+const bool RegionDataConstants::IsSupported(const std::string& region_code) {
+ static const std::set<std::string> kRegionCodes(GetRegionCodes().begin(),
+ GetRegionCodes().end());
+ return kRegionCodes.find(region_code) != kRegionCodes.end();
+}
+
+// static
+const std::vector<std::string>& RegionDataConstants::GetRegionCodes() {
+ static const std::vector<std::string> kRegionCodes(InitRegionCodes());
+ return kRegionCodes;
+}
+
+// static
+const std::string& RegionDataConstants::GetRegionData(
+ const std::string& region_code) {
+ static const std::string kEmptyString;
+ std::map<std::string, std::string>::const_iterator it =
+ GetAllRegionData().find(region_code);
+ return it != GetAllRegionData().end() ? it->second : kEmptyString;
+}
+
+// static
+size_t RegionDataConstants::GetMaxLookupKeyDepth(
+ const std::string& region_code) {
+ static const std::map<std::string, size_t> kMaxDepth(InitMaxLookupKeyDepth());
+ std::map<std::string, size_t>::const_iterator it =
+ kMaxDepth.find(region_code);
+ return it != kMaxDepth.end() ? it->second : 0;
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/region_data_constants.h b/chromium/third_party/libaddressinput/src/cpp/src/region_data_constants.h
new file mode 100644
index 00000000000..4159e722ccb
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/region_data_constants.h
@@ -0,0 +1,42 @@
+// 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.
+
+#ifndef I18N_ADDRESSINPUT_REGION_DATA_CONSTANTS_H_
+#define I18N_ADDRESSINPUT_REGION_DATA_CONSTANTS_H_
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+class RegionDataConstants {
+ public:
+ static const bool IsSupported(const std::string& region_code);
+ static const std::vector<std::string>& GetRegionCodes();
+ static const std::string& GetRegionData(const std::string& region_code);
+ static const std::string& GetDefaultRegionData();
+ static size_t GetMaxLookupKeyDepth(const std::string& region_code);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RegionDataConstants);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_REGION_DATA_CONSTANTS_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/retriever.cc b/chromium/third_party/libaddressinput/src/cpp/src/retriever.cc
new file mode 100644
index 00000000000..151b74d65a8
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/retriever.cc
@@ -0,0 +1,118 @@
+// 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 "retriever.h"
+
+#include <libaddressinput/callback.h>
+#include <libaddressinput/source.h>
+#include <libaddressinput/storage.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+
+#include "validating_storage.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+class Helper {
+ public:
+ // Does not take ownership of its parameters.
+ Helper(const std::string& key,
+ const Retriever::Callback& retrieved,
+ const Source& source,
+ ValidatingStorage* storage)
+ : retrieved_(retrieved),
+ source_(source),
+ storage_(storage),
+ fresh_data_ready_(BuildCallback(this, &Helper::OnFreshDataReady)),
+ validated_data_ready_(
+ BuildCallback(this, &Helper::OnValidatedDataReady)),
+ stale_data_() {
+ assert(storage_ != NULL);
+ storage_->Get(key, *validated_data_ready_);
+ }
+
+ private:
+ ~Helper() {}
+
+ void OnValidatedDataReady(bool success,
+ const std::string& key,
+ std::string* data) {
+ if (success) {
+ assert(data != NULL);
+ retrieved_(success, key, *data);
+ delete this;
+ } else {
+ // Validating storage returns (false, key, stale-data) for valid but stale
+ // data. If |data| is empty, however, then it's either missing or invalid.
+ if (data != NULL && !data->empty()) {
+ stale_data_ = *data;
+ }
+ source_.Get(key, *fresh_data_ready_);
+ }
+ delete data;
+ }
+
+ void OnFreshDataReady(bool success,
+ const std::string& key,
+ std::string* data) {
+ if (success) {
+ assert(data != NULL);
+ retrieved_(true, key, *data);
+ storage_->Put(key, data);
+ data = NULL; // Deleted by Storage::Put().
+ } else if (!stale_data_.empty()) {
+ // Reuse the stale data if a download fails. It's better to have slightly
+ // outdated validation rules than to suddenly lose validation ability.
+ retrieved_(true, key, stale_data_);
+ } else {
+ retrieved_(false, key, std::string());
+ }
+ delete data;
+ delete this;
+ }
+
+ const Retriever::Callback& retrieved_;
+ const Source& source_;
+ ValidatingStorage* storage_;
+ const scoped_ptr<const Source::Callback> fresh_data_ready_;
+ const scoped_ptr<const Storage::Callback> validated_data_ready_;
+ std::string stale_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(Helper);
+};
+
+} // namespace
+
+Retriever::Retriever(const Source* source, Storage* storage)
+ : source_(source), storage_(new ValidatingStorage(storage)) {
+ assert(source_ != NULL);
+ assert(storage_ != NULL);
+}
+
+Retriever::~Retriever() {}
+
+void Retriever::Retrieve(const std::string& key,
+ const Callback& retrieved) const {
+ new Helper(key, retrieved, *source_, storage_.get());
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/retriever.h b/chromium/third_party/libaddressinput/src/cpp/src/retriever.h
new file mode 100644
index 00000000000..4bf27a5d06c
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/retriever.h
@@ -0,0 +1,68 @@
+// 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.
+//
+// An object to retrieve data.
+
+#ifndef I18N_ADDRESSINPUT_RETRIEVER_H_
+#define I18N_ADDRESSINPUT_RETRIEVER_H_
+
+#include <libaddressinput/callback.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class Source;
+class Storage;
+class ValidatingStorage;
+
+// Retrieves data. Sample usage:
+// Source* source = ...;
+// Storage* storage = ...;
+// Retriever retriever(source, storage);
+// const scoped_ptr<const Retriever::Callback> retrieved(
+// BuildCallback(this, &MyClass::OnDataRetrieved));
+// retriever.Retrieve("data/CA/AB--fr", *retrieved);
+class Retriever {
+ public:
+ typedef i18n::addressinput::Callback<const std::string&,
+ const std::string&> Callback;
+
+ // Takes ownership of |source| and |storage|.
+ Retriever(const Source* source, Storage* storage);
+ ~Retriever();
+
+ // Retrieves the data for |key| and invokes the |retrieved| callback. Checks
+ // for the data in |storage_| first. If storage does not have the data for
+ // |key|, then gets the data from |source_| and places it in storage. If the
+ // data in storage is corrupted, then it's discarded and requested anew. If
+ // the data is stale, then it's requested anew. If the request fails, then
+ // stale data will be returned this one time. Any subsequent call to
+ // Retrieve() will attempt to get fresh data again.
+ void Retrieve(const std::string& key, const Callback& retrieved) const;
+
+ private:
+ scoped_ptr<const Source> source_;
+ scoped_ptr<ValidatingStorage> storage_;
+
+ DISALLOW_COPY_AND_ASSIGN(Retriever);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_RETRIEVER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/rule.cc b/chromium/third_party/libaddressinput/src/cpp/src/rule.cc
new file mode 100644
index 00000000000..c3d2c22dd88
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/rule.cc
@@ -0,0 +1,306 @@
+// 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 "rule.h"
+
+#include <cassert>
+#include <cstddef>
+#include <map>
+#include <string>
+#include <utility>
+
+#include <re2/re2.h>
+
+#include "address_field_util.h"
+#include "format_element.h"
+#include "grit.h"
+#include "messages.h"
+#include "region_data_constants.h"
+#include "util/json.h"
+#include "util/re2ptr.h"
+#include "util/string_split.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+typedef std::map<std::string, int> NameMessageIdMap;
+
+// Used as a separator in a list of items. For example, the list of supported
+// languages can be "de~fr~it".
+const char kSeparator = '~';
+
+NameMessageIdMap InitAdminAreaMessageIds() {
+ NameMessageIdMap message_ids;
+ message_ids.insert(std::make_pair(
+ "area", IDS_LIBADDRESSINPUT_AREA));
+ message_ids.insert(std::make_pair(
+ "county", IDS_LIBADDRESSINPUT_COUNTY));
+ message_ids.insert(std::make_pair(
+ "department", IDS_LIBADDRESSINPUT_DEPARTMENT));
+ message_ids.insert(std::make_pair(
+ "district", IDS_LIBADDRESSINPUT_DISTRICT));
+ message_ids.insert(std::make_pair(
+ "do_si", IDS_LIBADDRESSINPUT_DO_SI));
+ message_ids.insert(std::make_pair(
+ "emirate", IDS_LIBADDRESSINPUT_EMIRATE));
+ message_ids.insert(std::make_pair(
+ "island", IDS_LIBADDRESSINPUT_ISLAND));
+ message_ids.insert(std::make_pair(
+ "oblast", IDS_LIBADDRESSINPUT_OBLAST));
+ message_ids.insert(std::make_pair(
+ "parish", IDS_LIBADDRESSINPUT_PARISH));
+ message_ids.insert(std::make_pair(
+ "prefecture", IDS_LIBADDRESSINPUT_PREFECTURE));
+ message_ids.insert(std::make_pair(
+ "province", IDS_LIBADDRESSINPUT_PROVINCE));
+ message_ids.insert(std::make_pair(
+ "state", IDS_LIBADDRESSINPUT_STATE));
+ return message_ids;
+}
+
+const NameMessageIdMap& GetAdminAreaMessageIds() {
+ static const NameMessageIdMap kAdminAreaMessageIds(InitAdminAreaMessageIds());
+ return kAdminAreaMessageIds;
+}
+
+NameMessageIdMap InitPostalCodeMessageIds() {
+ NameMessageIdMap message_ids;
+ message_ids.insert(std::make_pair(
+ "pin", IDS_LIBADDRESSINPUT_PIN_CODE_LABEL));
+ message_ids.insert(std::make_pair(
+ "postal", IDS_LIBADDRESSINPUT_POSTAL_CODE_LABEL));
+ message_ids.insert(std::make_pair(
+ "zip", IDS_LIBADDRESSINPUT_ZIP_CODE_LABEL));
+ return message_ids;
+}
+
+const NameMessageIdMap& GetPostalCodeMessageIds() {
+ static const NameMessageIdMap kPostalCodeMessageIds(
+ InitPostalCodeMessageIds());
+ return kPostalCodeMessageIds;
+}
+
+NameMessageIdMap InitLocalityMessageIds() {
+ NameMessageIdMap message_ids;
+ message_ids.insert(std::make_pair(
+ "city", IDS_LIBADDRESSINPUT_LOCALITY_LABEL));
+ message_ids.insert(std::make_pair(
+ "post_town", IDS_LIBADDRESSINPUT_POST_TOWN));
+ message_ids.insert(std::make_pair(
+ "district", IDS_LIBADDRESSINPUT_DISTRICT));
+ return message_ids;
+}
+
+const NameMessageIdMap& GetLocalityMessageIds() {
+ static const NameMessageIdMap kLocalityMessageIds(
+ InitLocalityMessageIds());
+ return kLocalityMessageIds;
+}
+
+NameMessageIdMap InitSublocalityMessageIds() {
+ NameMessageIdMap message_ids;
+ message_ids.insert(std::make_pair(
+ "suburb", IDS_LIBADDRESSINPUT_SUBURB));
+ message_ids.insert(std::make_pair(
+ "district", IDS_LIBADDRESSINPUT_DISTRICT));
+ message_ids.insert(std::make_pair(
+ "neighborhood", IDS_LIBADDRESSINPUT_NEIGHBORHOOD));
+ message_ids.insert(std::make_pair(
+ "village_township", IDS_LIBADDRESSINPUT_VILLAGE_TOWNSHIP));
+ return message_ids;
+}
+
+const NameMessageIdMap& GetSublocalityMessageIds() {
+ static const NameMessageIdMap kSublocalityMessageIds(
+ InitSublocalityMessageIds());
+ return kSublocalityMessageIds;
+}
+
+int GetMessageIdFromName(const std::string& name,
+ const NameMessageIdMap& message_ids) {
+ NameMessageIdMap::const_iterator it = message_ids.find(name);
+ return it != message_ids.end() ? it->second : INVALID_MESSAGE_ID;
+}
+
+// Determines whether a given string is a reg-exp or a string. We consider a
+// string to be anything that doesn't contain characters with special meanings
+// in regular expressions - (, [, \, {, ?. These special characters are all the
+// ones that appear in the postal code regular expressions.
+bool ContainsRegExSpecialCharacters(const std::string& input) {
+ return input.find_first_of("([\\{?") != std::string::npos;
+}
+
+} // namespace
+
+Rule::Rule()
+ : id_(),
+ format_(),
+ latin_format_(),
+ required_(),
+ sub_keys_(),
+ languages_(),
+ postal_code_matcher_(NULL),
+ sole_postal_code_(),
+ admin_area_name_message_id_(INVALID_MESSAGE_ID),
+ postal_code_name_message_id_(INVALID_MESSAGE_ID),
+ locality_name_message_id_(INVALID_MESSAGE_ID),
+ sublocality_name_message_id_(INVALID_MESSAGE_ID),
+ name_(),
+ latin_name_(),
+ postal_code_example_(),
+ post_service_url_() {}
+
+Rule::~Rule() {}
+
+// static
+const Rule& Rule::GetDefault() {
+ // Allocated once and leaked on shutdown.
+ static Rule* default_rule = NULL;
+ if (default_rule == NULL) {
+ default_rule = new Rule;
+ default_rule->ParseSerializedRule(
+ RegionDataConstants::GetDefaultRegionData());
+ }
+ return *default_rule;
+}
+
+void Rule::CopyFrom(const Rule& rule) {
+ assert(this != &rule);
+ id_ = rule.id_;
+ format_ = rule.format_;
+ latin_format_ = rule.latin_format_;
+ required_ = rule.required_;
+ sub_keys_ = rule.sub_keys_;
+ languages_ = rule.languages_;
+ postal_code_matcher_.reset(
+ rule.postal_code_matcher_ == NULL
+ ? NULL
+ : new RE2ptr(new RE2(rule.postal_code_matcher_->ptr->pattern(),
+ rule.postal_code_matcher_->ptr->options())));
+ sole_postal_code_ = rule.sole_postal_code_;
+ admin_area_name_message_id_ = rule.admin_area_name_message_id_;
+ postal_code_name_message_id_ = rule.postal_code_name_message_id_;
+ locality_name_message_id_ = rule.locality_name_message_id_;
+ sublocality_name_message_id_ = rule.sublocality_name_message_id_;
+ name_ = rule.name_;
+ latin_name_ = rule.latin_name_;
+ postal_code_example_ = rule.postal_code_example_;
+ post_service_url_ = rule.post_service_url_;
+}
+
+bool Rule::ParseSerializedRule(const std::string& serialized_rule) {
+ Json json;
+ if (!json.ParseObject(serialized_rule)) {
+ return false;
+ }
+ ParseJsonRule(json);
+ return true;
+}
+
+void Rule::ParseJsonRule(const Json& json) {
+ std::string value;
+ if (json.GetStringValueForKey("id", &value)) {
+ id_.swap(value);
+ }
+
+ if (json.GetStringValueForKey("fmt", &value)) {
+ ParseFormatRule(value, &format_);
+ }
+
+ if (json.GetStringValueForKey("lfmt", &value)) {
+ ParseFormatRule(value, &latin_format_);
+ }
+
+ if (json.GetStringValueForKey("require", &value)) {
+ ParseAddressFieldsRequired(value, &required_);
+ }
+
+ if (json.GetStringValueForKey("sub_keys", &value)) {
+ SplitString(value, kSeparator, &sub_keys_);
+ }
+
+ if (json.GetStringValueForKey("languages", &value)) {
+ SplitString(value, kSeparator, &languages_);
+ }
+
+ sole_postal_code_.clear();
+ if (json.GetStringValueForKey("zip", &value)) {
+ // The "zip" field in the JSON data is used in two different ways to
+ // validate the postal code. At the country level, the "zip" field indicates
+ // a Java compatible regular expression corresponding to all postal codes in
+ // the country. At other levels, the regular expression indicates the postal
+ // code prefix expected for addresses in that region.
+ //
+ // In order to make the RE2 object created from the "zip" field useable for
+ // both these purposes, the pattern string is here prefixed with "^" to
+ // anchor it at the beginning of the string so that it can be used with
+ // RE2::PartialMatch() to perform prefix matching or else with
+ // RE2::FullMatch() to perform matching against the entire string.
+ RE2::Options options;
+ options.set_never_capture(true);
+ RE2* matcher = new RE2("^(" + value + ")", options);
+ if (matcher->ok()) {
+ postal_code_matcher_.reset(new RE2ptr(matcher));
+ } else {
+ postal_code_matcher_.reset(NULL);
+ delete matcher;
+ }
+ // If the "zip" field is not a regular expression, then it is the sole
+ // postal code for this rule.
+ if (!ContainsRegExSpecialCharacters(value)) {
+ sole_postal_code_.swap(value);
+ }
+ }
+
+ if (json.GetStringValueForKey("state_name_type", &value)) {
+ admin_area_name_message_id_ =
+ GetMessageIdFromName(value, GetAdminAreaMessageIds());
+ }
+
+ if (json.GetStringValueForKey("zip_name_type", &value)) {
+ postal_code_name_message_id_ =
+ GetMessageIdFromName(value, GetPostalCodeMessageIds());
+ }
+
+ if (json.GetStringValueForKey("locality_name_type", &value)) {
+ locality_name_message_id_ =
+ GetMessageIdFromName(value, GetLocalityMessageIds());
+ }
+
+ if (json.GetStringValueForKey("sublocality_name_type", &value)) {
+ sublocality_name_message_id_ =
+ GetMessageIdFromName(value, GetSublocalityMessageIds());
+ }
+
+ if (json.GetStringValueForKey("name", &value)) {
+ name_.swap(value);
+ }
+
+ if (json.GetStringValueForKey("lname", &value)) {
+ latin_name_.swap(value);
+ }
+
+ if (json.GetStringValueForKey("zipex", &value)) {
+ postal_code_example_.swap(value);
+ }
+
+ if (json.GetStringValueForKey("posturl", &value)) {
+ post_service_url_.swap(value);
+ }
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/rule.h b/chromium/third_party/libaddressinput/src/cpp/src/rule.h
new file mode 100644
index 00000000000..87948df4264
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/rule.h
@@ -0,0 +1,165 @@
+// 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.
+//
+// An object to store address metadata, describing the addressing rules for
+// regions and sub-regions. The address metadata format is documented here:
+//
+// https://github.com/googlei18n/libaddressinput/wiki/AddressValidationMetadata
+
+#ifndef I18N_ADDRESSINPUT_RULE_H_
+#define I18N_ADDRESSINPUT_RULE_H_
+
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+class FormatElement;
+class Json;
+struct RE2ptr;
+
+// Stores address metadata addressing rules, to be used for determining the
+// layout of an address input widget or for address validation. Sample usage:
+// Rule rule;
+// if (rule.ParseSerializedRule("{\"fmt\": \"%A%n%C%S %Z\"}")) {
+// Process(rule.GetFormat());
+// }
+class Rule {
+ public:
+ Rule();
+ ~Rule();
+
+ // Returns the default rule at a country level. If a country does not specify
+ // address format, for example, then the format from this rule should be used
+ // instead.
+ static const Rule& GetDefault();
+
+ // Copies all data from |rule|.
+ void CopyFrom(const Rule& rule);
+
+ // Parses |serialized_rule|. Returns |true| if the |serialized_rule| has valid
+ // format (JSON dictionary).
+ bool ParseSerializedRule(const std::string& serialized_rule);
+
+ // Reads data from |json|, which must already have parsed a serialized rule.
+ void ParseJsonRule(const Json& json);
+
+ // Returns the ID string for this rule.
+ const std::string& GetId() const { return id_; }
+
+ // Returns the format elements for this rule. The format can include the
+ // relevant address fields, but also strings used for formatting, or newline
+ // information.
+ const std::vector<FormatElement>& GetFormat() const { return format_; }
+
+ // Returns the approximate address format with the Latin order of fields. The
+ // format can include the relevant address fields, but also strings used for
+ // formatting, or newline information.
+ const std::vector<FormatElement>& GetLatinFormat() const {
+ return latin_format_;
+ }
+
+ // Returns the required fields for this rule.
+ const std::vector<AddressField>& GetRequired() const { return required_; }
+
+ // Returns the sub-keys for this rule, which are the administrative areas of a
+ // country, the localities of an administrative area, or the dependent
+ // localities of a locality. For example, the rules for "US" have sub-keys of
+ // "CA", "NY", "TX", etc.
+ const std::vector<std::string>& GetSubKeys() const { return sub_keys_; }
+
+ // Returns all of the language tags supported by this rule, for example ["de",
+ // "fr", "it"].
+ const std::vector<std::string>& GetLanguages() const { return languages_; }
+
+ // Returns a pointer to a RE2 regular expression object created from the
+ // postal code format string, if specified, or NULL otherwise. The regular
+ // expression is anchored to the beginning of the string so that it can be
+ // used either with RE2::PartialMatch() to perform prefix matching or else
+ // with RE2::FullMatch() to perform matching against the entire string.
+ const RE2ptr* GetPostalCodeMatcher() const {
+ return postal_code_matcher_.get();
+ }
+
+ // Returns the sole postal code for this rule, if there is one.
+ const std::string& GetSolePostalCode() const { return sole_postal_code_; }
+
+ // The message string identifier for admin area name. If not set, then
+ // INVALID_MESSAGE_ID.
+ int GetAdminAreaNameMessageId() const { return admin_area_name_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 message string identifier for locality name. If not set, then
+ // INVALID_MESSAGE_ID.
+ int GetLocalityNameMessageId() const {
+ return locality_name_message_id_;
+ }
+
+ // The message string identifier for sublocality name. If not set, then
+ // INVALID_MESSAGE_ID.
+ int GetSublocalityNameMessageId() const {
+ return sublocality_name_message_id_;
+ }
+
+ // Returns the name for the most specific place described by this rule, if
+ // there is one. This is typically set when it differs from the key.
+ const std::string& GetName() const { return name_; }
+
+ // Returns the Latin-script name for the most specific place described by this
+ // rule, if there is one.
+ const std::string& GetLatinName() const { return latin_name_; }
+
+ // Returns the postal code example string for this rule.
+ const std::string& GetPostalCodeExample() const {
+ return postal_code_example_;
+ }
+
+ // Returns the post service URL string for this rule.
+ const std::string& GetPostServiceUrl() const { return post_service_url_; }
+
+ private:
+ std::string id_;
+ std::vector<FormatElement> format_;
+ std::vector<FormatElement> latin_format_;
+ std::vector<AddressField> required_;
+ std::vector<std::string> sub_keys_;
+ std::vector<std::string> languages_;
+ scoped_ptr<const RE2ptr> postal_code_matcher_;
+ std::string sole_postal_code_;
+ int admin_area_name_message_id_;
+ int postal_code_name_message_id_;
+ int locality_name_message_id_;
+ int sublocality_name_message_id_;
+ std::string name_;
+ std::string latin_name_;
+ std::string postal_code_example_;
+ std::string post_service_url_;
+
+ DISALLOW_COPY_AND_ASSIGN(Rule);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_RULE_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/rule_retriever.cc b/chromium/third_party/libaddressinput/src/cpp/src/rule_retriever.cc
new file mode 100644
index 00000000000..f0ed848a807
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/rule_retriever.cc
@@ -0,0 +1,80 @@
+// 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 "rule_retriever.h"
+
+#include <libaddressinput/callback.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+
+#include "retriever.h"
+#include "rule.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+class Helper {
+ public:
+ Helper(const std::string& key,
+ const RuleRetriever::Callback& rule_ready,
+ const Retriever& data_retriever)
+ : rule_ready_(rule_ready),
+ data_retrieved_(BuildCallback(this, &Helper::OnDataRetrieved)) {
+ data_retriever.Retrieve(key, *data_retrieved_);
+ }
+
+ private:
+ ~Helper() {}
+
+ void OnDataRetrieved(bool success,
+ const std::string& key,
+ const std::string& data) {
+ Rule rule;
+ if (!success) {
+ rule_ready_(false, key, rule);
+ } else {
+ success = rule.ParseSerializedRule(data);
+ rule_ready_(success, key, rule);
+ }
+ delete this;
+ }
+
+ const RuleRetriever::Callback& rule_ready_;
+ const scoped_ptr<const Retriever::Callback> data_retrieved_;
+
+ DISALLOW_COPY_AND_ASSIGN(Helper);
+};
+
+} // namespace
+
+RuleRetriever::RuleRetriever(const Retriever* retriever)
+ : data_retriever_(retriever) {
+ assert(data_retriever_ != NULL);
+}
+
+RuleRetriever::~RuleRetriever() {}
+
+void RuleRetriever::RetrieveRule(const std::string& key,
+ const Callback& rule_ready) const {
+ new Helper(key, rule_ready, *data_retriever_);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/rule_retriever.h b/chromium/third_party/libaddressinput/src/cpp/src/rule_retriever.h
new file mode 100644
index 00000000000..ae4b5ee97d2
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/rule_retriever.h
@@ -0,0 +1,59 @@
+// 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.
+//
+// An object to retrieve validation rules.
+
+#ifndef I18N_ADDRESSINPUT_RULE_RETRIEVER_H_
+#define I18N_ADDRESSINPUT_RULE_RETRIEVER_H_
+
+#include <libaddressinput/callback.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class Retriever;
+class Rule;
+
+// Retrieves validation rules. Sample usage:
+// const Retriever* retriever = ...
+// RuleRetriever rules(retriever);
+// const scoped_ptr<const RuleRetriever::Callback> rule_ready(
+// BuildCallback(this, &MyClass::OnRuleReady));
+// rules.RetrieveRule("data/CA/AB--fr", *rule_ready);
+class RuleRetriever {
+ public:
+ typedef i18n::addressinput::Callback<const std::string&,
+ const Rule&> Callback;
+
+ // Takes ownership of |retriever|.
+ explicit RuleRetriever(const Retriever* retriever);
+ ~RuleRetriever();
+
+ // Retrieves the rule for |key| and invokes the |rule_ready| callback.
+ void RetrieveRule(const std::string& key, const Callback& rule_ready) const;
+
+ private:
+ scoped_ptr<const Retriever> data_retriever_;
+
+ DISALLOW_COPY_AND_ASSIGN(RuleRetriever);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_RULE_RETRIEVER_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/cctype_tolower_equal.cc b/chromium/third_party/libaddressinput/src/cpp/src/util/cctype_tolower_equal.cc
new file mode 100644
index 00000000000..819138f6170
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/cctype_tolower_equal.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2014 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 "cctype_tolower_equal.h"
+
+#include <algorithm>
+#include <cctype>
+#include <functional>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+struct EqualToTolowerChar
+ : public std::binary_function<std::string::value_type,
+ std::string::value_type, bool> {
+ result_type operator()(first_argument_type a, second_argument_type b) const {
+ return std::tolower(a) == std::tolower(b);
+ }
+};
+
+} // namespace
+
+EqualToTolowerString::result_type EqualToTolowerString::operator()(
+ const first_argument_type& a, const second_argument_type& b) const {
+ return a.size() == b.size() &&
+ std::equal(a.begin(), a.end(), b.begin(), EqualToTolowerChar());
+}
+
+} // addressinput
+} // i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/cctype_tolower_equal.h b/chromium/third_party/libaddressinput/src/cpp/src/util/cctype_tolower_equal.h
new file mode 100644
index 00000000000..106087e8c44
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/cctype_tolower_equal.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_UTIL_CCTYPE_TOLOWER_EQUAL_H_
+#define I18N_ADDRESSINPUT_UTIL_CCTYPE_TOLOWER_EQUAL_H_
+
+#include <functional>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+// Performs case insensitive comparison of |a| and |b| by calling std::tolower()
+// from <cctype>.
+struct EqualToTolowerString
+ : public std::binary_function<std::string, std::string, bool> {
+ result_type operator()(const first_argument_type& a,
+ const second_argument_type& b) const;
+};
+
+} // addressinput
+} // i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_CCTYPE_TOLOWER_EQUAL_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/json.cc b/chromium/third_party/libaddressinput/src/cpp/src/util/json.cc
new file mode 100644
index 00000000000..9d30b664332
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/json.cc
@@ -0,0 +1,133 @@
+// 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 "json.h"
+
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include <rapidjson/document.h>
+#include <rapidjson/reader.h>
+
+namespace i18n {
+namespace addressinput {
+
+using rapidjson::Document;
+using rapidjson::kParseValidateEncodingFlag;
+using rapidjson::Value;
+
+class Json::JsonImpl {
+ public:
+ explicit JsonImpl(const std::string& json)
+ : document_(new Document),
+ value_(document_.get()),
+ dictionaries_(),
+ valid_(false) {
+ document_->Parse<kParseValidateEncodingFlag>(json.c_str());
+ valid_ = !document_->HasParseError() && document_->IsObject();
+ }
+
+ ~JsonImpl() {
+ for (std::vector<const Json*>::const_iterator it = dictionaries_.begin();
+ it != dictionaries_.end(); ++it) {
+ delete *it;
+ }
+ }
+
+ bool valid() const { return valid_; }
+
+ const std::vector<const Json*>& GetSubDictionaries() {
+ if (dictionaries_.empty()) {
+ for (Value::ConstMemberIterator member = value_->MemberBegin();
+ member != value_->MemberEnd(); ++member) {
+ if (member->value.IsObject()) {
+ dictionaries_.push_back(new Json(new JsonImpl(&member->value)));
+ }
+ }
+ }
+ return dictionaries_;
+ }
+
+ bool GetStringValueForKey(const std::string& key, std::string* value) const {
+ assert(value != NULL);
+
+ Value::ConstMemberIterator member = value_->FindMember(key.c_str());
+ if (member == value_->MemberEnd() || !member->value.IsString()) {
+ return false;
+ }
+
+ value->assign(member->value.GetString(),
+ member->value.GetStringLength());
+ return true;
+ }
+
+ private:
+ // Does not take ownership of |value|.
+ explicit JsonImpl(const Value* value)
+ : document_(),
+ value_(value),
+ dictionaries_(),
+ valid_(true) {
+ assert(value_ != NULL);
+ assert(value_->IsObject());
+ }
+
+ // An owned JSON document. Can be NULL if the JSON document is not owned.
+ const scoped_ptr<Document> document_;
+
+ // A JSON document that is not owned. Cannot be NULL. Can point to document_.
+ const Value* const value_;
+
+ // Owned JSON objects of sub-dictionaries.
+ std::vector<const Json*> dictionaries_;
+
+ // True if the JSON object was parsed successfully.
+ bool valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(JsonImpl);
+};
+
+Json::Json() : impl_() {}
+
+Json::~Json() {}
+
+bool Json::ParseObject(const std::string& json) {
+ assert(impl_ == NULL);
+ impl_.reset(new JsonImpl(json));
+ if (!impl_->valid()) {
+ impl_.reset();
+ }
+ return impl_ != NULL;
+}
+
+const std::vector<const Json*>& Json::GetSubDictionaries() const {
+ assert(impl_ != NULL);
+ return impl_->GetSubDictionaries();
+}
+
+bool Json::GetStringValueForKey(const std::string& key,
+ std::string* value) const {
+ assert(impl_ != NULL);
+ return impl_->GetStringValueForKey(key, value);
+}
+
+Json::Json(JsonImpl* impl) : impl_(impl) {}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/json.h b/chromium/third_party/libaddressinput/src/cpp/src/util/json.h
new file mode 100644
index 00000000000..1aac803c1fd
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/json.h
@@ -0,0 +1,68 @@
+// 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.
+
+#ifndef I18N_ADDRESSINPUT_UTIL_JSON_H_
+#define I18N_ADDRESSINPUT_UTIL_JSON_H_
+
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+// Parses a JSON dictionary of strings. Sample usage:
+// Json json;
+// if (json.ParseObject("{'key1':'value1', 'key2':'value2'}") &&
+// json.HasStringKey("key1")) {
+// Process(json.GetStringValueForKey("key1"));
+// }
+class Json {
+ public:
+ Json();
+ ~Json();
+
+ // Parses the |json| string and returns true if |json| is valid and it is an
+ // object.
+ bool ParseObject(const std::string& json);
+
+ // Returns the list of sub dictionaries. The JSON object must be parsed
+ // successfully in ParseObject() before invoking this method. The caller does
+ // not own the result.
+ const std::vector<const Json*>& GetSubDictionaries() const;
+
+ // Returns true if the parsed JSON contains a string value for |key|. Sets
+ // |value| to the string value of the |key|. The JSON object must be parsed
+ // successfully in ParseObject() before invoking this method. The |value|
+ // parameter should not be NULL.
+ bool GetStringValueForKey(const std::string& key, std::string* value) const;
+
+ private:
+ class JsonImpl;
+ friend class JsonImpl;
+
+ // Constructor to be called by JsonImpl.
+ explicit Json(JsonImpl* impl);
+
+ scoped_ptr<JsonImpl> impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(Json);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_JSON_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/lru_cache_using_std.h b/chromium/third_party/libaddressinput/src/cpp/src/util/lru_cache_using_std.h
new file mode 100644
index 00000000000..6062d284e6d
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/lru_cache_using_std.h
@@ -0,0 +1,170 @@
+/******************************************************************************/
+/* Copyright (c) 2010-2011, Tim Day <timday@timday.com> */
+/* */
+/* Permission to use, copy, modify, and/or distribute this software for any */
+/* purpose with or without fee is hereby granted, provided that the above */
+/* copyright notice and this permission notice appear in all copies. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES */
+/* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF */
+/* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR */
+/* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
+/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN */
+/* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF */
+/* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+/******************************************************************************/
+
+// The original source code is from:
+// https://bitbucket.org/timday/lru_cache/src/497822a492a8/include/lru_cache_using_std.h
+
+#ifndef I18N_ADDRESSINPUT_UTIL_LRU_CACHE_USING_STD_H_
+#define I18N_ADDRESSINPUT_UTIL_LRU_CACHE_USING_STD_H_
+
+#include <cassert>
+#include <cstddef>
+#include <list>
+#include <map>
+#include <utility>
+
+// Class providing fixed-size (by number of records)
+// LRU-replacement cache of a function with signature
+// V f(K).
+// The default comparator/hash/allocator will be used.
+template <
+ typename K,
+ typename V
+ > class lru_cache_using_std
+{
+public:
+
+ typedef K key_type;
+ typedef V value_type;
+
+ // Key access history, most recent at back
+ typedef std::list<key_type> key_tracker_type;
+
+ // Key to value and key history iterator
+ typedef std::map<
+ key_type,
+ std::pair<
+ value_type,
+ typename key_tracker_type::iterator
+ >
+ > key_to_value_type;
+
+ // Constuctor specifies the cached function and
+ // the maximum number of records to be stored
+ lru_cache_using_std(
+ value_type (*f)(const key_type&),
+ size_t c
+ )
+ :_fn(f)
+ ,_capacity(c)
+ {
+ assert(_capacity!=0);
+ }
+
+ // Obtain value of the cached function for k
+ value_type operator()(const key_type& k) {
+
+ // Attempt to find existing record
+ const typename key_to_value_type::iterator it
+ =_key_to_value.find(k);
+
+ if (it==_key_to_value.end()) {
+
+ // We don't have it:
+
+ // Evaluate function and create new record
+ const value_type v=_fn(k);
+ insert(k,v);
+
+ // Return the freshly computed value
+ return v;
+
+ } else {
+
+ // We do have it:
+
+ // Update access record by moving
+ // accessed key to back of list
+ _key_tracker.splice(
+ _key_tracker.end(),
+ _key_tracker,
+ (*it).second.second
+ );
+
+ // Return the retrieved value
+ return (*it).second.first;
+ }
+ }
+
+ // Obtain the cached keys, most recently used element
+ // at head, least recently used at tail.
+ // This method is provided purely to support testing.
+ template <typename IT> void get_keys(IT dst) const {
+ typename key_tracker_type::const_reverse_iterator src
+ =_key_tracker.rbegin();
+ while (src!=_key_tracker.rend()) {
+ *dst++ = *src++;
+ }
+ }
+
+private:
+
+ // Record a fresh key-value pair in the cache
+ void insert(const key_type& k,const value_type& v) {
+
+ // Method is only called on cache misses
+ assert(_key_to_value.find(k)==_key_to_value.end());
+
+ // Make space if necessary
+ if (_key_to_value.size()==_capacity)
+ evict();
+
+ // Record k as most-recently-used key
+ typename key_tracker_type::iterator it
+ =_key_tracker.insert(_key_tracker.end(),k);
+
+ // Create the key-value entry,
+ // linked to the usage record.
+ _key_to_value.insert(
+ std::make_pair(
+ k,
+ std::make_pair(v,it)
+ )
+ );
+ // No need to check return,
+ // given previous assert.
+ }
+
+ // Purge the least-recently-used element in the cache
+ void evict() {
+
+ // Assert method is never called when cache is empty
+ assert(!_key_tracker.empty());
+
+ // Identify least recently used key
+ const typename key_to_value_type::iterator it
+ =_key_to_value.find(_key_tracker.front());
+ assert(it!=_key_to_value.end());
+
+ // Erase both elements to completely purge record
+ _key_to_value.erase(it);
+ _key_tracker.pop_front();
+ }
+
+ // The function to be cached
+ value_type (*_fn)(const key_type&);
+
+ // Maximum number of key-value pairs to be retained
+ const size_t _capacity;
+
+ // Key access history
+ key_tracker_type _key_tracker;
+
+ // Key-to-value lookup
+ key_to_value_type _key_to_value;
+};
+
+#endif // I18N_ADDRESSINPUT_UTIL_LRU_CACHE_USING_STD_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/md5.cc b/chromium/third_party/libaddressinput/src/cpp/src/util/md5.cc
new file mode 100644
index 00000000000..ea7561be606
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/md5.cc
@@ -0,0 +1,301 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The original source code is from:
+// http://src.chromium.org/viewvc/chrome/trunk/src/base/md5.cc?revision=94203
+
+// The original file was copied from sqlite, and was in the public domain.
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "md5.h"
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <cstddef>
+#include <string>
+#include <string.h>
+
+namespace {
+
+struct Context {
+ uint32 buf[4];
+ uint32 bits[2];
+ unsigned char in[64];
+};
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+void byteReverse(unsigned char *buf, unsigned longs) {
+ uint32 t;
+ do {
+ t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
+ ((unsigned)buf[1]<<8 | buf[0]);
+ *(uint32 *)buf = t;
+ buf += 4;
+ } while (--longs);
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform(uint32 buf[4], const uint32 in[16]) {
+ register uint32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+} // namespace
+
+namespace i18n {
+namespace addressinput {
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(MD5Context* context) {
+ struct Context *ctx = (struct Context *)context;
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(MD5Context* context, const std::string& data) {
+ const unsigned char* inbuf = (const unsigned char*)data.data();
+ size_t len = data.size();
+ struct Context *ctx = (struct Context *)context;
+ const unsigned char* buf = (const unsigned char*)inbuf;
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += static_cast<uint32>(len >> 29);
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *)ctx->in + t;
+
+ t = 64-t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32 *)ctx->in);
+ buf += t;
+ len -= t;
+ }
+
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32 *)ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(MD5Digest* digest, MD5Context* context) {
+ struct Context *ctx = (struct Context *)context;
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32 *)ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count-8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
+ ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
+
+ MD5Transform(ctx->buf, (uint32 *)ctx->in);
+ byteReverse((unsigned char *)ctx->buf, 4);
+ memcpy(digest->a, ctx->buf, 16);
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
+}
+
+std::string MD5DigestToBase16(const MD5Digest& digest) {
+ static char const zEncode[] = "0123456789abcdef";
+
+ std::string ret;
+ ret.resize(32);
+
+ int j = 0;
+ for (int i = 0; i < 16; i ++) {
+ int a = digest.a[i];
+ ret[j++] = zEncode[(a>>4)&0xf];
+ ret[j++] = zEncode[a & 0xf];
+ }
+ return ret;
+}
+
+void MD5Sum(const void* data, size_t length, MD5Digest* digest) {
+ MD5Context ctx;
+ MD5Init(&ctx);
+ MD5Update(&ctx,
+ std::string(reinterpret_cast<const char*>(data), length));
+ MD5Final(digest, &ctx);
+}
+
+std::string MD5String(const std::string& str) {
+ MD5Digest digest;
+ MD5Sum(str.data(), str.length(), &digest);
+ return MD5DigestToBase16(digest);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/md5.h b/chromium/third_party/libaddressinput/src/cpp/src/util/md5.h
new file mode 100644
index 00000000000..98bc3254fbc
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/md5.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The original source code is from:
+// http://src.chromium.org/viewvc/chrome/trunk/src/base/md5.h?revision=94203
+
+#ifndef I18N_ADDRESSINPUT_UTIL_MD5_H_
+#define I18N_ADDRESSINPUT_UTIL_MD5_H_
+
+#include <cstddef>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+// MD5 stands for Message Digest algorithm 5.
+// MD5 is a robust hash function, designed for cyptography, but often used
+// for file checksums. The code is complex and slow, but has few
+// collisions.
+// See Also:
+// http://en.wikipedia.org/wiki/MD5
+
+// These functions perform MD5 operations. The simplest call is MD5Sum() to
+// generate the MD5 sum of the given data.
+//
+// You can also compute the MD5 sum of data incrementally by making multiple
+// calls to MD5Update():
+// MD5Context ctx; // intermediate MD5 data: do not use
+// MD5Init(&ctx);
+// MD5Update(&ctx, data1, length1);
+// MD5Update(&ctx, data2, length2);
+// ...
+//
+// MD5Digest digest; // the result of the computation
+// MD5Final(&digest, &ctx);
+//
+// You can call MD5DigestToBase16() to generate a string of the digest.
+
+// The output of an MD5 operation.
+struct MD5Digest {
+ unsigned char a[16];
+};
+
+// Used for storing intermediate data during an MD5 computation. Callers
+// should not access the data.
+typedef char MD5Context[88];
+
+// Computes the MD5 sum of the given data buffer with the given length.
+// The given 'digest' structure will be filled with the result data.
+void MD5Sum(const void* data, size_t length, MD5Digest* digest);
+
+// Initializes the given MD5 context structure for subsequent calls to
+// MD5Update().
+void MD5Init(MD5Context* context);
+
+// For the given buffer of |data| as a StringPiece, updates the given MD5
+// context with the sum of the data. You can call this any number of times
+// during the computation, except that MD5Init() must have been called first.
+void MD5Update(MD5Context* context, const std::string& data);
+
+// Finalizes the MD5 operation and fills the buffer with the digest.
+void MD5Final(MD5Digest* digest, MD5Context* context);
+
+// Converts a digest into human-readable hexadecimal.
+std::string MD5DigestToBase16(const MD5Digest& digest);
+
+// Returns the MD5 (in hexadecimal) of a string.
+std::string MD5String(const std::string& str);
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_MD5_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/re2ptr.h b/chromium/third_party/libaddressinput/src/cpp/src/util/re2ptr.h
new file mode 100644
index 00000000000..e04bcfd85cf
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/re2ptr.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2014 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.
+//
+// Work-around for problems with the RE2 library. Must be the first #include
+// statement in the compilation unit. Do not #include in other header files.
+
+#ifndef I18N_ADDRESSINPUT_UTIL_RE2PTR_H_
+#define I18N_ADDRESSINPUT_UTIL_RE2PTR_H_
+
+// RE2 will, in some environments, define class RE2 inside namespace re2 and
+// then have a public "using re2::RE2;" statement to bring that definition into
+// the root namespace, while in other environments it will define class RE2
+// directly in the root namespace.
+//
+// Because of that, it's impossible to write a portable forward declaration of
+// class RE2.
+//
+// The work-around in this file works by wrapping pointers to RE2 object in the
+// simple struct RE2ptr, which is trivial to forward declare.
+
+#include <re2/re2.h>
+
+namespace i18n {
+namespace addressinput {
+
+struct RE2ptr {
+ RE2ptr(RE2* init_ptr) : ptr(init_ptr) {}
+ ~RE2ptr() { delete ptr; }
+ RE2* const ptr;
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_RE2PTR_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/string_compare.cc b/chromium/third_party/libaddressinput/src/cpp/src/util/string_compare.cc
new file mode 100644
index 00000000000..31a75346af2
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/string_compare.cc
@@ -0,0 +1,102 @@
+// Copyright (C) 2014 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 "string_compare.h"
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <cassert>
+#include <string>
+
+#include <re2/re2.h>
+
+#include "lru_cache_using_std.h"
+
+// RE2 uses type string, which is not necessarily the same as type std::string.
+// In order to create objects of the correct type, to be able to pass pointers
+// to these objects to RE2, the function that does that is defined inside an
+// unnamed namespace inside the re2 namespace. Oh, my ...
+namespace re2 {
+namespace {
+
+// In order to (mis-)use RE2 to implement UTF-8 capable less<>, this function
+// calls RE2::PossibleMatchRange() to calculate the "lessest" string that would
+// be a case-insensitive match to the string. This is far too expensive to do
+// repeatedly, so the function is only ever called through an LRU cache.
+std::string ComputeMinPossibleMatch(const std::string& str) {
+ string min, max; // N.B.: RE2 type string!
+
+ RE2::Options options;
+ options.set_literal(true);
+ options.set_case_sensitive(false);
+ RE2 matcher(str, options);
+
+ bool success = matcher.PossibleMatchRange(&min, &max, str.size());
+ assert(success);
+ (void)success; // Prevent unused variable if assert() is optimized away.
+
+ return min;
+}
+
+} // namespace
+} // namespace re2
+
+namespace i18n {
+namespace addressinput {
+
+class StringCompare::Impl {
+ enum { MAX_CACHE_SIZE = 1 << 15 };
+
+ public:
+ Impl() : min_possible_match_(&re2::ComputeMinPossibleMatch, MAX_CACHE_SIZE) {
+ options_.set_literal(true);
+ options_.set_case_sensitive(false);
+ }
+
+ ~Impl() {}
+
+ bool NaturalEquals(const std::string& a, const std::string& b) const {
+ RE2 matcher(b, options_);
+ return RE2::FullMatch(a, matcher);
+ }
+
+ bool NaturalLess(const std::string& a, const std::string& b) const {
+ const std::string& min_a(min_possible_match_(a));
+ const std::string& min_b(min_possible_match_(b));
+ return min_a < min_b;
+ }
+
+ private:
+ RE2::Options options_;
+ mutable lru_cache_using_std<std::string, std::string> min_possible_match_;
+
+ DISALLOW_COPY_AND_ASSIGN(Impl);
+};
+
+StringCompare::StringCompare() : impl_(new Impl) {}
+
+StringCompare::~StringCompare() {}
+
+bool StringCompare::NaturalEquals(const std::string& a,
+ const std::string& b) const {
+ return impl_->NaturalEquals(a, b);
+}
+
+bool StringCompare::NaturalLess(const std::string& a,
+ const std::string& b) const {
+ return impl_->NaturalLess(a, b);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/string_compare.h b/chromium/third_party/libaddressinput/src/cpp/src/util/string_compare.h
new file mode 100644
index 00000000000..ae680ddc3b6
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/string_compare.h
@@ -0,0 +1,52 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_UTIL_STRING_COMPARE_H_
+#define I18N_ADDRESSINPUT_UTIL_STRING_COMPARE_H_
+
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class StringCompare {
+ public:
+ StringCompare();
+ ~StringCompare();
+
+ // Returns true if a human reader would consider |a| and |b| to be "the same".
+ // Libaddressinput itself isn't really concerned about how this is done. This
+ // default implementation just does case insensitive string matching.
+ bool NaturalEquals(const std::string& a, const std::string& b) const;
+
+ // Comparison function for use with the STL analogous to NaturalEquals().
+ // Libaddressinput itself isn't really concerned about how this is done, as
+ // long as it conforms to the STL requirements on less<> predicates. This
+ // default implementation is VERY SLOW! Must be replaced if you need speed.
+ bool NaturalLess(const std::string& a, const std::string& b) const;
+
+ private:
+ class Impl;
+ scoped_ptr<Impl> impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(StringCompare);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_STRING_COMPARE_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/string_split.cc b/chromium/third_party/libaddressinput/src/cpp/src/util/string_split.cc
new file mode 100644
index 00000000000..114cd92f5c6
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/string_split.cc
@@ -0,0 +1,37 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The original source code is from:
+// http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_split.cc?revision=216633
+
+#include "string_split.h"
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+void SplitString(const std::string& str, char s, std::vector<std::string>* r) {
+ assert(r != NULL);
+ r->clear();
+ size_t last = 0;
+ size_t c = str.size();
+ for (size_t i = 0; i <= c; ++i) {
+ if (i == c || str[i] == s) {
+ std::string tmp(str, last, i - last);
+ // Avoid converting an empty or all-whitespace source string into a vector
+ // of one empty string.
+ if (i != c || !r->empty() || !tmp.empty()) {
+ r->push_back(tmp);
+ }
+ last = i + 1;
+ }
+ }
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/string_split.h b/chromium/third_party/libaddressinput/src/cpp/src/util/string_split.h
new file mode 100644
index 00000000000..680929646f4
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/string_split.h
@@ -0,0 +1,34 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The original source code is from:
+// http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_split.h?revision=236210
+//
+// Modifications from original:
+// 1) Supports only std::string type.
+// 2) Does not trim whitespace.
+
+#ifndef I18N_ADDRESSINPUT_UTIL_STRING_SPLIT_H_
+#define I18N_ADDRESSINPUT_UTIL_STRING_SPLIT_H_
+
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+// Splits |str| into a vector of strings delimited by |c|, placing the results
+// in |r|. If several instances of |c| are contiguous, or if |str| begins with
+// or ends with |c|, then an empty string is inserted.
+//
+// |str| should not be in a multi-byte encoding like Shift-JIS or GBK in which
+// the trailing byte of a multi-byte character can be in the ASCII range.
+// UTF-8, and other single/multi-byte ASCII-compatible encodings are OK.
+// Note: |c| must be in the ASCII range.
+void SplitString(const std::string& str, char c, std::vector<std::string>* r);
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_STRING_SPLIT_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/string_util.cc b/chromium/third_party/libaddressinput/src/cpp/src/util/string_util.cc
new file mode 100644
index 00000000000..8396d51faac
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/string_util.cc
@@ -0,0 +1,68 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The original source code is from:
+// http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_util.cc?revision=268754
+//
+// Modified to contain only the DoReplaceStringPlaceholders() that works with
+// std::string. Replaced DCHECK() with assert() and removed offsets.
+
+#include "string_util.h"
+
+#include <cassert>
+#include <cstddef>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+std::string DoReplaceStringPlaceholders(const std::string& format_string,
+ const std::vector<std::string>& subst) {
+ size_t substitutions = subst.size();
+
+ size_t sub_length = 0;
+ for (std::vector<std::string>::const_iterator iter = subst.begin();
+ iter != subst.end(); ++iter) {
+ sub_length += iter->length();
+ }
+
+ std::string formatted;
+ formatted.reserve(format_string.length() + sub_length);
+
+ for (std::string::const_iterator i = format_string.begin();
+ i != format_string.end(); ++i) {
+ if ('$' == *i) {
+ if (i + 1 != format_string.end()) {
+ ++i;
+ assert('$' == *i || '1' <= *i);
+ if ('$' == *i) {
+ while (i != format_string.end() && '$' == *i) {
+ formatted.push_back('$');
+ ++i;
+ }
+ --i;
+ } else {
+ uintptr_t index = 0;
+ while (i != format_string.end() && '0' <= *i && *i <= '9') {
+ index *= 10;
+ index += *i - '0';
+ ++i;
+ }
+ --i;
+ index -= 1;
+ if (index < substitutions)
+ formatted.append(subst.at(index));
+ }
+ }
+ } else {
+ formatted.push_back(*i);
+ }
+ }
+ return formatted;
+}
+
+} // addressinput
+} // i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/util/string_util.h b/chromium/third_party/libaddressinput/src/cpp/src/util/string_util.h
new file mode 100644
index 00000000000..4266347c621
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/util/string_util.h
@@ -0,0 +1,28 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This file defines utility functions for working with strings.
+//
+// The original source code is from:
+// http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_util.h?revision=268754
+//
+// Modified to contain only DoReplaceStringPlaceholders() that works only with
+// std::string.
+
+#ifndef I18N_ADDRESSINPUT_UTIL_STRING_UTIL_H_
+#define I18N_ADDRESSINPUT_UTIL_STRING_UTIL_H_
+
+#include <string>
+#include <vector>
+
+namespace i18n {
+namespace addressinput {
+
+std::string DoReplaceStringPlaceholders(const std::string& format_string,
+ const std::vector<std::string>& subst);
+
+} // addressinput
+} // i18n
+
+#endif // I18N_ADDRESSINPUT_UTIL_STRING_UTIL_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/validating_storage.cc b/chromium/third_party/libaddressinput/src/cpp/src/validating_storage.cc
new file mode 100644
index 00000000000..a504db4502b
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/validating_storage.cc
@@ -0,0 +1,97 @@
+// 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.
+//
+// ValidatingStorage saves data with checksum and timestamp using
+// ValidatingUtil.
+
+#include "validating_storage.h"
+
+#include <libaddressinput/callback.h>
+#include <libaddressinput/storage.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <cassert>
+#include <cstddef>
+#include <ctime>
+#include <string>
+
+#include "validating_util.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+class Helper {
+ public:
+ Helper(const std::string& key,
+ const ValidatingStorage::Callback& data_ready,
+ const Storage& wrapped_storage)
+ : data_ready_(data_ready),
+ wrapped_data_ready_(BuildCallback(this, &Helper::OnWrappedDataReady)) {
+ wrapped_storage.Get(key, *wrapped_data_ready_);
+ }
+
+ private:
+ ~Helper() {}
+
+ void OnWrappedDataReady(bool success,
+ const std::string& key,
+ std::string* data) {
+ if (success) {
+ assert(data != NULL);
+ bool is_stale = !ValidatingUtil::UnwrapTimestamp(data, std::time(NULL));
+ bool is_corrupted = !ValidatingUtil::UnwrapChecksum(data);
+ success = !is_corrupted && !is_stale;
+ if (is_corrupted) {
+ delete data;
+ data = NULL;
+ }
+ } else {
+ delete data;
+ data = NULL;
+ }
+ data_ready_(success, key, data);
+ delete this;
+ }
+
+ const Storage::Callback& data_ready_;
+ const scoped_ptr<const Storage::Callback> wrapped_data_ready_;
+
+ DISALLOW_COPY_AND_ASSIGN(Helper);
+};
+
+} // namespace
+
+ValidatingStorage::ValidatingStorage(Storage* storage)
+ : wrapped_storage_(storage) {
+ assert(wrapped_storage_ != NULL);
+}
+
+ValidatingStorage::~ValidatingStorage() {}
+
+void ValidatingStorage::Put(const std::string& key, std::string* data) {
+ assert(data != NULL);
+ ValidatingUtil::Wrap(std::time(NULL), data);
+ wrapped_storage_->Put(key, data);
+}
+
+void ValidatingStorage::Get(const std::string& key,
+ const Callback& data_ready) const {
+ new Helper(key, data_ready, *wrapped_storage_);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/validating_storage.h b/chromium/third_party/libaddressinput/src/cpp/src/validating_storage.h
new file mode 100644
index 00000000000..1cf3f955e1d
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/validating_storage.h
@@ -0,0 +1,64 @@
+// 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.
+//
+// A wrapper object for Storage that stores data with a checksum and a
+// timestamp. The existence of checksum and timestamp fields is transparent to
+// the user of the object.
+
+#ifndef I18N_ADDRESSINPUT_VALIDATING_STORAGE_H_
+#define I18N_ADDRESSINPUT_VALIDATING_STORAGE_H_
+
+#include <libaddressinput/storage.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+// Wraps Storage to add checksum and timestamp to stored data. Sample usage:
+// scoped_ptr<Storage> file_storage = ...;
+// ValidatingStorage storage(file_storage));
+// storage.Put("key", new std::string("data"));
+// const scoped_ptr<const ValidatingStorage::Callback> data_ready(
+// BuildCallback(this, &MyClass::OnDataReady));
+// storage.Get("key", *data_ready);
+class ValidatingStorage : public Storage {
+ public:
+ // Takes ownership of |storage|.
+ explicit ValidatingStorage(Storage* storage);
+ virtual ~ValidatingStorage();
+
+ // Storage implementation.
+ virtual void Put(const std::string& key, std::string* data);
+
+ // Storage implementation.
+ // If the data is invalid, then |data_ready| will be called with (false, key,
+ // empty-string). If the data is valid, but stale, then |data_ready| will be
+ // called with (false, key, stale-data). If the data is valid and fresh, then
+ // |data_ready| will be called with (true, key, fresh-data).
+ virtual void Get(const std::string& key, const Callback& data_ready) const;
+
+ private:
+ // The storage being wrapped.
+ scoped_ptr<Storage> wrapped_storage_;
+
+ DISALLOW_COPY_AND_ASSIGN(ValidatingStorage);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_VALIDATING_STORAGE_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/validating_util.cc b/chromium/third_party/libaddressinput/src/cpp/src/validating_util.cc
new file mode 100644
index 00000000000..935668945e4
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/validating_util.cc
@@ -0,0 +1,145 @@
+// 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.
+//
+// ValidatingUtil wraps data with checksum and timestamp. Format:
+//
+// timestamp=<timestamp>
+// checksum=<checksum>
+// <data>
+//
+// The timestamp is the time_t that was returned from time() function. The
+// timestamp does not need to be portable because it is written and read only by
+// ValidatingUtil. The value is somewhat human-readable: it is the number of
+// seconds since the epoch.
+//
+// The checksum is the 32-character hexadecimal MD5 checksum of <data>. It is
+// meant to protect from random file changes on disk.
+
+#include "validating_util.h"
+
+#include <cassert>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <ctime>
+#include <string>
+
+#include "util/md5.h"
+
+namespace i18n {
+namespace addressinput {
+
+namespace {
+
+const char kTimestampPrefix[] = "timestamp=";
+const size_t kTimestampPrefixLength = sizeof kTimestampPrefix - 1;
+
+const char kChecksumPrefix[] = "checksum=";
+const size_t kChecksumPrefixLength = sizeof kChecksumPrefix - 1;
+
+const char kSeparator = '\n';
+
+// Places the header value into |header_value| parameter and erases the header
+// from |data|. Returns |true| if the header format is valid.
+bool UnwrapHeader(const char* header_prefix,
+ size_t header_prefix_length,
+ std::string* data,
+ std::string* header_value) {
+ assert(header_prefix != NULL);
+ assert(data != NULL);
+ assert(header_value != NULL);
+
+ if (data->compare(
+ 0, header_prefix_length, header_prefix, header_prefix_length) != 0) {
+ return false;
+ }
+
+ std::string::size_type separator_position =
+ data->find(kSeparator, header_prefix_length);
+ if (separator_position == std::string::npos) {
+ return false;
+ }
+
+ header_value->assign(
+ *data, header_prefix_length, separator_position - header_prefix_length);
+ data->erase(0, separator_position + 1);
+
+ return true;
+}
+
+} // namespace
+
+// static
+void ValidatingUtil::Wrap(time_t timestamp, std::string* data) {
+ assert(data != NULL);
+ char timestamp_string[2 + 3 * sizeof timestamp];
+ int size =
+ std::sprintf(timestamp_string, "%ld", static_cast<long>(timestamp));
+ assert(size > 0);
+ assert(size < sizeof timestamp_string);
+ (void)size;
+
+ std::string header;
+ header.append(kTimestampPrefix, kTimestampPrefixLength);
+ header.append(timestamp_string);
+ header.push_back(kSeparator);
+
+ header.append(kChecksumPrefix, kChecksumPrefixLength);
+ header.append(MD5String(*data));
+ header.push_back(kSeparator);
+
+ data->reserve(header.size() + data->size());
+ data->insert(0, header);
+}
+
+// static
+bool ValidatingUtil::UnwrapTimestamp(std::string* data, time_t now) {
+ assert(data != NULL);
+ if (now < 0) {
+ return false;
+ }
+
+ std::string timestamp_string;
+ if (!UnwrapHeader(
+ kTimestampPrefix, kTimestampPrefixLength, data, &timestamp_string)) {
+ return false;
+ }
+
+ time_t timestamp = atol(timestamp_string.c_str());
+ if (timestamp < 0) {
+ return false;
+ }
+
+ // One month contains:
+ // 30 days *
+ // 24 hours per day *
+ // 60 minutes per hour *
+ // 60 seconds per minute.
+ static const double kOneMonthInSeconds = 30.0 * 24.0 * 60.0 * 60.0;
+ double age_in_seconds = difftime(now, timestamp);
+ return !(age_in_seconds < 0.0) && age_in_seconds < kOneMonthInSeconds;
+}
+
+// static
+bool ValidatingUtil::UnwrapChecksum(std::string* data) {
+ assert(data != NULL);
+ std::string checksum;
+ if (!UnwrapHeader(kChecksumPrefix, kChecksumPrefixLength, data, &checksum)) {
+ return false;
+ }
+ return checksum == MD5String(*data);
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/validating_util.h b/chromium/third_party/libaddressinput/src/cpp/src/validating_util.h
new file mode 100644
index 00000000000..20d541b291a
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/validating_util.h
@@ -0,0 +1,60 @@
+// 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.
+//
+// An object to wrap data with a checksum and a timestamp. These fields are used
+// to verify that the data is not stale or corrupted. Staleness threshold is 1
+// month.
+
+#ifndef I18N_ADDRESSINPUT_VALIDATING_UTIL_H_
+#define I18N_ADDRESSINPUT_VALIDATING_UTIL_H_
+
+#include <libaddressinput/util/basictypes.h>
+
+#include <ctime>
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+// Wraps data with a checksum and a timestamp. Sample usage:
+// std::string data = ...
+// ValidatingUtil::Wrap(time(NULL), &data);
+// Process(data);
+//
+// std::string unwrapped = wrapped;
+// if (ValidatingUtil::UnwrapTimestamp(&unwrapped, time(NULL)) &&
+// ValidatingUtil::UnwrapChecksum(&unwrapped)) {
+// Process(unwrapped);
+// }
+class ValidatingUtil {
+ public:
+ // Adds checksum and given |timestamp| to |data|.
+ static void Wrap(time_t timestamp, std::string* data);
+
+ // Strips out the timestamp from |data|. Returns |true| if the timestamp is
+ // present, formatted correctly, valid, and recent with respect to |now|.
+ static bool UnwrapTimestamp(std::string* data, time_t now);
+
+ // Strips out the checksum from |data|. Returns |true| if the checksum is
+ // present, formatted correctly, and valid for this data.
+ static bool UnwrapChecksum(std::string* data);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ValidatingUtil);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_VALIDATING_UTIL_H_
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/validation_task.cc b/chromium/third_party/libaddressinput/src/cpp/src/validation_task.cc
new file mode 100644
index 00000000000..1e7911aad18
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/validation_task.cc
@@ -0,0 +1,268 @@
+// Copyright (C) 2014 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 "validation_task.h"
+
+#include <libaddressinput/address_data.h>
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/address_metadata.h>
+#include <libaddressinput/address_problem.h>
+#include <libaddressinput/address_validator.h>
+#include <libaddressinput/callback.h>
+#include <libaddressinput/supplier.h>
+#include <libaddressinput/util/basictypes.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <re2/re2.h>
+
+#include "lookup_key.h"
+#include "post_box_matchers.h"
+#include "rule.h"
+#include "util/re2ptr.h"
+
+namespace i18n {
+namespace addressinput {
+
+ValidationTask::ValidationTask(const AddressData& address,
+ bool allow_postal,
+ bool require_name,
+ const FieldProblemMap* filter,
+ FieldProblemMap* problems,
+ const AddressValidator::Callback& validated)
+ : address_(address),
+ allow_postal_(allow_postal),
+ require_name_(require_name),
+ filter_(filter),
+ problems_(problems),
+ validated_(validated),
+ supplied_(BuildCallback(this, &ValidationTask::Validate)),
+ lookup_key_(new LookupKey) {
+ assert(problems_ != NULL);
+ assert(supplied_ != NULL);
+ assert(lookup_key_ != NULL);
+}
+
+ValidationTask::~ValidationTask() {
+}
+
+void ValidationTask::Run(Supplier* supplier) const {
+ assert(supplier != NULL);
+ problems_->clear();
+ lookup_key_->FromAddress(address_);
+ supplier->Supply(*lookup_key_, *supplied_);
+}
+
+void ValidationTask::Validate(bool success,
+ const LookupKey& lookup_key,
+ const Supplier::RuleHierarchy& hierarchy) {
+ assert(&lookup_key == lookup_key_.get()); // Sanity check.
+
+ if (success) {
+ if (address_.IsFieldEmpty(COUNTRY)) {
+ ReportProblemMaybe(COUNTRY, MISSING_REQUIRED_FIELD);
+ } else if (hierarchy.rule[0] == NULL) {
+ ReportProblemMaybe(COUNTRY, UNKNOWN_VALUE);
+ } else {
+ // Checks which use statically linked metadata.
+ const std::string& region_code = address_.region_code;
+ CheckUnexpectedField(region_code);
+ CheckMissingRequiredField(region_code);
+
+ // Checks which use data from the metadata server. Note that
+ // CheckPostalCodeFormatAndValue assumes CheckUnexpectedField has already
+ // been called.
+ CheckUnknownValue(hierarchy);
+ CheckPostalCodeFormatAndValue(hierarchy);
+ CheckUsesPoBox(hierarchy);
+ }
+ }
+
+ validated_(success, address_, *problems_);
+ delete this;
+}
+
+// A field will return an UNEXPECTED_FIELD problem type if the current value of
+// that field is not empty and the field should not be used by that region.
+void ValidationTask::CheckUnexpectedField(
+ const std::string& region_code) const {
+ static const AddressField kFields[] = {
+ // COUNTRY is never unexpected.
+ ADMIN_AREA,
+ LOCALITY,
+ DEPENDENT_LOCALITY,
+ SORTING_CODE,
+ POSTAL_CODE,
+ STREET_ADDRESS,
+ ORGANIZATION,
+ RECIPIENT
+ };
+
+ for (size_t i = 0; i < arraysize(kFields); ++i) {
+ AddressField field = kFields[i];
+ if (!address_.IsFieldEmpty(field) && !IsFieldUsed(field, region_code)) {
+ ReportProblemMaybe(field, UNEXPECTED_FIELD);
+ }
+ }
+}
+
+// A field will return an MISSING_REQUIRED_FIELD problem type if the current
+// value of that field is empty and the field is required by that region.
+void ValidationTask::CheckMissingRequiredField(
+ const std::string& region_code) const {
+ static const AddressField kFields[] = {
+ // COUNTRY is assumed to have already been checked.
+ ADMIN_AREA,
+ LOCALITY,
+ DEPENDENT_LOCALITY,
+ SORTING_CODE,
+ POSTAL_CODE,
+ STREET_ADDRESS
+ // ORGANIZATION is never required.
+ // RECIPIENT is handled separately.
+ };
+
+ for (size_t i = 0; i < arraysize(kFields); ++i) {
+ AddressField field = kFields[i];
+ if (address_.IsFieldEmpty(field) && IsFieldRequired(field, region_code)) {
+ ReportProblemMaybe(field, MISSING_REQUIRED_FIELD);
+ }
+ }
+
+ if (require_name_ && address_.IsFieldEmpty(RECIPIENT)) {
+ ReportProblemMaybe(RECIPIENT, MISSING_REQUIRED_FIELD);
+ }
+}
+
+// A field is UNKNOWN_VALUE if the metadata contains a list of possible values
+// for the field and the address data server could not match the current value
+// of that field to one of those possible values, therefore returning NULL.
+void ValidationTask::CheckUnknownValue(
+ const Supplier::RuleHierarchy& hierarchy) const {
+ for (size_t depth = 1; depth < arraysize(LookupKey::kHierarchy); ++depth) {
+ AddressField field = LookupKey::kHierarchy[depth];
+ if (!(address_.IsFieldEmpty(field) ||
+ hierarchy.rule[depth - 1] == NULL ||
+ hierarchy.rule[depth - 1]->GetSubKeys().empty() ||
+ hierarchy.rule[depth] != NULL)) {
+ ReportProblemMaybe(field, UNKNOWN_VALUE);
+ }
+ }
+}
+
+// Note that it is assumed that CheckUnexpectedField has already been called.
+void ValidationTask::CheckPostalCodeFormatAndValue(
+ const Supplier::RuleHierarchy& hierarchy) const {
+ assert(hierarchy.rule[0] != NULL);
+ const Rule& country_rule = *hierarchy.rule[0];
+
+ if (!(ShouldReport(POSTAL_CODE, INVALID_FORMAT) ||
+ ShouldReport(POSTAL_CODE, MISMATCHING_VALUE))) {
+ return;
+ }
+
+ if (address_.IsFieldEmpty(POSTAL_CODE)) {
+ return;
+ } else if (std::find(problems_->begin(), problems_->end(),
+ FieldProblemMap::value_type(POSTAL_CODE,
+ UNEXPECTED_FIELD))
+ != problems_->end()) {
+ return; // Problem already reported.
+ }
+
+ // Validate general postal code format. A country-level rule specifies the
+ // regular expression for the whole postal code.
+ const RE2ptr* format_ptr = country_rule.GetPostalCodeMatcher();
+ if (format_ptr != NULL &&
+ !RE2::FullMatch(address_.postal_code, *format_ptr->ptr) &&
+ ShouldReport(POSTAL_CODE, INVALID_FORMAT)) {
+ ReportProblem(POSTAL_CODE, INVALID_FORMAT);
+ return;
+ }
+
+ if (!ShouldReport(POSTAL_CODE, MISMATCHING_VALUE)) {
+ return;
+ }
+
+ for (size_t depth = arraysize(LookupKey::kHierarchy) - 1;
+ depth > 0; --depth) {
+ if (hierarchy.rule[depth] != NULL) {
+ // Validate sub-region specific postal code format. A sub-region specifies
+ // the regular expression for a prefix of the postal code.
+ const RE2ptr* prefix_ptr = hierarchy.rule[depth]->GetPostalCodeMatcher();
+ if (prefix_ptr != NULL) {
+ if (!RE2::PartialMatch(address_.postal_code, *prefix_ptr->ptr)) {
+ ReportProblem(POSTAL_CODE, MISMATCHING_VALUE);
+ }
+ return;
+ }
+ }
+ }
+}
+
+void ValidationTask::CheckUsesPoBox(
+ const Supplier::RuleHierarchy& hierarchy) const {
+ assert(hierarchy.rule[0] != NULL);
+ const Rule& country_rule = *hierarchy.rule[0];
+
+ if (allow_postal_ ||
+ !ShouldReport(STREET_ADDRESS, USES_P_O_BOX) ||
+ address_.IsFieldEmpty(STREET_ADDRESS)) {
+ return;
+ }
+
+ std::vector<const RE2ptr*> matchers =
+ PostBoxMatchers::GetMatchers(country_rule);
+ for (std::vector<std::string>::const_iterator
+ line = address_.address_line.begin();
+ line != address_.address_line.end(); ++line) {
+ for (std::vector<const RE2ptr*>::const_iterator
+ matcher = matchers.begin();
+ matcher != matchers.end(); ++matcher) {
+ if (RE2::PartialMatch(*line, *(*matcher)->ptr)) {
+ ReportProblem(STREET_ADDRESS, USES_P_O_BOX);
+ return;
+ }
+ }
+ }
+}
+
+void ValidationTask::ReportProblem(AddressField field,
+ AddressProblem problem) const {
+ problems_->insert(std::make_pair(field, problem));
+}
+
+void ValidationTask::ReportProblemMaybe(AddressField field,
+ AddressProblem problem) const {
+ if (ShouldReport(field, problem)) {
+ ReportProblem(field, problem);
+ }
+}
+
+bool ValidationTask::ShouldReport(AddressField field,
+ AddressProblem problem) const {
+ return filter_ == NULL || filter_->empty() ||
+ std::find(filter_->begin(),
+ filter_->end(),
+ FieldProblemMap::value_type(field, problem)) !=
+ filter_->end();
+}
+
+} // namespace addressinput
+} // namespace i18n
diff --git a/chromium/third_party/libaddressinput/src/cpp/src/validation_task.h b/chromium/third_party/libaddressinput/src/cpp/src/validation_task.h
new file mode 100644
index 00000000000..165867864fa
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/cpp/src/validation_task.h
@@ -0,0 +1,101 @@
+// Copyright (C) 2014 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.
+
+#ifndef I18N_ADDRESSINPUT_VALIDATION_TASK_H_
+#define I18N_ADDRESSINPUT_VALIDATION_TASK_H_
+
+#include <libaddressinput/address_field.h>
+#include <libaddressinput/address_problem.h>
+#include <libaddressinput/address_validator.h>
+#include <libaddressinput/supplier.h>
+#include <libaddressinput/util/basictypes.h>
+#include <libaddressinput/util/scoped_ptr.h>
+
+#include <string>
+
+namespace i18n {
+namespace addressinput {
+
+class LookupKey;
+struct AddressData;
+
+// A ValidationTask object encapsulates the information necessary to perform
+// validation of one particular address and call a callback when that has been
+// done. Calling the Run() method will load required metadata, then perform
+// validation, call the callback and delete the ValidationTask object itself.
+class ValidationTask {
+ public:
+ ValidationTask(const AddressData& address,
+ bool allow_postal,
+ bool require_name,
+ const FieldProblemMap* filter,
+ FieldProblemMap* problems,
+ const AddressValidator::Callback& validated);
+
+ ~ValidationTask();
+
+ // Calls supplier->Load(), with Validate() as callback.
+ void Run(Supplier* supplier) const;
+
+ private:
+ friend class ValidationTaskTest;
+
+ // Uses the address metadata of |hierarchy| to validate |address_|, writing
+ // problems found into |problems_|, then calls the |validated_| callback and
+ // deletes this ValidationTask object.
+ void Validate(bool success,
+ const LookupKey& lookup_key,
+ const Supplier::RuleHierarchy& hierarchy);
+
+ // Checks all fields for UNEXPECTED_FIELD problems.
+ void CheckUnexpectedField(const std::string& region_code) const;
+
+ // Checks all fields for MISSING_REQUIRED_FIELD problems.
+ void CheckMissingRequiredField(const std::string& region_code) const;
+
+ // Checks the hierarchical fields for UNKNOWN_VALUE problems.
+ void CheckUnknownValue(const Supplier::RuleHierarchy& hierarchy) const;
+
+ // Checks the POSTAL_CODE field for problems.
+ void CheckPostalCodeFormatAndValue(
+ const Supplier::RuleHierarchy& hierarchy) const;
+
+ // Checks the STREET_ADDRESS field for USES_P_O_BOX problems.
+ void CheckUsesPoBox(const Supplier::RuleHierarchy& hierarchy) const;
+
+ // Writes (|field|,|problem|) to |problems_|.
+ void ReportProblem(AddressField field, AddressProblem problem) const;
+
+ // Writes (|field|,|problem|) to |problems_|, if this pair should be reported.
+ void ReportProblemMaybe(AddressField field, AddressProblem problem) const;
+
+ // Returns whether (|field|,|problem|) should be reported.
+ bool ShouldReport(AddressField field, AddressProblem problem) const;
+
+ const AddressData& address_;
+ const bool allow_postal_;
+ const bool require_name_;
+ const FieldProblemMap* filter_;
+ FieldProblemMap* const problems_;
+ const AddressValidator::Callback& validated_;
+ const scoped_ptr<const Supplier::Callback> supplied_;
+ const scoped_ptr<LookupKey> lookup_key_;
+
+ DISALLOW_COPY_AND_ASSIGN(ValidationTask);
+};
+
+} // namespace addressinput
+} // namespace i18n
+
+#endif // I18N_ADDRESSINPUT_VALIDATION_TASK_H_
diff --git a/chromium/third_party/libaddressinput/src/settings.gradle b/chromium/third_party/libaddressinput/src/settings.gradle
new file mode 100644
index 00000000000..18077ac4d39
--- /dev/null
+++ b/chromium/third_party/libaddressinput/src/settings.gradle
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/*
+ * The Android address input widget is formed from the common (non-UI) classes
+ * and the Android specific classes.
+ */
+include 'android', 'common'