1/* 2 * Copyright (c) 2021-2022 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#include "locale_util.h" 16 17namespace OHOS { 18namespace Global { 19namespace I18n { 20bool LocaleUtil::IsRTL(const std::string &locale) 21{ 22 icu::Locale curLocale(locale.c_str()); 23 return curLocale.isRightToLeft(); 24} 25 26uint16_t LocaleUtil::EncodeLanguageByLocaleInfo(const LocaleInfo *locale) 27{ 28 if (locale == nullptr) { 29 return NULL_LANGUAGE; 30 } 31 return EncodeLanguage(locale->GetLanguage().c_str()); 32} 33 34uint32_t LocaleUtil::EncodeScriptByLocaleInfo(const LocaleInfo *locale) 35{ 36 if (locale == nullptr) { 37 return NULL_SCRIPT; 38 } 39 return EncodeScript(locale->GetScript().c_str()); 40} 41 42uint16_t LocaleUtil::EncodeRegionByLocaleInfo(const LocaleInfo *locale) 43{ 44 if (locale == nullptr) { 45 return NULL_REGION; 46 } 47 return EncodeRegion(locale->GetRegion().c_str()); 48} 49 50uint16_t LocaleUtil::EncodeLanguage(const char *language) 51{ 52 if (IsStrEmpty(language)) { 53 return NULL_LANGUAGE; 54 } 55 return EncodeLanguageOrRegion(language, 'a'); 56} 57 58uint32_t LocaleUtil::EncodeScript(const char *script) 59{ 60 if (IsStrEmpty(script)) { 61 return NULL_SCRIPT; 62 } 63 // 0, 1, 2, 3 is index of characters in script, 24, 16, 8 is offset. 64 return ((uint8_t)script[0] << 24) | ((uint8_t)script[1] << 16) | ((uint8_t)script[2] << 8) | (uint8_t)script[3]; 65} 66 67uint16_t LocaleUtil::EncodeRegion(const char *region) 68{ 69 if (IsStrEmpty(region)) { 70 return NULL_REGION; 71 } 72 if (region[0] >= '0' && region[0] <= '9') { 73 return EncodeLanguageOrRegion(region, '0'); 74 } 75 return EncodeLanguageOrRegion(region, 'A'); 76} 77 78uint64_t LocaleUtil::EncodeLocale(const char *language, const char *script, const char *region) 79{ 80 uint16_t languageData = EncodeLanguage(language); 81 uint32_t scriptData = EncodeScript(script); 82 uint16_t regionData = EncodeRegion(region); 83 // 48 is the offset of language. 84 uint32_t languageOffset = 48; 85 uint32_t scriptOffset = 16; 86 return (uint64_t)(0xffff000000000000 & (((uint64_t)languageData) << languageOffset)) | 87 (0x0000ffffffff0000 & (((uint64_t)scriptData) << scriptOffset)) |(0x000000000000ffff & (uint64_t)(regionData)); 88} 89 90bool LocaleUtil::IsStrEmpty(const char *s) 91{ 92 return (s == nullptr || *s == '\0'); 93} 94 95void LocaleUtil::DecodeScript(uint32_t encodeScript, char *outValue) 96{ 97 if (outValue == nullptr) { 98 return; 99 } 100 outValue[0] = (encodeScript & 0xFF000000) >> 24; // 0 is index, 24 is first script character offset 101 outValue[1] = (encodeScript & 0x00FF0000) >> 16; // 1 is index, 16 is second script character offset 102 outValue[2] = (encodeScript & 0x0000FF00) >> 8; // 2 is index, 8 is third script character offset 103 outValue[3] = (encodeScript & 0x000000FF); // 3 is index 104} 105 106bool LocaleUtil::IsAlphaString(const char *s, int32_t len) 107{ 108 if (s == nullptr) { 109 return false; 110 } 111 int32_t i; 112 for (i = 0; i < len; i++) { 113 char c = *(s + i); 114 if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) { 115 return false; 116 } 117 } 118 return true; 119} 120 121bool LocaleUtil::IsNumericString(const char *s, int32_t len) 122{ 123 if (s == nullptr) { 124 return false; 125 } 126 int32_t i; 127 for (i = 0; i < len; i++) { 128 char c = *(s + i); 129 if (!(c >= '0' && c <= '9')) { 130 return false; 131 } 132 } 133 134 return true; 135} 136 137uint16_t LocaleUtil::EncodeLanguageOrRegion(const char *str, char base) 138{ 139 // 2 is index of splitor 140 if (str[2] == 0 || str[2] == '-' || str[2] == '_') { 141 // 0, 1 is index, 8 is offset 142 return ((uint8_t)str[0] << 8) | ((uint8_t)str[1]); 143 } 144 uint8_t first = ((uint8_t)(str[0] - base)) & 0x7f; // 0 is index 145 uint8_t second = ((uint8_t)(str[1] - base)) & 0x7f; // 1 is index 146 uint8_t third = ((uint8_t)(str[2] - base)) & 0x7f; // 2 is index 147 // 2, 3, 5, 8 is offset. 148 return ((0x80 | (first << 2) | (second >> 3)) << 8) | ((second << 5) | third); 149} 150} // namespace I18n 151} // namespace Global 152} // namespace OHOS