11767c5feSopenharmony_ci/*
21767c5feSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
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
161767c5feSopenharmony_ci#include <dirent.h>
171767c5feSopenharmony_ci#include <fcntl.h>
181767c5feSopenharmony_ci#include <stdlib.h>
191767c5feSopenharmony_ci#include <unistd.h>
201767c5feSopenharmony_ci#include "update_geocoding.h"
211767c5feSopenharmony_ci
221767c5feSopenharmony_cinamespace i18n {
231767c5feSopenharmony_cinamespace phonenumbers {
241767c5feSopenharmony_ciGeocodingInfo* UpdateGeocoding::geocodingInfo = nullptr;
251767c5feSopenharmony_ci
261767c5feSopenharmony_cistd::map<std::string, PrefixDescriptions>* UpdateGeocoding::prefixDescriptionsMap = new std::map<std::string, PrefixDescriptions>();
271767c5feSopenharmony_cistd::map<std::string, PrefixesInfo>* UpdateGeocoding::prefixesInfoMap = new std::map<std::string, PrefixesInfo>();
281767c5feSopenharmony_ciconst PrefixDescriptions** UpdateGeocoding::prefixDescriptionsArray = nullptr;
291767c5feSopenharmony_ciLanguageCodeInfo* UpdateGeocoding::languageCodeInfo = nullptr;
301767c5feSopenharmony_cibool UpdateGeocoding::isupdatedLanguageCodes = false;
311767c5feSopenharmony_ciconst char** UpdateGeocoding::preLanguageCodes = nullptr;
321767c5feSopenharmony_ciconst char** UpdateGeocoding::curLanguageCodes = nullptr;
331767c5feSopenharmony_ciint UpdateGeocoding::curLanguageCodesSize = 0;
341767c5feSopenharmony_ciint UpdateGeocoding::preLanguageCodesSize = 0;
351767c5feSopenharmony_ci
361767c5feSopenharmony_cistd::map<int, CountryLanguages>* UpdateGeocoding::countryLanguagesMap = new std::map<int, CountryLanguages>();
371767c5feSopenharmony_cistd::map<int, CountriesInfo>* UpdateGeocoding::countriesInfoMap = new std::map<int, CountriesInfo>();
381767c5feSopenharmony_ciconst CountryLanguages** UpdateGeocoding::countryLanguagesArray = nullptr;
391767c5feSopenharmony_ciCountryCodeInfo* UpdateGeocoding::countryCodeInfo = nullptr;
401767c5feSopenharmony_cibool UpdateGeocoding::isupdatedCountryCodes = false;
411767c5feSopenharmony_ciconst int* UpdateGeocoding::preCountryCodes = nullptr;
421767c5feSopenharmony_ciint* UpdateGeocoding::curCountryCodes = nullptr;
431767c5feSopenharmony_ciint UpdateGeocoding::curCountryCodesSize = 0;
441767c5feSopenharmony_ciint UpdateGeocoding::preCountryCodesSize = 0;
451767c5feSopenharmony_ci
461767c5feSopenharmony_civoid UpdateGeocoding::LoadGeocodingData(int fd)
471767c5feSopenharmony_ci{
481767c5feSopenharmony_ci    if (geocodingInfo != nullptr) {
491767c5feSopenharmony_ci        return;
501767c5feSopenharmony_ci    }
511767c5feSopenharmony_ci    if (fd == -1) {
521767c5feSopenharmony_ci        return;
531767c5feSopenharmony_ci    }
541767c5feSopenharmony_ci    geocodingInfo = new GeocodingInfo();
551767c5feSopenharmony_ci    geocodingInfo->ParseFromFileDescriptor(fd);
561767c5feSopenharmony_ci    languageCodeInfo = new  LanguageCodeInfo(geocodingInfo->language_code_info());
571767c5feSopenharmony_ci    countryCodeInfo = new CountryCodeInfo(geocodingInfo->country_code_info());
581767c5feSopenharmony_ci    for (int i = 0; i < geocodingInfo->languages_size(); i++) {
591767c5feSopenharmony_ci        prefixesInfoMap->insert(std::make_pair(geocodingInfo->languages(i), geocodingInfo->prefixes_info(i)));
601767c5feSopenharmony_ci    }
611767c5feSopenharmony_ci    for (int i = 0; i < geocodingInfo->countries_size(); i++) {
621767c5feSopenharmony_ci        countriesInfoMap->insert(std::make_pair(geocodingInfo->countries(i), geocodingInfo->countries_info(i)));
631767c5feSopenharmony_ci    }
641767c5feSopenharmony_ci}
651767c5feSopenharmony_ci
661767c5feSopenharmony_ciconst PrefixDescriptions* UpdateGeocoding::UpdatePrefixDescriptions(
671767c5feSopenharmony_ci    const PrefixDescriptions** prePrefixDescriptionsArray, int index)
681767c5feSopenharmony_ci{
691767c5feSopenharmony_ci    prefixDescriptionsArray = prePrefixDescriptionsArray;
701767c5feSopenharmony_ci    std::string languageCode = isupdatedLanguageCodes ? curLanguageCodes[index] : preLanguageCodes[index];
711767c5feSopenharmony_ci    if (prefixDescriptionsMap->find(languageCode) != prefixDescriptionsMap->end()) {
721767c5feSopenharmony_ci        return &prefixDescriptionsMap->at(languageCode);
731767c5feSopenharmony_ci    }
741767c5feSopenharmony_ci    int preIndex = isupdatedLanguageCodes ? FindLanguageCode(languageCode) : index;
751767c5feSopenharmony_ci    AddPrefixDescriptions(languageCode, preIndex);
761767c5feSopenharmony_ci
771767c5feSopenharmony_ci    if (prefixDescriptionsMap->find(languageCode) == prefixDescriptionsMap->end()) {
781767c5feSopenharmony_ci        prefixDescriptionsMap->insert(std::make_pair(languageCode, *(prefixDescriptionsArray[preIndex])));
791767c5feSopenharmony_ci    }
801767c5feSopenharmony_ci    return &prefixDescriptionsMap->at(languageCode);
811767c5feSopenharmony_ci}
821767c5feSopenharmony_ci
831767c5feSopenharmony_ciconst char** UpdateGeocoding::UpdateLanguageCodes(const char** languageCodes, int languageCodesSize)
841767c5feSopenharmony_ci{
851767c5feSopenharmony_ci    preLanguageCodes = languageCodes;
861767c5feSopenharmony_ci    preLanguageCodesSize = languageCodesSize;
871767c5feSopenharmony_ci    if (languageCodeInfo == nullptr || languageCodeInfo->language_codes_size() == 0) {
881767c5feSopenharmony_ci        return preLanguageCodes;
891767c5feSopenharmony_ci    }
901767c5feSopenharmony_ci    int curLength = languageCodeInfo->language_codes_num();
911767c5feSopenharmony_ci    curLanguageCodesSize = curLength;
921767c5feSopenharmony_ci    curLanguageCodes = (const char **)malloc(sizeof(char*) * curLength);
931767c5feSopenharmony_ci    if (!curLanguageCodes) {
941767c5feSopenharmony_ci        return preLanguageCodes;
951767c5feSopenharmony_ci    }
961767c5feSopenharmony_ci    int preIndex = 0;
971767c5feSopenharmony_ci    int curIndex = 0;
981767c5feSopenharmony_ci    int mdyIndex = 0;
991767c5feSopenharmony_ci    while (preIndex < preLanguageCodesSize && mdyIndex < languageCodeInfo->language_codes_size()) {
1001767c5feSopenharmony_ci        if (strcmp(languageCodeInfo->language_codes(mdyIndex).c_str(), preLanguageCodes[preIndex]) < 0) {
1011767c5feSopenharmony_ci            curLanguageCodes[curIndex] = WriteStr(languageCodeInfo->language_codes(mdyIndex));
1021767c5feSopenharmony_ci            curIndex++;
1031767c5feSopenharmony_ci            mdyIndex++;
1041767c5feSopenharmony_ci        } else if (strcmp(languageCodeInfo->language_codes(mdyIndex).c_str(), preLanguageCodes[preIndex]) == 0) {
1051767c5feSopenharmony_ci            preIndex++;
1061767c5feSopenharmony_ci            mdyIndex++;
1071767c5feSopenharmony_ci        } else {
1081767c5feSopenharmony_ci            curLanguageCodes[curIndex] = preLanguageCodes[preIndex];
1091767c5feSopenharmony_ci            curIndex++;
1101767c5feSopenharmony_ci            preIndex++;
1111767c5feSopenharmony_ci        }
1121767c5feSopenharmony_ci    }
1131767c5feSopenharmony_ci
1141767c5feSopenharmony_ci    while (preIndex < preLanguageCodesSize) {
1151767c5feSopenharmony_ci        curLanguageCodes[curIndex] = preLanguageCodes[preIndex];
1161767c5feSopenharmony_ci        curIndex++;
1171767c5feSopenharmony_ci        preIndex++;
1181767c5feSopenharmony_ci    }
1191767c5feSopenharmony_ci
1201767c5feSopenharmony_ci    while (mdyIndex < languageCodeInfo->language_codes_size()) {
1211767c5feSopenharmony_ci        curLanguageCodes[curIndex] = WriteStr(languageCodeInfo->language_codes(mdyIndex));
1221767c5feSopenharmony_ci        curIndex++;
1231767c5feSopenharmony_ci        mdyIndex++;
1241767c5feSopenharmony_ci    }
1251767c5feSopenharmony_ci    isupdatedLanguageCodes = true;
1261767c5feSopenharmony_ci    return curLanguageCodes;
1271767c5feSopenharmony_ci}
1281767c5feSopenharmony_ci
1291767c5feSopenharmony_ciint UpdateGeocoding::UpdateLanguageCodesSize()
1301767c5feSopenharmony_ci{
1311767c5feSopenharmony_ci    if (isupdatedLanguageCodes) {
1321767c5feSopenharmony_ci        return curLanguageCodesSize;
1331767c5feSopenharmony_ci    }
1341767c5feSopenharmony_ci    return preLanguageCodesSize;
1351767c5feSopenharmony_ci}
1361767c5feSopenharmony_ci
1371767c5feSopenharmony_civoid UpdateGeocoding::AddPrefixDescriptions(const std::string& languageCode, int index)
1381767c5feSopenharmony_ci{
1391767c5feSopenharmony_ci    if (prefixesInfoMap->find(languageCode) == prefixesInfoMap->end()) {
1401767c5feSopenharmony_ci        return;
1411767c5feSopenharmony_ci    }
1421767c5feSopenharmony_ci    PrefixesInfo prefixesInfo = prefixesInfoMap->at(languageCode);
1431767c5feSopenharmony_ci    int prefixesSize = static_cast<int>(prefixesInfo.prefixes_num());
1441767c5feSopenharmony_ci    int32_t* prefixes = (int32_t*)malloc(sizeof(int32_t) * prefixesSize);
1451767c5feSopenharmony_ci    if (!prefixes) {
1461767c5feSopenharmony_ci        return;
1471767c5feSopenharmony_ci    }
1481767c5feSopenharmony_ci    memset(prefixes, 0, sizeof(int32_t) * prefixesSize);
1491767c5feSopenharmony_ci    const char** descriptions = (const char **)malloc(sizeof(char*) * prefixesSize);
1501767c5feSopenharmony_ci    if (!descriptions) {
1511767c5feSopenharmony_ci        return;
1521767c5feSopenharmony_ci    }
1531767c5feSopenharmony_ci    ModifyPrefixDescriptions(prefixes, descriptions, prefixesInfo, index);
1541767c5feSopenharmony_ci
1551767c5feSopenharmony_ci    int lengthsSize = prefixesInfo.lengths_num();
1561767c5feSopenharmony_ci    int32_t* possibleLengths = (int32_t*)malloc(sizeof(int32_t) * lengthsSize);
1571767c5feSopenharmony_ci    if (!possibleLengths) {
1581767c5feSopenharmony_ci        return;
1591767c5feSopenharmony_ci    }
1601767c5feSopenharmony_ci    ModifyPossibleLengths(possibleLengths, prefixesInfo, index);
1611767c5feSopenharmony_ci
1621767c5feSopenharmony_ci    PrefixDescriptions prefixDescriptions = {
1631767c5feSopenharmony_ci        prefixes,
1641767c5feSopenharmony_ci        prefixesSize,
1651767c5feSopenharmony_ci        descriptions,
1661767c5feSopenharmony_ci        possibleLengths,
1671767c5feSopenharmony_ci        lengthsSize
1681767c5feSopenharmony_ci    };
1691767c5feSopenharmony_ci    prefixDescriptionsMap->insert(std::make_pair(languageCode, prefixDescriptions));
1701767c5feSopenharmony_ci}
1711767c5feSopenharmony_ci
1721767c5feSopenharmony_civoid UpdateGeocoding::ModifyPrefixDescriptions(int32_t* prefixes, const char** descriptions,
1731767c5feSopenharmony_ci    PrefixesInfo& prefixesInfo, int index)
1741767c5feSopenharmony_ci{
1751767c5feSopenharmony_ci    int curIndex = 0;
1761767c5feSopenharmony_ci    int preIndex = 0;
1771767c5feSopenharmony_ci    int mdyIndex = 0;
1781767c5feSopenharmony_ci    const PrefixDescriptions* prefixDescriptions = nullptr;
1791767c5feSopenharmony_ci    std::string description;
1801767c5feSopenharmony_ci    int prefixesSize = 0;
1811767c5feSopenharmony_ci    if (index != -1) {
1821767c5feSopenharmony_ci        prefixDescriptions = prefixDescriptionsArray[index];
1831767c5feSopenharmony_ci        prefixesSize = prefixDescriptions->prefixes_size;
1841767c5feSopenharmony_ci    }
1851767c5feSopenharmony_ci    while (preIndex < prefixesSize && mdyIndex < prefixesInfo.prefixes_size()) {
1861767c5feSopenharmony_ci        int prePrefix = prefixDescriptions->prefixes[preIndex];
1871767c5feSopenharmony_ci        int mdyPrefix = static_cast<int>(prefixesInfo.prefixes(mdyIndex));
1881767c5feSopenharmony_ci        if (prePrefix == mdyPrefix) {
1891767c5feSopenharmony_ci            if (prefixesInfo.descriptions(mdyIndex) == "NULL") {
1901767c5feSopenharmony_ci                preIndex++;
1911767c5feSopenharmony_ci                mdyIndex++;
1921767c5feSopenharmony_ci                continue;
1931767c5feSopenharmony_ci            } else {
1941767c5feSopenharmony_ci                prefixes[curIndex] = mdyPrefix;
1951767c5feSopenharmony_ci                descriptions[curIndex] = WriteStr(prefixesInfo.descriptions(mdyIndex));
1961767c5feSopenharmony_ci                preIndex++;
1971767c5feSopenharmony_ci                mdyIndex++;
1981767c5feSopenharmony_ci            }
1991767c5feSopenharmony_ci        } else if (prePrefix > mdyPrefix) {
2001767c5feSopenharmony_ci            prefixes[curIndex] = mdyPrefix;
2011767c5feSopenharmony_ci            descriptions[curIndex] = WriteStr(prefixesInfo.descriptions(mdyIndex));
2021767c5feSopenharmony_ci            mdyIndex++;
2031767c5feSopenharmony_ci        } else {
2041767c5feSopenharmony_ci            prefixes[curIndex] = prePrefix;
2051767c5feSopenharmony_ci            descriptions[curIndex] = prefixDescriptions->descriptions[preIndex];
2061767c5feSopenharmony_ci            preIndex++;
2071767c5feSopenharmony_ci        }
2081767c5feSopenharmony_ci        curIndex++;
2091767c5feSopenharmony_ci    }
2101767c5feSopenharmony_ci    while (preIndex < prefixesSize) {
2111767c5feSopenharmony_ci        prefixes[curIndex] = prefixDescriptions->prefixes[preIndex];
2121767c5feSopenharmony_ci        descriptions[curIndex] = prefixDescriptions->descriptions[preIndex];
2131767c5feSopenharmony_ci        preIndex++;
2141767c5feSopenharmony_ci        curIndex++;
2151767c5feSopenharmony_ci    }
2161767c5feSopenharmony_ci    while (mdyIndex < prefixesInfo.prefixes_size()) {
2171767c5feSopenharmony_ci        prefixes[curIndex] = static_cast<int>(prefixesInfo.prefixes(mdyIndex));
2181767c5feSopenharmony_ci        descriptions[curIndex] = WriteStr(prefixesInfo.descriptions(mdyIndex));
2191767c5feSopenharmony_ci        mdyIndex++;
2201767c5feSopenharmony_ci        curIndex++;
2211767c5feSopenharmony_ci    }
2221767c5feSopenharmony_ci}
2231767c5feSopenharmony_ci
2241767c5feSopenharmony_civoid UpdateGeocoding::ModifyPossibleLengths(int32_t* possibleLengths, PrefixesInfo& prefixesInfo, int index)
2251767c5feSopenharmony_ci{
2261767c5feSopenharmony_ci    if (index == -1) {
2271767c5feSopenharmony_ci        for (int i = 0; i < prefixesInfo.lengths_size(); i++) {
2281767c5feSopenharmony_ci            possibleLengths[i] = prefixesInfo.lengths(i);
2291767c5feSopenharmony_ci        }
2301767c5feSopenharmony_ci    } else {
2311767c5feSopenharmony_ci        for (int i = 0; i < prefixDescriptionsArray[index]->possible_lengths_size; i++) {
2321767c5feSopenharmony_ci            possibleLengths[i] = prefixDescriptionsArray[index]->possible_lengths[i];
2331767c5feSopenharmony_ci        }
2341767c5feSopenharmony_ci    }
2351767c5feSopenharmony_ci}
2361767c5feSopenharmony_ci
2371767c5feSopenharmony_ciconst CountryLanguages* UpdateGeocoding::UpdateCountryLanguages(const CountryLanguages** preCountryLanguagesArray, int index)
2381767c5feSopenharmony_ci{
2391767c5feSopenharmony_ci    countryLanguagesArray = preCountryLanguagesArray;
2401767c5feSopenharmony_ci    int countryCode = isupdatedCountryCodes ? curCountryCodes[index] : preCountryCodes[index];
2411767c5feSopenharmony_ci    if (countryLanguagesMap->find(countryCode) != countryLanguagesMap->end()) {
2421767c5feSopenharmony_ci        return &countryLanguagesMap->at(countryCode);
2431767c5feSopenharmony_ci    }
2441767c5feSopenharmony_ci    int preIndex = isupdatedCountryCodes ? FindCountryCode(countryCode) : index;
2451767c5feSopenharmony_ci    AddCountryLanguages(countryCode);
2461767c5feSopenharmony_ci    if (countryLanguagesMap->find(countryCode) == countryLanguagesMap->end() && preIndex != -1) {
2471767c5feSopenharmony_ci        countryLanguagesMap->insert(std::make_pair(countryCode, *(countryLanguagesArray[preIndex])));
2481767c5feSopenharmony_ci    }
2491767c5feSopenharmony_ci    return &countryLanguagesMap->at(countryCode);
2501767c5feSopenharmony_ci}
2511767c5feSopenharmony_ci
2521767c5feSopenharmony_ciconst int* UpdateGeocoding::UpdateCountryCodes(const int* countryCodes, int countryCodesSize)
2531767c5feSopenharmony_ci{
2541767c5feSopenharmony_ci    preCountryCodes = countryCodes;
2551767c5feSopenharmony_ci    preCountryCodesSize = countryCodesSize;
2561767c5feSopenharmony_ci    if (countryCodeInfo == nullptr || countryCodeInfo->country_codes_size() == 0) {
2571767c5feSopenharmony_ci        return preCountryCodes;
2581767c5feSopenharmony_ci    }
2591767c5feSopenharmony_ci    int curLength = countryCodeInfo->country_codes_num();
2601767c5feSopenharmony_ci    curCountryCodesSize = curLength;
2611767c5feSopenharmony_ci    curCountryCodes = (int *)malloc(sizeof(int) * curLength);
2621767c5feSopenharmony_ci    if (!curCountryCodes) {
2631767c5feSopenharmony_ci        return preCountryCodes;
2641767c5feSopenharmony_ci    }
2651767c5feSopenharmony_ci    int preIndex = 0;
2661767c5feSopenharmony_ci    int curIndex = 0;
2671767c5feSopenharmony_ci    int mdyIndex = 0;
2681767c5feSopenharmony_ci    while (preIndex < preCountryCodesSize && mdyIndex < countryCodeInfo->country_codes_size()) {
2691767c5feSopenharmony_ci        int preCountryCode = preCountryCodes[preIndex];
2701767c5feSopenharmony_ci        int mdyCountryCode = static_cast<int>(countryCodeInfo->country_codes(mdyIndex));
2711767c5feSopenharmony_ci        if (preCountryCode > mdyCountryCode) {
2721767c5feSopenharmony_ci            curCountryCodes[curIndex] = mdyCountryCode;
2731767c5feSopenharmony_ci            curIndex++;
2741767c5feSopenharmony_ci            mdyIndex++;
2751767c5feSopenharmony_ci        } else if (mdyCountryCode == preCountryCode) {
2761767c5feSopenharmony_ci            preIndex++;
2771767c5feSopenharmony_ci            mdyIndex++;
2781767c5feSopenharmony_ci        } else {
2791767c5feSopenharmony_ci            curCountryCodes[curIndex] = preCountryCode;
2801767c5feSopenharmony_ci            curIndex++;
2811767c5feSopenharmony_ci            preIndex++;
2821767c5feSopenharmony_ci        }
2831767c5feSopenharmony_ci    }
2841767c5feSopenharmony_ci    while (preIndex < preCountryCodesSize) {
2851767c5feSopenharmony_ci        curCountryCodes[curIndex] = preCountryCodes[preIndex];
2861767c5feSopenharmony_ci        curIndex++;
2871767c5feSopenharmony_ci        preIndex++;
2881767c5feSopenharmony_ci    }
2891767c5feSopenharmony_ci    while (mdyIndex < countryCodeInfo->country_codes_size()) {
2901767c5feSopenharmony_ci        curCountryCodes[curIndex] = static_cast<int>(countryCodeInfo->country_codes(mdyIndex));
2911767c5feSopenharmony_ci        curIndex++;
2921767c5feSopenharmony_ci        mdyIndex++;
2931767c5feSopenharmony_ci    }
2941767c5feSopenharmony_ci    isupdatedCountryCodes = true;
2951767c5feSopenharmony_ci    return curCountryCodes;
2961767c5feSopenharmony_ci}
2971767c5feSopenharmony_ci
2981767c5feSopenharmony_ciint UpdateGeocoding::UpdateCountryCodesSize()
2991767c5feSopenharmony_ci{
3001767c5feSopenharmony_ci    if (isupdatedCountryCodes) {
3011767c5feSopenharmony_ci        return curCountryCodesSize;
3021767c5feSopenharmony_ci    }
3031767c5feSopenharmony_ci    return preCountryCodesSize;
3041767c5feSopenharmony_ci}
3051767c5feSopenharmony_ci
3061767c5feSopenharmony_civoid UpdateGeocoding::AddCountryLanguages(int countryCode)
3071767c5feSopenharmony_ci{
3081767c5feSopenharmony_ci    if (countriesInfoMap->find(countryCode) == countriesInfoMap->end()) {
3091767c5feSopenharmony_ci        return;
3101767c5feSopenharmony_ci    }
3111767c5feSopenharmony_ci    CountriesInfo countriesInfo = countriesInfoMap->at(countryCode);
3121767c5feSopenharmony_ci
3131767c5feSopenharmony_ci    int availableLanguagesSize = static_cast<int>(countriesInfo.country_languages_num());
3141767c5feSopenharmony_ci    const char** availableLanguages = (const char **)malloc(sizeof(char*) * availableLanguagesSize);
3151767c5feSopenharmony_ci    if (!availableLanguages) {
3161767c5feSopenharmony_ci        return;
3171767c5feSopenharmony_ci    }
3181767c5feSopenharmony_ci    for (int i = 0; i < countriesInfo.country_languages_size(); i++) {
3191767c5feSopenharmony_ci        std::string language = countriesInfo.country_languages(i);
3201767c5feSopenharmony_ci        int len = sizeof(char) * (language.length() + 1);
3211767c5feSopenharmony_ci        char* temp = (char *)malloc(len);
3221767c5feSopenharmony_ci        if (!temp) {
3231767c5feSopenharmony_ci            return;
3241767c5feSopenharmony_ci        }
3251767c5feSopenharmony_ci        memset(temp, '\0', len);
3261767c5feSopenharmony_ci        strncpy(temp, language.c_str(), len);
3271767c5feSopenharmony_ci        availableLanguages[i] = temp;
3281767c5feSopenharmony_ci    }
3291767c5feSopenharmony_ci    CountryLanguages countryLanguages = {
3301767c5feSopenharmony_ci        availableLanguages,
3311767c5feSopenharmony_ci        availableLanguagesSize
3321767c5feSopenharmony_ci    };
3331767c5feSopenharmony_ci    countryLanguagesMap->insert(std::make_pair(countryCode, countryLanguages));
3341767c5feSopenharmony_ci}
3351767c5feSopenharmony_ci
3361767c5feSopenharmony_ciint UpdateGeocoding::FindLanguageCode(const std::string& languageCode)
3371767c5feSopenharmony_ci{
3381767c5feSopenharmony_ci    const char** const preLanguageCodesEnd = preLanguageCodes + preLanguageCodesSize;
3391767c5feSopenharmony_ci    const char** const preIndex = std::lower_bound(preLanguageCodes,
3401767c5feSopenharmony_ci                                                   preLanguageCodesEnd,
3411767c5feSopenharmony_ci                                                   languageCode.c_str(),
3421767c5feSopenharmony_ci                                                   IsLowerThan);
3431767c5feSopenharmony_ci    if (preIndex == preLanguageCodesEnd || languageCode.compare(*preIndex) != 0) {
3441767c5feSopenharmony_ci        return -1;
3451767c5feSopenharmony_ci    }
3461767c5feSopenharmony_ci    return preIndex - preLanguageCodes;
3471767c5feSopenharmony_ci}
3481767c5feSopenharmony_ci
3491767c5feSopenharmony_ciint UpdateGeocoding::FindCountryCode(int countryCode)
3501767c5feSopenharmony_ci{
3511767c5feSopenharmony_ci    const int* const preCountryCodesEnd = preCountryCodes + preCountryCodesSize;
3521767c5feSopenharmony_ci    const int* const preIndex = std::lower_bound(preCountryCodes,
3531767c5feSopenharmony_ci                                                 preCountryCodesEnd,
3541767c5feSopenharmony_ci                                                 countryCode);
3551767c5feSopenharmony_ci    if (preIndex == preCountryCodesEnd || *preIndex != countryCode) {
3561767c5feSopenharmony_ci        return -1;
3571767c5feSopenharmony_ci    }
3581767c5feSopenharmony_ci    return preIndex - preCountryCodes;
3591767c5feSopenharmony_ci}
3601767c5feSopenharmony_ci
3611767c5feSopenharmony_cibool UpdateGeocoding::IsLowerThan(const char* s1, const char* s2)
3621767c5feSopenharmony_ci{
3631767c5feSopenharmony_ci    return strcmp(s1, s2) < 0;
3641767c5feSopenharmony_ci}
3651767c5feSopenharmony_ci
3661767c5feSopenharmony_cichar* UpdateGeocoding::WriteStr(const std::string& str)
3671767c5feSopenharmony_ci{
3681767c5feSopenharmony_ci    int len = sizeof(char) * (str.length() + 1);
3691767c5feSopenharmony_ci    char* result = (char*)malloc(len);
3701767c5feSopenharmony_ci    if (!result) {
3711767c5feSopenharmony_ci        return nullptr;
3721767c5feSopenharmony_ci    }
3731767c5feSopenharmony_ci    memset(result, '\0', len);
3741767c5feSopenharmony_ci    strncpy(result, str.c_str(), len);
3751767c5feSopenharmony_ci    return result;
3761767c5feSopenharmony_ci}
3771767c5feSopenharmony_ci}
3781767c5feSopenharmony_ci}