This source file includes following definitions.
- ParseToken
- ParseAddressFieldsFormat
- ParseAddressFieldsRequired
- GetAdminAreaMessageId
- GetPostalCodeMessageId
- literal
- literal
- invalid_postal_code_message_id_
- GetDefault
- CopyFrom
- ParseSerializedRule
- ParseJsonRule
- GetIdentityField
- GetInvalidFieldMessageId
- CanonicalizeSubKey
- GetMatchingSubKey
#include "rule.h"
#include <libaddressinput/address_field.h>
#include <libaddressinput/util/scoped_ptr.h>
#include <cassert>
#include <cstddef>
#include <string>
#include <vector>
#include "grit.h"
#include "grit/libaddressinput_strings.h"
#include "region_data_constants.h"
#include "util/json.h"
#include "util/string_util.h"
namespace i18n {
namespace addressinput {
namespace {
bool ParseToken(char c, AddressField* field) {
assert(field != NULL);
switch (c) {
case 'R':
*field = COUNTRY;
return true;
case 'S':
*field = ADMIN_AREA;
return true;
case 'C':
*field = LOCALITY;
return true;
case 'D':
*field = DEPENDENT_LOCALITY;
return true;
case 'X':
*field = SORTING_CODE;
return true;
case 'Z':
*field = POSTAL_CODE;
return true;
case 'A':
*field = STREET_ADDRESS;
return true;
case 'O':
*field = ORGANIZATION;
return true;
case 'N':
*field = RECIPIENT;
return true;
default:
return false;
}
}
void ParseAddressFieldsFormat(const std::string& format,
std::vector<std::vector<FormatElement> >* lines) {
assert(lines != NULL);
lines->clear();
lines->resize(1);
std::vector<std::string> format_parts;
SplitString(format, '%', &format_parts);
if (!format_parts.empty() && !format_parts[0].empty()) {
lines->back().push_back(FormatElement(format_parts[0]));
}
for (size_t i = 1; i < format_parts.size(); ++i) {
if (format_parts[i].empty()) {
continue;
}
const char control_character = format_parts[i][0];
const std::string literal = format_parts[i].substr(1);
AddressField field = COUNTRY;
if (ParseToken(control_character, &field)) {
lines->back().push_back(FormatElement(field));
} else if (control_character == 'n') {
lines->push_back(std::vector<FormatElement>());
}
if (!literal.empty()) {
lines->back().push_back(FormatElement(literal));
}
}
}
void ParseAddressFieldsRequired(const std::string& required,
std::vector<AddressField>* fields) {
assert(fields != NULL);
fields->clear();
for (size_t i = 0; i < required.length(); ++i) {
AddressField field = COUNTRY;
if (ParseToken(required[i], &field)) {
fields->push_back(field);
}
}
}
int GetAdminAreaMessageId(const std::string& admin_area_type, bool error) {
if (admin_area_type == "area") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_AREA
: IDS_LIBADDRESSINPUT_I18N_AREA;
}
if (admin_area_type == "county") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_COUNTY_LABEL
: IDS_LIBADDRESSINPUT_I18N_COUNTY_LABEL;
}
if (admin_area_type == "department") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_DEPARTMENT
: IDS_LIBADDRESSINPUT_I18N_DEPARTMENT;
}
if (admin_area_type == "district") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_DEPENDENT_LOCALITY_LABEL
: IDS_LIBADDRESSINPUT_I18N_DEPENDENT_LOCALITY_LABEL;
}
if (admin_area_type == "do_si") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_DO_SI
: IDS_LIBADDRESSINPUT_I18N_DO_SI;
}
if (admin_area_type == "emirate") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_EMIRATE
: IDS_LIBADDRESSINPUT_I18N_EMIRATE;
}
if (admin_area_type == "island") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_ISLAND
: IDS_LIBADDRESSINPUT_I18N_ISLAND;
}
if (admin_area_type == "parish") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_PARISH
: IDS_LIBADDRESSINPUT_I18N_PARISH;
}
if (admin_area_type == "prefecture") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_PREFECTURE
: IDS_LIBADDRESSINPUT_I18N_PREFECTURE;
}
if (admin_area_type == "province") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_PROVINCE
: IDS_LIBADDRESSINPUT_I18N_PROVINCE;
}
if (admin_area_type == "state") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_STATE_LABEL
: IDS_LIBADDRESSINPUT_I18N_STATE_LABEL;
}
return INVALID_MESSAGE_ID;
}
int GetPostalCodeMessageId(const std::string& postal_code_type, bool error) {
if (postal_code_type == "postal") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_POSTAL_CODE_LABEL
: IDS_LIBADDRESSINPUT_I18N_POSTAL_CODE_LABEL;
}
if (postal_code_type == "zip") {
return error ? IDS_LIBADDRESSINPUT_I18N_INVALID_ZIP_CODE_LABEL
: IDS_LIBADDRESSINPUT_I18N_ZIP_CODE_LABEL;
}
return INVALID_MESSAGE_ID;
}
}
FormatElement::FormatElement(AddressField field)
: field(field), literal() {}
FormatElement::FormatElement(const std::string& literal)
: field(COUNTRY), literal(literal) {
assert(!literal.empty());
}
FormatElement::~FormatElement() {}
bool FormatElement::operator==(const FormatElement& other) const {
return field == other.field && literal == other.literal;
}
Rule::Rule()
: key_(),
name_(),
latin_name_(),
format_(),
latin_format_(),
required_(),
sub_keys_(),
sub_names_(),
sub_lnames_(),
languages_(),
input_languages_(),
language_(),
postal_code_format_(),
admin_area_name_message_id_(INVALID_MESSAGE_ID),
invalid_admin_area_message_id_(INVALID_MESSAGE_ID),
postal_code_name_message_id_(INVALID_MESSAGE_ID),
invalid_postal_code_message_id_(INVALID_MESSAGE_ID) {}
Rule::~Rule() {}
const Rule& Rule::GetDefault() {
static Rule* default_rule = NULL;
if (default_rule == NULL) {
default_rule = new Rule;
default_rule->ParseSerializedRule(
RegionDataConstants::GetDefaultRegionData());
}
return *default_rule;
}
void Rule::CopyFrom(const Rule& rule) {
key_ = rule.key_;
name_ = rule.name_;
latin_name_ = rule.latin_name_;
format_ = rule.format_;
latin_format_ = rule.latin_format_;
required_ = rule.required_;
sub_keys_ = rule.sub_keys_;
languages_ = rule.languages_;
input_languages_ = rule.input_languages_;
language_ = rule.language_;
sub_keys_ = rule.sub_keys_;
sub_names_ = rule.sub_names_;
sub_lnames_ = rule.sub_lnames_;
postal_code_format_ = rule.postal_code_format_;
admin_area_name_message_id_ = rule.admin_area_name_message_id_;
invalid_admin_area_message_id_ = rule.invalid_admin_area_message_id_;
postal_code_name_message_id_ = rule.postal_code_name_message_id_;
invalid_postal_code_message_id_ = rule.invalid_postal_code_message_id_;
}
bool Rule::ParseSerializedRule(const std::string& serialized_rule) {
scoped_ptr<Json> json(Json::Build());
if (!json->ParseObject(serialized_rule)) {
return false;
}
ParseJsonRule(*json);
return true;
}
void Rule::ParseJsonRule(const Json& json_rule) {
std::string value;
if (json_rule.GetStringValueForKey("key", &value)) {
key_.swap(value);
}
if (json_rule.GetStringValueForKey("name", &value)) {
name_.swap(value);
}
if (json_rule.GetStringValueForKey("lname", &value)) {
latin_name_.swap(value);
}
if (json_rule.GetStringValueForKey("fmt", &value)) {
ParseAddressFieldsFormat(value, &format_);
}
if (json_rule.GetStringValueForKey("lfmt", &value)) {
ParseAddressFieldsFormat(value, &latin_format_);
}
if (json_rule.GetStringValueForKey("require", &value)) {
ParseAddressFieldsRequired(value, &required_);
}
static const char kSeparator = '~';
if (json_rule.GetStringValueForKey("sub_keys", &value)) {
SplitString(value, kSeparator, &sub_keys_);
}
if (json_rule.GetStringValueForKey("sub_names", &value)) {
SplitString(value, kSeparator, &sub_names_);
assert(sub_names_.size() == sub_keys_.size());
}
if (json_rule.GetStringValueForKey("sub_lnames", &value)) {
SplitString(value, kSeparator, &sub_lnames_);
assert(sub_lnames_.size() == sub_keys_.size());
}
if (json_rule.GetStringValueForKey("languages", &value)) {
SplitString(value, kSeparator, &languages_);
}
if (json_rule.GetStringValueForKey("input_languages", &value)) {
SplitString(value, kSeparator, &input_languages_);
}
if (json_rule.GetStringValueForKey("lang", &value)) {
language_.swap(value);
}
if (json_rule.GetStringValueForKey("zip", &value)) {
postal_code_format_.swap(value);
}
if (json_rule.GetStringValueForKey("state_name_type", &value)) {
admin_area_name_message_id_ = GetAdminAreaMessageId(value, false);
invalid_admin_area_message_id_ = GetAdminAreaMessageId(value, true);
}
if (json_rule.GetStringValueForKey("zip_name_type", &value)) {
postal_code_name_message_id_ = GetPostalCodeMessageId(value, false);
invalid_postal_code_message_id_ = GetPostalCodeMessageId(value, true);
}
}
const std::string& Rule::GetIdentityField(IdentityField identity_field) const {
switch (identity_field) {
case KEY:
return key_;
case NAME:
return name_;
case LATIN_NAME:
return latin_name_;
case IDENTITY_FIELDS_SIZE:
assert(false);
}
return key_;
}
int Rule::GetInvalidFieldMessageId(AddressField field) const {
switch (field) {
case ADMIN_AREA:
return invalid_admin_area_message_id_;
case LOCALITY:
return IDS_LIBADDRESSINPUT_I18N_INVALID_LOCALITY_LABEL;
case DEPENDENT_LOCALITY:
return IDS_LIBADDRESSINPUT_I18N_INVALID_DEPENDENT_LOCALITY_LABEL;
case POSTAL_CODE:
return invalid_postal_code_message_id_;
default:
return IDS_LIBADDRESSINPUT_I18N_INVALID_ENTRY;
}
}
bool Rule::CanonicalizeSubKey(const std::string& user_input,
std::string* sub_key) const {
if (sub_keys_.empty()) {
*sub_key = user_input;
return true;
}
return GetMatchingSubKey(user_input, sub_keys_, sub_key) ||
GetMatchingSubKey(user_input, sub_names_, sub_key) ||
GetMatchingSubKey(user_input, sub_lnames_, sub_key);
}
bool Rule::GetMatchingSubKey(const std::string& target,
const std::vector<std::string>& values,
std::string* sub_key) const {
for (size_t i = 0; i < values.size(); ++i) {
if (LooseStringCompare(values[i], target)) {
*sub_key = sub_keys_[i];
return true;
}
}
return false;
}
}
}