Chromium Code Reviews| Index: third_party/libaddressinput/chromium/cpp/src/rule.cc |
| diff --git a/third_party/libaddressinput/chromium/cpp/src/rule.cc b/third_party/libaddressinput/chromium/cpp/src/rule.cc |
| index 15d13443de680420e50729ae32a8ad90096dd443..ae003f17c8b457eb702a69bb9cf923c142c657fa 100644 |
| --- a/third_party/libaddressinput/chromium/cpp/src/rule.cc |
| +++ b/third_party/libaddressinput/chromium/cpp/src/rule.cc |
| @@ -17,11 +17,13 @@ |
| #include <libaddressinput/address_field.h> |
| #include <libaddressinput/util/scoped_ptr.h> |
| +#include <cassert> |
| +#include <cstddef> |
| #include <map> |
| #include <string> |
| #include <utility> |
| +#include <vector> |
| -#include "address_field_util.h" |
| #include "grit.h" |
| #include "messages.h" |
| #include "util/json.h" |
| @@ -38,7 +40,9 @@ const char kAdminAreaNameTypeKey[] = "state_name_type"; |
| const char kFormatKey[] = "fmt"; |
| const char kLanguageKey[] = "lang"; |
| const char kLanguagesKey[] = "languages"; |
| +const char kPostalCodeFormatKey[] = "zip"; |
| const char kPostalCodeNameTypeKey[] = "zip_name_type"; |
| +const char kRequiredKey[] = "require"; |
| const char kSubKeysKey[] = "sub_keys"; |
| // Used as a separator in a list of items. For example, the list of supported |
| @@ -98,13 +102,94 @@ int GetMessageIdFromName(const std::string& name, |
| return it != message_ids.end() ? it->second : INVALID_MESSAGE_ID; |
| } |
| +std::map<char, AddressField> InitFields() { |
| + std::map<char, AddressField> fields; |
| + fields.insert(std::make_pair('R', COUNTRY)); |
| + fields.insert(std::make_pair('S', ADMIN_AREA)); |
| + fields.insert(std::make_pair('C', LOCALITY)); |
| + fields.insert(std::make_pair('D', DEPENDENT_LOCALITY)); |
| + fields.insert(std::make_pair('x', SORTING_CODE)); |
| + fields.insert(std::make_pair('Z', POSTAL_CODE)); |
| + fields.insert(std::make_pair('A', STREET_ADDRESS)); |
| + fields.insert(std::make_pair('O', ORGANIZATION)); |
| + fields.insert(std::make_pair('N', RECIPIENT)); |
| + return fields; |
| +} |
| + |
| +const std::map<char, AddressField>& GetFields() { |
| + static const std::map<char, AddressField> kFields(InitFields()); |
|
Evan Stade
2013/12/19 23:00:04
no static non-PODs allowed
use switch/case for th
please use gerrit instead
2013/12/20 00:37:43
Switch/case does not work for strings. Changed to
|
| + return kFields; |
| +} |
| + |
| +bool IsTokenPrefix(char c) { |
| + return c == '%'; |
| +} |
| + |
| +bool IsNewlineToken(char c) { |
| + return c == 'n'; |
| +} |
| + |
| +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; |
| +} |
| + |
| +// Clears |fields|, parses |format|, and adds the format address fields to |
| +// |fields|. For example, parses "%S%C%n%D%X" into {{ADMIN_AREA, LOCALITY}, |
| +// {DEPENDENT_LOCALITY, SORTING_CODE}}. |
| +void ParseAddressFieldsFormat(const std::string& format, |
| + std::vector<std::vector<AddressField> >* fields) { |
| + assert(fields != NULL); |
| + fields->clear(); |
| + bool begin_newline = true; |
| + for (std::string::const_iterator current = format.begin(), |
| + next = format.begin() + 1; |
|
Evan Stade
2013/12/19 23:00:04
splitstring on % makes this shorter I think?
please use gerrit instead
2013/12/20 00:37:43
Good guess! I tried your suggestion, but the resul
|
| + current != format.end() && next != format.end(); |
| + ++current, ++next) { |
| + if (!IsTokenPrefix(*current)) { |
| + continue; |
| + } |
| + if (IsToken(*next)) { |
| + if (begin_newline) { |
| + fields->push_back(std::vector<AddressField>()); |
| + begin_newline = false; |
| + } |
| + fields->back().push_back(ParseToken(*next)); |
| + } else if (IsNewlineToken(*next)) { |
| + begin_newline = true; |
| + } |
| + } |
| +} |
| + |
| +// Clears |fields|, parses |required|, and adds the required fields to |fields|. |
| +// For example, parses "SCDX" into {ADMIN_AREA, LOCALITY, DEPENDENT_LOCALITY, |
| +// SORTING_CODE}. |
| +void ParseAddressFieldsRequired(const std::string& required, |
| + std::vector<AddressField>* fields) { |
| + assert(fields != NULL); |
| + fields->clear(); |
| + for (std::string::const_iterator token = required.begin(); |
| + token != required.end(); ++token) { |
| + if (IsToken(*token)) { |
| + fields->push_back(ParseToken(*token)); |
| + } |
| + } |
| +} |
| + |
| } // namespace |
| Rule::Rule() |
| : format_(), |
| + required_(), |
| sub_keys_(), |
| languages_(), |
| language_(), |
| + postal_code_format_(), |
| admin_area_name_message_id_(INVALID_MESSAGE_ID), |
| postal_code_name_message_id_(INVALID_MESSAGE_ID) {} |
| @@ -112,9 +197,11 @@ Rule::~Rule() {} |
| void Rule::CopyFrom(const Rule& rule) { |
| format_ = rule.format_; |
| + required_ = rule.required_; |
| sub_keys_ = rule.sub_keys_; |
| languages_ = rule.languages_; |
| language_ = rule.language_; |
| + postal_code_format_ = rule.postal_code_format_; |
| admin_area_name_message_id_ = rule.admin_area_name_message_id_; |
| postal_code_name_message_id_ = rule.postal_code_name_message_id_; |
| } |
| @@ -129,6 +216,11 @@ bool Rule::ParseSerializedRule(const std::string& serialized_rule) { |
| ParseAddressFieldsFormat(json->GetStringValueForKey(kFormatKey), &format_); |
| } |
| + if (json->HasStringValueForKey(kRequiredKey)) { |
| + ParseAddressFieldsRequired( |
| + json->GetStringValueForKey(kRequiredKey), &required_); |
| + } |
| + |
| if (json->HasStringValueForKey(kSubKeysKey)) { |
| SplitString( |
| json->GetStringValueForKey(kSubKeysKey), kSeparator, &sub_keys_); |
| @@ -143,6 +235,10 @@ bool Rule::ParseSerializedRule(const std::string& serialized_rule) { |
| language_ = json->GetStringValueForKey(kLanguageKey); |
| } |
| + if (json->HasStringValueForKey(kPostalCodeFormatKey)) { |
| + postal_code_format_ = json->GetStringValueForKey(kPostalCodeFormatKey); |
| + } |
| + |
| if (json->HasStringValueForKey(kAdminAreaNameTypeKey)) { |
| admin_area_name_message_id_ = |
| GetMessageIdFromName(json->GetStringValueForKey(kAdminAreaNameTypeKey), |