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