11767c5feSopenharmony_ci// Copyright (C) 2012 The Libphonenumber Authors 21767c5feSopenharmony_ci// 31767c5feSopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 41767c5feSopenharmony_ci// you may not use this file except in compliance with the License. 51767c5feSopenharmony_ci// You may obtain a copy of the License at 61767c5feSopenharmony_ci// 71767c5feSopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 81767c5feSopenharmony_ci// 91767c5feSopenharmony_ci// Unless required by applicable law or agreed to in writing, software 101767c5feSopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 111767c5feSopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 121767c5feSopenharmony_ci// See the License for the specific language governing permissions and 131767c5feSopenharmony_ci// limitations under the License. 141767c5feSopenharmony_ci// 151767c5feSopenharmony_ci// Author: Patrick Mezard 161767c5feSopenharmony_ci 171767c5feSopenharmony_ci#include "phonenumbers/geocoding/mapping_file_provider.h" 181767c5feSopenharmony_ci 191767c5feSopenharmony_ci#include <algorithm> 201767c5feSopenharmony_ci#include <cstddef> 211767c5feSopenharmony_ci#include <cstring> 221767c5feSopenharmony_ci#include <sstream> 231767c5feSopenharmony_ci#include <string> 241767c5feSopenharmony_ci 251767c5feSopenharmony_ci#include "phonenumbers/geocoding/geocoding_data.h" 261767c5feSopenharmony_ci 271767c5feSopenharmony_cinamespace i18n { 281767c5feSopenharmony_cinamespace phonenumbers { 291767c5feSopenharmony_ci 301767c5feSopenharmony_ciusing std::string; 311767c5feSopenharmony_ci 321767c5feSopenharmony_cinamespace { 331767c5feSopenharmony_ci 341767c5feSopenharmony_cistruct NormalizedLocale { 351767c5feSopenharmony_ci const char* locale; 361767c5feSopenharmony_ci const char* normalized_locale; 371767c5feSopenharmony_ci}; 381767c5feSopenharmony_ci 391767c5feSopenharmony_ciconst NormalizedLocale kNormalizedLocales[] = { 401767c5feSopenharmony_ci {"zh_TW", "zh_Hant"}, 411767c5feSopenharmony_ci {"zh_HK", "zh_Hant"}, 421767c5feSopenharmony_ci {"zh_MO", "zh_Hant"}, 431767c5feSopenharmony_ci}; 441767c5feSopenharmony_ci 451767c5feSopenharmony_ciconst char* GetNormalizedLocale(const string& full_locale) { 461767c5feSopenharmony_ci const int size = sizeof(kNormalizedLocales) / sizeof(*kNormalizedLocales); 471767c5feSopenharmony_ci for (int i = 0; i != size; ++i) { 481767c5feSopenharmony_ci if (full_locale.compare(kNormalizedLocales[i].locale) == 0) { 491767c5feSopenharmony_ci return kNormalizedLocales[i].normalized_locale; 501767c5feSopenharmony_ci } 511767c5feSopenharmony_ci } 521767c5feSopenharmony_ci return NULL; 531767c5feSopenharmony_ci} 541767c5feSopenharmony_ci 551767c5feSopenharmony_civoid AppendLocalePart(const string& part, string* full_locale) { 561767c5feSopenharmony_ci if (!part.empty()) { 571767c5feSopenharmony_ci full_locale->append("_"); 581767c5feSopenharmony_ci full_locale->append(part); 591767c5feSopenharmony_ci } 601767c5feSopenharmony_ci} 611767c5feSopenharmony_ci 621767c5feSopenharmony_civoid ConstructFullLocale(const string& language, const string& script, const 631767c5feSopenharmony_ci string& region, string* full_locale) { 641767c5feSopenharmony_ci full_locale->assign(language); 651767c5feSopenharmony_ci AppendLocalePart(script, full_locale); 661767c5feSopenharmony_ci AppendLocalePart(region, full_locale); 671767c5feSopenharmony_ci} 681767c5feSopenharmony_ci 691767c5feSopenharmony_ci// Returns true if s1 comes strictly before s2 in lexicographic order. 701767c5feSopenharmony_cibool IsLowerThan(const char* s1, const char* s2) { 711767c5feSopenharmony_ci return strcmp(s1, s2) < 0; 721767c5feSopenharmony_ci} 731767c5feSopenharmony_ci 741767c5feSopenharmony_ci// Returns true if languages contains language. 751767c5feSopenharmony_cibool HasLanguage(const CountryLanguages* languages, const string& language) { 761767c5feSopenharmony_ci const char** const start = languages->available_languages; 771767c5feSopenharmony_ci const char** const end = start + languages->available_languages_size; 781767c5feSopenharmony_ci const char** const it = 791767c5feSopenharmony_ci std::lower_bound(start, end, language.c_str(), IsLowerThan); 801767c5feSopenharmony_ci return it != end && strcmp(language.c_str(), *it) == 0; 811767c5feSopenharmony_ci} 821767c5feSopenharmony_ci 831767c5feSopenharmony_ci} // namespace 841767c5feSopenharmony_ci 851767c5feSopenharmony_ciMappingFileProvider::MappingFileProvider( 861767c5feSopenharmony_ci const int* country_calling_codes, int country_calling_codes_size, 871767c5feSopenharmony_ci country_languages_getter get_country_languages) 881767c5feSopenharmony_ci : country_calling_codes_(country_calling_codes), 891767c5feSopenharmony_ci country_calling_codes_size_(country_calling_codes_size), 901767c5feSopenharmony_ci get_country_languages_(get_country_languages) { 911767c5feSopenharmony_ci} 921767c5feSopenharmony_ci 931767c5feSopenharmony_ciconst string& MappingFileProvider::GetFileName(int country_calling_code, 941767c5feSopenharmony_ci const string& language, 951767c5feSopenharmony_ci const string& script, 961767c5feSopenharmony_ci const string& region, 971767c5feSopenharmony_ci string* filename) const { 981767c5feSopenharmony_ci filename->clear(); 991767c5feSopenharmony_ci if (language.empty()) { 1001767c5feSopenharmony_ci return *filename; 1011767c5feSopenharmony_ci } 1021767c5feSopenharmony_ci const int* const country_calling_codes_end = country_calling_codes_ + 1031767c5feSopenharmony_ci country_calling_codes_size_; 1041767c5feSopenharmony_ci const int* const it = 1051767c5feSopenharmony_ci std::lower_bound(country_calling_codes_, 1061767c5feSopenharmony_ci country_calling_codes_end, 1071767c5feSopenharmony_ci country_calling_code); 1081767c5feSopenharmony_ci if (it == country_calling_codes_end || *it != country_calling_code) { 1091767c5feSopenharmony_ci return *filename; 1101767c5feSopenharmony_ci } 1111767c5feSopenharmony_ci const CountryLanguages* const langs = 1121767c5feSopenharmony_ci get_country_languages_(it - country_calling_codes_); 1131767c5feSopenharmony_ci if (langs->available_languages_size > 0) { 1141767c5feSopenharmony_ci string language_code; 1151767c5feSopenharmony_ci FindBestMatchingLanguageCode(langs, language, script, region, 1161767c5feSopenharmony_ci &language_code); 1171767c5feSopenharmony_ci if (!language_code.empty()) { 1181767c5feSopenharmony_ci std::stringstream filename_buf; 1191767c5feSopenharmony_ci filename_buf << country_calling_code << "_" << language_code; 1201767c5feSopenharmony_ci *filename = filename_buf.str(); 1211767c5feSopenharmony_ci } 1221767c5feSopenharmony_ci } 1231767c5feSopenharmony_ci return *filename; 1241767c5feSopenharmony_ci} 1251767c5feSopenharmony_ci 1261767c5feSopenharmony_civoid MappingFileProvider::FindBestMatchingLanguageCode( 1271767c5feSopenharmony_ci const CountryLanguages* languages, const string& language, 1281767c5feSopenharmony_ci const string& script, const string& region, string* best_match) const { 1291767c5feSopenharmony_ci string full_locale; 1301767c5feSopenharmony_ci ConstructFullLocale(language, script, region, &full_locale); 1311767c5feSopenharmony_ci const char* const normalized_locale = GetNormalizedLocale(full_locale); 1321767c5feSopenharmony_ci if (normalized_locale != NULL) { 1331767c5feSopenharmony_ci string normalized_locale_str(normalized_locale); 1341767c5feSopenharmony_ci if (HasLanguage(languages, normalized_locale_str)) { 1351767c5feSopenharmony_ci best_match->swap(normalized_locale_str); 1361767c5feSopenharmony_ci return; 1371767c5feSopenharmony_ci } 1381767c5feSopenharmony_ci } 1391767c5feSopenharmony_ci 1401767c5feSopenharmony_ci if (HasLanguage(languages, full_locale)) { 1411767c5feSopenharmony_ci best_match->swap(full_locale); 1421767c5feSopenharmony_ci return; 1431767c5feSopenharmony_ci } 1441767c5feSopenharmony_ci 1451767c5feSopenharmony_ci if (script.empty() != region.empty()) { 1461767c5feSopenharmony_ci if (HasLanguage(languages, language)) { 1471767c5feSopenharmony_ci *best_match = language; 1481767c5feSopenharmony_ci return; 1491767c5feSopenharmony_ci } 1501767c5feSopenharmony_ci } else if (!script.empty() && !region.empty()) { 1511767c5feSopenharmony_ci string lang_with_script(language); 1521767c5feSopenharmony_ci lang_with_script.append("_"); 1531767c5feSopenharmony_ci lang_with_script.append(script); 1541767c5feSopenharmony_ci if (HasLanguage(languages, lang_with_script)) { 1551767c5feSopenharmony_ci best_match->swap(lang_with_script); 1561767c5feSopenharmony_ci return; 1571767c5feSopenharmony_ci } 1581767c5feSopenharmony_ci } 1591767c5feSopenharmony_ci 1601767c5feSopenharmony_ci string lang_with_region(language); 1611767c5feSopenharmony_ci lang_with_region.append("_"); 1621767c5feSopenharmony_ci lang_with_region.append(region); 1631767c5feSopenharmony_ci if (HasLanguage(languages, lang_with_region)) { 1641767c5feSopenharmony_ci best_match->swap(lang_with_region); 1651767c5feSopenharmony_ci return; 1661767c5feSopenharmony_ci } 1671767c5feSopenharmony_ci if (HasLanguage(languages, language)) { 1681767c5feSopenharmony_ci *best_match = language; 1691767c5feSopenharmony_ci return; 1701767c5feSopenharmony_ci } 1711767c5feSopenharmony_ci best_match->clear(); 1721767c5feSopenharmony_ci} 1731767c5feSopenharmony_ci 1741767c5feSopenharmony_ci} // namespace phonenumbers 1751767c5feSopenharmony_ci} // namespace i18n 176