• 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     for (int i = 0; i < validCount; i++) {
36         allValidLocales.insert(validLocales[i].getLanguage());
37     }
38     allValidLocales.insert("in");
39     allValidLocales.insert("iw");
40     allValidLocales.insert("tl");
41     return allValidLocales;
42 }
43 
ResetFinalLocaleStatus()44 void LocaleInfo::ResetFinalLocaleStatus()
45 {
46     finalLocaleTag = "";
47     calendar = "";
48     collation = "";
49     hourCycle = "";
50     numberingSystem = "";
51     numeric = "";
52     caseFirst = "";
53     configs = {};
54 }
55 
InitLocaleInfo(const std::string & localeTag,std::map<std::string,std::string> & configMap)56 void LocaleInfo::InitLocaleInfo(const std::string &localeTag, std::map<std::string, std::string> &configMap)
57 {
58     UErrorCode status = U_ZERO_ERROR;
59     configs = configMap;
60     if (localeTag != "") {
61         ComputeFinalLocaleTag(localeTag);
62         locale = icu::Locale::forLanguageTag(icu::StringPiece(finalLocaleTag), status);
63     }
64     if (localeTag == "" || status != U_ZERO_ERROR) {
65         std::string defaultLocaleTag = LocaleConfig::GetSystemLocale();
66         ResetFinalLocaleStatus();
67         ComputeFinalLocaleTag(defaultLocaleTag);
68         status = U_ZERO_ERROR;
69         locale = icu::Locale::forLanguageTag(icu::StringPiece(finalLocaleTag), status);
70     }
71     if (status == U_ZERO_ERROR) {
72         localeStatus = true;
73         language = locale.getLanguage();
74         script = locale.getScript();
75         region = locale.getCountry();
76         baseName = locale.getBaseName();
77         std::replace(baseName.begin(), baseName.end(), '_', '-');
78     }
79 }
80 
LocaleInfo(const std::string & localeTag)81 LocaleInfo::LocaleInfo(const std::string &localeTag)
82 {
83     std::map<std::string, std::string> configMap;
84     InitLocaleInfo(localeTag, configMap);
85 }
86 
LocaleInfo(const std::string & localeTag,std::map<std::string,std::string> & configMap)87 LocaleInfo::LocaleInfo(const std::string &localeTag, std::map<std::string, std::string> &configMap)
88 {
89     InitLocaleInfo(localeTag, configMap);
90 }
91 
~LocaleInfo()92 LocaleInfo::~LocaleInfo() {}
93 
ComputeFinalLocaleTag(const std::string & localeTag)94 void LocaleInfo::ComputeFinalLocaleTag(const std::string &localeTag)
95 {
96     if (localeTag.find("-u-") == std::string::npos) {
97         finalLocaleTag = localeTag;
98         ParseConfigs();
99     } else {
100         finalLocaleTag = localeTag.substr(0, localeTag.find("-u-"));
101         ParseLocaleTag(localeTag);
102         ParseConfigs();
103     }
104     if (!script.empty()) {
105         finalLocaleTag += "-" + script;
106     }
107     if (!region.empty()) {
108         finalLocaleTag += "-" + region;
109     }
110     if (!hourCycle.empty() || !numberingSystem.empty() || !calendar.empty() || !collation.empty() ||
111         !caseFirst.empty() || !numeric.empty()) {
112         finalLocaleTag += "-u";
113     }
114     if (!hourCycle.empty()) {
115         finalLocaleTag += hourCycleTag + hourCycle;
116     }
117     if (!numberingSystem.empty()) {
118         finalLocaleTag += numberingSystemTag + numberingSystem;
119     }
120     if (!calendar.empty()) {
121         finalLocaleTag += calendarTag + calendar;
122     }
123     if (!collation.empty()) {
124         finalLocaleTag += collationTag + collation;
125     }
126     if (!caseFirst.empty()) {
127         finalLocaleTag += caseFirstTag + caseFirst;
128     }
129     if (!numeric.empty()) {
130         finalLocaleTag += numericTag + numeric;
131     }
132 }
133 
ParseLocaleTag(const std::string & localeTag)134 void LocaleInfo::ParseLocaleTag(const std::string &localeTag)
135 {
136     std::string flag = "-";
137     if (localeTag.find(hourCycleTag) != std::string::npos) {
138         hourCycle = localeTag.substr(localeTag.find(hourCycleTag) + CONFIG_TAG_LEN);
139         hourCycle = hourCycle.substr(0, hourCycle.find(flag));
140     }
141     if (localeTag.find(numberingSystemTag) != std::string::npos) {
142         numberingSystem = localeTag.substr(localeTag.find(numberingSystemTag) + CONFIG_TAG_LEN);
143         numberingSystem = numberingSystem.substr(0, numberingSystem.find(flag));
144     }
145     if (localeTag.find(calendarTag) != std::string::npos) {
146         calendar = localeTag.substr(localeTag.find(calendarTag) + CONFIG_TAG_LEN);
147         calendar = calendar.substr(0, calendar.find(flag));
148     }
149     if (localeTag.find(collationTag) != std::string::npos) {
150         collation = localeTag.substr(localeTag.find(collationTag) + CONFIG_TAG_LEN);
151         collation = collation.substr(0, collation.find(flag));
152     }
153     if (localeTag.find(caseFirstTag) != std::string::npos) {
154         caseFirst = localeTag.substr(localeTag.find(caseFirstTag) + CONFIG_TAG_LEN);
155         caseFirst = caseFirst.substr(0, caseFirst.find(flag));
156     }
157     if (localeTag.find(numericTag) != std::string::npos) {
158         numeric = localeTag.substr(localeTag.find(numericTag) + CONFIG_TAG_LEN);
159         numeric = numeric.substr(0, numeric.find(flag));
160     }
161 }
162 
ParseConfigs()163 void LocaleInfo::ParseConfigs()
164 {
165     if (configs.count("script") > 0) {
166         script = configs["script"];
167     }
168     if (configs.count("region") > 0) {
169         region = configs["region"];
170     }
171     if (configs.count("hourCycle") > 0) {
172         hourCycle = configs["hourCycle"];
173     }
174     if (configs.count("numberingSystem") > 0) {
175         numberingSystem = configs["numberingSystem"];
176     }
177     if (configs.count("calendar") > 0) {
178         calendar = configs["calendar"];
179     }
180     if (configs.count("collation") > 0) {
181         collation = configs["collation"];
182     }
183     if (configs.count("caseFirst") > 0) {
184         caseFirst = configs["caseFirst"];
185     }
186     if (configs.count("numeric") > 0) {
187         numeric = configs["numeric"];
188     }
189 }
190 
191 bool LocaleInfo::icuInitialized = LocaleInfo::Init();
192 
GetLanguage() const193 std::string LocaleInfo::GetLanguage() const
194 {
195     return language;
196 }
197 
GetScript() const198 std::string LocaleInfo::GetScript() const
199 {
200     return script;
201 }
202 
GetRegion() const203 std::string LocaleInfo::GetRegion() const
204 {
205     return region;
206 }
207 
GetBaseName() const208 std::string LocaleInfo::GetBaseName() const
209 {
210     return baseName;
211 }
212 
GetCalendar() const213 std::string LocaleInfo::GetCalendar() const
214 {
215     return calendar;
216 }
217 
GetCollation() const218 std::string LocaleInfo::GetCollation() const
219 {
220     return collation;
221 }
222 
GetHourCycle() const223 std::string LocaleInfo::GetHourCycle() const
224 {
225     return hourCycle;
226 }
227 
GetNumberingSystem() const228 std::string LocaleInfo::GetNumberingSystem() const
229 {
230     return numberingSystem;
231 }
232 
GetNumeric() const233 std::string LocaleInfo::GetNumeric() const
234 {
235     return numeric;
236 }
237 
GetCaseFirst() const238 std::string LocaleInfo::GetCaseFirst() const
239 {
240     return caseFirst;
241 }
242 
ToString() const243 std::string LocaleInfo::ToString() const
244 {
245     return finalLocaleTag;
246 }
247 
GetLocale() const248 Locale LocaleInfo::GetLocale() const
249 {
250     return locale;
251 }
252 
Maximize()253 std::string LocaleInfo::Maximize()
254 {
255     if (!localeStatus) {
256         return "";
257     }
258     UErrorCode status = U_ZERO_ERROR;
259     Locale curLocale = locale;
260     curLocale.addLikelySubtags(status);
261     if (status == U_ZERO_ERROR) {
262         std::string restConfigs = "";
263         if (finalLocaleTag.find("-u-") != std::string::npos) {
264             restConfigs = finalLocaleTag.substr(finalLocaleTag.find("-u-"));
265         }
266         std::string curBaseName = (!curLocale.getBaseName()) ? "" : curLocale.getBaseName();
267         std::replace(curBaseName.begin(), curBaseName.end(), '_', '-');
268         std::string localeTag = curBaseName + restConfigs;
269         return localeTag;
270     }
271     return finalLocaleTag;
272 }
273 
Minimize()274 std::string LocaleInfo::Minimize()
275 {
276     if (!localeStatus) {
277         return "";
278     }
279     UErrorCode status = U_ZERO_ERROR;
280     Locale curLocale = locale;
281     curLocale.minimizeSubtags(status);
282     if (status == U_ZERO_ERROR) {
283         std::string restConfigs = "";
284         if (finalLocaleTag.find("-u-") != std::string::npos) {
285             restConfigs = finalLocaleTag.substr(finalLocaleTag.find("-u-"));
286         }
287         std::string curBaseName = (!curLocale.getBaseName()) ? "" : curLocale.getBaseName();
288         std::replace(curBaseName.begin(), curBaseName.end(), '_', '-');
289         std::string localeTag = curBaseName + restConfigs;
290         return localeTag;
291     }
292     return finalLocaleTag;
293 }
294 
Init()295 bool LocaleInfo::Init()
296 {
297     SetHwIcuDirectory();
298     return true;
299 }
300 
InitSuccess() const301 bool LocaleInfo::InitSuccess() const
302 {
303     return localeStatus;
304 }
305 } // namespace I18n
306 } // namespace Global
307 } // namespace OHOS
308