aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad>2013-11-14 23:04:51 +0000
committerrouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad>2013-11-14 23:04:51 +0000
commite44b60b2f13cd40ca783937f0b1a418bd8510921 (patch)
tree3b7e1964207b6167b0115205ec24af00ec731f13
parent04e3fcc1dd4a9beae60228d3a390025761cc2b65 (diff)
downloadsrc-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.h46
-rw-r--r--cpp/libaddressinput.gyp3
-rw-r--r--cpp/src/address_field.cc59
-rw-r--r--cpp/src/address_field_util.cc83
-rw-r--r--cpp/src/address_field_util.h42
-rw-r--r--cpp/test/address_field_util_test.cc73
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