1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cstring>
17 #include <filesystem>
18 #include <sys/stat.h>
19 #include "i18n_hilog.h"
20 #include "libxml/globals.h"
21 #include "libxml/tree.h"
22 #include "libxml/xmlstring.h"
23 #include "locale_compare.h"
24 #include "locale_config.h"
25 #include "utils.h"
26 #include "taboo.h"
27
28 namespace OHOS {
29 namespace Global {
30 namespace I18n {
31 const std::string Taboo::TABOO_CONFIG_FILE = "taboo-config.xml";
32 const std::string Taboo::TABOO_DATA_FILE = "taboo-data.xml";
33 const std::string Taboo::FILE_PATH_SPLITOR = "/";
34 const std::string Taboo::LANGUAGE_REGION_SPLITOR = "_";
35 const std::string Taboo::TABOO_DATA_SPLITOR = ",";
36 const std::string Taboo::OMITTED_SYMBOL = "*";
37 const std::string Taboo::ROOT_TAG = "taboo";
38 const std::string Taboo::ITEM_TAG = "item";
39 const std::string Taboo::NAME_TAG = "name";
40 const std::string Taboo::VALUE_TAG = "value";
41 const std::string Taboo::SUPPORTED_LANGUAGE_TAG = "languages";
42 const std::string Taboo::SUPPORTED_REGION_TAG = "regions";
43 const std::string Taboo::SUPPORTED_TIME_ZONE_TAG = "timezones";
44 const std::string Taboo::SUPPORTED_CITY_TAG = "cities";
45 const std::string Taboo::SUPPORTED_PHONE_NUMBER_TAG = "phonenumbers";
46 const std::string Taboo::LANGUAGE_KEY = "language_";
47 const std::string Taboo::REGION_KEY = "region_";
48 const std::string Taboo::TIME_ZONE_KEY = "timezone_";
49 const std::string Taboo::CITY_KEY = "city_";
50 const std::string Taboo::PHONE_NUMBER_KEY = "phonenumber_";
51 const std::string Taboo::BLOCKED_LANG_TAG = "taboo_blocked_lang";
52 const std::string Taboo::BLOCKED_CITY_TAG = "taboo_blocked_city";
53 const std::string Taboo::BLOCKED_PHONE_NUMBER_TAG = "taboo_blocked_phonenumber";
54 const std::string Taboo::MCC_MNC_FIRST_KEY = "telephony.sim.opkey0";
55 const std::string Taboo::MCC_MNC_SECOND_KEY = "telephony.sim.opkey1";
56 const std::string Taboo::CUST_REGION_KEY = "const.cust.region";
57 const std::string Taboo::MCC_MNC_TAG = "_mccmnc_";
58 const std::string Taboo::MCC_TAG = "_mcc_";
59 const std::string Taboo::CUST_REGION_TAG = "_vc_";
60 const std::string Taboo::DEFAULT_REGION_TAG = "_c_";
61 const std::string Taboo::COMMON_SUFFIX = "_r_all";
62 const size_t Taboo::MCC_MNC_LENGTH = 5;
63 const size_t Taboo::MCC_LENGTH = 3;
64
Taboo(const std::string & path)65 Taboo::Taboo(const std::string& path) : tabooDataPath(path)
66 {
67 using std::filesystem::directory_iterator;
68
69 std::string tabooConfigFilePath = tabooDataPath + TABOO_CONFIG_FILE;
70 struct stat s;
71 isTabooDataExist = stat(tabooConfigFilePath.c_str(), &s) == 0;
72 if (!isTabooDataExist) {
73 HILOG_ERROR_I18N("Taboo::Taboo: Taboo data not exist.");
74 return;
75 }
76 // parse taboo-config.xml to obtain supported regions and languages for name replacement.
77 ParseTabooData(tabooConfigFilePath, DataFileType::CONFIG_FILE);
78 ReadResourceList();
79 InitFallBackSuffixes();
80 }
81
~Taboo()82 Taboo::~Taboo()
83 {
84 }
85
ReplaceCountryName(const std::string & region,const std::string & displayLanguage,const std::string & name)86 std::string Taboo::ReplaceCountryName(const std::string& region, const std::string& displayLanguage,
87 const std::string& name)
88 {
89 if (!isTabooDataExist) {
90 HILOG_ERROR_I18N("Taboo::ReplaceCountryName: Taboo data not exist.");
91 return name;
92 }
93 if (supportedRegions.find(region) == supportedRegions.end()) {
94 return name;
95 }
96 std::string fallbackLanguage;
97 std::string fileName;
98 std::tie(fallbackLanguage, fileName) = LanguageFallBack(displayLanguage);
99 if (fallbackLanguage.empty()) {
100 return name;
101 }
102 InitLocaleTabooData(fallbackLanguage, fileName);
103 auto tabooData = localeTabooData[fallbackLanguage];
104 std::string key = REGION_KEY + region;
105 std::vector<std::string> fallbackRegionKeys = QueryKeyFallBack(key);
106 for (auto& fallbackRegionKey : fallbackRegionKeys) {
107 if (tabooData.find(fallbackRegionKey) != tabooData.end()) {
108 return tabooData.at(fallbackRegionKey);
109 }
110 }
111 return name;
112 }
113
ReplaceLanguageName(const std::string & language,const std::string & displayLanguage,const std::string & name)114 std::string Taboo::ReplaceLanguageName(const std::string& language, const std::string& displayLanguage,
115 const std::string& name)
116 {
117 if (!isTabooDataExist) {
118 HILOG_ERROR_I18N("Taboo::ReplaceCountryName: Taboo data not exist.");
119 return name;
120 }
121 if (supportedLanguages.find(language) == supportedLanguages.end()) {
122 return name;
123 }
124 std::string fallbackLanguage;
125 std::string fileName;
126 std::tie(fallbackLanguage, fileName) = LanguageFallBack(displayLanguage);
127 if (fallbackLanguage.empty()) {
128 return name;
129 }
130 InitLocaleTabooData(fallbackLanguage, fileName);
131 auto tabooData = localeTabooData[fallbackLanguage];
132 std::string key = LANGUAGE_KEY + language;
133 std::vector<std::string> fallbackLanguageKeys = QueryKeyFallBack(key);
134 for (const auto& fallbackLanguageKey : fallbackLanguageKeys) {
135 if (tabooData.find(fallbackLanguageKey) != tabooData.end()) {
136 return tabooData.at(fallbackLanguageKey);
137 }
138 }
139 return name;
140 }
141
ReplaceTimeZoneName(const std::string & tzId,const std::string & displayLanguage,const std::string & name)142 std::string Taboo::ReplaceTimeZoneName(const std::string& tzId, const std::string& displayLanguage,
143 const std::string& name)
144 {
145 if (!isTabooDataExist) {
146 HILOG_ERROR_I18N("Taboo::ReplaceCountryName: Taboo data not exist.");
147 return name;
148 }
149 if (supportedTimeZones.find(tzId) == supportedTimeZones.end()) {
150 return name;
151 }
152 std::string fallbackLanguage;
153 std::string fileName;
154 std::tie(fallbackLanguage, fileName) = LanguageFallBack(displayLanguage);
155 if (fallbackLanguage.empty()) {
156 return name;
157 }
158 InitLocaleTabooData(fallbackLanguage, fileName);
159 auto tabooData = localeTabooData[fallbackLanguage];
160 std::string key = TIME_ZONE_KEY + tzId;
161 std::vector<std::string> fallbackTimeZoneKeys = QueryKeyFallBack(key);
162 for (const auto& fallbackTimeZoneKey : fallbackTimeZoneKeys) {
163 if (tabooData.find(fallbackTimeZoneKey) != tabooData.end()) {
164 return tabooData.at(fallbackTimeZoneKey);
165 }
166 }
167 return name;
168 }
169
ReplaceCityName(const std::string & cityId,const std::string & displayLanguage,const std::string & name)170 std::string Taboo::ReplaceCityName(const std::string& cityId, const std::string& displayLanguage,
171 const std::string& name)
172 {
173 if (!isTabooDataExist) {
174 HILOG_ERROR_I18N("Taboo::ReplaceCityName: Taboo data not exist.");
175 return name;
176 }
177 if (supportedcities.find(cityId) == supportedcities.end()) {
178 return name;
179 }
180 std::string fallbackLanguage;
181 std::string fileName;
182 std::tie(fallbackLanguage, fileName) = LanguageFallBack(displayLanguage);
183 if (fallbackLanguage.empty()) {
184 return name;
185 }
186 InitLocaleTabooData(fallbackLanguage, fileName);
187 auto tabooData = localeTabooData[fallbackLanguage];
188 std::string key = CITY_KEY + cityId;
189 std::vector<std::string> fallbackCityKeys = QueryKeyFallBack(key);
190 for (const auto& fallbackCityKey : fallbackCityKeys) {
191 if (tabooData.find(fallbackCityKey) != tabooData.end()) {
192 return tabooData.at(fallbackCityKey);
193 }
194 }
195 return name;
196 }
197
ReplacePhoneLocationName(const std::string & phoneNumber,const std::string & displayLanguage,const std::string & name)198 std::string Taboo::ReplacePhoneLocationName(const std::string& phoneNumber, const std::string& displayLanguage,
199 const std::string& name)
200 {
201 if (!isTabooDataExist) {
202 HILOG_ERROR_I18N("Taboo::ReplaceCountryName: Taboo data not exist.");
203 return name;
204 }
205 std::string prefix;
206 for (const auto& supportedPhoneNumber : supportedPhoneNumbers) {
207 if (phoneNumber.compare(0, supportedPhoneNumber.length(), supportedPhoneNumber) == 0) {
208 prefix = supportedPhoneNumber;
209 break;
210 }
211 }
212 if (prefix.empty()) {
213 return name;
214 }
215 std::string fallbackLanguage;
216 std::string fileName;
217 std::tie(fallbackLanguage, fileName) = LanguageFallBack(displayLanguage);
218 if (fallbackLanguage.empty()) {
219 return name;
220 }
221 InitLocaleTabooData(fallbackLanguage, fileName);
222 auto tabooData = localeTabooData[fallbackLanguage];
223 std::string key = PHONE_NUMBER_KEY + prefix;
224 std::vector<std::string> fallbackPhoneNunberKeys = QueryKeyFallBack(key);
225 for (const auto& fallbackPhoneNunberKey : fallbackPhoneNunberKeys) {
226 if (tabooData.find(fallbackPhoneNunberKey) != tabooData.end()) {
227 return tabooData.at(fallbackPhoneNunberKey);
228 }
229 }
230 return name;
231 }
232
GetBlockedLanguages() const233 std::unordered_set<std::string> Taboo::GetBlockedLanguages() const
234 {
235 std::vector<std::string> fallbackKeys = QueryKeyFallBack(BLOCKED_LANG_TAG);
236 for (const auto& fallbackKey : fallbackKeys) {
237 if (blockedLanguages.find(fallbackKey) != blockedLanguages.end()) {
238 return blockedLanguages.at(fallbackKey);
239 }
240 }
241 return {};
242 }
243
GetBlockedRegions() const244 std::unordered_set<std::string> Taboo::GetBlockedRegions() const
245 {
246 std::vector<std::string> fallbackKeys = QueryKeyFallBack(BLOCKED_LANG_TAG);
247 for (const auto& fallbackKey : fallbackKeys) {
248 if (blockedRegions.find(fallbackKey) != blockedRegions.end()) {
249 return blockedRegions.at(fallbackKey);
250 }
251 }
252 return {};
253 }
254
GetBlockedRegions(const std::string & language) const255 std::unordered_set<std::string> Taboo::GetBlockedRegions(const std::string& language) const
256 {
257 std::unordered_set<std::string> result = GetBlockedRegions();
258 if (language.empty()) {
259 return result;
260 }
261 std::unordered_set<std::string> temp;
262 std::vector<std::string> fallbackKeys = QueryKeyFallBack(BLOCKED_LANG_TAG);
263 for (const auto& fallbackKey : fallbackKeys) {
264 if (languageBlockedRegions.find(fallbackKey) != languageBlockedRegions.end()) {
265 auto languageBlockedRegion = languageBlockedRegions.at(fallbackKey);
266 if (languageBlockedRegion.find(language) != languageBlockedRegion.end()) {
267 temp = languageBlockedRegion.at(language);
268 }
269 break;
270 }
271 }
272 result.insert(temp.begin(), temp.end());
273 return result;
274 }
275
GetBlockedCities() const276 std::unordered_set<std::string> Taboo::GetBlockedCities() const
277 {
278 std::vector<std::string> fallbackKeys = QueryKeyFallBack(BLOCKED_CITY_TAG);
279 for (const auto& fallbackKey : fallbackKeys) {
280 if (blockedCities.find(fallbackKey) != blockedCities.end()) {
281 return blockedCities.at(fallbackKey);
282 }
283 }
284 return {};
285 }
286
GetBlockedPhoneNumbers() const287 std::unordered_set<std::string> Taboo::GetBlockedPhoneNumbers() const
288 {
289 std::vector<std::string> fallbackKeys = QueryKeyFallBack(BLOCKED_PHONE_NUMBER_TAG);
290 for (const auto& fallbackKey : fallbackKeys) {
291 if (blockedPhoneNumbers.find(fallbackKey) != blockedPhoneNumbers.end()) {
292 return blockedPhoneNumbers.at(fallbackKey);
293 }
294 }
295 return {};
296 }
297
ParseTabooData(const std::string & path,DataFileType fileType,const std::string & locale)298 void Taboo::ParseTabooData(const std::string& path, DataFileType fileType, const std::string& locale)
299 {
300 xmlKeepBlanksDefault(0);
301 xmlDocPtr doc = xmlParseFile(path.c_str());
302 if (doc == nullptr) {
303 HILOG_ERROR_I18N("Taboo::ParseTabooData: Parse taboo data file failed: %{public}s", path.c_str());
304 return;
305 }
306 xmlNodePtr cur = xmlDocGetRootElement(doc);
307 if (cur == nullptr || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(ROOT_TAG.c_str())) != 0) {
308 xmlFreeDoc(doc);
309 HILOG_ERROR_I18N("Taboo::ParseTabooData: Get root tag from taboo data file failed: %{public}s", path.c_str());
310 return;
311 }
312 cur = cur->xmlChildrenNode;
313 const xmlChar* nameTag = reinterpret_cast<const xmlChar*>(NAME_TAG.c_str());
314 const xmlChar* valueTag = reinterpret_cast<const xmlChar*>(VALUE_TAG.c_str());
315 while (cur != nullptr && xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(ITEM_TAG.c_str())) == 0) {
316 xmlChar* name = xmlGetProp(cur, nameTag);
317 xmlChar* value = xmlGetProp(cur, valueTag);
318 if (name == nullptr || value == nullptr) {
319 HILOG_ERROR_I18N("Taboo::ParseTabooData: Get name and value property failed: %{public}s", path.c_str());
320 xmlFree(name);
321 xmlFree(value);
322 cur = cur->next;
323 continue;
324 }
325 std::string nameStr = reinterpret_cast<const char*>(name);
326 std::string valueStr = reinterpret_cast<const char*>(value);
327 HandleTabooData(fileType, locale, nameStr, valueStr);
328 xmlFree(name);
329 xmlFree(value);
330 cur = cur->next;
331 }
332 xmlFreeDoc(doc);
333 }
334
HandleTabooData(DataFileType fileType,const std::string & locale,const std::string & name,const std::string & value)335 void Taboo::HandleTabooData(DataFileType fileType, const std::string& locale, const std::string& name,
336 const std::string& value)
337 {
338 switch (fileType) {
339 case DataFileType::CONFIG_FILE:
340 ProcessTabooConfigData(name, value);
341 break;
342 case DataFileType::DATA_FILE:
343 ProcessTabooLocaleData(locale, name, value);
344 break;
345 default:
346 break;
347 }
348 }
349
ProcessTabooConfigData(const std::string & key,const std::string & value)350 void Taboo::ProcessTabooConfigData(const std::string& key, const std::string& value)
351 {
352 if (key.compare(0, BLOCKED_LANG_TAG.length(), BLOCKED_LANG_TAG) == 0) {
353 ParseBlockedLanguagesAndRegions(key, value);
354 } else if (key.compare(0, BLOCKED_CITY_TAG.length(), BLOCKED_CITY_TAG) == 0) {
355 ParseBlockedCities(key, value);
356 } else if (key.compare(0, BLOCKED_PHONE_NUMBER_TAG.length(), BLOCKED_PHONE_NUMBER_TAG) == 0) {
357 ParseBlockedPhoneNumbers(key, value);
358 } else if (key.compare(SUPPORTED_LANGUAGE_TAG) == 0) {
359 Split(value, TABOO_DATA_SPLITOR, supportedLanguages);
360 } else if (key.compare(SUPPORTED_REGION_TAG) == 0) {
361 Split(value, TABOO_DATA_SPLITOR, supportedRegions);
362 } else if (key.compare(SUPPORTED_TIME_ZONE_TAG) == 0) {
363 Split(value, TABOO_DATA_SPLITOR, supportedTimeZones);
364 } else if (key.compare(SUPPORTED_CITY_TAG) == 0) {
365 Split(value, TABOO_DATA_SPLITOR, supportedcities);
366 } else if (key.compare(SUPPORTED_PHONE_NUMBER_TAG) == 0) {
367 Split(value, TABOO_DATA_SPLITOR, supportedPhoneNumbers);
368 }
369 }
370
ProcessTabooLocaleData(const std::string & locale,const std::string & name,const std::string & value)371 void Taboo::ProcessTabooLocaleData(const std::string& locale, const std::string& name, const std::string& value)
372 {
373 if (localeTabooData.find(locale) != localeTabooData.end()) {
374 localeTabooData[locale][name] = value;
375 return;
376 }
377 std::unordered_map<std::string, std::string> data;
378 data[name] = value;
379 localeTabooData[locale] = data;
380 }
381
QueryKeyFallBack(const std::string & key) const382 std::vector<std::string> Taboo::QueryKeyFallBack(const std::string& key) const
383 {
384 size_t len = fallBackSuffixes.size();
385 std::vector<std::string> fallback(len);
386 for (size_t i = 0; i < len; i++) {
387 fallback[i] = key + fallBackSuffixes[i];
388 }
389 return fallback;
390 }
391
LanguageFallBack(const std::string & language)392 std::tuple<std::string, std::string> Taboo::LanguageFallBack(const std::string& language)
393 {
394 std::string bestMatch;
395 std::string fileName;
396 int32_t bestScore = -1;
397
398 for (auto it = resources.begin(); it != resources.end(); ++it) {
399 std::string resLanguage = it->first;
400 int32_t score = LocaleCompare::Compare(language, resLanguage);
401 if (score > bestScore) {
402 bestMatch = resLanguage;
403 fileName = it->second;
404 bestScore = score;
405 }
406 }
407 if (bestScore < 0) {
408 return std::make_tuple("", "");
409 }
410 return std::make_tuple(bestMatch, fileName);
411 }
412
ReadResourceList()413 void Taboo::ReadResourceList()
414 {
415 using std::filesystem::directory_iterator;
416 struct stat s;
417 for (const auto &dirEntry : directory_iterator{tabooDataPath}) {
418 std::string path = dirEntry.path();
419 if (stat(path.c_str(), &s) != 0) {
420 HILOG_ERROR_I18N("Taboo::ReadResourceList: Get path status failed.");
421 continue;
422 }
423 if (s.st_mode & S_IFDIR) {
424 std::string fileName = path.substr(tabooDataPath.length());
425 std::string language = GetLanguageFromFileName(fileName);
426 resources[language] = fileName;
427 }
428 }
429 }
430
GetLanguageFromFileName(const std::string & fileName)431 std::string Taboo::GetLanguageFromFileName(const std::string& fileName)
432 {
433 if (fileName.length() == 3) { // 3 is the length of file 'xml'
434 return "en";
435 }
436 std::string language = fileName.substr(4);
437 if (language[0] == 'b' && language[1] == '+') {
438 language = language.substr(2); // 2 is the length of "b+"
439 }
440 size_t pos = language.find("+");
441 if (pos != std::string::npos) {
442 language = language.replace(pos, 1, "-");
443 }
444 pos = language.find("-r");
445 if (pos != std::string::npos) {
446 language = language.replace(pos, 2, "-"); // 2 is the length of "-r"
447 }
448 return language;
449 }
450
ParseBlockedLanguagesAndRegions(const std::string & key,const std::string & value)451 void Taboo::ParseBlockedLanguagesAndRegions(const std::string& key, const std::string& value)
452 {
453 std::vector<std::string> blockedDatas;
454 Split(value, TABOO_DATA_SPLITOR, blockedDatas);
455 if (blockedDatas.size() == 0) {
456 return;
457 }
458 std::unordered_set<std::string> blockedLanguage;
459 std::unordered_set<std::string> blockedRegion;
460 std::unordered_map<std::string, std::unordered_set<std::string>> languageBlockedRegion;
461 for (const auto& blockedData : blockedDatas) {
462 if (blockedData.empty()) {
463 continue;
464 }
465 size_t pos = blockedData.find(LANGUAGE_REGION_SPLITOR);
466 if (pos == std::string::npos) {
467 HILOG_ERROR_I18N("Taboo::ParseBlockedLanguagesAndRegions: Invalid blocked data %{public}s.",
468 blockedData.c_str());
469 continue;
470 }
471 std::string language = blockedData.substr(0, pos);
472 std::string region = blockedData.substr(pos + 1);
473 if (language.empty() || region.empty()) {
474 HILOG_ERROR_I18N("Taboo::ParseBlockedLanguagesAndRegions: Language or region is empty, data %{public}s.",
475 blockedData.c_str());
476 continue;
477 }
478 if (language.compare(OMITTED_SYMBOL) == 0 && region.compare(OMITTED_SYMBOL) == 0) {
479 HILOG_ERROR_I18N("Taboo::ParseBlockedLanguagesAndRegions: BlockedData is inValid.");
480 continue;
481 } else if (region.compare(OMITTED_SYMBOL) == 0) {
482 blockedLanguage.insert(language);
483 } else if (language.compare(OMITTED_SYMBOL) == 0) {
484 blockedRegion.insert(region);
485 } else {
486 languageBlockedRegion[language].insert(region);
487 }
488 }
489 blockedLanguages[key] = blockedLanguage;
490 blockedRegions[key] = blockedRegion;
491 languageBlockedRegions[key] = languageBlockedRegion;
492 }
493
ParseBlockedCities(const std::string & key,const std::string & value)494 void Taboo::ParseBlockedCities(const std::string& key, const std::string& value)
495 {
496 std::unordered_set<std::string> blockedCity;
497 Split(value, TABOO_DATA_SPLITOR, blockedCity);
498 blockedCities[key] = blockedCity;
499 }
500
ParseBlockedPhoneNumbers(const std::string & key,const std::string & value)501 void Taboo::ParseBlockedPhoneNumbers(const std::string& key, const std::string& value)
502 {
503 std::unordered_set<std::string> blockedPhoneNumber;
504 Split(value, TABOO_DATA_SPLITOR, blockedPhoneNumber);
505 blockedPhoneNumbers[key] = blockedPhoneNumber;
506 }
507
InitLocaleTabooData(const std::string & fallbackLanguage,const std::string & fileName)508 void Taboo::InitLocaleTabooData(const std::string& fallbackLanguage, const std::string& fileName)
509 {
510 if (initResourcesList.find(fallbackLanguage) != initResourcesList.end()) {
511 return;
512 }
513 std::lock_guard<std::mutex> tabooLock(tabooMutex);
514 if (initResourcesList.find(fallbackLanguage) != initResourcesList.end()) {
515 return;
516 }
517 localeTabooData[fallbackLanguage] = {};
518 std::string localeTabooDataFilePath = tabooDataPath + fileName + FILE_PATH_SPLITOR + TABOO_DATA_FILE;
519 ParseTabooData(localeTabooDataFilePath, DataFileType::DATA_FILE, fallbackLanguage);
520 initResourcesList.insert(fallbackLanguage);
521 }
522
InitFallBackSuffixes()523 void Taboo::InitFallBackSuffixes()
524 {
525 std::string mccmncFirst = ReadSystemParameter(MCC_MNC_FIRST_KEY.c_str(), LocaleConfig::CONFIG_LEN);
526 if (mccmncFirst.empty()) {
527 HILOG_ERROR_I18N("Taboo::InitFallBackSuffixes: Get first mccmnc failed.");
528 }
529 std::string mccFirst;
530 if (mccmncFirst.length() == MCC_MNC_LENGTH) {
531 fallBackSuffixes.emplace_back(MCC_MNC_TAG + mccmncFirst);
532 mccFirst = mccmncFirst.substr(0, MCC_LENGTH);
533 }
534 std::string mccmncSecond = ReadSystemParameter(MCC_MNC_SECOND_KEY.c_str(), LocaleConfig::CONFIG_LEN);
535 if (mccmncSecond.empty()) {
536 HILOG_ERROR_I18N("Taboo::InitFallBackSuffixes: Get second mccmnc failed.");
537 }
538 std::string mccSecond;
539 if (mccmncSecond.length() == MCC_MNC_LENGTH) {
540 fallBackSuffixes.emplace_back(MCC_MNC_TAG + mccmncSecond);
541 mccSecond = mccmncSecond.substr(0, MCC_LENGTH);
542 }
543 if (!mccFirst.empty()) {
544 fallBackSuffixes.emplace_back(MCC_TAG + mccFirst);
545 }
546 if (!mccSecond.empty()) {
547 fallBackSuffixes.emplace_back(MCC_TAG + mccSecond);
548 }
549 std::string custRegion = ReadSystemParameter(CUST_REGION_KEY.c_str(), LocaleConfig::CONFIG_LEN);
550 if (!custRegion.empty()) {
551 fallBackSuffixes.emplace_back(CUST_REGION_TAG + custRegion);
552 } else {
553 HILOG_ERROR_I18N("Taboo::InitFallBackSuffixes: Get cust region failed.");
554 }
555 std::string defaultRegion = ReadSystemParameter(LocaleConfig::DEFAULT_REGION_KEY, LocaleConfig::CONFIG_LEN);
556 if (!defaultRegion.empty()) {
557 fallBackSuffixes.emplace_back(DEFAULT_REGION_TAG + defaultRegion);
558 } else {
559 HILOG_ERROR_I18N("Taboo::InitFallBackSuffixes: Get default region failed.");
560 }
561 fallBackSuffixes.emplace_back(COMMON_SUFFIX);
562 }
563 } // namespace I18n
564 } // namespace Global
565 } // namespace OHOS