├── .gitignore ├── .gitmodules ├── .travis.yml ├── AUTHORS ├── CONTRIBUTORS ├── LICENSE ├── README.md ├── android ├── README.md ├── build.gradle └── src │ ├── androidTest │ ├── AndroidManifest.xml │ └── java │ │ ├── android │ │ └── util │ │ │ └── Log.java │ │ └── com │ │ └── android │ │ └── i18n │ │ └── addressinput │ │ ├── AddressAutocompleteControllerTest.java │ │ ├── AddressWidgetUiComponentProviderTest.java │ │ ├── AndroidAsyncEncodedRequestApiTest.java │ │ ├── AsyncTestCaseTest.java │ │ ├── DummyTest.java │ │ ├── PlaceDetailsClientTest.java │ │ ├── autocomplete │ │ └── gmscore │ │ │ └── AddressAutocompleteApiImplTest.java │ │ └── testing │ │ ├── AsyncTestCase.java │ │ └── TestActivity.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── android │ │ └── i18n │ │ └── addressinput │ │ ├── AddressAutocompleteController.java │ │ ├── AddressUiComponent.java │ │ ├── AddressWidget.java │ │ ├── AddressWidgetUiComponentProvider.java │ │ ├── AndroidAsyncEncodedRequestApi.java │ │ ├── AndroidAsyncRequestApi.java │ │ ├── PlaceDetailsApi.java │ │ ├── PlaceDetailsClient.java │ │ └── autocomplete │ │ └── gmscore │ │ ├── AddressAutocompleteApiImpl.java │ │ └── AddressAutocompletePredictionImpl.java │ └── res │ ├── drawable-v19 │ └── autocomplete_dropdown_item_background_selected.xml │ ├── drawable-v21 │ └── autocomplete_dropdown_item_background_selected.xml │ ├── layout │ ├── address_autocomplete_dropdown_item.xml │ ├── address_autocomplete_textview.xml │ ├── address_autocomplete_view_group.xml │ ├── address_edittext.xml │ ├── address_layout.xml │ ├── address_spinner.xml │ └── address_textview.xml │ └── values │ ├── address_dimens.xml │ └── address_strings.xml ├── build.gradle ├── common ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── i18n │ │ └── addressinput │ │ └── common │ │ ├── AddressAutocompleteApi.java │ │ ├── AddressAutocompletePrediction.java │ │ ├── AddressData.java │ │ ├── AddressDataKey.java │ │ ├── AddressField.java │ │ ├── AddressProblemType.java │ │ ├── AddressProblems.java │ │ ├── AddressVerificationData.java │ │ ├── AddressVerificationNodeData.java │ │ ├── AsyncRequestApi.java │ │ ├── CacheData.java │ │ ├── ClientCacheManager.java │ │ ├── ClientData.java │ │ ├── DataLoadListener.java │ │ ├── DataSource.java │ │ ├── FieldVerifier.java │ │ ├── FormController.java │ │ ├── FormOptions.java │ │ ├── FormatInterpreter.java │ │ ├── JsoMap.java │ │ ├── LookupKey.java │ │ ├── NotifyingListener.java │ │ ├── OnAddressSelectedListener.java │ │ ├── RegionData.java │ │ ├── RegionDataConstants.java │ │ ├── SimpleClientCacheManager.java │ │ ├── StandardAddressVerifier.java │ │ ├── StandardChecks.java │ │ └── Util.java │ └── test │ └── java │ └── com │ └── google │ └── i18n │ └── addressinput │ ├── common │ ├── AddressDataTest.java │ ├── AddressFieldTest.java │ ├── AddressProblemsTest.java │ ├── AddressVerificationDataTest.java │ ├── CacheDataTest.java │ ├── ClientDataTest.java │ ├── FieldVerifierTest.java │ ├── FormControllerTest.java │ ├── FormOptionsTest.java │ ├── FormatInterpreterTest.java │ ├── JsoMapTest.java │ ├── LookupKeyTest.java │ ├── RegionDataConstantsTest.java │ ├── RegionDataTest.java │ ├── StandardAddressVerifierTest.java │ └── UtilTest.java │ └── testing │ ├── AddressDataMapLoader.java │ ├── InMemoryAsyncRequest.java │ └── countryinfo.txt ├── cpp ├── LICENSE.chromium ├── README.md ├── grit.gyp ├── gtest.gyp ├── include │ └── libaddressinput │ │ ├── address_data.h │ │ ├── address_field.h │ │ ├── address_formatter.h │ │ ├── address_input_helper.h │ │ ├── address_metadata.h │ │ ├── address_normalizer.h │ │ ├── address_problem.h │ │ ├── address_ui.h │ │ ├── address_ui_component.h │ │ ├── address_validator.h │ │ ├── callback.h │ │ ├── localization.h │ │ ├── null_storage.h │ │ ├── ondemand_supplier.h │ │ ├── preload_supplier.h │ │ ├── region_data.h │ │ ├── region_data_builder.h │ │ ├── source.h │ │ ├── storage.h │ │ └── supplier.h ├── libaddressinput.gyp ├── libaddressinput.gypi ├── rapidjson.gyp ├── re2.gyp ├── res │ ├── messages.grd │ └── messages.grdp ├── src │ ├── address_data.cc │ ├── address_field.cc │ ├── address_field_util.cc │ ├── address_field_util.h │ ├── address_formatter.cc │ ├── address_input_helper.cc │ ├── address_metadata.cc │ ├── address_normalizer.cc │ ├── address_problem.cc │ ├── address_ui.cc │ ├── address_validator.cc │ ├── format_element.cc │ ├── format_element.h │ ├── grit.h │ ├── language.cc │ ├── language.h │ ├── localization.cc │ ├── lookup_key.cc │ ├── lookup_key.h │ ├── null_storage.cc │ ├── ondemand_supplier.cc │ ├── ondemand_supply_task.cc │ ├── ondemand_supply_task.h │ ├── post_box_matchers.cc │ ├── post_box_matchers.h │ ├── preload_supplier.cc │ ├── region_data.cc │ ├── region_data_builder.cc │ ├── region_data_constants.cc │ ├── region_data_constants.h │ ├── retriever.cc │ ├── retriever.h │ ├── rule.cc │ ├── rule.h │ ├── rule_retriever.cc │ ├── rule_retriever.h │ ├── util │ │ ├── cctype_tolower_equal.cc │ │ ├── cctype_tolower_equal.h │ │ ├── json.cc │ │ ├── json.h │ │ ├── lru_cache_using_std.h │ │ ├── md5.cc │ │ ├── md5.h │ │ ├── re2ptr.h │ │ ├── size.h │ │ ├── string_compare.cc │ │ ├── string_compare.h │ │ ├── string_split.cc │ │ ├── string_split.h │ │ ├── string_util.cc │ │ └── string_util.h │ ├── validating_storage.cc │ ├── validating_storage.h │ ├── validating_util.cc │ ├── validating_util.h │ ├── validation_task.cc │ └── validation_task.h └── test │ ├── address_data_test.cc │ ├── address_field_test.cc │ ├── address_field_util_test.cc │ ├── address_formatter_test.cc │ ├── address_input_helper_test.cc │ ├── address_metadata_test.cc │ ├── address_normalizer_test.cc │ ├── address_problem_test.cc │ ├── address_ui_test.cc │ ├── address_validator_test.cc │ ├── fake_storage.cc │ ├── fake_storage.h │ ├── fake_storage_test.cc │ ├── format_element_test.cc │ ├── language_test.cc │ ├── localization_test.cc │ ├── lookup_key_test.cc │ ├── mock_source.cc │ ├── mock_source.h │ ├── null_storage_test.cc │ ├── ondemand_supply_task_test.cc │ ├── post_box_matchers_test.cc │ ├── preload_supplier_test.cc │ ├── region_data_builder_test.cc │ ├── region_data_constants_test.cc │ ├── region_data_test.cc │ ├── retriever_test.cc │ ├── rule_retriever_test.cc │ ├── rule_test.cc │ ├── supplier_test.cc │ ├── testdata_source.cc │ ├── testdata_source.h │ ├── testdata_source_test.cc │ ├── util │ ├── json_test.cc │ ├── md5_unittest.cc │ ├── string_compare_test.cc │ ├── string_split_unittest.cc │ └── string_util_test.cc │ ├── validating_storage_test.cc │ ├── validating_util_test.cc │ └── validation_task_test.cc ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── testdata └── countryinfo.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | cpp/out/ 3 | java/**/build/ 4 | android/build/ 5 | build/ 6 | common/build/ 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "externals/grit"] 2 | path = externals/grit 3 | url = https://chromium.googlesource.com/chromium/src/tools/grit/ 4 | [submodule "externals/rapidjson"] 5 | path = externals/rapidjson 6 | url = https://github.com/miloyip/rapidjson.git 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | language: cpp 16 | os: linux 17 | dist: trusty 18 | sudo: false 19 | compiler: clang 20 | cache: ccache 21 | addons: 22 | apt: 23 | packages: gyp libgtest-dev ninja-build python 24 | install: 25 | # Download re2 from source because Ubuntu Trusty (the newest version of Ubuntu 26 | # in Travis-CI) does not include a package. Packages from newer releases of 27 | # Ubuntu are not binary compatible with Trusty. The re2 shared library is 28 | # installed into $HOME/usr/local/lib. 29 | - git clone https://github.com/google/re2.git 30 | - make -C re2 31 | - env DESTDIR="$HOME" make -C re2 install 32 | script: 33 | - cd cpp 34 | - env CXXFLAGS="-I$HOME/usr/local/include" LDFLAGS="-L$HOME/usr/local/lib" GYP_GENERATORS="ninja" gyp --depth . 35 | - ninja -C out/Default 36 | after_script: 37 | - env LD_LIBRARY_PATH="$HOME/usr/local/lib" out/Default/unit_tests 38 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of libaddressinput authors for copyright purposes. 2 | # This file is distinct from the CONTRIBUTORS files. 3 | # See the latter for an explanation. 4 | 5 | # Names should be added to this file as: 6 | # Name or Organization 7 | # The email address is not required for organizations. 8 | 9 | Google Inc. 10 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # People who have agreed to one of the CLAs and can contribute patches. 2 | # The AUTHORS file lists the copyright holders; this file 3 | # lists people. For example, Google employees are listed here 4 | # but not in AUTHORS, because Google holds the copyright. 5 | # 6 | # https://developers.google.com/open-source/cla/individual 7 | # https://developers.google.com/open-source/cla/corporate 8 | # 9 | # Names should be added to this file as: 10 | # Name 11 | 12 | David Beaumont 13 | David Yonge-Mallo 14 | Dong Zhou 15 | Fredrik Roubert 16 | Jeanine Lilleng 17 | Keghani Kouzoujian 18 | Lara Scheidegger 19 | Rouslan Solomakhin 20 | Shaopeng Jia 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![](https://github.com/google/libaddressinput/wiki/libaddressinput-icon-70x55.png) libaddressinput 2 | 3 | [![Build Status](https://travis-ci.org/googlei18n/libaddressinput.svg?branch=master)](https://travis-ci.org/googlei18n/libaddressinput) 4 | 5 | The _libaddressinput_ project consists of two different libraries (one 6 | implemented in C++, one implemented in Java for Android) that use 7 | [address metadata](https://github.com/google/libaddressinput/wiki/AddressValidationMetadata) 8 | from 9 | [Google](https://developers.google.com/)'s 10 | [Address Data Service](https://chromium-i18n.appspot.com/ssl-address/data) 11 | to assist application developers in collecting and handling _postal addresses_ 12 | from all over the world. 13 | 14 | These libraries can provide information about what input fields are required for 15 | a correct address input form for any country in the world and can validate an 16 | address to highlight input errors like missing required fields or invalid 17 | values. 18 | 19 | ## C++ 20 | 21 | The C++ library (in very portable C++11) of _libaddressinput_ is used in address-related 22 | projects in [Chromium](http://www.chromium.org/Home). 23 | 24 | https://chromium.googlesource.com/chromium/src/+/master/third_party/libaddressinput/ 25 | 26 | ## Java 27 | 28 | The Java library of _libaddressinput_ is written for use in 29 | [Android](https://developer.android.com/) and includes an Android UI address 30 | input widget ready for use, but only the UI parts are tied to Android. 31 | 32 | Non-UI code and tests can be run in Java SE, and the rest of the library could 33 | easily be adapted to run in any Java environment. 34 | 35 | ## Mailing List 36 | 37 | Using and developing libaddressinput is discussed on this mailing list: 38 | 39 | https://groups.google.com/forum/#!forum/libaddressinput-discuss 40 | 41 | ## License 42 | 43 | Source code licensed under the Apache 2.0. Data licensed under the CC-BY 4.0 44 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'com.android.library' 18 | 19 | tasks.withType(JavaCompile) { 20 | options.encoding = 'UTF-8' 21 | } 22 | 23 | dependencies { 24 | api project(':common') 25 | implementation 'com.google.android.gms:play-services-location:10.0.0' 26 | implementation 'com.google.android.gms:play-services-places:9.2.0' 27 | implementation 'com.google.guava:guava-gwt:18.0' 28 | } 29 | 30 | android { 31 | /* 32 | * If these are modified, update the README to reflect the new versions. 33 | */ 34 | namespace "com.android.i18n.addressinput" 35 | compileSdk 34 36 | defaultConfig { 37 | minSdkVersion 17 38 | targetSdkVersion 34 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /android/src/androidTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /android/src/androidTest/java/android/util/Log.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.util; 18 | 19 | /** 20 | * Simple mock of Android logger class. 21 | */ 22 | public final class Log { 23 | public static int v(String tag, String msg) { return 0; } 24 | public static int v(String tag, String msg, Throwable tr) { return 0; } 25 | public static int d(String tag, String msg) { return 0; } 26 | public static int d(String tag, String msg, Throwable tr) { return 0; } 27 | public static int i(String tag, String msg) { return 0; } 28 | public static int i(String tag, String msg, Throwable tr) { return 0; } 29 | public static int w(String tag, String msg) { return 0; } 30 | public static int w(String tag, String msg, Throwable tr) { return 0; } 31 | public static boolean isLoggable(String tag, int level) { return false; } 32 | public static int w(String tag, Throwable tr) { return 0; } 33 | public static int e(String tag, String msg) { return 0; } 34 | public static int e(String tag, String msg, Throwable tr) { return 0; } 35 | public static int wtf(String tag, String msg) { return 0; } 36 | public static int wtf(String tag, Throwable tr) { return 0; } 37 | public static int wtf(String tag, String msg, Throwable tr) { return 0; } 38 | } 39 | -------------------------------------------------------------------------------- /android/src/androidTest/java/com/android/i18n/addressinput/AsyncTestCaseTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.i18n.addressinput; 18 | 19 | import com.android.i18n.addressinput.testing.AsyncTestCase; 20 | 21 | import junit.framework.AssertionFailedError; 22 | 23 | import java.util.concurrent.TimeoutException; 24 | 25 | public class AsyncTestCaseTest extends AsyncTestCase { 26 | 27 | public void testSuccess() { 28 | delayTestFinish(1000); 29 | AsyncCallback.execute(500, new Runnable() { 30 | @Override 31 | public void run() { 32 | finishTest(); 33 | } 34 | }); 35 | } 36 | 37 | public void testFailure() { 38 | expectTimeout = true; 39 | delayTestFinish(1000); 40 | AsyncCallback.execute(1500, new Runnable() { 41 | @Override 42 | public void run() { 43 | finishTest(); 44 | } 45 | }); 46 | } 47 | 48 | @Override 49 | protected void runTest() throws Throwable { 50 | expectTimeout = false; 51 | try { 52 | super.runTest(); 53 | } catch (TimeoutException e) { 54 | if (expectTimeout) { 55 | return; 56 | } else { 57 | throw e; 58 | } 59 | } 60 | if (expectTimeout) { 61 | throw new AssertionFailedError("Test case did not time out."); 62 | } 63 | } 64 | 65 | private boolean expectTimeout; 66 | 67 | /** 68 | * Helper class to perform an asynchronous callback after a specified delay. 69 | */ 70 | private static class AsyncCallback extends Thread { 71 | private long waitMillis; 72 | private Runnable callback; 73 | 74 | private AsyncCallback(long waitMillis, Runnable callback) { 75 | this.waitMillis = waitMillis; 76 | this.callback = callback; 77 | } 78 | 79 | public static void execute(long waitMillis, Runnable callback) { 80 | (new AsyncCallback(waitMillis, callback)).start(); 81 | } 82 | 83 | @Override 84 | public void run() { 85 | try { 86 | synchronized (this) { 87 | wait(this.waitMillis); 88 | } 89 | } catch (InterruptedException e) { 90 | throw new RuntimeException(e); 91 | } 92 | this.callback.run(); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /android/src/androidTest/java/com/android/i18n/addressinput/DummyTest.java: -------------------------------------------------------------------------------- 1 | package com.android.i18n.addressinput; 2 | 3 | import android.test.ActivityInstrumentationTestCase2; 4 | import com.android.i18n.addressinput.testing.TestActivity; 5 | 6 | /** 7 | * Empty test file. The API level 19 test emulator requires a nonempty dex to run tests. 8 | * This empty file is included in the srcs attribute of the android_test rule so that the real test 9 | * source files can be included via the binary_under_test attribute. 10 | */ 11 | public class DummyTest extends ActivityInstrumentationTestCase2 { 12 | public DummyTest() { 13 | super(TestActivity.class); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /android/src/androidTest/java/com/android/i18n/addressinput/testing/AsyncTestCase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.i18n.addressinput.testing; 18 | 19 | import junit.framework.TestCase; 20 | 21 | import java.util.concurrent.TimeoutException; 22 | 23 | /** 24 | * An extension of TestCase that provides delayTestFinish() and finishTest() methods that behave 25 | * like the corresponding methods in GWTTestCase for testing asynchronous code. 26 | */ 27 | public abstract class AsyncTestCase extends TestCase { 28 | /** 29 | * Tracks whether this test is completely done. 30 | */ 31 | private boolean testIsFinished; 32 | 33 | /** 34 | * The system time in milliseconds when the test should time out. 35 | */ 36 | private long testTimeoutMillis; 37 | 38 | /** 39 | * Puts the current test in asynchronous mode. 40 | * 41 | * @param timeoutMillis time to wait before failing the test for timing out 42 | */ 43 | protected void delayTestFinish(int timeoutMillis) { 44 | testTimeoutMillis = System.currentTimeMillis() + timeoutMillis; 45 | } 46 | 47 | /** 48 | * Causes this test to succeed during asynchronous mode. 49 | */ 50 | protected void finishTest() { 51 | testIsFinished = true; 52 | synchronized (this) { 53 | notify(); 54 | } 55 | } 56 | 57 | @Override 58 | protected void runTest() throws Throwable { 59 | testIsFinished = false; 60 | testTimeoutMillis = 0; 61 | super.runTest(); 62 | 63 | if (testTimeoutMillis > 0) { 64 | long timeoutMillis = testTimeoutMillis - System.currentTimeMillis(); 65 | if (timeoutMillis > 0) { 66 | synchronized (this) { 67 | wait(timeoutMillis); 68 | } 69 | } 70 | if (!testIsFinished) { 71 | throw new TimeoutException("Waited " + timeoutMillis + " ms!"); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /android/src/androidTest/java/com/android/i18n/addressinput/testing/TestActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.i18n.addressinput.testing; 18 | 19 | import android.app.Activity; 20 | 21 | public class TestActivity extends Activity {} 22 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/src/main/java/com/android/i18n/addressinput/AndroidAsyncEncodedRequestApi.java: -------------------------------------------------------------------------------- 1 | package com.android.i18n.addressinput; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.MalformedURLException; 5 | import java.net.URL; 6 | import java.net.URLEncoder; 7 | 8 | public class AndroidAsyncEncodedRequestApi extends AndroidAsyncRequestApi { 9 | /** 10 | * A quick hack to transform a string into an RFC 3986 compliant URL. 11 | * 12 | *

TODO: Refactor the code to stop passing URLs around as strings, to eliminate the need for 13 | * this broken hack. 14 | */ 15 | @Override 16 | protected URL stringToUrl(String url) throws MalformedURLException { 17 | int length = url.length(); 18 | StringBuilder tmp = new StringBuilder(length); 19 | 20 | try { 21 | for (int i = 0; i < length; i++) { 22 | int j = i; 23 | char c = '\0'; 24 | for (; j < length; j++) { 25 | c = url.charAt(j); 26 | if (c == ':' || c == '/') { 27 | break; 28 | } 29 | } 30 | if (j == length) { 31 | tmp.append(URLEncoder.encode(url.substring(i), "UTF-8")); 32 | break; 33 | } else if (j > i) { 34 | tmp.append(URLEncoder.encode(url.substring(i, j), "UTF-8")); 35 | tmp.append(c); 36 | i = j; 37 | } else { 38 | tmp.append(c); 39 | } 40 | } 41 | } catch (UnsupportedEncodingException e) { 42 | throw new AssertionError(e); // Impossible. 43 | } 44 | return new URL(tmp.toString()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /android/src/main/java/com/android/i18n/addressinput/PlaceDetailsApi.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.i18n.addressinput; 18 | 19 | import com.google.common.util.concurrent.ListenableFuture; 20 | import com.google.i18n.addressinput.common.AddressAutocompletePrediction; 21 | import com.google.i18n.addressinput.common.AddressData; 22 | 23 | /** 24 | * An interface for transforming an {@link AddressAutocompletePrediction} into {@link AddressData}. 25 | */ 26 | public interface PlaceDetailsApi { 27 | ListenableFuture getAddressData(AddressAutocompletePrediction prediction); 28 | } 29 | -------------------------------------------------------------------------------- /android/src/main/java/com/android/i18n/addressinput/autocomplete/gmscore/AddressAutocompletePredictionImpl.java: -------------------------------------------------------------------------------- 1 | package com.android.i18n.addressinput.autocomplete.gmscore; 2 | 3 | import com.google.android.gms.location.places.AutocompletePrediction; 4 | import com.google.i18n.addressinput.common.AddressAutocompletePrediction; 5 | 6 | /** 7 | * GMSCore implementation of {@link 8 | * com.google.i18n.addressinput.common.AddressAutocompletePrediction}. 9 | */ 10 | public class AddressAutocompletePredictionImpl extends AddressAutocompletePrediction { 11 | 12 | private AutocompletePrediction prediction; 13 | 14 | AddressAutocompletePredictionImpl(AutocompletePrediction prediction) { 15 | this.prediction = prediction; 16 | } 17 | 18 | @Override 19 | public String getPlaceId() { 20 | return prediction.getPlaceId(); 21 | } 22 | 23 | @Override 24 | public CharSequence getPrimaryText() { 25 | return prediction.getPrimaryText(null); 26 | } 27 | 28 | @Override 29 | public CharSequence getSecondaryText() { 30 | return prediction.getSecondaryText(null); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /android/src/main/res/drawable-v19/autocomplete_dropdown_item_background_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /android/src/main/res/drawable-v21/autocomplete_dropdown_item_background_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /android/src/main/res/layout/address_autocomplete_dropdown_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 27 | 28 | 37 | 38 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /android/src/main/res/layout/address_autocomplete_textview.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 28 | -------------------------------------------------------------------------------- /android/src/main/res/layout/address_autocomplete_view_group.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 23 | 24 | 33 | 34 | -------------------------------------------------------------------------------- /android/src/main/res/layout/address_edittext.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 26 | -------------------------------------------------------------------------------- /android/src/main/res/layout/address_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 26 | -------------------------------------------------------------------------------- /android/src/main/res/layout/address_spinner.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 25 | -------------------------------------------------------------------------------- /android/src/main/res/layout/address_textview.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 27 | -------------------------------------------------------------------------------- /android/src/main/res/values/address_dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 4dp 21 | 3dp 22 | 23 | 5dp 24 | 25 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Root Gradle file for Java address input widget (under "common" and "android") 19 | */ 20 | buildscript { 21 | repositories { 22 | mavenCentral() 23 | mavenLocal() 24 | google() 25 | } 26 | dependencies { 27 | classpath 'com.android.tools.build:gradle:8.2.2' 28 | } 29 | } 30 | 31 | allprojects { 32 | repositories { 33 | mavenCentral() 34 | mavenLocal() 35 | google() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /common/README.md: -------------------------------------------------------------------------------- 1 | # Building and running tests 2 | 3 | The common (non-UI) parts of libaddressinput are built and run using the Gradle 4 | project automation tool: 5 | 6 | https://developer.android.com/build http://www.gradle.org/ 7 | 8 | ## Prerequisite dependencies for using Gradle 9 | 10 | Use Android Studio to build packages and run tests. Alternatively, make use of 11 | the Gradle Wrapper Scripts: `gradlew` or `gradlew.bat`. 12 | 13 | ## Building and Running 14 | 15 | After installing all the prerequisites, check that everything is working by 16 | running: 17 | 18 | ##### On Linux / Unix / Mac 19 | 20 | - `gradlew build` 21 | - `gradlew test` 22 | 23 | ##### On Windows 24 | 25 | - `gradlew.bat build` 26 | - `gradlew.bat test` 27 | -------------------------------------------------------------------------------- /common/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'java-library' 18 | 19 | sourceCompatibility = JavaVersion.VERSION_11 20 | targetCompatibility = JavaVersion.VERSION_11 21 | 22 | tasks.withType(JavaCompile).configureEach { 23 | options.encoding = 'UTF-8' 24 | } 25 | 26 | sourceSets { 27 | /* It's simpler if the test resources are next to the java sources. */ 28 | test { 29 | resources { 30 | srcDir 'src/test/java' 31 | } 32 | } 33 | } 34 | 35 | test { 36 | /* Listen to events in the test execution lifecycle. */ 37 | beforeTest { descriptor -> logger.lifecycle("Running test: " + descriptor) } 38 | 39 | /* Show standard out and standard error of the test JVM(s) on the console. */ 40 | // testLogging.showStandardStreams = true 41 | 42 | /* Listen to standard out and standard error of the test JVM(s). */ 43 | // onOutput { descriptor, event -> 44 | // logger.lifecycle("Test: " + descriptor + " produced standard out/err: " + event.message ) 45 | // } 46 | } 47 | 48 | repositories { 49 | google() 50 | mavenLocal() 51 | mavenCentral() 52 | } 53 | 54 | dependencies { 55 | api 'com.google.errorprone:error_prone_annotations:2.18.0' 56 | api 'org.jspecify:jspecify:0.3.0' 57 | implementation 'com.google.guava:guava-gwt:18.0' 58 | /* Note that gradle will warn about this not being the same version as * 59 | * the Android JSON library (but will not compile if it's removed). */ 60 | implementation 'org.json:json:20090211' 61 | testImplementation 'junit:junit:4.11' 62 | testImplementation 'com.google.truth:truth:0.25' 63 | testImplementation 'org.mockito:mockito-core:5.11.0' 64 | } 65 | 66 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/AddressAutocompleteApi.java: -------------------------------------------------------------------------------- 1 | package com.google.i18n.addressinput.common; 2 | 3 | import com.google.common.util.concurrent.FutureCallback; 4 | import java.util.List; 5 | 6 | /** 7 | * AddressAutocompleteApi encapsulates the functionality required to fetch address autocomplete 8 | * suggestions for an unstructured address query string entered by the user. 9 | * 10 | * An implementation using GMSCore is provided under 11 | * libaddressinput/android/src/main.java/com/android/i18n/addressinput/autocomplete/gmscore. 12 | */ 13 | public interface AddressAutocompleteApi { 14 | /** 15 | * Returns true if the AddressAutocompleteApi is properly configured to fetch autocomplete 16 | * predictions. This allows the caller to enable autocomplete only if the AddressAutocompleteApi 17 | * is properly configured (e.g. the user has granted all the necessary permissions). 18 | */ 19 | boolean isConfiguredCorrectly(); 20 | 21 | /** 22 | * Given an unstructured address query, getAutocompletePredictions fetches autocomplete 23 | * suggestions for the intended address and provides these suggestions via the callback. 24 | */ 25 | void getAutocompletePredictions( 26 | String query, FutureCallback> callback); 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/AddressAutocompletePrediction.java: -------------------------------------------------------------------------------- 1 | package com.google.i18n.addressinput.common; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * AddressAutocompletePrediction represents an autocomplete suggestion. 7 | * 8 | * Concrete inheriting classes must provide implementations of {@link #getPlaceId}, {@link 9 | * #getPrimaryText}, and {@link #getSecondaryText}. An implementation using GMSCore is provided 10 | * under libaddressinput/android/src/main.java/com/android/i18n/addressinput/autocomplete/gmscore. 11 | */ 12 | public abstract class AddressAutocompletePrediction { 13 | /** 14 | * Returns the place ID of the predicted place. A place ID is a textual identifier that uniquely 15 | * identifies a place, which you can use to retrieve the Place object again later (for example, 16 | * with Google's Place Details Web API). 17 | */ 18 | public abstract String getPlaceId(); 19 | 20 | /** 21 | * Returns the main text describing a place. This is usually the name of the place. Examples: 22 | * "Eiffel Tower", and "123 Pitt Street". 23 | */ 24 | public abstract CharSequence getPrimaryText(); 25 | 26 | /** 27 | * Returns the subsidiary text of a place description. This is useful, for example, as a second 28 | * line when showing autocomplete predictions. Examples: "Avenue Anatole France, Paris, France", 29 | * and "Sydney, New South Wales". 30 | */ 31 | public abstract CharSequence getSecondaryText(); 32 | 33 | // equals and hashCode overridden for testing. 34 | 35 | @Override 36 | public boolean equals(Object o) { 37 | if (!(o instanceof AddressAutocompletePrediction)) { 38 | return false; 39 | } 40 | AddressAutocompletePrediction p = (AddressAutocompletePrediction) o; 41 | 42 | return getPlaceId().equals(p.getPlaceId()) 43 | && getPrimaryText().equals(p.getPrimaryText()) 44 | && getSecondaryText().equals(p.getSecondaryText()); 45 | } 46 | 47 | @Override 48 | public int hashCode() { 49 | return Objects.hash(getPlaceId(), getPrimaryText(), getSecondaryText()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/AddressProblemType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | /** 20 | * Enumerates problems that default address verification can report. 21 | */ 22 | // This is an external class and part of the widget's public API. 23 | // TODO: Review public API for external classes. 24 | public enum AddressProblemType { 25 | /** 26 | * The field is not null and not whitespace, and the field should not be used by addresses in this 27 | * country. 28 | *

29 | * For example, in the U.S. the SORTING_CODE field is unused, so its presence is an 30 | * error. This cannot happen when using the Address Widget to enter an address. 31 | */ 32 | UNEXPECTED_FIELD, 33 | 34 | /** 35 | * The field is null or whitespace, and the field is required for addresses in this country. 36 | *

37 | * For example, in the U.S. ADMIN_AREA is a required field. 38 | */ 39 | MISSING_REQUIRED_FIELD, 40 | 41 | /** 42 | * A list of values for the field is defined and the value does not occur in the list. Applies 43 | * to hierarchical elements like REGION, ADMIN_AREA, LOCALITY, and DEPENDENT_LOCALITY. 44 | * 45 | *

For example, in the U.S. the only valid values for ADMIN_AREA are the two-letter state 46 | * codes. 47 | */ 48 | UNKNOWN_VALUE, 49 | 50 | /** 51 | * A format for the field is defined and the value does not match. This is used to match 52 | * POSTAL_CODE against the general format pattern. Formats indicate how many digits/letters should 53 | * be present, and what punctuation is allowed. 54 | *

55 | * For example, in the U.S. postal codes are five digits with an optional hyphen followed by 56 | * four digits. 57 | */ 58 | INVALID_FORMAT, 59 | 60 | /** 61 | * A specific pattern for the field is defined and the value does not match. This is used to match 62 | * example) and the value does not match. This is used to match POSTAL_CODE against a regular 63 | * expression. 64 | *

65 | * For example, in the US postal codes in the state of California start with a '9'. 66 | */ 67 | MISMATCHING_VALUE; 68 | 69 | /** 70 | * Returns a unique string identifying this problem (for use in a message catalog). 71 | */ 72 | public String keyname() { 73 | return Util.toLowerCaseLocaleIndependent(name()); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/AddressProblems.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | import java.util.Map.Entry; 22 | 23 | /** 24 | * This structure keeps track of any errors found when validating the AddressData. 25 | */ 26 | // This is an external class and part of the widget's public API. 27 | // TODO: Review public API for external classes and tidy JavaDoc. 28 | public final class AddressProblems { 29 | private Map problems = 30 | new HashMap(); 31 | 32 | /** 33 | * Adds a problem of the given type for the given address field. Only one address problem is 34 | * saved per address field. 35 | */ 36 | void add(AddressField addressField, AddressProblemType problem) { 37 | problems.put(addressField, problem); 38 | } 39 | 40 | /** 41 | * Returns true if no problems have been added. 42 | */ 43 | public boolean isEmpty() { 44 | return problems.isEmpty(); 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return problems.toString(); 50 | } 51 | 52 | public void clear() { 53 | problems.clear(); 54 | } 55 | 56 | /** 57 | * Returns null if no problems exists. 58 | */ 59 | public AddressProblemType getProblem(AddressField addressField) { 60 | return problems.get(addressField); 61 | } 62 | 63 | /** 64 | * This will return an empty map if there are no problems. 65 | */ 66 | public Map getProblems() { 67 | return problems; 68 | } 69 | 70 | /** 71 | * Adds all problems this object contains to the given {@link AddressProblems} object. 72 | */ 73 | public void copyInto(AddressProblems other) { 74 | for (Entry problem : problems.entrySet()) { 75 | other.add(problem.getKey(), problem.getValue()); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/AddressVerificationNodeData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | import java.util.Map; 20 | 21 | /** 22 | * A map of {@link AddressDataKey}s to JSON strings. Provides data for a single node in the address 23 | * data hierarchy (for example, "data/US/CA"). Key is an AddressDataKey and the value is the raw 24 | * string representing that data. This is either a single string, or an array of strings represented 25 | * as a single string using '~' to separate the elements of the array, depending on the 26 | * AddressDataKey. 27 | */ 28 | public final class AddressVerificationNodeData { 29 | private final Map map; 30 | 31 | public AddressVerificationNodeData(Map map) { 32 | Util.checkNotNull(map, "Cannot construct StandardNodeData with null map"); 33 | this.map = map; 34 | } 35 | 36 | public boolean containsKey(AddressDataKey key) { 37 | return map.containsKey(key); 38 | } 39 | 40 | /** 41 | * Gets the value for a particular key in the map. 42 | */ 43 | public String get(AddressDataKey key) { 44 | return map.get(key); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/AsyncRequestApi.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | /** 20 | * Abstracted low-level network request API. Implementations making real network requests should 21 | * attempt to redirect and retry as necessary such that any failure can be considered definitive, as 22 | * the users of this interface will never retry failed requests. 23 | */ 24 | public interface AsyncRequestApi { 25 | /** 26 | * Requests JSON metadata from the given URL and invokes the appropriate methods in the given 27 | * callback. If the given callback is null, the asynchronous request is still made but no callback 28 | * methods are invoked. If the given timeout is exceeded then the implementation should, where 29 | * feasible, attempt to cancel the in-progress network request, but must always invoke the 30 | * {@link AsyncCallback#onFailure()} callback a short, bounded time after the timeout occurred. 31 | * 32 | * @param url the complete URL for the request 33 | * @param callback the optional callback to be invoked when the request is complete 34 | * @param timeoutMillis the timeout for the request in milliseconds 35 | */ 36 | void requestObject(String url, AsyncCallback callback, int timeoutMillis); 37 | 38 | /** 39 | * Callback API for network requests. One of the methods in this API will be invoked by the 40 | * {@link AsyncRequestApi} implementation once the network request is complete or has timed out. 41 | */ 42 | public interface AsyncCallback { 43 | /** Invoked with the parsed JsoMap from the successful request. */ 44 | public void onSuccess(JsoMap result); 45 | 46 | /** Invoked when a request has definitely failed (after possible retries, redirection ...). */ 47 | public void onFailure(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/ClientCacheManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | /** 20 | * Used by AddressWidget to handle caching in client-specific ways. 21 | */ 22 | // This is an external class and part of the widget's public API. 23 | // TODO: Review public API for external classes and tidy JavaDoc. 24 | public interface ClientCacheManager { 25 | /** Get the data that is cached for the given key. */ 26 | public String get(String key); 27 | /** Put the data for the given key into the cache. */ 28 | public void put(String key, String data); 29 | /** Get the URL of the server that serves address metadata. */ 30 | public String getAddressServerUrl(); 31 | } 32 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/DataLoadListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | /** 20 | * Invoked when the data is fetched from the server or the cache. 21 | */ 22 | public interface DataLoadListener { 23 | // These callbacks are invoked from a background thread. 24 | void dataLoadingBegin(); 25 | void dataLoadingEnd(); 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/DataSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | /** 20 | * API for returning JSON content for a given key string (eg, "data/US"). The content is 21 | * returned as a map within an {@link AddressVerificationNodeData} instance. This interface 22 | * exists only to isolate this API and allow us to swap in a different version in future 23 | * without risking callers depending on unexpected parts of the verifier API. 24 | */ 25 | // TODO: Add a way to load static data without using the AddressVerificationData and remove 26 | // this interface (along with AddressVerificationData). 27 | public interface DataSource { 28 | /** 29 | * Returns the default JSON data for the given key string (this method should complete immediately 30 | * and must not trigger any network requests. 31 | */ 32 | AddressVerificationNodeData getDefaultData(String key); 33 | 34 | /** 35 | * A blocking method to return the JSON data for the given key string. This method will 36 | * block the current thread until data is available or until a timeout occurs (at which point the 37 | * default data will be returned). All networking and failure states are hidden from the caller by 38 | * this API. 39 | */ 40 | // TODO: This is very poor API and should be changed to avoid blocking and let the caller 41 | // manage requests asynchronously. 42 | AddressVerificationNodeData get(String key); 43 | } 44 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/NotifyingListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | /** 20 | * A helper class to let the calling thread wait until loading has finished. 21 | */ 22 | // TODO: Consider dealing with interruption in a more recoverable way. 23 | public final class NotifyingListener implements DataLoadListener { 24 | private boolean done = false; 25 | 26 | @Override 27 | public void dataLoadingBegin() { 28 | } 29 | 30 | @Override 31 | public synchronized void dataLoadingEnd() { 32 | done = true; 33 | notifyAll(); 34 | } 35 | 36 | /** 37 | * Waits for a call to {@link #dataLoadingEnd} to have occurred. If this thread is interrupted, 38 | * the {@code InterruptedException} is propagated immediately and the loading may not yet have 39 | * finished. This leaves callers in a potentially unrecoverable state. 40 | */ 41 | public synchronized void waitLoadingEnd() throws InterruptedException { 42 | while (!done) { 43 | wait(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/OnAddressSelectedListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | /** 20 | * If autocomplete is enabled on the AddressWidget, setting an OnAddressSelectedListener 21 | * will cause onAddressSelected to be called when the user clicks on an autocomplete 22 | * suggestion in the dropdown list. 23 | */ 24 | public interface OnAddressSelectedListener { 25 | void onAddressSelected(AddressData addressData); 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/com/google/i18n/addressinput/common/SimpleClientCacheManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | /** 20 | * A simple implementation of ClientCacheManager which doesn't do any caching on its own. 21 | */ 22 | // This is an external class and part of the widget's public API. 23 | // TODO: Review public API for external classes and tidy JavaDoc. 24 | public final class SimpleClientCacheManager implements ClientCacheManager { 25 | // URL to get public address data. 26 | static final String PUBLIC_ADDRESS_SERVER = "https://chromium-i18n.appspot.com/ssl-address"; 27 | 28 | @Override 29 | public String get(String key) { 30 | return ""; 31 | } 32 | 33 | @Override 34 | public void put(String key, String data) { 35 | } 36 | 37 | @Override 38 | public String getAddressServerUrl() { 39 | return PUBLIC_ADDRESS_SERVER; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /common/src/test/java/com/google/i18n/addressinput/common/AddressFieldTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import com.google.i18n.addressinput.common.AddressField.WidthType; 22 | 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.junit.runners.JUnit4; 26 | 27 | @RunWith(JUnit4.class) 28 | public class AddressFieldTest { 29 | @Test public void testOf() throws Exception { 30 | assertEquals(AddressField.COUNTRY, AddressField.of('R')); 31 | } 32 | 33 | @Test public void testGetChar() throws Exception { 34 | assertEquals('R', AddressField.COUNTRY.getChar()); 35 | } 36 | 37 | @Test public void testGetWidthTypeForPostalCode() throws Exception { 38 | // Postal (& sorting) code always have SHORT width. 39 | assertEquals(WidthType.SHORT, AddressField.POSTAL_CODE.getWidthTypeForRegion("US")); 40 | assertEquals(WidthType.SHORT, AddressField.SORTING_CODE.getWidthTypeForRegion("DE")); 41 | } 42 | 43 | @Test public void testGetWidthTypeForCountry() throws Exception { 44 | // No overrides for country, so we use the default, LONG. 45 | assertEquals(WidthType.LONG, AddressField.COUNTRY.getWidthTypeForRegion("US")); 46 | assertEquals(WidthType.LONG, AddressField.COUNTRY.getWidthTypeForRegion("CH")); 47 | } 48 | 49 | @Test public void testGetWidthTypeWithOverride() throws Exception { 50 | // With an override. 51 | assertEquals(WidthType.SHORT, AddressField.LOCALITY.getWidthTypeForRegion("CN")); 52 | // Without an override. 53 | assertEquals(WidthType.LONG, AddressField.LOCALITY.getWidthTypeForRegion("US")); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /common/src/test/java/com/google/i18n/addressinput/common/AddressProblemsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertNull; 21 | import static org.junit.Assert.assertTrue; 22 | 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.junit.runners.JUnit4; 26 | 27 | @RunWith(JUnit4.class) 28 | public class AddressProblemsTest { 29 | @Test public void testAddError() { 30 | AddressProblems ap = new AddressProblems(); 31 | ap.add(AddressField.POSTAL_CODE, AddressProblemType.MISSING_REQUIRED_FIELD); 32 | assertEquals(AddressProblemType.MISSING_REQUIRED_FIELD, 33 | ap.getProblem(AddressField.POSTAL_CODE)); 34 | } 35 | 36 | @Test public void testEmptyErrorList() { 37 | AddressProblems ap = new AddressProblems(); 38 | assertNull(ap.getProblem(AddressField.POSTAL_CODE)); 39 | assertTrue(ap.isEmpty()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /common/src/test/java/com/google/i18n/addressinput/common/RegionDataConstantsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | import static org.junit.Assert.assertFalse; 20 | import static org.junit.Assert.assertNotNull; 21 | import static org.junit.Assert.assertTrue; 22 | 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.junit.runners.JUnit4; 26 | 27 | /** 28 | * Tests for the region data constants to check they are populated and that the data can be read in 29 | * and converted into the appropriate format. 30 | */ 31 | @RunWith(JUnit4.class) 32 | public class RegionDataConstantsTest { 33 | @Test public void testDataLoad() throws Exception { 34 | assertFalse("The list of countries should not be empty", 35 | RegionDataConstants.getCountryFormatMap().isEmpty()); 36 | } 37 | 38 | @Test public void testZZRegion() throws Exception { 39 | assertNotNull("Data for 'ZZ' is missing (needed for default region info.)", 40 | RegionDataConstants.getCountryFormatMap().get("ZZ")); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /common/src/test/java/com/google/i18n/addressinput/common/RegionDataTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.common; 18 | 19 | import junit.framework.TestCase; 20 | 21 | import org.junit.Test; 22 | import org.junit.runner.RunWith; 23 | import org.junit.runners.JUnit4; 24 | 25 | @RunWith(JUnit4.class) 26 | public class RegionDataTest extends TestCase { 27 | 28 | @Test public void testBuilder() throws Exception { 29 | RegionData data = new RegionData.Builder().setKey("CA").setName("California").build(); 30 | assertEquals("CA", data.getKey()); 31 | assertEquals("California", data.getName()); 32 | assertTrue(data.isValidName("CA")); 33 | // Should match either the key or the name. 34 | assertTrue(data.isValidName("California")); 35 | // Matching should be case-insensitive. 36 | assertTrue(data.isValidName("ca")); 37 | assertFalse(data.isValidName("Cat")); 38 | } 39 | 40 | @Test public void testBuilderNoName() throws Exception { 41 | RegionData data = new RegionData.Builder().setKey("CA").build(); 42 | assertEquals("CA", data.getKey()); 43 | assertEquals(null, data.getName()); 44 | } 45 | 46 | @Test public void testBuilderWhitespaceName() throws Exception { 47 | RegionData data = new RegionData.Builder().setKey("CA").setName(" ").build(); 48 | assertEquals("CA", data.getKey()); 49 | assertEquals(null, data.getName()); 50 | assertEquals("CA", data.getDisplayName()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /common/src/test/java/com/google/i18n/addressinput/testing/AddressDataMapLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.testing; 18 | 19 | import java.io.BufferedReader; 20 | import java.io.IOException; 21 | import java.io.InputStreamReader; 22 | import java.util.Collections; 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | 26 | /** 27 | * Helper class to load JSON data for testing. 28 | */ 29 | public class AddressDataMapLoader { 30 | private static final String DATA_PATH = "countryinfo.txt"; 31 | 32 | private AddressDataMapLoader() { 33 | } 34 | 35 | public static final Map TEST_COUNTRY_DATA = loadImmutableTestDataMap(); 36 | 37 | private static Map loadImmutableTestDataMap() { 38 | HashMap map = new HashMap(); 39 | try { 40 | BufferedReader br = new BufferedReader(new InputStreamReader( 41 | AddressDataMapLoader.class.getResourceAsStream(DATA_PATH), "UTF-8")); 42 | String line; 43 | while (null != (line = br.readLine())) { 44 | line = line.trim(); 45 | if (line.length() == 0 || line.charAt(0) == '#') { 46 | continue; 47 | } 48 | int x = line.indexOf('='); 49 | map.put(line.substring(0, x), line.substring(x + 1)); 50 | } 51 | } catch (IOException e) { 52 | System.err.println("unable to create map: " + e.getMessage()); 53 | } 54 | return Collections.unmodifiableMap(map); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /common/src/test/java/com/google/i18n/addressinput/testing/InMemoryAsyncRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.i18n.addressinput.testing; 18 | 19 | import com.google.i18n.addressinput.common.AsyncRequestApi; 20 | import com.google.i18n.addressinput.common.JsoMap; 21 | 22 | import org.json.JSONException; 23 | 24 | import java.util.HashMap; 25 | import java.util.Map; 26 | 27 | /** 28 | * Fake implementation of AsyncRequestApi which loads data synchronously and immediately. 29 | * Can be used manually with custom test data or with a snapshot of real data found in 30 | * {@link AddressDataMapLoader#TEST_COUNTRY_DATA}. 31 | */ 32 | public class InMemoryAsyncRequest implements AsyncRequestApi { 33 | private final Map responseMap = new HashMap(); 34 | 35 | public InMemoryAsyncRequest(String urlPrefix, Map keyToJsonMap) { 36 | try { 37 | for (Map.Entry e : keyToJsonMap.entrySet()) { 38 | responseMap.put(urlPrefix + "/" + e.getKey(), JsoMap.buildJsoMap(e.getValue())); 39 | } 40 | } catch (JSONException e) { 41 | throw new AssertionError("Invalid test JSON data: " + keyToJsonMap, e); 42 | } 43 | } 44 | 45 | @Override 46 | public void requestObject(String url, AsyncCallback callback, int timeoutMillis) { 47 | if (responseMap.containsKey(url)) { 48 | callback.onSuccess(responseMap.get(url)); 49 | } else { 50 | callback.onFailure(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /cpp/LICENSE.chromium: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are 5 | // met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above 10 | // copyright notice, this list of conditions and the following disclaimer 11 | // in the documentation and/or other materials provided with the 12 | // distribution. 13 | // * Neither the name of Google Inc. nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /cpp/README.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | The C++ version of libaddressinput library provides UI layout information and 4 | validation for address input forms. 5 | 6 | The library does not provide a UI. The user of the library must provide the user 7 | interface that uses libaddressinput. The user of the library must also provide a 8 | way to store data on disk and download data from the internet. 9 | 10 | The first client of the library is Chrome web browser. This motivates not 11 | providing UI or networking capabilities. Chrome will provide those. 12 | 13 | When including the library in your project, you can override the dependencies 14 | and include directories in libaddressinput.gypi to link with your own 15 | third-party libraries. 16 | 17 | # Dependencies 18 | 19 | The library depends on these tools and libraries: 20 | 21 | GYP: Generates the build files. 22 | Ninja: Executes the build files. 23 | GTest: Used for unit tests. 24 | Python: Used by GRIT, which generates localization files. 25 | RE2: Used for validating postal code format. 26 | 27 | Most of these packages are available on Debian-like distributions. You can 28 | install them with this command: 29 | 30 | $ sudo apt-get install gyp ninja-build libgtest-dev python3 libre2-dev 31 | 32 | Make sure that your version of GYP is at least 0.1~svn1395. Older versions of 33 | GYP do not generate the Ninja build files correctly. You can download a 34 | new-enough version from http://packages.ubuntu.com/saucy/gyp. 35 | 36 | Make sure that your version of RE2 is at least 20140111+dfsg-1. Older versions 37 | of RE2 don't support set_never_capture() and the packages don't provide shared 38 | libraries. 39 | 40 | If your distribution does not include the binary packages for the dependencies, 41 | you can download them from these locations: 42 | 43 | http://packages.ubuntu.com/saucy/gyp 44 | http://packages.ubuntu.com/saucy/ninja-build 45 | http://packages.ubuntu.com/saucy/libgtest-dev 46 | http://packages.ubuntu.com/saucy/python 47 | http://packages.ubuntu.com/utopic/libre2-1 48 | http://packages.ubuntu.com/utopic/libre2-dev 49 | 50 | Alternatively, you can download, build, and install these tools and libraries 51 | from source code. Their home pages contain information on how to accomplish 52 | that. 53 | 54 | https://code.google.com/p/gyp/ 55 | http://martine.github.io/ninja/ 56 | https://code.google.com/p/googletest/ 57 | http://python.org/ 58 | https://code.google.com/p/re2/ 59 | 60 | # Build 61 | 62 | Building the library involves generating an out/Default/build.ninja file and 63 | running ninja: 64 | 65 | ``` 66 | export GYP_GENERATORS='ninja' 67 | gyp --depth . 68 | ninja -C out/Default 69 | ``` 70 | 71 | Overriding paths defined in the *.gyp files can be done by setting the 72 | GYP_DEFINES environment variable before running gyp: 73 | 74 | ``` 75 | export GYP_DEFINES="gtest_dir='/xxx/include' gtest_src_dir='/xxx'" 76 | ``` 77 | 78 | # Test 79 | 80 | This command will execute the unit tests for the library: 81 | 82 | $ out/Default/unit_tests 83 | -------------------------------------------------------------------------------- /cpp/grit.gyp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | { 15 | 'variables': { 16 | 'grit_dir%': '<(DEPTH)/../externals/grit', 17 | }, 18 | 'targets': [ 19 | { 20 | 'target_name': 'generated_messages', 21 | 'type': 'none', 22 | 'sources': [ 23 | 'res/messages.grd', 24 | ], 25 | 'actions': [ 26 | { 27 | 'action_name': 'generate_messages', 28 | 'inputs': [ 29 | '<(grit_dir)/grit.py', 30 | 'res/messages.grd', 31 | 'res/messages.grdp', 32 | ], 33 | 'outputs': [ 34 | '<(SHARED_INTERMEDIATE_DIR)/en_messages.cc', 35 | '<(SHARED_INTERMEDIATE_DIR)/messages.h', 36 | ], 37 | 'action': [ 38 | 'python3', 39 | '<(grit_dir)/grit.py', 40 | '-i', 41 | 'res/messages.grd', 42 | 'build', 43 | '-o', 44 | '<(SHARED_INTERMEDIATE_DIR)', 45 | ], 46 | }, 47 | ], 48 | 'all_dependent_settings': { 49 | 'include_dirs': [ 50 | '<(SHARED_INTERMEDIATE_DIR)', 51 | ], 52 | }, 53 | }, 54 | ], 55 | } 56 | -------------------------------------------------------------------------------- /cpp/gtest.gyp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | { 15 | 'variables': { 16 | # Default include directories. Override with your system's include paths or 17 | # paths to your own implementations. 18 | 'gtest_dir%': '/usr/include', 19 | 'gtest_src_dir%': '/usr/src/gtest', 20 | }, 21 | 'targets': [ 22 | { 23 | 'target_name': 'main', 24 | 'type': 'static_library', 25 | 'sources': [ 26 | '<(SHARED_INTERMEDIATE_DIR)/src/gtest-all.cc', 27 | ], 28 | 'include_dirs': [ 29 | '<(gtest_dir)', 30 | '<(gtest_src_dir)', 31 | ], 32 | 'copies': [ 33 | { 34 | 'destination': '<(SHARED_INTERMEDIATE_DIR)/src', 35 | 'files': [ 36 | '<(gtest_src_dir)/src/gtest-all.cc', 37 | '<(gtest_src_dir)/src/gtest_main.cc', 38 | ], 39 | }, 40 | ], 41 | 'direct_dependent_settings': { 42 | 'sources': [ 43 | '<(SHARED_INTERMEDIATE_DIR)/src/gtest_main.cc', 44 | ], 45 | 'include_dirs': [ 46 | '<(gtest_dir)', 47 | ], 48 | 'conditions': [ 49 | ['OS == "linux"', { 50 | 'ldflags': [ 51 | '-pthread', # GTest needs to link to pthread on Linux. 52 | ], 53 | }], 54 | ], 55 | }, 56 | }, 57 | ], 58 | } 59 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/address_field.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ADDRESS_FIELD_H_ 16 | #define I18N_ADDRESSINPUT_ADDRESS_FIELD_H_ 17 | 18 | #include 19 | 20 | namespace i18n { 21 | namespace addressinput { 22 | 23 | // Address field types, ordered by size, from largest to smallest. 24 | enum AddressField { 25 | COUNTRY, // Country code. 26 | ADMIN_AREA, // Administrative area such as a state, province, 27 | // island, etc. 28 | LOCALITY, // City or locality. 29 | DEPENDENT_LOCALITY, // Dependent locality (may be an inner-city district or 30 | // a suburb). 31 | SORTING_CODE, // Sorting code. 32 | POSTAL_CODE, // Zip or postal code. 33 | STREET_ADDRESS, // Street address lines. 34 | ORGANIZATION, // Organization, company, firm, institution, etc. 35 | RECIPIENT // Name. 36 | }; 37 | 38 | } // namespace addressinput 39 | } // namespace i18n 40 | 41 | // Produces human-readable output in logging, for example in unit tests. Prints 42 | // what you would expect for valid fields, e.g. "COUNTRY" for COUNTRY. For 43 | // invalid values, prints "[INVALID ENUM VALUE x]". 44 | std::ostream& operator<<(std::ostream& o, 45 | i18n::addressinput::AddressField field); 46 | 47 | #endif // I18N_ADDRESSINPUT_ADDRESS_FIELD_H_ 48 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/address_formatter.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // Utility functions for formatting the addresses represented as AddressData. 16 | // 17 | // Note these work best if the address has a language code specified - this can 18 | // be obtained when building the UI components (calling BuildComponents on 19 | // address_ui.h). 20 | 21 | #ifndef I18N_ADDRESSINPUT_ADDRESS_FORMATTER_H_ 22 | #define I18N_ADDRESSINPUT_ADDRESS_FORMATTER_H_ 23 | 24 | #include 25 | #include 26 | 27 | namespace i18n { 28 | namespace addressinput { 29 | 30 | struct AddressData; 31 | 32 | // Formats the address onto multiple lines. This formats the address in national 33 | // format; without the country. 34 | void GetFormattedNationalAddress( 35 | const AddressData& address_data, std::vector* lines); 36 | 37 | // Formats the address as a single line. This formats the address in national 38 | // format; without the country. 39 | void GetFormattedNationalAddressLine( 40 | const AddressData& address_data, std::string* line); 41 | 42 | // Formats the street-level part of an address as a single line. For example, 43 | // two lines of "Apt 1", "10 Red St." will be concatenated in a 44 | // language-appropriate way, to give something like "Apt 1, 10 Red St". 45 | void GetStreetAddressLinesAsSingleLine( 46 | const AddressData& address_data, std::string* line); 47 | 48 | } // namespace addressinput 49 | } // namespace i18n 50 | 51 | #endif // I18N_ADDRESSINPUT_ADDRESS_FORMATTER_H_ 52 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/address_input_helper.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ADDRESS_INPUT_HELPER_H_ 16 | #define I18N_ADDRESSINPUT_ADDRESS_INPUT_HELPER_H_ 17 | 18 | #include 19 | 20 | namespace i18n { 21 | namespace addressinput { 22 | 23 | class LookupKey; 24 | class PreloadSupplier; 25 | struct AddressData; 26 | struct Node; 27 | 28 | class AddressInputHelper { 29 | public: 30 | AddressInputHelper(const AddressInputHelper&) = delete; 31 | AddressInputHelper& operator=(const AddressInputHelper&) = delete; 32 | 33 | // Creates an input helper that uses the supplier provided to get metadata to 34 | // help a user complete or fix an address. Doesn't take ownership of 35 | // |supplier|. Since latency is important for these kinds of tasks, we expect 36 | // the supplier to have the data already. 37 | AddressInputHelper(PreloadSupplier* supplier); 38 | ~AddressInputHelper() = default; 39 | 40 | // Fill in missing components of an address as best as we can based on 41 | // existing data. For example, for some countries only one postal code is 42 | // valid; this would enter that one. For others, the postal code indicates 43 | // what state should be selected. Existing data will never be overwritten. 44 | // 45 | // Note that the preload supplier must have had the rules for the country 46 | // represented by this address loaded before this method is called - otherwise 47 | // an assertion failure will result. 48 | // 49 | // The address should have the best language tag as returned from 50 | // BuildComponents(). 51 | void FillAddress(AddressData* address) const; 52 | 53 | private: 54 | void CheckChildrenForPostCodeMatches( 55 | const AddressData& address, const LookupKey& lookup_key, 56 | const Node* parent, std::vector* hierarchy) const; 57 | 58 | // We don't own the supplier_. 59 | PreloadSupplier* const supplier_; 60 | }; 61 | 62 | } // namespace addressinput 63 | } // namespace i18n 64 | 65 | #endif // I18N_ADDRESSINPUT_ADDRESS_INPUT_HELPER_H_ 66 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/address_metadata.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ADDRESS_METADATA_H_ 16 | #define I18N_ADDRESSINPUT_ADDRESS_METADATA_H_ 17 | 18 | #include 19 | 20 | #include 21 | 22 | namespace i18n { 23 | namespace addressinput { 24 | 25 | // Checks whether |field| is a required field for |region_code|. Returns false 26 | // also if no data could be found for region_code. Note: COUNTRY is always 27 | // required. 28 | bool IsFieldRequired(AddressField field, const std::string& region_code); 29 | 30 | // Checks whether |field| is a field that is used for |region_code|. Returns 31 | // false also if no data could be found for region_code. Note: COUNTRY is always 32 | // used. 33 | bool IsFieldUsed(AddressField field, const std::string& region_code); 34 | 35 | } // namespace addressinput 36 | } // namespace i18n 37 | 38 | #endif // I18N_ADDRESSINPUT_ADDRESS_METADATA_H_ 39 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/address_normalizer.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ADDRESS_NORMALIZER_H_ 16 | #define I18N_ADDRESSINPUT_ADDRESS_NORMALIZER_H_ 17 | 18 | #include 19 | 20 | namespace i18n { 21 | namespace addressinput { 22 | 23 | class PreloadSupplier; 24 | class StringCompare; 25 | struct AddressData; 26 | 27 | class AddressNormalizer { 28 | public: 29 | AddressNormalizer(const AddressNormalizer&) = delete; 30 | AddressNormalizer& operator=(const AddressNormalizer&) = delete; 31 | 32 | // Does not take ownership of |supplier|. 33 | explicit AddressNormalizer(const PreloadSupplier* supplier); 34 | ~AddressNormalizer(); 35 | 36 | // Converts the names of different fields in the address into their canonical 37 | // form. Should be called only when supplier->IsLoaded() returns true for 38 | // the region code of the |address|. 39 | void Normalize(AddressData* address) const; 40 | 41 | private: 42 | const PreloadSupplier* const supplier_; // Not owned. 43 | const std::unique_ptr compare_; 44 | }; 45 | 46 | } // namespace addressinput 47 | } // namespace i18n 48 | 49 | #endif // I18N_ADDRESSINPUT_ADDRESS_NORMALIZER_H_ 50 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/address_ui.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ADDRESS_UI_H_ 16 | #define I18N_ADDRESSINPUT_ADDRESS_UI_H_ 17 | 18 | #include 19 | #include 20 | 21 | namespace i18n { 22 | namespace addressinput { 23 | 24 | class Localization; 25 | struct AddressUiComponent; 26 | 27 | // Returns the list of supported CLDR region codes. 28 | const std::vector& GetRegionCodes(); 29 | 30 | // Returns the UI components for the CLDR |region_code|. Uses the strings from 31 | // |localization|. The components can be in default or Latin order, depending on 32 | // the BCP 47 |ui_language_tag|. 33 | // 34 | // Sets the |best_address_language_tag| to the BCP 47 language tag that should 35 | // be saved with this address. This language will be used to get drop-downs to 36 | // help users fill in their address, and to format the address that the user 37 | // entered. The parameter should not be nullptr. 38 | // 39 | // Returns an empty vector on error. 40 | std::vector BuildComponents( 41 | const std::string& region_code, 42 | const Localization& localization, 43 | const std::string& ui_language_tag, 44 | std::string* best_address_language_tag); 45 | 46 | // Similar to BuildComponents() but in addition, it returns literals such as 47 | // "-", "\n" and ",". 48 | std::vector BuildComponentsWithLiterals( 49 | const std::string& region_code, const Localization& localization, 50 | const std::string& ui_language_tag, std::string* best_address_language_tag); 51 | 52 | } // namespace addressinput 53 | } // namespace i18n 54 | 55 | #endif // I18N_ADDRESSINPUT_ADDRESS_UI_H_ 56 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/address_ui_component.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ADDRESS_UI_COMPONENT_H_ 16 | #define I18N_ADDRESSINPUT_ADDRESS_UI_COMPONENT_H_ 17 | 18 | #include 19 | 20 | #include 21 | 22 | namespace i18n { 23 | namespace addressinput { 24 | 25 | // A description of an input field or a literal in an address form. The user of 26 | // the library will use a list of these elements to layout the address form 27 | // input fields. If `literal` is empty, this AddressUiComponent represents a 28 | // field, otherwise, it represent the literal stored in `literal`. 29 | struct AddressUiComponent { 30 | // The types of hints for how large the field should be in a multiline address 31 | // form. 32 | enum LengthHint { 33 | HINT_LONG, // The field should take up the whole line. 34 | HINT_SHORT // The field does not need to take up the whole line. 35 | }; 36 | 37 | // The address field type for this UI component, for example LOCALITY. 38 | AddressField field; 39 | 40 | // The name of the field, for example "City". 41 | std::string name; 42 | 43 | // The hint for how large the input field should be in a multiline address 44 | // form. 45 | LengthHint length_hint; 46 | 47 | // The literal string for this element. This field is dedicated 48 | // for literals such as "," "-", "\n" and " ". If empty, then this 49 | // AddressUiComponent represents an address field type not a literal. 50 | std::string literal; 51 | }; 52 | 53 | } // namespace addressinput 54 | } // namespace i18n 55 | 56 | #endif // I18N_ADDRESSINPUT_ADDRESS_UI_COMPONENT_H_ 57 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/null_storage.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // It is not always desirable to cache libaddressinput data. Sometimes it might 16 | // give better performance characteristics to not cache. This implementation of 17 | // the Storage interface therefore doesn't actually store anything. 18 | 19 | #ifndef I18N_ADDRESSINPUT_NULL_STORAGE_H_ 20 | #define I18N_ADDRESSINPUT_NULL_STORAGE_H_ 21 | 22 | #include 23 | 24 | #include 25 | 26 | namespace i18n { 27 | namespace addressinput { 28 | 29 | class NullStorage : public Storage { 30 | public: 31 | NullStorage(const NullStorage&) = delete; 32 | NullStorage& operator=(const NullStorage&) = delete; 33 | 34 | NullStorage(); 35 | ~NullStorage() override; 36 | 37 | // No-op. 38 | void Put(const std::string& key, std::string* data) override; 39 | 40 | // Always calls the |data_ready| callback function signaling failure. 41 | void Get(const std::string& key, const Callback& data_ready) const override; 42 | }; 43 | 44 | } // namespace addressinput 45 | } // namespace i18n 46 | 47 | #endif // I18N_ADDRESSINPUT_NULL_STORAGE_H_ 48 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/ondemand_supplier.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ONDEMAND_SUPPLIER_H_ 16 | #define I18N_ADDRESSINPUT_ONDEMAND_SUPPLIER_H_ 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace i18n { 26 | namespace addressinput { 27 | 28 | class LookupKey; 29 | class Retriever; 30 | class Rule; 31 | class Source; 32 | class Storage; 33 | 34 | // An implementation of the Supplier interface that owns a Retriever object, 35 | // through which it loads address metadata as needed, creating Rule objects and 36 | // caching these. 37 | // 38 | // When using an OndemandSupplier, address validation will benefit from address 39 | // metadata server synonym resolution, because the server will be contacted for 40 | // every new LookupKey (ie. every LookupKey that isn't on canonical form and 41 | // isn't already cached). 42 | // 43 | // The maximum size of this cache is naturally limited to the amount of data 44 | // available from the data server. (Currently this is less than 12,000 items of 45 | // in total less than 2 MB of JSON data.) 46 | class OndemandSupplier : public Supplier { 47 | public: 48 | OndemandSupplier(const OndemandSupplier&) = delete; 49 | OndemandSupplier& operator=(const OndemandSupplier&) = delete; 50 | 51 | // Takes ownership of |source| and |storage|. 52 | OndemandSupplier(const Source* source, Storage* storage); 53 | ~OndemandSupplier() override; 54 | 55 | // Loads the metadata needed for |lookup_key|, then calls |supplied|. 56 | void Supply(const LookupKey& lookup_key, const Callback& supplied) override; 57 | // For now, this is identical to Supply. 58 | void SupplyGlobally(const LookupKey& lookup_key, 59 | const Callback& supplied) override; 60 | // OnDemandSupplier doesn't care about UNSUPPORTED fields. 61 | size_t GetLoadedRuleDepth(const std::string& region_code) const override; 62 | 63 | private: 64 | const std::unique_ptr retriever_; 65 | std::map rule_cache_; 66 | }; 67 | 68 | } // namespace addressinput 69 | } // namespace i18n 70 | 71 | #endif // I18N_ADDRESSINPUT_ONDEMAND_SUPPLIER_H_ 72 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/region_data.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_REGION_DATA_H_ 16 | #define I18N_ADDRESSINPUT_REGION_DATA_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace i18n { 24 | namespace addressinput { 25 | 26 | // The key and name of a region that can be used as one of the items in a 27 | // dropdown UI element. 28 | class RegionData { 29 | public: 30 | RegionData(const RegionData&) = delete; 31 | RegionData& operator=(const RegionData&) = delete; 32 | 33 | // Creates a top-level RegionData object. Use AddSubRegion() to add data below 34 | // it. Does not make a copy of data in |region_code|. 35 | explicit RegionData(const std::string& region_code); 36 | ~RegionData(); 37 | 38 | // Creates a sub-level RegionData object, with this object as its parent and 39 | // owner. Does not make copies of the data in |key| or |name|. 40 | RegionData* AddSubRegion(const std::string& key, const std::string& name); 41 | 42 | const std::string& key() const { return key_; } 43 | 44 | const std::string& name() const { return name_; } 45 | 46 | bool has_parent() const { return parent_ != nullptr; } 47 | 48 | // Should be called only if has_parent() returns true. 49 | const RegionData& parent() const { 50 | assert(parent_ != nullptr); 51 | return *parent_; 52 | } 53 | 54 | // The caller does not own the results. The results are not nullptr and have a 55 | // parent. 56 | const std::vector& sub_regions() const { 57 | return sub_regions_; 58 | } 59 | 60 | private: 61 | // Private constructor used by AddSubRegion(). 62 | RegionData(const std::string& key, 63 | const std::string& name, 64 | RegionData* parent); 65 | 66 | const std::string& key_; 67 | const std::string& name_; 68 | const RegionData* const parent_; // Not owned. 69 | std::vector sub_regions_; // Owned. 70 | }; 71 | 72 | } // namespace addressinput 73 | } // namespace i18n 74 | 75 | #endif // I18N_ADDRESSINPUT_REGION_DATA_H_ 76 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/source.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // The interface to be implemented by the user of the library to access address 16 | // metadata, typically by downloading this from the address metadata server or 17 | // by linking the metadata into the binary. 18 | 19 | #ifndef I18N_ADDRESSINPUT_SOURCE_H_ 20 | #define I18N_ADDRESSINPUT_SOURCE_H_ 21 | 22 | #include 23 | 24 | #include 25 | 26 | namespace i18n { 27 | namespace addressinput { 28 | 29 | // Gets address metadata. The callback data must be allocated on the heap, 30 | // passing ownership to the callback. Sample usage: 31 | // 32 | // class MySource : public Source { 33 | // public: 34 | // virtual void Get(const std::string& key, 35 | // const Callback& data_ready) const { 36 | // bool success = ... 37 | // std::string* data = new ... 38 | // data_ready(success, key, data); 39 | // } 40 | // }; 41 | class Source { 42 | public: 43 | using Callback = 44 | i18n::addressinput::Callback; 45 | 46 | virtual ~Source() = default; 47 | 48 | // Gets metadata for |key| and invokes the |data_ready| callback. 49 | virtual void Get(const std::string& key, 50 | const Callback& data_ready) const = 0; 51 | }; 52 | 53 | } // namespace addressinput 54 | } // namespace i18n 55 | 56 | #endif // I18N_ADDRESSINPUT_SOURCE_H_ 57 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/storage.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // The interface to be implemented by the user of the library to enable storing 16 | // address metadata (e.g. on disk). 17 | 18 | #ifndef I18N_ADDRESSINPUT_STORAGE_H_ 19 | #define I18N_ADDRESSINPUT_STORAGE_H_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace i18n { 26 | namespace addressinput { 27 | 28 | // Stores address metadata. The data must be allocated on the heap, passing 29 | // ownership to the called function. Sample usage: 30 | // 31 | // class MyStorage : public Storage { 32 | // public: 33 | // virtual void Put(const std::string& key, std::string* data) { 34 | // ... 35 | // delete data; 36 | // } 37 | // 38 | // virtual void Get(const std::string& key, 39 | // const Callback& data_ready) const { 40 | // bool success = ... 41 | // std::string* data = new ... 42 | // data_ready(success, key, data); 43 | // } 44 | // }; 45 | class Storage { 46 | public: 47 | using Callback = 48 | i18n::addressinput::Callback; 49 | 50 | virtual ~Storage() = default; 51 | 52 | // Stores |data| for |key|, where |data| is an object allocated on the heap, 53 | // which Storage takes ownership of. 54 | virtual void Put(const std::string& key, std::string* data) = 0; 55 | 56 | // Retrieves the data for |key| and invokes the |data_ready| callback. 57 | virtual void Get(const std::string& key, 58 | const Callback& data_ready) const = 0; 59 | }; 60 | 61 | } // namespace addressinput 62 | } // namespace i18n 63 | 64 | #endif // I18N_ADDRESSINPUT_STORAGE_H_ 65 | -------------------------------------------------------------------------------- /cpp/include/libaddressinput/supplier.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_SUPPLIER_H_ 16 | #define I18N_ADDRESSINPUT_SUPPLIER_H_ 17 | 18 | #include 19 | #include 20 | 21 | namespace i18n { 22 | namespace addressinput { 23 | 24 | class LookupKey; 25 | class Rule; 26 | 27 | // Interface for objects that are able to supply the AddressValidator with the 28 | // metadata needed to validate an address, as described by a LookupKey. 29 | class Supplier { 30 | public: 31 | struct RuleHierarchy; 32 | using Callback = 33 | i18n::addressinput::Callback; 34 | 35 | virtual ~Supplier() = default; 36 | 37 | // Aggregates the metadata needed for |lookup_key| into a RuleHierarchy 38 | // object, then calls |supplied|. Implementations of this interface may 39 | // either load the necessary data on demand, or fail if the necessary data 40 | // hasn't already been loaded. 41 | virtual void Supply(const LookupKey& lookup_key, 42 | const Callback& supplied) = 0; 43 | 44 | // Aggregates the metadata (in all available languages) needed for 45 | // |lookup_key| into a RuleHierarchy object, then calls |supplied|. 46 | // Implementations of this interface may either load the necessary data on 47 | // demand, or fail if the necessary data hasn't already been loaded. 48 | virtual void SupplyGlobally(const LookupKey& lookup_key, 49 | const Callback& supplied) = 0; 50 | 51 | // Looking at the metadata, returns the depths of the available rules for the 52 | // region code. For example, if for a certain |region_code|, |rule_index_| has 53 | // the list of values for admin area and city, but not for the dependent 54 | // locality the depth would be 3. 55 | virtual size_t GetLoadedRuleDepth(const std::string& region_code) const { 56 | return 0; 57 | } 58 | 59 | // A RuleHierarchy object encapsulates the hierarchical list of Rule objects 60 | // that corresponds to a particular LookupKey. 61 | struct RuleHierarchy { 62 | RuleHierarchy() : rule() {} 63 | const Rule* rule[4]; // Cf. LookupKey::kHierarchy. 64 | }; 65 | }; 66 | 67 | } // namespace addressinput 68 | } // namespace i18n 69 | 70 | #endif // I18N_ADDRESSINPUT_SUPPLIER_H_ 71 | -------------------------------------------------------------------------------- /cpp/libaddressinput.gyp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | { 15 | 'variables': { 16 | 'component%': 'shared_library', 17 | }, 18 | 'includes': ['libaddressinput.gypi'], 19 | 'target_defaults': { 20 | 'cflags_cc': [ 21 | '-std=c++11', 22 | ], 23 | 'conditions': [ 24 | [ 'OS == "mac"', { 25 | 'xcode_settings': { 26 | 'OTHER_CPLUSPLUSFLAGS': [ 27 | '-std=c++11', 28 | ], 29 | }, 30 | }], 31 | ], 32 | 'include_dirs': [ 33 | 'include', 34 | ], 35 | }, 36 | 'targets': [ 37 | { 38 | 'target_name': 'libaddressinput', 39 | 'type': '<(component)', 40 | 'sources': [ 41 | '<@(libaddressinput_files)', 42 | ], 43 | 'dependencies': [ 44 | 'grit.gyp:generated_messages', 45 | 'rapidjson.gyp:rapidjson', 46 | 're2.gyp:re2', 47 | ], 48 | 'conditions': [ 49 | ['OS == "linux" and _type == "shared_library"', { 50 | # https://code.google.com/p/gyp/issues/detail?id=374 51 | 'cflags': ['-fPIC'], 52 | }], 53 | ], 54 | }, 55 | { 56 | 'target_name': 'unit_tests', 57 | 'type': 'executable', 58 | 'sources': [ 59 | '<@(libaddressinput_test_files)', 60 | ], 61 | 'defines': [ 62 | 'TEST_DATA_DIR="../testdata"', 63 | ], 64 | 'include_dirs': [ 65 | 'src', 66 | ], 67 | 'dependencies': [ 68 | 'libaddressinput', 69 | 'gtest.gyp:main', 70 | ], 71 | 'conditions': [ 72 | [ 'OS == "mac"', { 73 | 'postbuilds': [ 74 | { 75 | # To make it possible to execute the unit tests directly from the 76 | # build directory, without first installing the library, the path 77 | # to the library is set to be relative to the unit test executable 78 | # (so that also the library will be loaded directly from the build 79 | # directory). 80 | 'postbuild_name': 'Make dylib path relative to executable', 81 | 'action': [ 82 | 'install_name_tool', 83 | '-change', 84 | '/usr/local/lib/libaddressinput.dylib', 85 | '@executable_path/libaddressinput.dylib', 86 | '${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}' 87 | ], 88 | }, 89 | ], 90 | }], 91 | ], 92 | }, 93 | ], 94 | } 95 | -------------------------------------------------------------------------------- /cpp/rapidjson.gyp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | { 15 | 'variables': { 16 | 'rapidjson_dir%': '<(DEPTH)/../externals/rapidjson/include', 17 | }, 18 | 'targets': [ 19 | { 20 | 'target_name': 'rapidjson', 21 | 'type': 'none', 22 | 'all_dependent_settings': { 23 | 'include_dirs': [ 24 | '<(rapidjson_dir)', 25 | ], 26 | }, 27 | }, 28 | ], 29 | } 30 | -------------------------------------------------------------------------------- /cpp/re2.gyp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | { 15 | 'variables': { 16 | 're2_root%': '/usr', 17 | 're2_lib%': '-lre2', 18 | }, 19 | 'targets': [ 20 | { 21 | 'target_name': 're2', 22 | 'type': 'none', 23 | 'all_dependent_settings': { 24 | 'include_dirs': [ 25 | '<(re2_root)/include', 26 | ], 27 | 'library_dirs': [ 28 | '<(re2_root)/lib', 29 | ], 30 | 'libraries': [ 31 | '<(re2_lib)', 32 | ], 33 | 'conditions': [ 34 | [ 'OS == "mac"', { 35 | 'link_settings': { 36 | 'xcode_settings': { 37 | 'OTHER_LDFLAGS': [ 38 | '<(re2_lib)', 39 | ], 40 | }, 41 | } 42 | }], 43 | ], 44 | }, 45 | }, 46 | ], 47 | } 48 | -------------------------------------------------------------------------------- /cpp/res/messages.grd: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /cpp/src/address_field.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include "util/size.h" 21 | 22 | using i18n::addressinput::AddressField; 23 | using i18n::addressinput::COUNTRY; 24 | using i18n::addressinput::RECIPIENT; 25 | using i18n::addressinput::size; 26 | 27 | std::ostream& operator<<(std::ostream& o, AddressField field) { 28 | static const char* const kFieldNames[] = { 29 | "COUNTRY", 30 | "ADMIN_AREA", 31 | "LOCALITY", 32 | "DEPENDENT_LOCALITY", 33 | "SORTING_CODE", 34 | "POSTAL_CODE", 35 | "STREET_ADDRESS", 36 | "ORGANIZATION", 37 | "RECIPIENT", 38 | }; 39 | static_assert(COUNTRY == 0, "bad_base"); 40 | static_assert(RECIPIENT == size(kFieldNames) - 1, "bad_length"); 41 | 42 | if (field < 0 || static_cast(field) >= size(kFieldNames)) { 43 | o << "[INVALID ENUM VALUE " << static_cast(field) << "]"; 44 | } else { 45 | o << kFieldNames[field]; 46 | } 47 | return o; 48 | } 49 | -------------------------------------------------------------------------------- /cpp/src/address_field_util.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_ 16 | #define I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace i18n { 24 | namespace addressinput { 25 | 26 | class FormatElement; 27 | 28 | // Clears |fields|, parses |format|, and adds the format address fields to 29 | // |fields|. The |fields| may also contain NEWLINE elements. For example, parses 30 | // "%S%C%n%D%X" into {ADMIN_AREA, LOCALITY, NEWLINE, DEPENDENT_LOCALITY, 31 | // SORTING_CODE}. 32 | void ParseFormatRule(const std::string& format, 33 | std::vector* elements); 34 | 35 | // Clears |fields|, parses |required|, and adds the required fields to |fields|. 36 | // For example, parses "SCDX" into {ADMIN_AREA, LOCALITY, DEPENDENT_LOCALITY, 37 | // SORTING_CODE}. 38 | void ParseAddressFieldsRequired(const std::string& required, 39 | std::vector* fields); 40 | 41 | } // namespace addressinput 42 | } // namespace i18n 43 | 44 | #endif // I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_ 45 | -------------------------------------------------------------------------------- /cpp/src/address_metadata.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | #include "format_element.h" 23 | #include "region_data_constants.h" 24 | #include "rule.h" 25 | 26 | namespace i18n { 27 | namespace addressinput { 28 | 29 | bool IsFieldRequired(AddressField field, const std::string& region_code) { 30 | if (field == COUNTRY) { 31 | return true; 32 | } 33 | 34 | Rule rule; 35 | rule.CopyFrom(Rule::GetDefault()); 36 | if (!rule.ParseSerializedRule( 37 | RegionDataConstants::GetRegionData(region_code))) { 38 | return false; 39 | } 40 | 41 | return std::find(rule.GetRequired().begin(), 42 | rule.GetRequired().end(), 43 | field) != rule.GetRequired().end(); 44 | } 45 | 46 | bool IsFieldUsed(AddressField field, const std::string& region_code) { 47 | if (field == COUNTRY) { 48 | return true; 49 | } 50 | 51 | Rule rule; 52 | rule.CopyFrom(Rule::GetDefault()); 53 | if (!rule.ParseSerializedRule( 54 | RegionDataConstants::GetRegionData(region_code))) { 55 | return false; 56 | } 57 | 58 | return std::find(rule.GetFormat().begin(), 59 | rule.GetFormat().end(), 60 | FormatElement(field)) != rule.GetFormat().end(); 61 | } 62 | 63 | } // namespace addressinput 64 | } // namespace i18n 65 | -------------------------------------------------------------------------------- /cpp/src/address_problem.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include "util/size.h" 21 | 22 | using i18n::addressinput::AddressProblem; 23 | using i18n::addressinput::size; 24 | using i18n::addressinput::UNEXPECTED_FIELD; 25 | using i18n::addressinput::UNSUPPORTED_FIELD; 26 | 27 | std::ostream& operator<<(std::ostream& o, AddressProblem problem) { 28 | static const char* const kProblemNames[] = { 29 | "UNEXPECTED_FIELD", "MISSING_REQUIRED_FIELD", "UNKNOWN_VALUE", 30 | "INVALID_FORMAT", "MISMATCHING_VALUE", "USES_P_O_BOX", 31 | "UNSUPPORTED_FIELD", 32 | }; 33 | static_assert(UNEXPECTED_FIELD == 0, "bad_base"); 34 | static_assert(UNSUPPORTED_FIELD == size(kProblemNames) - 1, "bad_length"); 35 | 36 | if (problem < 0 || static_cast(problem) >= size(kProblemNames)) { 37 | o << "[INVALID ENUM VALUE " << static_cast(problem) << "]"; 38 | } else { 39 | o << kProblemNames[problem]; 40 | } 41 | return o; 42 | } 43 | -------------------------------------------------------------------------------- /cpp/src/address_validator.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include "validation_task.h" 21 | 22 | namespace i18n { 23 | namespace addressinput { 24 | 25 | AddressValidator::AddressValidator(Supplier* supplier) : supplier_(supplier) { 26 | assert(supplier_ != nullptr); 27 | } 28 | 29 | void AddressValidator::Validate(const AddressData& address, 30 | bool allow_postal, 31 | bool require_name, 32 | const FieldProblemMap* filter, 33 | FieldProblemMap* problems, 34 | const Callback& validated) const { 35 | // The ValidationTask object will delete itself after Run() has finished. 36 | (new ValidationTask( 37 | address, 38 | allow_postal, 39 | require_name, 40 | filter, 41 | problems, 42 | validated))->Run(supplier_); 43 | } 44 | 45 | } // namespace addressinput 46 | } // namespace i18n 47 | -------------------------------------------------------------------------------- /cpp/src/format_element.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "format_element.h" 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace i18n { 24 | namespace addressinput { 25 | 26 | FormatElement::FormatElement(AddressField field) : field_(field), literal_() {} 27 | 28 | // Use COUNTRY as the default as this field is not used anyway 29 | FormatElement::FormatElement(const std::string& literal) 30 | : field_(COUNTRY), literal_(literal) { 31 | assert(!literal.empty()); 32 | } 33 | 34 | // Use COUNTRY as the default as this field is not used anyway 35 | FormatElement::FormatElement() : field_(COUNTRY), literal_("\n") {} 36 | 37 | bool FormatElement::operator==(const FormatElement& other) const { 38 | return field_ == other.field_ && literal_ == other.literal_; 39 | } 40 | 41 | } // namespace addressinput 42 | } // namespace i18n 43 | 44 | std::ostream& operator<<(std::ostream& o, 45 | const i18n::addressinput::FormatElement& element) { 46 | if (element.IsField()) { 47 | o << "Field: " << element.GetField(); 48 | } else if (element.IsNewline()) { 49 | o << "Newline"; 50 | } else { 51 | o << "Literal: " << element.GetLiteral(); 52 | } 53 | return o; 54 | } 55 | -------------------------------------------------------------------------------- /cpp/src/format_element.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // An object representing a token in a formatting string. This may be a 16 | // placeholder for a field in the address data such as ADMIN_AREA, a literal 17 | // string such as " ", or a newline. 18 | 19 | #ifndef I18N_ADDRESSINPUT_FORMAT_ELEMENT_H_ 20 | #define I18N_ADDRESSINPUT_FORMAT_ELEMENT_H_ 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace i18n { 28 | namespace addressinput { 29 | 30 | class FormatElement { 31 | public: 32 | // Builds a format element to represent |field|. 33 | explicit FormatElement(AddressField field); 34 | 35 | // Builds an element representing a literal string |literal|. 36 | explicit FormatElement(const std::string& literal); 37 | 38 | // Builds a newline element. 39 | FormatElement(); 40 | 41 | // Returns true if this element represents a field element. 42 | bool IsField() const { return literal_.empty(); } 43 | 44 | // Returns true if this element represents a new line. 45 | bool IsNewline() const { return literal_ == "\n"; } 46 | 47 | AddressField GetField() const { return field_; } 48 | const std::string& GetLiteral() const { return literal_; } 49 | 50 | bool operator==(const FormatElement& other) const; 51 | 52 | private: 53 | // The field this element represents. Should only be used if |literal| is an 54 | // empty string. 55 | AddressField field_; 56 | 57 | // The literal string for this element. This will be "\n" if this is a 58 | // newline - but IsNewline() is preferred to determine this. If empty, then 59 | // this FormatElement represents an address field. 60 | std::string literal_; 61 | }; 62 | 63 | } // namespace addressinput 64 | } // namespace i18n 65 | 66 | // Produces human-readable output in logging, for example in unit tests. 67 | std::ostream& operator<<(std::ostream& o, 68 | const i18n::addressinput::FormatElement& element); 69 | 70 | #endif // I18N_ADDRESSINPUT_FORMAT_ELEMENT_H_ 71 | -------------------------------------------------------------------------------- /cpp/src/grit.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_GRIT_H_ 16 | #define I18N_ADDRESSINPUT_GRIT_H_ 17 | 18 | namespace i18n { 19 | namespace addressinput { 20 | 21 | // A message identifier that is guaranteed to not clash with any 22 | // IDS_ADDRESSINPUT_I18N_* identifiers that are generated by GRIT. GRIT 23 | // generates messages in the range from decimal 101 to 0x7FFF in order to work 24 | // with Windows. 25 | // https://code.google.com/p/grit-i18n/source/browse/trunk/grit/format/rc_header.py?r=94#169 26 | // http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx 27 | // 28 | // The enum must be named to enable using it in GTest templates, e.g. 29 | // EXPECT_EQ(INVALID_MESSAGE_ID, my_id) will not compile on some platforms when 30 | // the enum is unnamed. 31 | enum MessageIdentifier { INVALID_MESSAGE_ID = 0 }; 32 | 33 | } // namespace addressinput 34 | } // namespace i18n 35 | 36 | #endif // I18N_ADDRESSINPUT_GRIT_H_ 37 | -------------------------------------------------------------------------------- /cpp/src/language.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_LANGUAGE_H_ 16 | #define I18N_ADDRESSINPUT_LANGUAGE_H_ 17 | 18 | #include 19 | 20 | namespace i18n { 21 | namespace addressinput { 22 | 23 | class Rule; 24 | 25 | // Helper for working with a BCP 47 language tag. 26 | // http://tools.ietf.org/html/bcp47 27 | struct Language { 28 | explicit Language(const std::string& language_tag); 29 | ~Language(); 30 | 31 | // The language tag (with '_' replaced with '-'), for example "zh-Latn-CN". 32 | std::string tag; 33 | 34 | // The base language, for example "zh". Always lowercase. 35 | std::string base; 36 | 37 | // True if the language tag explicitly has a Latin script. For example, this 38 | // is true for "zh-Latn", but false for "zh". Only the second and third subtag 39 | // positions are supported for script. 40 | bool has_latin_script; 41 | }; 42 | 43 | Language ChooseBestAddressLanguage(const Rule& address_region_rule, 44 | const Language& ui_language); 45 | 46 | } // namespace addressinput 47 | } // namespace i18n 48 | 49 | #endif // I18N_ADDRESSINPUT_LANGUAGE_H_ 50 | -------------------------------------------------------------------------------- /cpp/src/lookup_key.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_LOOKUP_KEY_H_ 16 | #define I18N_ADDRESSINPUT_LOOKUP_KEY_H_ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "util/size.h" 25 | 26 | namespace i18n { 27 | namespace addressinput { 28 | 29 | struct AddressData; 30 | 31 | // A LookupKey maps between an AddressData struct and the key string used to 32 | // request address data from an address data server. 33 | class LookupKey { 34 | public: 35 | // The array length is explicitly specified here, to make it possible to get 36 | // the length through size(LookupKey::kHierarchy). 37 | static const AddressField kHierarchy[4]; 38 | 39 | LookupKey(const LookupKey&) = delete; 40 | LookupKey& operator=(const LookupKey&) = delete; 41 | 42 | LookupKey(); 43 | ~LookupKey(); 44 | 45 | // Initializes this object by parsing |address|. 46 | void FromAddress(const AddressData& address); 47 | 48 | // Initializes this object to be a copy of |parent| key that's one level 49 | // deeper with the next level node being |child_node|. 50 | // 51 | // For example, if |parent| is "data/US" and |child_node| is "CA", then this 52 | // key becomes "data/US/CA". 53 | // 54 | // The |parent| can be at most LOCALITY level. The |child_node| cannot be 55 | // empty. 56 | void FromLookupKey(const LookupKey& parent, const std::string& child_node); 57 | 58 | // Returns the lookup key string (of |max_depth|). 59 | std::string ToKeyString(size_t max_depth) const; 60 | 61 | // Returns the region code. Must not be called on an empty object. 62 | const std::string& GetRegionCode() const; 63 | 64 | // Returns the depth. Must not be called on an empty object. 65 | size_t GetDepth() const; 66 | 67 | void set_language(const std::string& language) { language_ = language; } 68 | 69 | private: 70 | std::map nodes_; 71 | // The language of the key, obtained from the address (empty for default 72 | // language). 73 | std::string language_; 74 | }; 75 | 76 | } // namespace addressinput 77 | } // namespace i18n 78 | 79 | #endif // I18N_ADDRESSINPUT_LOOKUP_KEY_H_ 80 | -------------------------------------------------------------------------------- /cpp/src/null_storage.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace i18n { 22 | namespace addressinput { 23 | 24 | NullStorage::NullStorage() = default; 25 | NullStorage::~NullStorage() = default; 26 | 27 | void NullStorage::Put(const std::string& key, std::string* data) { 28 | assert(data != nullptr); // Sanity check. 29 | delete data; 30 | } 31 | 32 | void NullStorage::Get(const std::string& key, 33 | const Callback& data_ready) const { 34 | data_ready(false, key, nullptr); 35 | } 36 | 37 | } // namespace addressinput 38 | } // namespace i18n 39 | -------------------------------------------------------------------------------- /cpp/src/ondemand_supplier.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "lookup_key.h" 22 | #include "ondemand_supply_task.h" 23 | #include "region_data_constants.h" 24 | #include "retriever.h" 25 | #include "rule.h" 26 | 27 | namespace i18n { 28 | namespace addressinput { 29 | 30 | OndemandSupplier::OndemandSupplier(const Source* source, Storage* storage) 31 | : retriever_(new Retriever(source, storage)) { 32 | } 33 | 34 | OndemandSupplier::~OndemandSupplier() { 35 | for (const auto& pair : rule_cache_) { 36 | delete pair.second; 37 | } 38 | } 39 | 40 | void OndemandSupplier::SupplyGlobally(const LookupKey& lookup_key, 41 | const Callback& supplied) { 42 | Supply(lookup_key, supplied); 43 | } 44 | 45 | void OndemandSupplier::Supply(const LookupKey& lookup_key, 46 | const Callback& supplied) { 47 | auto* task = new OndemandSupplyTask(lookup_key, &rule_cache_, supplied); 48 | 49 | if (RegionDataConstants::IsSupported(lookup_key.GetRegionCode())) { 50 | size_t max_depth = std::min( 51 | lookup_key.GetDepth(), 52 | RegionDataConstants::GetMaxLookupKeyDepth(lookup_key.GetRegionCode())); 53 | 54 | for (size_t depth = 0; depth <= max_depth; ++depth) { 55 | const std::string key = lookup_key.ToKeyString(depth); 56 | auto it = rule_cache_.find(key); 57 | if (it != rule_cache_.end()) { 58 | task->hierarchy_.rule[depth] = it->second; 59 | } else { 60 | task->Queue(key); // If not in the cache, it needs to be loaded. 61 | } 62 | } 63 | } 64 | 65 | task->Retrieve(*retriever_); 66 | } 67 | 68 | size_t OndemandSupplier::GetLoadedRuleDepth( 69 | const std::string& region_code) const { 70 | return size(LookupKey::kHierarchy); 71 | } 72 | 73 | } // namespace addressinput 74 | } // namespace i18n 75 | -------------------------------------------------------------------------------- /cpp/src/ondemand_supply_task.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_ONDEMAND_SUPPLY_TASK_H_ 16 | #define I18N_ADDRESSINPUT_ONDEMAND_SUPPLY_TASK_H_ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "retriever.h" 26 | 27 | namespace i18n { 28 | namespace addressinput { 29 | 30 | class LookupKey; 31 | class Rule; 32 | 33 | // An OndemandSupplyTask object encapsulates the information necessary to 34 | // retrieve the set of Rule objects corresponding to a LookupKey and call a 35 | // callback when that has been done. Calling the Retrieve() method will load 36 | // required metadata, then call the callback and delete the OndemandSupplyTask 37 | // object itself. 38 | class OndemandSupplyTask { 39 | public: 40 | OndemandSupplyTask(const OndemandSupplyTask&) = delete; 41 | OndemandSupplyTask& operator=(const OndemandSupplyTask&) = delete; 42 | 43 | OndemandSupplyTask(const LookupKey& lookup_key, 44 | std::map* rules, 45 | const Supplier::Callback& supplied); 46 | ~OndemandSupplyTask(); 47 | 48 | // Adds lookup key string |key| to the queue of data to be retrieved. 49 | void Queue(const std::string& key); 50 | 51 | // Retrieves and parses data for all queued keys, then calls |supplied_|. 52 | void Retrieve(const Retriever& retriever); 53 | 54 | Supplier::RuleHierarchy hierarchy_; 55 | 56 | private: 57 | void Load(bool success, const std::string& key, const std::string& data); 58 | void Loaded(); 59 | 60 | std::set pending_; 61 | const LookupKey& lookup_key_; 62 | std::map* const rule_cache_; 63 | const Supplier::Callback& supplied_; 64 | const std::unique_ptr retrieved_; 65 | bool success_; 66 | }; 67 | 68 | } // namespace addressinput 69 | } // namespace i18n 70 | 71 | #endif // I18N_ADDRESSINPUT_ONDEMAND_SUPPLY_TASK_H_ 72 | -------------------------------------------------------------------------------- /cpp/src/post_box_matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // Post office box regular expressions. 16 | 17 | #ifndef I18N_ADDRESSINPUT_POST_BOX_MATCHERS_H_ 18 | #define I18N_ADDRESSINPUT_POST_BOX_MATCHERS_H_ 19 | 20 | #include 21 | 22 | namespace i18n { 23 | namespace addressinput { 24 | 25 | class Rule; 26 | struct RE2PlainPtr; 27 | 28 | class PostBoxMatchers { 29 | public: 30 | // Returns pointers to RE2 regular expression objects to test address lines 31 | // for those languages that are relevant for |country_rule|. 32 | static std::vector GetMatchers(const Rule& country_rule); 33 | 34 | PostBoxMatchers(const PostBoxMatchers&) = delete; 35 | PostBoxMatchers& operator=(const PostBoxMatchers&) = delete; 36 | }; 37 | 38 | } // namespace addressinput 39 | } // namespace i18n 40 | 41 | #endif // I18N_ADDRESSINPUT_POST_BOX_MATCHERS_H_ 42 | -------------------------------------------------------------------------------- /cpp/src/region_data.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace i18n { 22 | namespace addressinput { 23 | 24 | RegionData::RegionData(const std::string& region_code) 25 | : key_(region_code), 26 | name_(region_code), 27 | parent_(nullptr), 28 | sub_regions_() {} 29 | 30 | RegionData::~RegionData() { 31 | for (auto ptr : sub_regions_) { 32 | delete ptr; 33 | } 34 | } 35 | 36 | RegionData* RegionData::AddSubRegion(const std::string& key, 37 | const std::string& name) { 38 | auto* sub_region = new RegionData(key, name, this); 39 | sub_regions_.push_back(sub_region); 40 | return sub_region; 41 | } 42 | 43 | RegionData::RegionData(const std::string& key, 44 | const std::string& name, 45 | RegionData* parent) 46 | : key_(key), name_(name), parent_(parent), sub_regions_() {} 47 | 48 | } // namespace addressinput 49 | } // namespace i18n 50 | -------------------------------------------------------------------------------- /cpp/src/region_data_constants.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_REGION_DATA_CONSTANTS_H_ 16 | #define I18N_ADDRESSINPUT_REGION_DATA_CONSTANTS_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace i18n { 23 | namespace addressinput { 24 | 25 | class RegionDataConstants { 26 | public: 27 | static bool IsSupported(const std::string& region_code); 28 | static const std::vector& GetRegionCodes(); 29 | static std::string GetRegionData(const std::string& region_code); 30 | static const std::string& GetDefaultRegionData(); 31 | static size_t GetMaxLookupKeyDepth(const std::string& region_code); 32 | 33 | RegionDataConstants(const RegionDataConstants&) = delete; 34 | RegionDataConstants& operator=(const RegionDataConstants&) = delete; 35 | }; 36 | 37 | } // namespace addressinput 38 | } // namespace i18n 39 | 40 | #endif // I18N_ADDRESSINPUT_REGION_DATA_CONSTANTS_H_ 41 | -------------------------------------------------------------------------------- /cpp/src/retriever.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // An object to retrieve data. 16 | 17 | #ifndef I18N_ADDRESSINPUT_RETRIEVER_H_ 18 | #define I18N_ADDRESSINPUT_RETRIEVER_H_ 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | namespace i18n { 26 | namespace addressinput { 27 | 28 | class Source; 29 | class Storage; 30 | class ValidatingStorage; 31 | 32 | // Retrieves data. Sample usage: 33 | // Source* source = ...; 34 | // Storage* storage = ...; 35 | // Retriever retriever(source, storage); 36 | // const std::unique_ptr retrieved( 37 | // BuildCallback(this, &MyClass::OnDataRetrieved)); 38 | // retriever.Retrieve("data/CA/AB--fr", *retrieved); 39 | class Retriever { 40 | public: 41 | using Callback = 42 | i18n::addressinput::Callback; 43 | 44 | Retriever(const Retriever&) = delete; 45 | Retriever& operator=(const Retriever&) = delete; 46 | 47 | // Takes ownership of |source| and |storage|. 48 | Retriever(const Source* source, Storage* storage); 49 | ~Retriever(); 50 | 51 | // Retrieves the data for |key| and invokes the |retrieved| callback. Checks 52 | // for the data in |storage_| first. If storage does not have the data for 53 | // |key|, then gets the data from |source_| and places it in storage. If the 54 | // data in storage is corrupted, then it's discarded and requested anew. If 55 | // the data is stale, then it's requested anew. If the request fails, then 56 | // stale data will be returned this one time. Any subsequent call to 57 | // Retrieve() will attempt to get fresh data again. 58 | void Retrieve(const std::string& key, const Callback& retrieved) const; 59 | 60 | private: 61 | std::unique_ptr source_; 62 | std::unique_ptr storage_; 63 | }; 64 | 65 | } // namespace addressinput 66 | } // namespace i18n 67 | 68 | #endif // I18N_ADDRESSINPUT_RETRIEVER_H_ 69 | -------------------------------------------------------------------------------- /cpp/src/rule_retriever.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "rule_retriever.h" 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "retriever.h" 25 | #include "rule.h" 26 | 27 | namespace i18n { 28 | namespace addressinput { 29 | 30 | namespace { 31 | 32 | class Helper { 33 | public: 34 | Helper(const Helper&) = delete; 35 | Helper& operator=(const Helper&) = delete; 36 | 37 | Helper(const std::string& key, 38 | const RuleRetriever::Callback& rule_ready, 39 | const Retriever& data_retriever) 40 | : rule_ready_(rule_ready), 41 | data_retrieved_(BuildCallback(this, &Helper::OnDataRetrieved)) { 42 | data_retriever.Retrieve(key, *data_retrieved_); 43 | } 44 | 45 | private: 46 | ~Helper() = default; 47 | 48 | void OnDataRetrieved(bool success, 49 | const std::string& key, 50 | const std::string& data) { 51 | Rule rule; 52 | if (!success) { 53 | rule_ready_(false, key, rule); 54 | } else { 55 | success = rule.ParseSerializedRule(data); 56 | rule_ready_(success, key, rule); 57 | } 58 | delete this; 59 | } 60 | 61 | const RuleRetriever::Callback& rule_ready_; 62 | const std::unique_ptr data_retrieved_; 63 | }; 64 | 65 | } // namespace 66 | 67 | RuleRetriever::RuleRetriever(const Retriever* retriever) 68 | : data_retriever_(retriever) { 69 | assert(data_retriever_ != nullptr); 70 | } 71 | 72 | RuleRetriever::~RuleRetriever() = default; 73 | 74 | void RuleRetriever::RetrieveRule(const std::string& key, 75 | const Callback& rule_ready) const { 76 | new Helper(key, rule_ready, *data_retriever_); 77 | } 78 | 79 | } // namespace addressinput 80 | } // namespace i18n 81 | -------------------------------------------------------------------------------- /cpp/src/rule_retriever.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // An object to retrieve validation rules. 16 | 17 | #ifndef I18N_ADDRESSINPUT_RULE_RETRIEVER_H_ 18 | #define I18N_ADDRESSINPUT_RULE_RETRIEVER_H_ 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | namespace i18n { 26 | namespace addressinput { 27 | 28 | class Retriever; 29 | class Rule; 30 | 31 | // Retrieves validation rules. Sample usage: 32 | // const Retriever* retriever = ... 33 | // RuleRetriever rules(retriever); 34 | // const std::unique_ptr rule_ready( 35 | // BuildCallback(this, &MyClass::OnRuleReady)); 36 | // rules.RetrieveRule("data/CA/AB--fr", *rule_ready); 37 | class RuleRetriever { 38 | public: 39 | using Callback = 40 | i18n::addressinput::Callback; 41 | 42 | RuleRetriever(const RuleRetriever&) = delete; 43 | RuleRetriever& operator=(const RuleRetriever&) = delete; 44 | 45 | // Takes ownership of |retriever|. 46 | explicit RuleRetriever(const Retriever* retriever); 47 | ~RuleRetriever(); 48 | 49 | // Retrieves the rule for |key| and invokes the |rule_ready| callback. 50 | void RetrieveRule(const std::string& key, const Callback& rule_ready) const; 51 | 52 | private: 53 | std::unique_ptr data_retriever_; 54 | }; 55 | 56 | } // namespace addressinput 57 | } // namespace i18n 58 | 59 | #endif // I18N_ADDRESSINPUT_RULE_RETRIEVER_H_ 60 | -------------------------------------------------------------------------------- /cpp/src/util/cctype_tolower_equal.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "cctype_tolower_equal.h" 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace i18n { 22 | namespace addressinput { 23 | 24 | bool EqualToTolowerString(const std::string& a, const std::string& b) { 25 | return a.size() == b.size() && 26 | std::equal(a.begin(), a.end(), b.begin(), 27 | [](std::string::value_type a, std::string::value_type b) { 28 | return std::tolower(a) == std::tolower(b); 29 | }); 30 | } 31 | 32 | } // namespace addressinput 33 | } // namespace i18n 34 | -------------------------------------------------------------------------------- /cpp/src/util/cctype_tolower_equal.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_UTIL_CCTYPE_TOLOWER_EQUAL_H_ 16 | #define I18N_ADDRESSINPUT_UTIL_CCTYPE_TOLOWER_EQUAL_H_ 17 | 18 | #include 19 | 20 | namespace i18n { 21 | namespace addressinput { 22 | 23 | // Performs case insensitive comparison of |a| and |b| by calling std::tolower() 24 | // from . 25 | bool EqualToTolowerString(const std::string& a, const std::string& b); 26 | 27 | } // namespace addressinput 28 | } // namespace i18n 29 | 30 | #endif // I18N_ADDRESSINPUT_UTIL_CCTYPE_TOLOWER_EQUAL_H_ 31 | -------------------------------------------------------------------------------- /cpp/src/util/json.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_UTIL_JSON_H_ 16 | #define I18N_ADDRESSINPUT_UTIL_JSON_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace i18n { 23 | namespace addressinput { 24 | 25 | // Parses a JSON dictionary of strings. Sample usage: 26 | // Json json; 27 | // if (json.ParseObject("{'key1':'value1', 'key2':'value2'}") && 28 | // json.HasStringKey("key1")) { 29 | // Process(json.GetStringValueForKey("key1")); 30 | // } 31 | class Json { 32 | public: 33 | Json(const Json&) = delete; 34 | Json& operator=(const Json&) = delete; 35 | 36 | Json(); 37 | ~Json(); 38 | 39 | // Parses the |json| string and returns true if |json| is valid and it is an 40 | // object. 41 | bool ParseObject(const std::string& json); 42 | 43 | // Returns the list of sub dictionaries. The JSON object must be parsed 44 | // successfully in ParseObject() before invoking this method. The caller does 45 | // not own the result. 46 | const std::vector& GetSubDictionaries() const; 47 | 48 | // Returns true if the parsed JSON contains a string value for |key|. Sets 49 | // |value| to the string value of the |key|. The JSON object must be parsed 50 | // successfully in ParseObject() before invoking this method. The |value| 51 | // parameter should not be nullptr. 52 | bool GetStringValueForKey(const std::string& key, std::string* value) const; 53 | 54 | private: 55 | class JsonImpl; 56 | friend class JsonImpl; 57 | 58 | // Constructor to be called by JsonImpl. 59 | explicit Json(JsonImpl* impl); 60 | 61 | std::unique_ptr impl_; 62 | }; 63 | 64 | } // namespace addressinput 65 | } // namespace i18n 66 | 67 | #endif // I18N_ADDRESSINPUT_UTIL_JSON_H_ 68 | -------------------------------------------------------------------------------- /cpp/src/util/md5.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | // 5 | // The original source code is from: 6 | // https://chromium.googlesource.com/chromium/src/base/+/ec2c345/md5.h 7 | 8 | #ifndef I18N_ADDRESSINPUT_UTIL_MD5_H_ 9 | #define I18N_ADDRESSINPUT_UTIL_MD5_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace i18n { 16 | namespace addressinput { 17 | 18 | // MD5 stands for Message Digest algorithm 5. 19 | // MD5 is a robust hash function, designed for cyptography, but often used 20 | // for file checksums. The code is complex and slow, but has few 21 | // collisions. 22 | // See Also: 23 | // http://en.wikipedia.org/wiki/MD5 24 | 25 | // These functions perform MD5 operations. The simplest call is MD5Sum() to 26 | // generate the MD5 sum of the given data. 27 | // 28 | // You can also compute the MD5 sum of data incrementally by making multiple 29 | // calls to MD5Update(): 30 | // MD5Context ctx; // intermediate MD5 data: do not use 31 | // MD5Init(&ctx); 32 | // MD5Update(&ctx, data1, length1); 33 | // MD5Update(&ctx, data2, length2); 34 | // ... 35 | // 36 | // MD5Digest digest; // the result of the computation 37 | // MD5Final(&digest, &ctx); 38 | // 39 | // You can call MD5DigestToBase16() to generate a string of the digest. 40 | 41 | // The output of an MD5 operation. 42 | struct MD5Digest { 43 | uint8_t a[16]; 44 | }; 45 | 46 | // Used for storing intermediate data during an MD5 computation. Callers 47 | // should not access the data. 48 | typedef char MD5Context[88]; 49 | 50 | // Initializes the given MD5 context structure for subsequent calls to 51 | // MD5Update(). 52 | void MD5Init(MD5Context* context); 53 | 54 | // For the given buffer of |data| as a std::string, updates the given MD5 55 | // context with the sum of the data. You can call this any number of times 56 | // during the computation, except that MD5Init() must have been called first. 57 | void MD5Update(MD5Context* context, const std::string& data); 58 | 59 | // Finalizes the MD5 operation and fills the buffer with the digest. 60 | void MD5Final(MD5Digest* digest, MD5Context* context); 61 | 62 | // MD5IntermediateFinal() generates a digest without finalizing the MD5 63 | // operation. Can be used to generate digests for the input seen thus far, 64 | // without affecting the digest generated for the entire input. 65 | void MD5IntermediateFinal(MD5Digest* digest, const MD5Context* context); 66 | 67 | // Converts a digest into human-readable hexadecimal. 68 | std::string MD5DigestToBase16(const MD5Digest& digest); 69 | 70 | // Computes the MD5 sum of the given data buffer with the given length. 71 | // The given 'digest' structure will be filled with the result data. 72 | void MD5Sum(const void* data, size_t length, MD5Digest* digest); 73 | 74 | // Returns the MD5 (in hexadecimal) of a string. 75 | std::string MD5String(const std::string& str); 76 | 77 | } // namespace addressinput 78 | } // namespace i18n 79 | 80 | #endif // I18N_ADDRESSINPUT_UTIL_MD5_H_ 81 | -------------------------------------------------------------------------------- /cpp/src/util/re2ptr.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // Work-around for problems with the RE2 library. Must be the first #include 16 | // statement in the compilation unit. Do not #include in other header files. 17 | 18 | #ifndef I18N_ADDRESSINPUT_UTIL_RE2PTR_H_ 19 | #define I18N_ADDRESSINPUT_UTIL_RE2PTR_H_ 20 | 21 | // RE2 will, in some environments, define class RE2 inside namespace re2 and 22 | // then have a public "using re2::RE2;" statement to bring that definition into 23 | // the root namespace, while in other environments it will define class RE2 24 | // directly in the root namespace. 25 | // 26 | // Because of that, it's impossible to write a portable forward declaration of 27 | // class RE2. 28 | // 29 | // The work-around in this file works by wrapping pointers to RE2 object in the 30 | // simple structs RE2PlainPtr and RE2ptr, which are trivial to forward declare. 31 | 32 | #include 33 | 34 | namespace i18n { 35 | namespace addressinput { 36 | 37 | // A non-owner pointer to an RE2 instance. Since this is POD, it can be 38 | // initialized statically to NULL without a C++ static constructor. 39 | struct RE2PlainPtr { 40 | RE2* ptr; 41 | }; 42 | 43 | // This is an owning pointer to an RE2 instance. 44 | struct RE2ptr { 45 | RE2ptr(RE2* init_ptr) : ptr(init_ptr) {} 46 | ~RE2ptr() { delete ptr; } 47 | RE2* const ptr; 48 | }; 49 | 50 | } // namespace addressinput 51 | } // namespace i18n 52 | 53 | #endif // I18N_ADDRESSINPUT_UTIL_RE2PTR_H_ 54 | -------------------------------------------------------------------------------- /cpp/src/util/size.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_UTIL_SIZE_H_ 16 | #define I18N_ADDRESSINPUT_UTIL_SIZE_H_ 17 | 18 | #include 19 | #include 20 | 21 | namespace i18n { 22 | namespace addressinput { 23 | 24 | // If the C++17 std::size is provided by the standard library then the fallback 25 | // C++11 implementation must not be used for that would make it ambiguous which 26 | // one of the two implementations a call should be resolved to. 27 | // 28 | // Although libaddressinput.gyp explicitly sets -std=c++11 it's possible that 29 | // this is overridden at build time to use a newer version of the standard. 30 | // 31 | // It's also possible that C++17 std::size is defined even when building for an 32 | // older version of the standard, which is done in the Microsoft implementation 33 | // of the C++ Standard Library: 34 | // 35 | // https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance 36 | 37 | #if (_LIBCPP_VERSION >= 1101 && _LIBCPP_STD_VER > 14) || \ 38 | (!defined(_LIBCPP_STD_VER) && \ 39 | (_MSC_VER >= 1900 || __cpp_lib_nonmember_container_access >= 201411)) 40 | 41 | using std::size; 42 | 43 | #else 44 | 45 | // A C++11 implementation of the C++17 std::size, copied from the standard: 46 | // https://isocpp.org/files/papers/n4280.pdf 47 | 48 | template 49 | constexpr size_t size(const T (&array)[N]) { 50 | return N; 51 | } 52 | 53 | #endif 54 | 55 | } // namespace addressinput 56 | } // namespace i18n 57 | 58 | #endif // I18N_ADDRESSINPUT_UTIL_SIZE_H_ 59 | -------------------------------------------------------------------------------- /cpp/src/util/string_compare.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef I18N_ADDRESSINPUT_UTIL_STRING_COMPARE_H_ 16 | #define I18N_ADDRESSINPUT_UTIL_STRING_COMPARE_H_ 17 | 18 | #include 19 | #include 20 | 21 | namespace i18n { 22 | namespace addressinput { 23 | 24 | class StringCompare { 25 | public: 26 | StringCompare(const StringCompare&) = delete; 27 | StringCompare& operator=(const StringCompare&) = delete; 28 | 29 | StringCompare(); 30 | ~StringCompare(); 31 | 32 | // Returns true if a human reader would consider |a| and |b| to be "the same". 33 | // Libaddressinput itself isn't really concerned about how this is done. This 34 | // default implementation just does case insensitive string matching. 35 | bool NaturalEquals(const std::string& a, const std::string& b) const; 36 | 37 | // Comparison function for use with the STL analogous to NaturalEquals(). 38 | // Libaddressinput itself isn't really concerned about how this is done, as 39 | // long as it conforms to the STL requirements on less<> predicates. This 40 | // default implementation is VERY SLOW! Must be replaced if you need speed. 41 | bool NaturalLess(const std::string& a, const std::string& b) const; 42 | 43 | private: 44 | class Impl; 45 | std::unique_ptr impl_; 46 | }; 47 | 48 | } // namespace addressinput 49 | } // namespace i18n 50 | 51 | #endif // I18N_ADDRESSINPUT_UTIL_STRING_COMPARE_H_ 52 | -------------------------------------------------------------------------------- /cpp/src/util/string_split.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | // 5 | // The original source code is from: 6 | // http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_split.cc?revision=216633 7 | 8 | #include "string_split.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace i18n { 16 | namespace addressinput { 17 | 18 | void SplitString(const std::string& str, char s, std::vector* r) { 19 | assert(r != nullptr); 20 | r->clear(); 21 | size_t last = 0; 22 | size_t c = str.size(); 23 | for (size_t i = 0; i <= c; ++i) { 24 | if (i == c || str[i] == s) { 25 | std::string tmp(str, last, i - last); 26 | // Avoid converting an empty or all-whitespace source string into a vector 27 | // of one empty string. 28 | if (i != c || !r->empty() || !tmp.empty()) { 29 | r->push_back(tmp); 30 | } 31 | last = i + 1; 32 | } 33 | } 34 | } 35 | 36 | } // namespace addressinput 37 | } // namespace i18n 38 | -------------------------------------------------------------------------------- /cpp/src/util/string_split.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | // 5 | // The original source code is from: 6 | // http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_split.h?revision=236210 7 | // 8 | // Modifications from original: 9 | // 1) Supports only std::string type. 10 | // 2) Does not trim whitespace. 11 | 12 | #ifndef I18N_ADDRESSINPUT_UTIL_STRING_SPLIT_H_ 13 | #define I18N_ADDRESSINPUT_UTIL_STRING_SPLIT_H_ 14 | 15 | #include 16 | #include 17 | 18 | namespace i18n { 19 | namespace addressinput { 20 | 21 | // Splits |str| into a vector of strings delimited by |c|, placing the results 22 | // in |r|. If several instances of |c| are contiguous, or if |str| begins with 23 | // or ends with |c|, then an empty string is inserted. 24 | // 25 | // |str| should not be in a multi-byte encoding like Shift-JIS or GBK in which 26 | // the trailing byte of a multi-byte character can be in the ASCII range. 27 | // UTF-8, and other single/multi-byte ASCII-compatible encodings are OK. 28 | // Note: |c| must be in the ASCII range. 29 | void SplitString(const std::string& str, char s, std::vector* r); 30 | 31 | } // namespace addressinput 32 | } // namespace i18n 33 | 34 | #endif // I18N_ADDRESSINPUT_UTIL_STRING_SPLIT_H_ 35 | -------------------------------------------------------------------------------- /cpp/src/util/string_util.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | // 5 | // The original source code is from: 6 | // http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_util.cc?revision=268754 7 | // 8 | // Modified to contain only the DoReplaceStringPlaceholders() that works with 9 | // std::string. Replaced DCHECK() with assert() and removed offsets. 10 | 11 | #include "string_util.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace i18n { 20 | namespace addressinput { 21 | 22 | std::string DoReplaceStringPlaceholders(const std::string& format_string, 23 | const std::vector& subst) { 24 | size_t substitutions = subst.size(); 25 | 26 | size_t sub_length = 0; 27 | for (std::vector::const_iterator iter = subst.begin(); 28 | iter != subst.end(); ++iter) { 29 | sub_length += iter->length(); 30 | } 31 | 32 | std::string formatted; 33 | formatted.reserve(format_string.length() + sub_length); 34 | 35 | for (std::string::const_iterator i = format_string.begin(); 36 | i != format_string.end(); ++i) { 37 | if ('$' == *i) { 38 | if (i + 1 != format_string.end()) { 39 | ++i; 40 | assert('$' == *i || '1' <= *i); 41 | if ('$' == *i) { 42 | while (i != format_string.end() && '$' == *i) { 43 | formatted.push_back('$'); 44 | ++i; 45 | } 46 | --i; 47 | } else { 48 | uintptr_t index = 0; 49 | while (i != format_string.end() && '0' <= *i && *i <= '9') { 50 | index *= 10; 51 | index += *i - '0'; 52 | ++i; 53 | } 54 | --i; 55 | index -= 1; 56 | if (index < substitutions) 57 | formatted.append(subst.at(index)); 58 | } 59 | } 60 | } else { 61 | formatted.push_back(*i); 62 | } 63 | } 64 | return formatted; 65 | } 66 | 67 | } // namespace addressinput 68 | } // namespace i18n 69 | -------------------------------------------------------------------------------- /cpp/src/util/string_util.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | // 5 | // This file defines utility functions for working with strings. 6 | // 7 | // The original source code is from: 8 | // http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_util.h?revision=268754 9 | // 10 | // Modified to contain only DoReplaceStringPlaceholders() that works only with 11 | // std::string. 12 | 13 | #ifndef I18N_ADDRESSINPUT_UTIL_STRING_UTIL_H_ 14 | #define I18N_ADDRESSINPUT_UTIL_STRING_UTIL_H_ 15 | 16 | #include 17 | #include 18 | 19 | namespace i18n { 20 | namespace addressinput { 21 | 22 | std::string DoReplaceStringPlaceholders(const std::string& format_string, 23 | const std::vector& subst); 24 | 25 | } // addressinput 26 | } // i18n 27 | 28 | #endif // I18N_ADDRESSINPUT_UTIL_STRING_UTIL_H_ 29 | -------------------------------------------------------------------------------- /cpp/src/validating_storage.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // A wrapper object for Storage that stores data with a checksum and a 16 | // timestamp. The existence of checksum and timestamp fields is transparent to 17 | // the user of the object. 18 | 19 | #ifndef I18N_ADDRESSINPUT_VALIDATING_STORAGE_H_ 20 | #define I18N_ADDRESSINPUT_VALIDATING_STORAGE_H_ 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace i18n { 28 | namespace addressinput { 29 | 30 | // Wraps Storage to add checksum and timestamp to stored data. Sample usage: 31 | // std::unique_ptr file_storage = ...; 32 | // ValidatingStorage storage(file_storage)); 33 | // storage.Put("key", new std::string("data")); 34 | // const std::unique_ptr data_ready( 35 | // BuildCallback(this, &MyClass::OnDataReady)); 36 | // storage.Get("key", *data_ready); 37 | class ValidatingStorage : public Storage { 38 | public: 39 | ValidatingStorage(const ValidatingStorage&) = delete; 40 | ValidatingStorage& operator=(const ValidatingStorage&) = delete; 41 | 42 | // Takes ownership of |storage|. 43 | explicit ValidatingStorage(Storage* storage); 44 | ~ValidatingStorage() override; 45 | 46 | // Storage implementation. 47 | void Put(const std::string& key, std::string* data) override; 48 | 49 | // Storage implementation. 50 | // If the data is invalid, then |data_ready| will be called with (false, key, 51 | // empty-string). If the data is valid, but stale, then |data_ready| will be 52 | // called with (false, key, stale-data). If the data is valid and fresh, then 53 | // |data_ready| will be called with (true, key, fresh-data). 54 | void Get(const std::string& key, const Callback& data_ready) const override; 55 | 56 | private: 57 | // The storage being wrapped. 58 | std::unique_ptr wrapped_storage_; 59 | }; 60 | 61 | } // namespace addressinput 62 | } // namespace i18n 63 | 64 | #endif // I18N_ADDRESSINPUT_VALIDATING_STORAGE_H_ 65 | -------------------------------------------------------------------------------- /cpp/src/validating_util.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // An object to wrap data with a checksum and a timestamp. These fields are used 16 | // to verify that the data is not stale or corrupted. Staleness threshold is 1 17 | // month. 18 | 19 | #ifndef I18N_ADDRESSINPUT_VALIDATING_UTIL_H_ 20 | #define I18N_ADDRESSINPUT_VALIDATING_UTIL_H_ 21 | 22 | #include 23 | #include 24 | 25 | namespace i18n { 26 | namespace addressinput { 27 | 28 | // Wraps data with a checksum and a timestamp. Sample usage: 29 | // std::string data = ... 30 | // ValidatingUtil::Wrap(time(nullptr), &data); 31 | // Process(data); 32 | // 33 | // std::string unwrapped = wrapped; 34 | // if (ValidatingUtil::UnwrapTimestamp(&unwrapped, time(nullptr)) && 35 | // ValidatingUtil::UnwrapChecksum(&unwrapped)) { 36 | // Process(unwrapped); 37 | // } 38 | class ValidatingUtil { 39 | public: 40 | // Adds checksum and given |timestamp| to |data|. 41 | static void Wrap(time_t timestamp, std::string* data); 42 | 43 | // Strips out the timestamp from |data|. Returns |true| if the timestamp is 44 | // present, formatted correctly, valid, and recent with respect to |now|. 45 | static bool UnwrapTimestamp(std::string* data, time_t now); 46 | 47 | // Strips out the checksum from |data|. Returns |true| if the checksum is 48 | // present, formatted correctly, and valid for this data. 49 | static bool UnwrapChecksum(std::string* data); 50 | 51 | ValidatingUtil(const ValidatingUtil&) = delete; 52 | ValidatingUtil& operator=(const ValidatingUtil&) = delete; 53 | }; 54 | 55 | } // namespace addressinput 56 | } // namespace i18n 57 | 58 | #endif // I18N_ADDRESSINPUT_VALIDATING_UTIL_H_ 59 | -------------------------------------------------------------------------------- /cpp/test/address_field_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace { 22 | 23 | using i18n::addressinput::SORTING_CODE; 24 | 25 | TEST(AddressFieldTest, ValidEnumValue) { 26 | std::ostringstream oss; 27 | oss << SORTING_CODE; 28 | EXPECT_EQ("SORTING_CODE", oss.str()); 29 | } 30 | 31 | } // namespace 32 | -------------------------------------------------------------------------------- /cpp/test/address_metadata_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace { 22 | 23 | using i18n::addressinput::IsFieldRequired; 24 | using i18n::addressinput::IsFieldUsed; 25 | 26 | using i18n::addressinput::COUNTRY; 27 | using i18n::addressinput::ADMIN_AREA; 28 | using i18n::addressinput::DEPENDENT_LOCALITY; 29 | 30 | TEST(AddressMetadataTest, IsFieldRequiredCountry) { 31 | EXPECT_TRUE(IsFieldRequired(COUNTRY, "US")); 32 | EXPECT_TRUE(IsFieldRequired(COUNTRY, "CH")); 33 | EXPECT_TRUE(IsFieldRequired(COUNTRY, "rrr")); 34 | } 35 | 36 | TEST(AddressMetadataTest, IsUsedRequiredCountry) { 37 | EXPECT_TRUE(IsFieldUsed(COUNTRY, "US")); 38 | EXPECT_TRUE(IsFieldUsed(COUNTRY, "CH")); 39 | EXPECT_TRUE(IsFieldUsed(COUNTRY, "rrr")); 40 | } 41 | 42 | TEST(AddressMetadataTest, IsFieldRequiredAdminAreaUS) { 43 | EXPECT_TRUE(IsFieldRequired(ADMIN_AREA, "US")); 44 | } 45 | 46 | TEST(AddressMetadataTest, IsFieldRequiredAdminAreaAT) { 47 | EXPECT_FALSE(IsFieldRequired(ADMIN_AREA, "AT")); 48 | } 49 | 50 | TEST(AddressMetadataTest, IsFieldRequiredAdminAreaSU) { 51 | // Unsupported region. 52 | EXPECT_FALSE(IsFieldRequired(ADMIN_AREA, "SU")); 53 | } 54 | 55 | TEST(AddressMetadataTest, IsFieldUsedDependentLocalityUS) { 56 | EXPECT_FALSE(IsFieldUsed(DEPENDENT_LOCALITY, "US")); 57 | } 58 | 59 | TEST(AddressMetadataTest, IsFieldUsedDependentLocalityCN) { 60 | EXPECT_TRUE(IsFieldUsed(DEPENDENT_LOCALITY, "CN")); 61 | } 62 | 63 | TEST(AddressMetadataTest, IsFieldUsedDependentLocalitySU) { 64 | // Unsupported region. 65 | EXPECT_FALSE(IsFieldUsed(DEPENDENT_LOCALITY, "SU")); 66 | } 67 | 68 | } // namespace 69 | -------------------------------------------------------------------------------- /cpp/test/address_problem_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace { 22 | 23 | using i18n::addressinput::UNKNOWN_VALUE; 24 | 25 | TEST(AddressProblemTest, ValidEnumValue) { 26 | std::ostringstream oss; 27 | oss << UNKNOWN_VALUE; 28 | EXPECT_EQ("UNKNOWN_VALUE", oss.str()); 29 | } 30 | 31 | } // namespace 32 | -------------------------------------------------------------------------------- /cpp/test/fake_storage.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "fake_storage.h" 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace i18n { 22 | namespace addressinput { 23 | 24 | FakeStorage::FakeStorage() = default; 25 | 26 | FakeStorage::~FakeStorage() { 27 | for (const auto& pair : data_) { 28 | delete pair.second; 29 | } 30 | } 31 | 32 | void FakeStorage::Put(const std::string& key, std::string* data) { 33 | assert(data != nullptr); 34 | auto result = data_.emplace(key, data); 35 | if (!result.second) { 36 | // Replace data in existing entry for this key. 37 | delete result.first->second; 38 | result.first->second = data; 39 | } 40 | } 41 | 42 | void FakeStorage::Get(const std::string& key, 43 | const Callback& data_ready) const { 44 | auto data_it = data_.find(key); 45 | bool success = data_it != data_.end(); 46 | data_ready(success, key, 47 | success ? new std::string(*data_it->second) : nullptr); 48 | } 49 | 50 | } // namespace addressinput 51 | } // namespace i18n 52 | -------------------------------------------------------------------------------- /cpp/test/fake_storage.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // A fake storage object to use in tests. Stores data in memory instead of 16 | // writing it to disk. All operations are synchronous. 17 | 18 | #ifndef I18N_ADDRESSINPUT_FAKE_STORAGE_H_ 19 | #define I18N_ADDRESSINPUT_FAKE_STORAGE_H_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | namespace i18n { 27 | namespace addressinput { 28 | 29 | // Stores data in memory. Sample usage: 30 | // class MyClass { 31 | // public: 32 | // MyClass(const MyClass&) = delete; 33 | // MyClass& operator=(const MyClass&) = delete; 34 | // 35 | // MyClass() : storage_(), 36 | // data_ready_(BuildCallback(this, &MyClass::OnDataReady)) {} 37 | // 38 | // ~MyClass() {} 39 | // 40 | // void Write() { 41 | // storage_.Put("key", "value"); 42 | // } 43 | // 44 | // void Read() { 45 | // storage_.Get("key", *data_ready_); 46 | // } 47 | // 48 | // private: 49 | // void OnDataReady(bool success, 50 | // const std::string& key, 51 | // std::string* data) { 52 | // ... 53 | // delete data; 54 | // } 55 | // 56 | // FakeStorage storage_; 57 | // const std::unique_ptr data_ready_; 58 | // }; 59 | class FakeStorage : public Storage { 60 | public: 61 | FakeStorage(const FakeStorage&) = delete; 62 | FakeStorage& operator=(const FakeStorage&) = delete; 63 | 64 | FakeStorage(); 65 | ~FakeStorage() override; 66 | 67 | // Storage implementation. 68 | void Put(const std::string& key, std::string* data) override; 69 | void Get(const std::string& key, const Callback& data_ready) const override; 70 | 71 | private: 72 | std::map data_; 73 | }; 74 | 75 | } // namespace addressinput 76 | } // namespace i18n 77 | 78 | #endif // I18N_ADDRESSINPUT_FAKE_STORAGE_H_ 79 | -------------------------------------------------------------------------------- /cpp/test/fake_storage_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "fake_storage.h" 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace { 27 | 28 | using i18n::addressinput::BuildCallback; 29 | using i18n::addressinput::FakeStorage; 30 | using i18n::addressinput::Storage; 31 | 32 | // Tests for FakeStorage object. 33 | class FakeStorageTest : public testing::Test { 34 | public: 35 | FakeStorageTest(const FakeStorageTest&) = delete; 36 | FakeStorageTest& operator=(const FakeStorageTest&) = delete; 37 | 38 | protected: 39 | FakeStorageTest() 40 | : storage_(), 41 | success_(false), 42 | key_(), 43 | data_(), 44 | data_ready_(BuildCallback(this, &FakeStorageTest::OnDataReady)) {} 45 | 46 | FakeStorage storage_; 47 | bool success_; 48 | std::string key_; 49 | std::string data_; 50 | const std::unique_ptr data_ready_; 51 | 52 | private: 53 | void OnDataReady(bool success, const std::string& key, std::string* data) { 54 | ASSERT_FALSE(success && data == nullptr); 55 | success_ = success; 56 | key_ = key; 57 | if (data != nullptr) { 58 | data_ = *data; 59 | delete data; 60 | } 61 | } 62 | }; 63 | 64 | TEST_F(FakeStorageTest, GetWithoutPutReturnsEmptyData) { 65 | storage_.Get("key", *data_ready_); 66 | 67 | EXPECT_FALSE(success_); 68 | EXPECT_EQ("key", key_); 69 | EXPECT_TRUE(data_.empty()); 70 | } 71 | 72 | TEST_F(FakeStorageTest, GetReturnsWhatWasPut) { 73 | storage_.Put("key", new std::string("value")); 74 | storage_.Get("key", *data_ready_); 75 | 76 | EXPECT_TRUE(success_); 77 | EXPECT_EQ("key", key_); 78 | EXPECT_EQ("value", data_); 79 | } 80 | 81 | TEST_F(FakeStorageTest, SecondPutOverwritesData) { 82 | storage_.Put("key", new std::string("bad-value")); 83 | storage_.Put("key", new std::string("good-value")); 84 | storage_.Get("key", *data_ready_); 85 | 86 | EXPECT_TRUE(success_); 87 | EXPECT_EQ("key", key_); 88 | EXPECT_EQ("good-value", data_); 89 | } 90 | 91 | } // namespace 92 | -------------------------------------------------------------------------------- /cpp/test/format_element_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "format_element.h" 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include 22 | 23 | namespace { 24 | 25 | using i18n::addressinput::FormatElement; 26 | using i18n::addressinput::SORTING_CODE; 27 | 28 | TEST(FormatElementTest, StreamFunctionNewline) { 29 | std::ostringstream oss; 30 | oss << FormatElement(); 31 | EXPECT_EQ("Newline", oss.str()); 32 | } 33 | 34 | TEST(FormatElementTest, StreamFunctionLiteral) { 35 | std::ostringstream oss; 36 | oss << FormatElement("Text"); 37 | EXPECT_EQ("Literal: Text", oss.str()); 38 | } 39 | 40 | TEST(FormatElementTest, StreamFunctionField) { 41 | std::ostringstream oss; 42 | oss << FormatElement(SORTING_CODE); 43 | EXPECT_EQ("Field: SORTING_CODE", oss.str()); 44 | } 45 | 46 | TEST(FormatElementTest, IsNewline) { 47 | EXPECT_TRUE(FormatElement().IsNewline()); 48 | EXPECT_FALSE(FormatElement(" ").IsNewline()); 49 | EXPECT_FALSE(FormatElement(SORTING_CODE).IsNewline()); 50 | } 51 | 52 | TEST(FormatElementTest, IsField) { 53 | EXPECT_FALSE(FormatElement().IsField()); 54 | EXPECT_FALSE(FormatElement(" ").IsField()); 55 | EXPECT_TRUE(FormatElement(SORTING_CODE).IsField()); 56 | } 57 | 58 | } // namespace 59 | -------------------------------------------------------------------------------- /cpp/test/language_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "language.h" 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace { 22 | 23 | using i18n::addressinput::Language; 24 | 25 | struct LanguageTestCase { 26 | LanguageTestCase(const std::string& input_language_tag, 27 | const std::string& expected_language_tag, 28 | const std::string& expected_base_language, 29 | bool expected_has_latin_script) 30 | : input_language_tag(input_language_tag), 31 | expected_language_tag(expected_language_tag), 32 | expected_base_language(expected_base_language), 33 | expected_has_latin_script(expected_has_latin_script) {} 34 | 35 | ~LanguageTestCase() = default; 36 | 37 | const std::string input_language_tag; 38 | const std::string expected_language_tag; 39 | const std::string expected_base_language; 40 | const bool expected_has_latin_script; 41 | }; 42 | 43 | class LanguageTest : public testing::TestWithParam { 44 | public: 45 | LanguageTest(const LanguageTest&) = delete; 46 | LanguageTest& operator=(const LanguageTest&) = delete; 47 | 48 | protected: 49 | LanguageTest() = default; 50 | }; 51 | 52 | TEST_P(LanguageTest, ExtractedDataIsCorrect) { 53 | Language language(GetParam().input_language_tag); 54 | EXPECT_EQ(GetParam().expected_language_tag, language.tag); 55 | EXPECT_EQ(GetParam().expected_base_language, language.base); 56 | EXPECT_EQ(GetParam().expected_has_latin_script, language.has_latin_script); 57 | } 58 | 59 | INSTANTIATE_TEST_SUITE_P( 60 | LanguageTestCases, LanguageTest, 61 | testing::Values(LanguageTestCase("", "", "", false), 62 | LanguageTestCase("en", "en", "en", false), 63 | LanguageTestCase("zh-Latn-CN", "zh-Latn-CN", "zh", true), 64 | LanguageTestCase("zh-cmn-Latn-CN", "zh-cmn-Latn-CN", "zh", 65 | true), 66 | LanguageTestCase("zh-Hans", "zh-Hans", "zh", false), 67 | LanguageTestCase("en_GB", "en-GB", "en", false))); 68 | 69 | } // namespace 70 | -------------------------------------------------------------------------------- /cpp/test/mock_source.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "mock_source.h" 16 | 17 | #include 18 | #include 19 | 20 | namespace i18n { 21 | namespace addressinput { 22 | 23 | MockSource::MockSource() = default; 24 | MockSource::~MockSource() = default; 25 | 26 | void MockSource::Get(const std::string& key, const Callback& data_ready) const { 27 | auto it = data_.find(key); 28 | bool success = it != data_.end(); 29 | data_ready(success, key, success ? new std::string(it->second) : nullptr); 30 | } 31 | 32 | } // namespace addressinput 33 | } // namespace i18n 34 | -------------------------------------------------------------------------------- /cpp/test/mock_source.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // A mock implementation of the Source interface to be used in tests. 16 | 17 | #ifndef I18N_ADDRESSINPUT_TEST_MOCK_SOURCE_H_ 18 | #define I18N_ADDRESSINPUT_TEST_MOCK_SOURCE_H_ 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | namespace i18n { 26 | namespace addressinput { 27 | 28 | // Gets address metadata from a key-value map. Sample usage: 29 | // class MyClass { 30 | // public: 31 | // MyClass(const MyClass&) = delete; 32 | // MyClass& operator=(const MyClass&) = delete; 33 | // 34 | // MyClass() : source_(), 35 | // data_ready_(BuildCallback(this, &MyClass::OnDataReady)) { 36 | // source_.data_ = {{"data/XA", R"({"id":"data/XA"})"}}; 37 | // } 38 | // 39 | // ~MyClass() {} 40 | // 41 | // void GetData(const std::string& key) { 42 | // source_.Get(key, *data_ready_); 43 | // } 44 | // 45 | // private: 46 | // void OnDataReady(bool success, 47 | // const std::string& key, 48 | // std::string* data) { 49 | // ... 50 | // delete data; 51 | // } 52 | // 53 | // MockSource source_; 54 | // const std::unique_ptr data_ready_; 55 | // }; 56 | class MockSource : public Source { 57 | public: 58 | MockSource(const MockSource&) = delete; 59 | MockSource& operator=(const MockSource&) = delete; 60 | 61 | MockSource(); 62 | ~MockSource() override; 63 | 64 | // Source implementation. 65 | void Get(const std::string& key, const Callback& data_ready) const override; 66 | 67 | std::map data_; 68 | }; 69 | 70 | } // namespace addressinput 71 | } // namespace i18n 72 | 73 | #endif // I18N_ADDRESSINPUT_TEST_MOCK_SOURCE_H_ 74 | -------------------------------------------------------------------------------- /cpp/test/null_storage_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace { 27 | 28 | using i18n::addressinput::BuildCallback; 29 | using i18n::addressinput::NullStorage; 30 | using i18n::addressinput::Storage; 31 | 32 | class NullStorageTest : public testing::Test { 33 | public: 34 | NullStorageTest(const NullStorageTest&) = delete; 35 | NullStorageTest& operator=(const NullStorageTest&) = delete; 36 | 37 | protected: 38 | NullStorageTest() 39 | : data_ready_(BuildCallback(this, &NullStorageTest::OnDataReady)) {} 40 | 41 | NullStorage storage_; 42 | bool success_; 43 | std::string key_; 44 | std::string data_; 45 | const std::unique_ptr data_ready_; 46 | 47 | static const char kKey[]; 48 | 49 | private: 50 | void OnDataReady(bool success, const std::string& key, std::string* data) { 51 | ASSERT_FALSE(success && data == nullptr); 52 | success_ = success; 53 | key_ = key; 54 | if (data != nullptr) { 55 | data_ = *data; 56 | delete data; 57 | } 58 | } 59 | }; 60 | 61 | const char NullStorageTest::kKey[] = "foo"; 62 | 63 | TEST_F(NullStorageTest, Put) { 64 | // The Put() method should not do anything, so this test only tests that the 65 | // code compiles and that the call doesn't crash. 66 | storage_.Put(kKey, new std::string("bar")); 67 | } 68 | 69 | TEST_F(NullStorageTest, Get) { 70 | storage_.Get(kKey, *data_ready_); 71 | EXPECT_FALSE(success_); 72 | EXPECT_EQ(kKey, key_); 73 | EXPECT_TRUE(data_.empty()); 74 | } 75 | 76 | } // namespace 77 | -------------------------------------------------------------------------------- /cpp/test/post_box_matchers_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "post_box_matchers.h" 16 | 17 | #include 18 | 19 | #include "rule.h" 20 | 21 | namespace { 22 | 23 | using i18n::addressinput::PostBoxMatchers; 24 | using i18n::addressinput::Rule; 25 | 26 | TEST(PostBoxMatchersTest, AlwaysGetMatcherForLanguageUnd) { 27 | Rule rule; 28 | const auto& matchers = PostBoxMatchers::GetMatchers(rule); 29 | EXPECT_EQ(1, matchers.size()); 30 | EXPECT_TRUE(matchers[0] != nullptr); 31 | } 32 | 33 | TEST(PostBoxMatchersTest, NoMatcherForInvalidLanguage) { 34 | Rule rule; 35 | ASSERT_TRUE(rule.ParseSerializedRule("{\"languages\":\"xx\"}")); 36 | const auto& matchers = PostBoxMatchers::GetMatchers(rule); 37 | EXPECT_EQ(1, matchers.size()); 38 | EXPECT_TRUE(matchers[0] != nullptr); 39 | } 40 | 41 | TEST(PostBoxMatchersTest, HasMatcherForValidLanguage) { 42 | Rule rule; 43 | ASSERT_TRUE(rule.ParseSerializedRule("{\"languages\":\"sv\"}")); 44 | const auto& matchers = PostBoxMatchers::GetMatchers(rule); 45 | EXPECT_EQ(2, matchers.size()); 46 | EXPECT_TRUE(matchers[0] != nullptr); 47 | EXPECT_TRUE(matchers[1] != nullptr); 48 | } 49 | 50 | TEST(PostBoxMatchersTest, MixValidAndInvalidLanguage) { 51 | Rule rule; 52 | ASSERT_TRUE(rule.ParseSerializedRule("{\"languages\":\"xx~sv\"}")); 53 | const auto& matchers = PostBoxMatchers::GetMatchers(rule); 54 | EXPECT_EQ(2, matchers.size()); 55 | EXPECT_TRUE(matchers[0] != nullptr); 56 | EXPECT_TRUE(matchers[1] != nullptr); 57 | } 58 | 59 | TEST(PostBoxMatchersTest, UseBaseLanguageForMatching) { 60 | Rule rule; 61 | ASSERT_TRUE(rule.ParseSerializedRule("{\"languages\":\"sv-SE\"}")); 62 | const auto& matchers = PostBoxMatchers::GetMatchers(rule); 63 | EXPECT_EQ(2, matchers.size()); 64 | EXPECT_TRUE(matchers[0] != nullptr); 65 | EXPECT_TRUE(matchers[1] != nullptr); 66 | } 67 | 68 | TEST(PostBoxMatchersTest, LenientLanguageTagParsing) { 69 | Rule rule; 70 | ASSERT_TRUE(rule.ParseSerializedRule("{\"languages\":\"SV_SE\"}")); 71 | const auto& matchers = PostBoxMatchers::GetMatchers(rule); 72 | EXPECT_EQ(2, matchers.size()); 73 | EXPECT_TRUE(matchers[0] != nullptr); 74 | EXPECT_TRUE(matchers[1] != nullptr); 75 | } 76 | 77 | } // namespace 78 | -------------------------------------------------------------------------------- /cpp/test/region_data_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace { 23 | 24 | using i18n::addressinput::RegionData; 25 | 26 | TEST(RegionDataTest, NoParentByDefault) { 27 | static const std::string kEmpty; 28 | RegionData region(kEmpty); 29 | EXPECT_FALSE(region.has_parent()); 30 | } 31 | 32 | TEST(RegionDataTest, NoSubRegionsByDefault) { 33 | static const std::string kEmpty; 34 | RegionData region(kEmpty); 35 | EXPECT_TRUE(region.sub_regions().empty()); 36 | } 37 | 38 | TEST(RegionDataTest, SubRegionGetsParent) { 39 | static const std::string kEmpty; 40 | RegionData region(kEmpty); 41 | region.AddSubRegion(kEmpty, kEmpty); 42 | ASSERT_EQ(1U, region.sub_regions().size()); 43 | ASSERT_TRUE(region.sub_regions()[0] != nullptr); 44 | EXPECT_EQ(®ion, ®ion.sub_regions()[0]->parent()); 45 | } 46 | 47 | } // namespace 48 | -------------------------------------------------------------------------------- /cpp/test/rule_retriever_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "rule_retriever.h" 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include "retriever.h" 26 | #include "rule.h" 27 | #include "testdata_source.h" 28 | 29 | namespace { 30 | 31 | using i18n::addressinput::BuildCallback; 32 | using i18n::addressinput::NullStorage; 33 | using i18n::addressinput::Retriever; 34 | using i18n::addressinput::Rule; 35 | using i18n::addressinput::RuleRetriever; 36 | using i18n::addressinput::TestdataSource; 37 | 38 | // Tests for RuleRetriever object. 39 | class RuleRetrieverTest : public testing::Test { 40 | public: 41 | RuleRetrieverTest(const RuleRetrieverTest&) = delete; 42 | RuleRetrieverTest& operator=(const RuleRetrieverTest&) = delete; 43 | 44 | protected: 45 | RuleRetrieverTest() 46 | : rule_retriever_( 47 | new Retriever(new TestdataSource(false), new NullStorage)), 48 | success_(false), 49 | key_(), 50 | rule_(), 51 | rule_ready_(BuildCallback(this, &RuleRetrieverTest::OnRuleReady)) {} 52 | 53 | RuleRetriever rule_retriever_; 54 | bool success_; 55 | std::string key_; 56 | Rule rule_; 57 | const std::unique_ptr rule_ready_; 58 | 59 | private: 60 | void OnRuleReady(bool success, 61 | const std::string& key, 62 | const Rule& rule) { 63 | success_ = success; 64 | key_ = key; 65 | rule_.CopyFrom(rule); 66 | } 67 | }; 68 | 69 | TEST_F(RuleRetrieverTest, ExistingRule) { 70 | static const char kExistingKey[] = "data/CA"; 71 | 72 | rule_retriever_.RetrieveRule(kExistingKey, *rule_ready_); 73 | 74 | EXPECT_TRUE(success_); 75 | EXPECT_EQ(kExistingKey, key_); 76 | EXPECT_FALSE(rule_.GetFormat().empty()); 77 | } 78 | 79 | TEST_F(RuleRetrieverTest, MissingRule) { 80 | static const char kMissingKey[] = "junk"; 81 | 82 | rule_retriever_.RetrieveRule(kMissingKey, *rule_ready_); 83 | 84 | EXPECT_TRUE(success_); // The server returns "{}" for bad keys. 85 | EXPECT_EQ(kMissingKey, key_); 86 | EXPECT_TRUE(rule_.GetFormat().empty()); 87 | } 88 | 89 | } // namespace 90 | -------------------------------------------------------------------------------- /cpp/test/testdata_source.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // An implementation of the Source interface, that reads address metadata from a 16 | // text file, to be used in tests. 17 | 18 | #ifndef I18N_ADDRESSINPUT_TEST_TESTDATA_SOURCE_H_ 19 | #define I18N_ADDRESSINPUT_TEST_TESTDATA_SOURCE_H_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace i18n { 26 | namespace addressinput { 27 | 28 | // The name of the test data file. 29 | extern const char kDataFileName[]; 30 | 31 | // Gets address metadata from a text file. Sample usage: 32 | // class MyClass { 33 | // public: 34 | // MyClass(const MyClass&) = delete; 35 | // MyClass& operator=(const MyClass&) = delete; 36 | // 37 | // MyClass() : data_ready_(BuildCallback(this, &MyClass::OnDataReady)), 38 | // source_(/*aggregate=*/true, 39 | // "path/to/test/data/file") {} 40 | // 41 | // ~MyClass() {} 42 | // 43 | // void GetData(const std::string& key) { 44 | // source_->Get(key, *data_ready_); 45 | // } 46 | // 47 | // private: 48 | // void OnDataReady(bool success, 49 | // const std::string& key, 50 | // std::string* data) { 51 | // ... 52 | // delete data; 53 | // } 54 | // 55 | // const std::unique_ptr data_ready_; 56 | // const TestdataSource source_; 57 | // }; 58 | class TestdataSource : public Source { 59 | public: 60 | TestdataSource(const TestdataSource&) = delete; 61 | TestdataSource& operator=(const TestdataSource&) = delete; 62 | 63 | // Will return aggregate data if |aggregate| is set to true. 64 | // This constructor uses a relative path to the test file. 65 | explicit TestdataSource(bool aggregate); 66 | 67 | // |src_path| is a path to the test data file. 68 | TestdataSource(bool aggregate, const std::string& src_path); 69 | 70 | ~TestdataSource() override; 71 | 72 | // Source implementation. 73 | void Get(const std::string& key, const Callback& data_ready) const override; 74 | 75 | private: 76 | const bool aggregate_; 77 | const std::string src_path_; 78 | }; 79 | 80 | } // namespace addressinput 81 | } // namespace i18n 82 | 83 | #endif // I18N_ADDRESSINPUT_TEST_TESTDATA_SOURCE_H_ 84 | -------------------------------------------------------------------------------- /cpp/test/util/string_compare_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "util/string_compare.h" 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace { 22 | 23 | using i18n::addressinput::StringCompare; 24 | 25 | struct TestCase { 26 | TestCase(const std::string& left, 27 | const std::string& right, 28 | bool should_be_equal, 29 | bool should_be_less) 30 | : left(left), 31 | right(right), 32 | should_be_equal(should_be_equal), 33 | should_be_less(should_be_less) {} 34 | 35 | ~TestCase() = default; 36 | 37 | std::string left; 38 | std::string right; 39 | bool should_be_equal; 40 | bool should_be_less; 41 | }; 42 | 43 | class StringCompareTest : public testing::TestWithParam { 44 | public: 45 | StringCompareTest(const StringCompareTest&) = delete; 46 | StringCompareTest& operator=(const StringCompareTest&) = delete; 47 | 48 | protected: 49 | StringCompareTest() = default; 50 | StringCompare compare_; 51 | }; 52 | 53 | TEST_P(StringCompareTest, CorrectComparison) { 54 | if (GetParam().should_be_equal) { 55 | EXPECT_TRUE(compare_.NaturalEquals(GetParam().left, GetParam().right)); 56 | } else { 57 | EXPECT_FALSE(compare_.NaturalEquals(GetParam().left, GetParam().right)); 58 | } 59 | } 60 | 61 | TEST_P(StringCompareTest, CorrectLess) { 62 | if (GetParam().should_be_less) { 63 | EXPECT_TRUE(compare_.NaturalLess(GetParam().left, GetParam().right)); 64 | } else { 65 | EXPECT_FALSE(compare_.NaturalLess(GetParam().left, GetParam().right)); 66 | } 67 | } 68 | 69 | INSTANTIATE_TEST_SUITE_P( 70 | Comparisons, StringCompareTest, 71 | testing::Values(TestCase("foo", "foo", true, false), 72 | TestCase("foo", "FOO", true, false), 73 | TestCase("bar", "foo", false, true), 74 | TestCase("강원도", "강원도", true, false), 75 | TestCase("강원도", "대구광역시", false, true), 76 | TestCase("ZÜRICH", "zürich", true, false), 77 | TestCase("абв", "где", false, true), 78 | TestCase("абв", "ГДЕ", false, true), 79 | TestCase("где", "абв", false, false), 80 | TestCase("где", "АБВ", false, false))); 81 | 82 | } // namespace 83 | -------------------------------------------------------------------------------- /cpp/test/util/string_split_unittest.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | // 5 | // The original source code is from: 6 | // http://src.chromium.org/viewvc/chrome/trunk/src/base/strings/string_split_unittest.cc?revision=216633 7 | 8 | #include "util/string_split.h" 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace { 16 | 17 | using i18n::addressinput::SplitString; 18 | 19 | TEST(StringSplitTest, SplitString) { 20 | std::vector r; 21 | 22 | SplitString(std::string(), ',', &r); 23 | EXPECT_EQ(0U, r.size()); 24 | 25 | SplitString("a,b,c", ',', &r); 26 | ASSERT_EQ(3U, r.size()); 27 | EXPECT_EQ(r[0], "a"); 28 | EXPECT_EQ(r[1], "b"); 29 | EXPECT_EQ(r[2], "c"); 30 | 31 | SplitString("a, b, c", ',', &r); 32 | ASSERT_EQ(3U, r.size()); 33 | EXPECT_EQ(r[0], "a"); 34 | EXPECT_EQ(r[1], " b"); 35 | EXPECT_EQ(r[2], " c"); 36 | 37 | SplitString("a,,c", ',', &r); 38 | ASSERT_EQ(3U, r.size()); 39 | EXPECT_EQ(r[0], "a"); 40 | EXPECT_EQ(r[1], ""); 41 | EXPECT_EQ(r[2], "c"); 42 | 43 | SplitString(" ", '*', &r); 44 | EXPECT_EQ(1U, r.size()); 45 | 46 | SplitString("foo", '*', &r); 47 | ASSERT_EQ(1U, r.size()); 48 | EXPECT_EQ(r[0], "foo"); 49 | 50 | SplitString("foo ,", ',', &r); 51 | ASSERT_EQ(2U, r.size()); 52 | EXPECT_EQ(r[0], "foo "); 53 | EXPECT_EQ(r[1], ""); 54 | 55 | SplitString(",", ',', &r); 56 | ASSERT_EQ(2U, r.size()); 57 | EXPECT_EQ(r[0], ""); 58 | EXPECT_EQ(r[1], ""); 59 | 60 | SplitString("\t\ta\t", '\t', &r); 61 | ASSERT_EQ(4U, r.size()); 62 | EXPECT_EQ(r[0], ""); 63 | EXPECT_EQ(r[1], ""); 64 | EXPECT_EQ(r[2], "a"); 65 | EXPECT_EQ(r[3], ""); 66 | 67 | SplitString("\ta\t\nb\tcc", '\n', &r); 68 | ASSERT_EQ(2U, r.size()); 69 | EXPECT_EQ(r[0], "\ta\t"); 70 | EXPECT_EQ(r[1], "b\tcc"); 71 | 72 | SplitString(" ", '*', &r); 73 | ASSERT_EQ(1U, r.size()); 74 | EXPECT_EQ(r[0], " "); 75 | 76 | SplitString("\t \ta\t ", '\t', &r); 77 | ASSERT_EQ(4U, r.size()); 78 | EXPECT_EQ(r[0], ""); 79 | EXPECT_EQ(r[1], " "); 80 | EXPECT_EQ(r[2], "a"); 81 | EXPECT_EQ(r[3], " "); 82 | 83 | SplitString("\ta\t\nb\tcc", '\n', &r); 84 | ASSERT_EQ(2U, r.size()); 85 | EXPECT_EQ(r[0], "\ta\t"); 86 | EXPECT_EQ(r[1], "b\tcc"); 87 | } 88 | 89 | } // namespace 90 | -------------------------------------------------------------------------------- /cpp/test/util/string_util_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations under 13 | // the License. 14 | 15 | #include "util/string_util.h" 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace { 23 | 24 | using i18n::addressinput::DoReplaceStringPlaceholders; 25 | 26 | TEST(StringUtilTest, Ok) { 27 | const std::vector subst{ 28 | "A", 29 | "B", 30 | "C", 31 | }; 32 | 33 | EXPECT_EQ("aA,bB,cC", DoReplaceStringPlaceholders("a$1,b$2,c$3", subst)); 34 | } 35 | 36 | TEST(StringUtilTest, FewParameters) { 37 | const std::vector subst{ 38 | "A", 39 | "B", 40 | "C", 41 | }; 42 | 43 | EXPECT_EQ("aA,bB,cC,d,aA", 44 | DoReplaceStringPlaceholders("a$1,b$2,c$3,d$4,a$1", subst)); 45 | } 46 | 47 | TEST(StringUtilTest, MoreThan9Parameters) { 48 | const std::vector subst{ 49 | "A", 50 | "B", 51 | "C", 52 | "D", 53 | "E", 54 | "F", 55 | "G", 56 | "H", 57 | "I", 58 | "J", 59 | "K", 60 | }; 61 | 62 | EXPECT_EQ("aA,bB,cC,dD,eE,fF,gG,hH,iI,jJ,kK,aA", 63 | DoReplaceStringPlaceholders("a$1,b$2,c$3,d$4,e$5,f$6,g$7,h$8,i$9," 64 | "j$10,k$11,a$1", 65 | subst)); 66 | } 67 | 68 | TEST(StringUtilTest, ConsecutiveDollarSigns) { 69 | const std::vector subst{ 70 | "A", 71 | "B", 72 | "C", 73 | }; 74 | 75 | EXPECT_EQ("$1 $$2 $$$3", 76 | DoReplaceStringPlaceholders("$$1 $$$2 $$$$3", subst)); 77 | } 78 | 79 | } // namespace 80 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * The Android address input widget is formed from the common (non-UI) classes 19 | * and the Android specific classes. 20 | */ 21 | include 'android', 'common' 22 | --------------------------------------------------------------------------------