diff options
author | rouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad> | 2013-11-14 23:04:51 +0000 |
---|---|---|
committer | rouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad> | 2013-11-14 23:04:51 +0000 |
commit | e44b60b2f13cd40ca783937f0b1a418bd8510921 (patch) | |
tree | 3b7e1964207b6167b0115205ec24af00ec731f13 | |
parent | 04e3fcc1dd4a9beae60228d3a390025761cc2b65 (diff) | |
download | src-e44b60b2f13cd40ca783937f0b1a418bd8510921.tar.gz |
[cpp] Address fields
This patch is part of a series of patches that enable showing an address
input form. This patch adds an AddressField enum and functions to parse it
from a format string.
git-svn-id: http://libaddressinput.googlecode.com/svn/trunk@157 38ededc0-08b8-5190-f2ac-b31f878777ad
-rw-r--r-- | cpp/include/libaddressinput/address_field.h | 46 | ||||
-rw-r--r-- | cpp/libaddressinput.gyp | 3 | ||||
-rw-r--r-- | cpp/src/address_field.cc | 59 | ||||
-rw-r--r-- | cpp/src/address_field_util.cc | 83 | ||||
-rw-r--r-- | cpp/src/address_field_util.h | 42 | ||||
-rw-r--r-- | cpp/test/address_field_util_test.cc | 73 |
6 files changed, 306 insertions, 0 deletions
diff --git a/cpp/include/libaddressinput/address_field.h b/cpp/include/libaddressinput/address_field.h new file mode 100644 index 0000000..aed7332 --- /dev/null +++ b/cpp/include/libaddressinput/address_field.h @@ -0,0 +1,46 @@ +// Copyright (C) 2013 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef I18N_ADDRESSINPUT_ADDRESS_FIELD_H_ +#define I18N_ADDRESSINPUT_ADDRESS_FIELD_H_ + +#include <iosfwd> + +namespace i18n { +namespace addressinput { + +// Address field types, ordered by size, from largest to smallest. +enum AddressField { + COUNTRY, // Country code. + ADMIN_AREA, // Administrative area such as a state, province, + // island, etc. + LOCALITY, // City or locality. + DEPENDENT_LOCALITY, // Dependent locality (may be an inner-city district or + // a suburb). + SORTING_CODE, // Sorting code. + POSTAL_CODE, // Zip or postal code. + STREET_ADDRESS, // Street address lines. + ORGANIZATION, // Organization. + RECIPIENT // Name. +}; + +// Produces human-readable output in logging, for example in unit tests. Prints +// what you would expect for valid fields, e.g. "COUNTRY" for COUNTRY. For +// invalid values, prints "[INVALID]". +std::ostream& operator<<(std::ostream& o, AddressField field); + +} // namespace addressinput +} // namespace i18n + +#endif // I18N_ADDRESSINPUT_ADDRESS_FIELD_H_ diff --git a/cpp/libaddressinput.gyp b/cpp/libaddressinput.gyp index 2574bd8..a9dbe99 100644 --- a/cpp/libaddressinput.gyp +++ b/cpp/libaddressinput.gyp @@ -31,6 +31,8 @@ 'target_name': 'libaddressinput', 'type': '<(component)', 'sources': [ + 'src/address_field.cc', + 'src/address_field_util.cc', 'src/region_data_constants.cc', 'src/util/json.cc', ], @@ -43,6 +45,7 @@ 'target_name': 'unit_tests', 'type': 'executable', 'sources': [ + 'test/address_field_util_test.cc', 'test/region_data_constants_test.cc', 'test/util/json_test.cc', ], diff --git a/cpp/src/address_field.cc b/cpp/src/address_field.cc new file mode 100644 index 0000000..92360ee --- /dev/null +++ b/cpp/src/address_field.cc @@ -0,0 +1,59 @@ +// Copyright (C) 2013 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <libaddressinput/address_field.h> + +#include <ostream> + +namespace i18n { +namespace addressinput { + +std::ostream& operator<<(std::ostream& o, AddressField field) { + switch (field) { + case COUNTRY: + o << "COUNTRY"; + break; + case ADMIN_AREA: + o << "ADMIN_AREA"; + break; + case LOCALITY: + o << "LOCALITY"; + break; + case DEPENDENT_LOCALITY: + o << "DEPENDENT_LOCALITY"; + break; + case SORTING_CODE: + o << "SORTING_CODE"; + break; + case POSTAL_CODE: + o << "POSTAL_CODE"; + break; + case STREET_ADDRESS: + o << "STREET_ADDRESS"; + break; + case ORGANIZATION: + o << "ORGANIZATION"; + break; + case RECIPIENT: + o << "RECIPIENT"; + break; + default: + o << "[INVALID]"; + break; + } + return o; +} + +} // namespace addressinput +} // namespace i18n diff --git a/cpp/src/address_field_util.cc b/cpp/src/address_field_util.cc new file mode 100644 index 0000000..cb14794 --- /dev/null +++ b/cpp/src/address_field_util.cc @@ -0,0 +1,83 @@ +// Copyright (C) 2013 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "address_field_util.h" + +#include <libaddressinput/address_field.h> + +#include <cassert> +#include <map> +#include <string> +#include <utility> +#include <vector> + +namespace i18n { +namespace addressinput { + +namespace { + +std::map<char, AddressField> InitFields() { + std::map<char, AddressField> fields; + fields.insert(std::make_pair('R', COUNTRY)); + fields.insert(std::make_pair('S', ADMIN_AREA)); + fields.insert(std::make_pair('C', LOCALITY)); + fields.insert(std::make_pair('D', DEPENDENT_LOCALITY)); + fields.insert(std::make_pair('x', SORTING_CODE)); + fields.insert(std::make_pair('Z', POSTAL_CODE)); + fields.insert(std::make_pair('A', STREET_ADDRESS)); + fields.insert(std::make_pair('O', ORGANIZATION)); + fields.insert(std::make_pair('N', RECIPIENT)); + // An extension of AddressField enum used only internally: + fields.insert(std::make_pair( + 'n', static_cast<AddressField>(NEWLINE))); + return fields; +} + +const std::map<char, AddressField>& GetFields() { + static const std::map<char, AddressField> kFields(InitFields()); + return kFields; +} + +bool IsTokenPrefix(char c) { + return c == '%'; +} + +bool IsToken(char c) { + return GetFields().find(c) != GetFields().end(); +} + +AddressField ParseToken(char c) { + std::map<char, AddressField>::const_iterator it = GetFields().find(c); + assert(it != GetFields().end()); + return it->second; +} + +} // namespace + +void ParseAddressFieldsFormat(const std::string& format, + std::vector<AddressField>* fields) { + assert(fields != NULL); + fields->clear(); + for (std::string::const_iterator current = format.begin(), + next = format.begin() + 1; + current != format.end() && next != format.end(); + ++current, ++next) { + if (IsTokenPrefix(*current) && IsToken(*next)) { + fields->push_back(ParseToken(*next)); + } + } +} + +} // namespace addressinput +} // namespace i18n diff --git a/cpp/src/address_field_util.h b/cpp/src/address_field_util.h new file mode 100644 index 0000000..e55b950 --- /dev/null +++ b/cpp/src/address_field_util.h @@ -0,0 +1,42 @@ +// Copyright (C) 2013 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_ +#define I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_ + +#include <libaddressinput/address_field.h> + +#include <string> +#include <vector> + +namespace i18n { +namespace addressinput { + +// An extension of AddressField enum used only internally. The values are +// negative to avoid clashing with the values in AddressField. +enum { + NEWLINE = -1 +}; + +// Clears |fields|, parses |format|, and adds the format address fields to +// |fields|. The |fields| may also contain NEWLINE elements. For example, parses +// "%S%C%n%D%X" into {ADMIN_AREA, LOCALITY, NEWLINE, DEPENDENT_LOCALITY, +// SORTING_CODE}. +void ParseAddressFieldsFormat(const std::string& format, + std::vector<AddressField>* fields); + +} // namespace addressinput +} // namespace i18n + +#endif // I18N_ADDRESSINPUT_ADDRESS_FIELD_UTIL_H_ diff --git a/cpp/test/address_field_util_test.cc b/cpp/test/address_field_util_test.cc new file mode 100644 index 0000000..ce2ad77 --- /dev/null +++ b/cpp/test/address_field_util_test.cc @@ -0,0 +1,73 @@ +// Copyright (C) 2013 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "address_field_util.h" + +#include <libaddressinput/address_field.h> + +#include <string> +#include <vector> + +#include <gtest/gtest.h> + +namespace { + +using i18n::addressinput::AddressField; +using i18n::addressinput::COUNTRY; +using i18n::addressinput::LOCALITY; +using i18n::addressinput::NEWLINE; +using i18n::addressinput::ORGANIZATION; +using i18n::addressinput::ParseAddressFieldsFormat; +using i18n::addressinput::POSTAL_CODE; +using i18n::addressinput::RECIPIENT; +using i18n::addressinput::STREET_ADDRESS; + +TEST(AddressFieldUtilTest, ParseNewlineFormat) { + std::vector<AddressField> actual; + ParseAddressFieldsFormat("%O%n%N%n%A%nAX-%Z %C%nĂ…LAND", &actual); + + std::vector<AddressField> expected; + expected.push_back(ORGANIZATION); + expected.push_back(static_cast<AddressField>(NEWLINE)); + expected.push_back(RECIPIENT); + expected.push_back(static_cast<AddressField>(NEWLINE)); + expected.push_back(STREET_ADDRESS); + expected.push_back(static_cast<AddressField>(NEWLINE)); + expected.push_back(POSTAL_CODE); + expected.push_back(LOCALITY); + expected.push_back(static_cast<AddressField>(NEWLINE)); + + EXPECT_EQ(expected, actual); +} + +TEST(AddressFieldUtilTest, DoubleTokenPrefixIsIgnored) { + std::vector<AddressField> actual; + ParseAddressFieldsFormat("%%R", &actual); + std::vector<AddressField> expected(1, COUNTRY); + EXPECT_EQ(expected, actual); +} + +TEST(AddressFieldUtilTest, PrefixWithoutTokenIsIgnored) { + std::vector<AddressField> actual; + ParseAddressFieldsFormat("%", &actual); + EXPECT_TRUE(actual.empty()); +} + +TEST(AddressFieldUtilTest, EmptyString) { + std::vector<AddressField> fields; + ParseAddressFieldsFormat(std::string(), &fields); + EXPECT_TRUE(fields.empty()); +} + +} // namespace |