19596a2c1Sopenharmony_ci/*
29596a2c1Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License.
59596a2c1Sopenharmony_ci * You may obtain a copy of the License at
69596a2c1Sopenharmony_ci *
79596a2c1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
89596a2c1Sopenharmony_ci *
99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and
139596a2c1Sopenharmony_ci * limitations under the License.
149596a2c1Sopenharmony_ci */
159596a2c1Sopenharmony_ci#include "locale_util.h"
169596a2c1Sopenharmony_ci
179596a2c1Sopenharmony_cinamespace OHOS {
189596a2c1Sopenharmony_cinamespace Global {
199596a2c1Sopenharmony_cinamespace I18n {
209596a2c1Sopenharmony_cibool LocaleUtil::IsRTL(const std::string &locale)
219596a2c1Sopenharmony_ci{
229596a2c1Sopenharmony_ci    icu::Locale curLocale(locale.c_str());
239596a2c1Sopenharmony_ci    return curLocale.isRightToLeft();
249596a2c1Sopenharmony_ci}
259596a2c1Sopenharmony_ci
269596a2c1Sopenharmony_ciuint16_t LocaleUtil::EncodeLanguageByLocaleInfo(const LocaleInfo *locale)
279596a2c1Sopenharmony_ci{
289596a2c1Sopenharmony_ci    if (locale == nullptr) {
299596a2c1Sopenharmony_ci        return NULL_LANGUAGE;
309596a2c1Sopenharmony_ci    }
319596a2c1Sopenharmony_ci    return EncodeLanguage(locale->GetLanguage().c_str());
329596a2c1Sopenharmony_ci}
339596a2c1Sopenharmony_ci
349596a2c1Sopenharmony_ciuint32_t LocaleUtil::EncodeScriptByLocaleInfo(const LocaleInfo *locale)
359596a2c1Sopenharmony_ci{
369596a2c1Sopenharmony_ci    if (locale == nullptr) {
379596a2c1Sopenharmony_ci        return NULL_SCRIPT;
389596a2c1Sopenharmony_ci    }
399596a2c1Sopenharmony_ci    return EncodeScript(locale->GetScript().c_str());
409596a2c1Sopenharmony_ci}
419596a2c1Sopenharmony_ci
429596a2c1Sopenharmony_ciuint16_t LocaleUtil::EncodeRegionByLocaleInfo(const LocaleInfo *locale)
439596a2c1Sopenharmony_ci{
449596a2c1Sopenharmony_ci    if (locale == nullptr) {
459596a2c1Sopenharmony_ci        return NULL_REGION;
469596a2c1Sopenharmony_ci    }
479596a2c1Sopenharmony_ci    return EncodeRegion(locale->GetRegion().c_str());
489596a2c1Sopenharmony_ci}
499596a2c1Sopenharmony_ci
509596a2c1Sopenharmony_ciuint16_t LocaleUtil::EncodeLanguage(const char *language)
519596a2c1Sopenharmony_ci{
529596a2c1Sopenharmony_ci    if (IsStrEmpty(language)) {
539596a2c1Sopenharmony_ci            return NULL_LANGUAGE;
549596a2c1Sopenharmony_ci        }
559596a2c1Sopenharmony_ci    return EncodeLanguageOrRegion(language, 'a');
569596a2c1Sopenharmony_ci}
579596a2c1Sopenharmony_ci
589596a2c1Sopenharmony_ciuint32_t LocaleUtil::EncodeScript(const char *script)
599596a2c1Sopenharmony_ci{
609596a2c1Sopenharmony_ci    if (IsStrEmpty(script)) {
619596a2c1Sopenharmony_ci        return NULL_SCRIPT;
629596a2c1Sopenharmony_ci    }
639596a2c1Sopenharmony_ci    // 0, 1, 2, 3 is index of characters in script, 24, 16, 8 is offset.
649596a2c1Sopenharmony_ci    return ((uint8_t)script[0] << 24) | ((uint8_t)script[1] << 16) | ((uint8_t)script[2] << 8) | (uint8_t)script[3];
659596a2c1Sopenharmony_ci}
669596a2c1Sopenharmony_ci
679596a2c1Sopenharmony_ciuint16_t LocaleUtil::EncodeRegion(const char *region)
689596a2c1Sopenharmony_ci{
699596a2c1Sopenharmony_ci    if (IsStrEmpty(region)) {
709596a2c1Sopenharmony_ci        return NULL_REGION;
719596a2c1Sopenharmony_ci    }
729596a2c1Sopenharmony_ci    if (region[0] >= '0' && region[0] <= '9') {
739596a2c1Sopenharmony_ci        return EncodeLanguageOrRegion(region, '0');
749596a2c1Sopenharmony_ci    }
759596a2c1Sopenharmony_ci    return EncodeLanguageOrRegion(region, 'A');
769596a2c1Sopenharmony_ci}
779596a2c1Sopenharmony_ci
789596a2c1Sopenharmony_ciuint64_t LocaleUtil::EncodeLocale(const char *language, const char *script, const char *region)
799596a2c1Sopenharmony_ci{
809596a2c1Sopenharmony_ci    uint16_t languageData = EncodeLanguage(language);
819596a2c1Sopenharmony_ci    uint32_t scriptData = EncodeScript(script);
829596a2c1Sopenharmony_ci    uint16_t regionData = EncodeRegion(region);
839596a2c1Sopenharmony_ci    // 48 is the offset of language.
849596a2c1Sopenharmony_ci    uint32_t languageOffset = 48;
859596a2c1Sopenharmony_ci    uint32_t scriptOffset = 16;
869596a2c1Sopenharmony_ci    return (uint64_t)(0xffff000000000000 & (((uint64_t)languageData) << languageOffset)) |
879596a2c1Sopenharmony_ci        (0x0000ffffffff0000 & (((uint64_t)scriptData) << scriptOffset)) |(0x000000000000ffff & (uint64_t)(regionData));
889596a2c1Sopenharmony_ci}
899596a2c1Sopenharmony_ci
909596a2c1Sopenharmony_cibool LocaleUtil::IsStrEmpty(const char *s)
919596a2c1Sopenharmony_ci{
929596a2c1Sopenharmony_ci    return (s == nullptr || *s == '\0');
939596a2c1Sopenharmony_ci}
949596a2c1Sopenharmony_ci
959596a2c1Sopenharmony_civoid LocaleUtil::DecodeScript(uint32_t encodeScript, char *outValue)
969596a2c1Sopenharmony_ci{
979596a2c1Sopenharmony_ci    if (outValue == nullptr) {
989596a2c1Sopenharmony_ci        return;
999596a2c1Sopenharmony_ci    }
1009596a2c1Sopenharmony_ci    outValue[0] = (encodeScript & 0xFF000000) >> 24; // 0 is index, 24 is first script character offset
1019596a2c1Sopenharmony_ci    outValue[1] = (encodeScript & 0x00FF0000) >> 16; // 1 is index, 16 is second script character offset
1029596a2c1Sopenharmony_ci    outValue[2] = (encodeScript & 0x0000FF00) >> 8; // 2 is index, 8 is third script character offset
1039596a2c1Sopenharmony_ci    outValue[3] = (encodeScript & 0x000000FF); // 3 is index
1049596a2c1Sopenharmony_ci}
1059596a2c1Sopenharmony_ci
1069596a2c1Sopenharmony_cibool LocaleUtil::IsAlphaString(const char *s, int32_t len)
1079596a2c1Sopenharmony_ci{
1089596a2c1Sopenharmony_ci    if (s == nullptr) {
1099596a2c1Sopenharmony_ci        return false;
1109596a2c1Sopenharmony_ci    }
1119596a2c1Sopenharmony_ci    int32_t i;
1129596a2c1Sopenharmony_ci    for (i = 0; i < len; i++) {
1139596a2c1Sopenharmony_ci        char c = *(s + i);
1149596a2c1Sopenharmony_ci        if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
1159596a2c1Sopenharmony_ci            return false;
1169596a2c1Sopenharmony_ci        }
1179596a2c1Sopenharmony_ci    }
1189596a2c1Sopenharmony_ci    return true;
1199596a2c1Sopenharmony_ci}
1209596a2c1Sopenharmony_ci
1219596a2c1Sopenharmony_cibool LocaleUtil::IsNumericString(const char *s, int32_t len)
1229596a2c1Sopenharmony_ci{
1239596a2c1Sopenharmony_ci    if (s == nullptr) {
1249596a2c1Sopenharmony_ci        return false;
1259596a2c1Sopenharmony_ci    }
1269596a2c1Sopenharmony_ci    int32_t i;
1279596a2c1Sopenharmony_ci    for (i = 0; i < len; i++) {
1289596a2c1Sopenharmony_ci        char c = *(s + i);
1299596a2c1Sopenharmony_ci        if (!(c >= '0' && c <= '9')) {
1309596a2c1Sopenharmony_ci            return false;
1319596a2c1Sopenharmony_ci        }
1329596a2c1Sopenharmony_ci    }
1339596a2c1Sopenharmony_ci
1349596a2c1Sopenharmony_ci    return true;
1359596a2c1Sopenharmony_ci}
1369596a2c1Sopenharmony_ci
1379596a2c1Sopenharmony_ciuint16_t LocaleUtil::EncodeLanguageOrRegion(const char *str, char base)
1389596a2c1Sopenharmony_ci{
1399596a2c1Sopenharmony_ci    // 2 is index of splitor
1409596a2c1Sopenharmony_ci    if (str[2] == 0 || str[2] == '-' || str[2] == '_') {
1419596a2c1Sopenharmony_ci        // 0, 1 is index, 8 is offset
1429596a2c1Sopenharmony_ci        return ((uint8_t)str[0] << 8) | ((uint8_t)str[1]);
1439596a2c1Sopenharmony_ci    }
1449596a2c1Sopenharmony_ci    uint8_t first = ((uint8_t)(str[0] - base)) & 0x7f; // 0 is index
1459596a2c1Sopenharmony_ci    uint8_t second = ((uint8_t)(str[1] - base)) & 0x7f; // 1 is index
1469596a2c1Sopenharmony_ci    uint8_t third = ((uint8_t)(str[2] - base)) & 0x7f; // 2 is index
1479596a2c1Sopenharmony_ci    // 2, 3, 5, 8 is offset.
1489596a2c1Sopenharmony_ci    return ((0x80 | (first << 2) | (second >> 3)) << 8) | ((second << 5) | third);
1499596a2c1Sopenharmony_ci}
1509596a2c1Sopenharmony_ci} // namespace I18n
1519596a2c1Sopenharmony_ci} // namespace Global
1529596a2c1Sopenharmony_ci} // namespace OHOS