From 242431d78c2191494ebeb268e4dc9f22910cddfc Mon Sep 17 00:00:00 2001 From: "dbeaumont@google.com" Date: Fri, 16 May 2014 13:18:16 +0000 Subject: Adding support of language code in lookup keys (extracted from the address). git-svn-id: http://libaddressinput.googlecode.com/svn/trunk@218 38ededc0-08b8-5190-f2ac-b31f878777ad --- cpp/src/lookup_key.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++++----- cpp/src/lookup_key.h | 3 +++ 2 files changed, 55 insertions(+), 5 deletions(-) (limited to 'cpp/src') diff --git a/cpp/src/lookup_key.cc b/cpp/src/lookup_key.cc index 0b6f7d8..3148d02 100644 --- a/cpp/src/lookup_key.cc +++ b/cpp/src/lookup_key.cc @@ -19,20 +19,62 @@ #include #include #include +#include #include #include #include +#include "language.h" +#include "region_data_constants.h" +#include "rule.h" + namespace i18n { namespace addressinput { namespace { const char kSlashDelim[] = "/"; +const char kDashDelim[] = "--"; const char kData[] = "data"; const char kUnknown[] = "ZZ"; +// Case insensitive matcher for language tags. +struct LanguageMatcher { + LanguageMatcher(const std::string& tag) : tag(tag) { } + std::string tag; + bool operator() (const std::string& s) { + return strcasecmp(tag.c_str(), s.c_str()) == 0; + } +}; + +// Assume the language_tag has had "Latn" script removed when this is called. +bool ShouldSetLanguageForKey(const std::string& language_tag, + const std::string& region_code) { + // We only need a language in the key if there is subregion data at all. + if (RegionDataConstants::GetMaxLookupKeyDepth(region_code) == 0) { + return false; + } + Rule rule; + rule.CopyFrom(Rule::GetDefault()); + // TODO: Pre-parse the rules and have a map from region code to rule. + if (!rule.ParseSerializedRule( + RegionDataConstants::GetRegionData(region_code))) { + return false; + } + const std::vector& languages = rule.GetLanguages(); + // Do not add the default language (we want "data/US", not "data/US--en"). + // (empty should not happen here because we have some sub-region data). + if (languages.empty() || languages[0] == language_tag) { + return false; + } + // Finally, only return true if the language is one of the remaining ones. + return std::find_if(languages.begin() + 1, + languages.end(), + LanguageMatcher(language_tag)) + != languages.end(); +} + } // namespace const AddressField LookupKey::kHierarchy[] = { @@ -50,7 +92,6 @@ LookupKey::~LookupKey() { void LookupKey::FromAddress(const AddressData& address) { nodes_.clear(); - if (address.region_code.empty()) { nodes_.insert(std::make_pair(COUNTRY, kUnknown)); } else { @@ -63,12 +104,15 @@ void LookupKey::FromAddress(const AddressData& address) { nodes_.insert(std::make_pair(field, value)); } } + Language address_language(address.language_code); + std::string language_tag_no_latn = address_language.has_latin_script ? + address_language.base : address_language.tag; + if (ShouldSetLanguageForKey(language_tag_no_latn, address.region_code)) { + language_ = language_tag_no_latn; + } } std::string LookupKey::ToKeyString(size_t max_depth) const { - // TODO: For use by the address input widget, this key string would need to - // also include a language tag to request data in the appropriate language. - assert(max_depth < arraysize(kHierarchy)); std::string key_string(kData); @@ -81,7 +125,10 @@ std::string LookupKey::ToKeyString(size_t max_depth) const { key_string.append(kSlashDelim); key_string.append(it->second); } - + if (!language_.empty()) { + key_string.append(kDashDelim); + key_string.append(language_); + } return key_string; } diff --git a/cpp/src/lookup_key.h b/cpp/src/lookup_key.h index be76656..9e4e3d5 100644 --- a/cpp/src/lookup_key.h +++ b/cpp/src/lookup_key.h @@ -52,6 +52,9 @@ class LookupKey { private: std::map nodes_; + // The language of the key, obtained from the address (empty for default + // language). + std::string language_; DISALLOW_COPY_AND_ASSIGN(LookupKey); }; -- cgit v1.2.3