• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "algorithm"
17 #include "locale_config.h"
18 #include "map"
19 #include "memory"
20 #include "ohos/init_data.h"
21 #include "set"
22 #include "locale_info.h"
23 
24 namespace OHOS {
25 namespace Global {
26 namespace I18n {
27 using namespace icu;
28 std::set<std::string> LocaleInfo::allValidLocales = GetValidLocales();
29 
GetValidLocales()30 std::set<std::string> LocaleInfo::GetValidLocales()
31 {
32     int32_t validCount = 1;
33     const Locale *validLocales = Locale::getAvailableLocales(validCount);
34     std::set<std::string> allValidLocales;
35     if (validLocales != nullptr) {
36         for (int i = 0; i < validCount; i++) {
37             allValidLocales.insert(validLocales[i].getLanguage());
38         }
39     }
40     allValidLocales.insert("in");
41     allValidLocales.insert("iw");
42     allValidLocales.insert("tl");
43     return allValidLocales;
44 }
45 
ResetFinalLocaleStatus()46 void LocaleInfo::ResetFinalLocaleStatus()
47 {
48     finalLocaleTag = "";
49     calendar = "";
50     collation = "";
51     hourCycle = "";
52     numberingSystem = "";
53     numeric = "";
54     caseFirst = "";
55     configs = {};
56 }
57 
InitLocaleInfo(const std::string & localeTag,std::map<std::string,std::string> & configMap)58 void LocaleInfo::InitLocaleInfo(const std::string &localeTag, std::map<std::string, std::string> &configMap)
59 {
60     UErrorCode status = U_ZERO_ERROR;
61     configs = configMap;
62     if (localeTag != "") {
63         ComputeFinalLocaleTag(localeTag);
64         locale = icu::Locale::forLanguageTag(icu::StringPiece(finalLocaleTag), status);
65     }
66     if (localeTag == "" || status != U_ZERO_ERROR) {
67         std::string defaultLocaleTag = LocaleConfig::GetSystemLocale();
68         ResetFinalLocaleStatus();
69         ComputeFinalLocaleTag(defaultLocaleTag);
70         status = U_ZERO_ERROR;
71         locale = icu::Locale::forLanguageTag(icu::StringPiece(finalLocaleTag), status);
72     }
73     if (status == U_ZERO_ERROR) {
74         localeStatus = true;
75         language = locale.getLanguage();
76         script = locale.getScript();
77         region = locale.getCountry();
78         baseName = locale.getBaseName();
79         std::replace(baseName.begin(), baseName.end(), '_', '-');
80     }
81 }
82 
LocaleInfo(const std::string & localeTag)83 LocaleInfo::LocaleInfo(const std::string &localeTag)
84 {
85     std::map<std::string, std::string> configMap;
86     InitLocaleInfo(localeTag, configMap);
87 }
88 
LocaleInfo(const std::string & localeTag,std::map<std::string,std::string> & configMap)89 LocaleInfo::LocaleInfo(const std::string &localeTag, std::map<std::string, std::string> &configMap)
90 {
91     InitLocaleInfo(localeTag, configMap);
92 }
93 
~LocaleInfo()94 LocaleInfo::~LocaleInfo() {}
95 
ComputeFinalLocaleTag(const std::string & localeTag)96 void LocaleInfo::ComputeFinalLocaleTag(const std::string &localeTag)
97 {
98     if (localeTag.find("-u-") == std::string::npos) {
99         finalLocaleTag = localeTag;
100         ParseConfigs();
101     } else {
102         finalLocaleTag = localeTag.substr(0, localeTag.find("-u-"));
103         ParseLocaleTag(localeTag);
104         ParseConfigs();
105     }
106     if (!script.empty()) {
107         finalLocaleTag += "-" + script;
108     }
109     if (!region.empty()) {
110         finalLocaleTag += "-" + region;
111     }
112     if (!hourCycle.empty() || !numberingSystem.empty() || !calendar.empty() || !collation.empty() ||
113         !caseFirst.empty() || !numeric.empty()) {
114         finalLocaleTag += "-u";
115     }
116     if (!hourCycle.empty()) {
117         finalLocaleTag += hourCycleTag + hourCycle;
118     }
119     if (!numberingSystem.empty()) {
120         finalLocaleTag += numberingSystemTag + numberingSystem;
121     }
122     if (!calendar.empty()) {
123         finalLocaleTag += calendarTag + calendar;
124     }
125     if (!collation.empty()) {
126         finalLocaleTag += collationTag + collation;
127     }
128     if (!caseFirst.empty()) {
129         finalLocaleTag += caseFirstTag + caseFirst;
130     }
131     if (!numeric.empty()) {
132         finalLocaleTag += numericTag + numeric;
133     }
134 }
135 
ParseLocaleTag(const std::string & localeTag)136 void LocaleInfo::ParseLocaleTag(const std::string &localeTag)
137 {
138     std::string flag = "-";
139     if (localeTag.find(hourCycleTag) != std::string::npos) {
140         hourCycle = localeTag.substr(localeTag.find(hourCycleTag) + CONFIG_TAG_LEN);
141         hourCycle = hourCycle.substr(0, hourCycle.find(flag));
142     }
143     if (localeTag.find(numberingSystemTag) != std::string::npos) {
144         numberingSystem = localeTag.substr(localeTag.find(numberingSystemTag) + CONFIG_TAG_LEN);
145         numberingSystem = numberingSystem.substr(0, numberingSystem.find(flag));
146     }
147     if (localeTag.find(calendarTag) != std::string::npos) {
148         calendar = localeTag.substr(localeTag.find(calendarTag) + CONFIG_TAG_LEN);
149         calendar = calendar.substr(0, calendar.find(flag));
150     }
151     if (localeTag.find(collationTag) != std::string::npos) {
152         collation = localeTag.substr(localeTag.find(collationTag) + CONFIG_TAG_LEN);
153         collation = collation.substr(0, collation.find(flag));
154     }
155     if (localeTag.find(caseFirstTag) != std::string::npos) {
156         caseFirst = localeTag.substr(localeTag.find(caseFirstTag) + CONFIG_TAG_LEN);
157         caseFirst = caseFirst.substr(0, caseFirst.find(flag));
158     }
159     if (localeTag.find(numericTag) != std::string::npos) {
160         numeric = localeTag.substr(localeTag.find(numericTag) + CONFIG_TAG_LEN);
161         numeric = numeric.substr(0, numeric.find(flag));
162     }
163 }
164 
ParseConfigs()165 void LocaleInfo::ParseConfigs()
166 {
167     if (configs.count("script") > 0) {
168         script = configs["script"];
169     }
170     if (configs.count("region") > 0) {
171         region = configs["region"];
172     }
173     if (configs.count("hourCycle") > 0) {
174         hourCycle = configs["hourCycle"];
175     }
176     if (configs.count("numberingSystem") > 0) {
177         numberingSystem = configs["numberingSystem"];
178     }
179     if (configs.count("calendar") > 0) {
180         calendar = configs["calendar"];
181     }
182     if (configs.count("collation") > 0) {
183         collation = configs["collation"];
184     }
185     if (configs.count("caseFirst") > 0) {
186         caseFirst = configs["caseFirst"];
187     }
188     if (configs.count("numeric") > 0) {
189         numeric = configs["numeric"];
190     }
191 }
192 
193 bool LocaleInfo::icuInitialized = LocaleInfo::Init();
194 
GetLanguage() const195 std::string LocaleInfo::GetLanguage() const
196 {
197     return language;
198 }
199 
GetScript() const200 std::string LocaleInfo::GetScript() const
201 {
202     return script;
203 }
204 
GetRegion() const205 std::string LocaleInfo::GetRegion() const
206 {
207     return region;
208 }
209 
GetBaseName() const210 std::string LocaleInfo::GetBaseName() const
211 {
212     return baseName;
213 }
214 
GetCalendar() const215 std::string LocaleInfo::GetCalendar() const
216 {
217     return calendar;
218 }
219 
GetCollation() const220 std::string LocaleInfo::GetCollation() const
221 {
222     return collation;
223 }
224 
GetHourCycle() const225 std::string LocaleInfo::GetHourCycle() const
226 {
227     return hourCycle;
228 }
229 
GetNumberingSystem() const230 std::string LocaleInfo::GetNumberingSystem() const
231 {
232     return numberingSystem;
233 }
234 
GetNumeric() const235 std::string LocaleInfo::GetNumeric() const
236 {
237     return numeric;
238 }
239 
GetCaseFirst() const240 std::string LocaleInfo::GetCaseFirst() const
241 {
242     return caseFirst;
243 }
244 
ToString() const245 std::string LocaleInfo::ToString() const
246 {
247     return finalLocaleTag;
248 }
249 
GetLocale() const250 Locale LocaleInfo::GetLocale() const
251 {
252     return locale;
253 }
254 
Maximize()255 std::string LocaleInfo::Maximize()
256 {
257     if (!localeStatus) {
258         return "";
259     }
260     UErrorCode status = U_ZERO_ERROR;
261     Locale curLocale = locale;
262     curLocale.addLikelySubtags(status);
263     if (status == U_ZERO_ERROR) {
264         std::string restConfigs = "";
265         if (finalLocaleTag.find("-u-") != std::string::npos) {
266             restConfigs = finalLocaleTag.substr(finalLocaleTag.find("-u-"));
267         }
268         std::string curBaseName = (!curLocale.getBaseName()) ? "" : curLocale.getBaseName();
269         std::replace(curBaseName.begin(), curBaseName.end(), '_', '-');
270         std::string localeTag = curBaseName + restConfigs;
271         return localeTag;
272     }
273     return finalLocaleTag;
274 }
275 
Minimize()276 std::string LocaleInfo::Minimize()
277 {
278     if (!localeStatus) {
279         return "";
280     }
281     UErrorCode status = U_ZERO_ERROR;
282     Locale curLocale = locale;
283     curLocale.minimizeSubtags(status);
284     if (status == U_ZERO_ERROR) {
285         std::string restConfigs = "";
286         if (finalLocaleTag.find("-u-") != std::string::npos) {
287             restConfigs = finalLocaleTag.substr(finalLocaleTag.find("-u-"));
288         }
289         std::string curBaseName = (!curLocale.getBaseName()) ? "" : curLocale.getBaseName();
290         std::replace(curBaseName.begin(), curBaseName.end(), '_', '-');
291         std::string localeTag = curBaseName + restConfigs;
292         return localeTag;
293     }
294     return finalLocaleTag;
295 }
296 
Init()297 bool LocaleInfo::Init()
298 {
299     SetHwIcuDirectory();
300     return true;
301 }
302 
InitSuccess() const303 bool LocaleInfo::InitSuccess() const
304 {
305     return localeStatus;
306 }
307 } // namespace I18n
308 } // namespace Global
309 } // namespace OHOS
310