1 /*
2 * Copyright (c) 2021-2024 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 <unordered_map>
16 #include <vector>
17
18 #include "error_util.h"
19 #include "i18n_hilog.h"
20 #include "holiday_manager_addon.h"
21 #include "entity_recognizer_addon.h"
22 #include "i18n_calendar_addon.h"
23 #include "i18n_normalizer_addon.h"
24 #include "i18n_system_addon.h"
25 #include "i18n_timezone_addon.h"
26 #include "i18n_unicode_addon.h"
27 #include "js_utils.h"
28 #include "locale_config.h"
29 #include "locale_info.h"
30 #include "locale_matcher.h"
31 #include "node_api.h"
32 #include "simple_date_time_format_addon.h"
33 #include "simple_number_format_addon.h"
34 #include "styled_number_format_addon.h"
35 #include "system_locale_manager_addon.h"
36 #include "unicode/datefmt.h"
37 #include "unicode/locid.h"
38 #include "unicode/smpdtfmt.h"
39 #include "unicode/translit.h"
40 #include "utils.h"
41 #include "variable_convertor.h"
42 #include "i18n_addon.h"
43 #include "date_time_sequence.h"
44 #include "locale_info_addon.h"
45
46 namespace OHOS {
47 namespace Global {
48 namespace I18n {
49 static thread_local napi_ref* g_brkConstructor = nullptr;
50 static thread_local napi_ref g_indexUtilConstructor = nullptr;
51 static thread_local napi_ref* g_transConstructor = nullptr;
52
53 std::unordered_map<std::string, int32_t> I18nAddon::EnumTemperatureType {
54 { "CELSIUS", 1 },
55 { "FAHRENHEIT", 2 },
56 { "KELVIN", 3 }
57 };
58
59 std::unordered_map<std::string, int32_t> I18nAddon::EnumWeekDay {
60 { "MON", 1 },
61 { "TUE", 2 },
62 { "WED", 3 },
63 { "THU", 4 },
64 { "FRI", 5 },
65 { "SAT", 6 },
66 { "SUN", 7 }
67 };
68
I18nAddon()69 I18nAddon::I18nAddon() : env_(nullptr) {}
70
~I18nAddon()71 I18nAddon::~I18nAddon()
72 {
73 PhoneNumberFormat::CloseDynamicHandler();
74 }
75
Destructor(napi_env env,void * nativeObject,void * hint)76 void I18nAddon::Destructor(napi_env env, void *nativeObject, void *hint)
77 {
78 if (!nativeObject) {
79 return;
80 }
81 delete reinterpret_cast<I18nAddon *>(nativeObject);
82 nativeObject = nullptr;
83 }
84
InitI18nUtil(napi_env env,napi_value exports)85 napi_value I18nAddon::InitI18nUtil(napi_env env, napi_value exports)
86 {
87 napi_property_descriptor properties[] = {
88 DECLARE_NAPI_STATIC_FUNCTION("unitConvert", UnitConvert),
89 DECLARE_NAPI_STATIC_FUNCTION("getDateOrder", GetDateOrder),
90 DECLARE_NAPI_STATIC_FUNCTION("getTimePeriodName", GetTimePeriodName),
91 DECLARE_NAPI_STATIC_FUNCTION("getBestMatchLocale", GetBestMatchLocale),
92 DECLARE_NAPI_STATIC_FUNCTION("getThreeLetterLanguage", GetThreeLetterLanguage),
93 DECLARE_NAPI_STATIC_FUNCTION("getThreeLetterRegion", GetThreeLetterRegion),
94 DECLARE_NAPI_STATIC_FUNCTION("getUnicodeWrappedFilePath", GetUnicodeWrappedFilePath)
95 };
96 napi_value constructor = nullptr;
97 napi_status status = napi_define_class(env, "I18NUtil", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor, nullptr,
98 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
99 if (status != napi_ok) {
100 HILOG_ERROR_I18N("InitI18nUtil: Define class failed when InitI18NUtil.");
101 return nullptr;
102 }
103
104 status = napi_set_named_property(env, exports, "I18NUtil", constructor);
105 if (status != napi_ok) {
106 HILOG_ERROR_I18N("InitI18nUtil: Set property failed when InitI18NUtil.");
107 return nullptr;
108 }
109 return exports;
110 }
111
Init(napi_env env,napi_value exports)112 napi_value I18nAddon::Init(napi_env env, napi_value exports)
113 {
114 napi_status initStatus = napi_ok;
115 napi_property_descriptor properties[] = {
116 DECLARE_NAPI_FUNCTION("getDisplayLanguage", I18nSystemAddon::GetDisplayLanguage),
117 DECLARE_NAPI_FUNCTION("getDisplayCountry", I18nSystemAddon::GetDisplayCountry),
118 DECLARE_NAPI_FUNCTION("getSystemLanguage", I18nSystemAddon::GetSystemLanguage),
119 DECLARE_NAPI_FUNCTION("getSystemRegion", I18nSystemAddon::GetSystemRegion),
120 DECLARE_NAPI_FUNCTION("getSystemLocale", I18nSystemAddon::GetSystemLocale),
121 DECLARE_NAPI_FUNCTION("getCalendar", I18nCalendarAddon::GetCalendar),
122 DECLARE_NAPI_FUNCTION("isRTL", IsRTL),
123 DECLARE_NAPI_FUNCTION("getLineInstance", GetLineInstance),
124 DECLARE_NAPI_FUNCTION("getInstance", GetIndexUtil),
125 DECLARE_NAPI_FUNCTION("addPreferredLanguage", I18nSystemAddon::AddPreferredLanguage),
126 DECLARE_NAPI_FUNCTION("removePreferredLanguage", I18nSystemAddon::RemovePreferredLanguage),
127 DECLARE_NAPI_FUNCTION("getPreferredLanguageList", I18nSystemAddon::GetPreferredLanguageList),
128 DECLARE_NAPI_FUNCTION("getFirstPreferredLanguage", I18nSystemAddon::GetFirstPreferredLanguage),
129 DECLARE_NAPI_FUNCTION("getSimpleNumberFormatBySkeleton",
130 SimpleNumberFormatAddon::GetSimpleNumberFormatBySkeleton),
131 DECLARE_NAPI_FUNCTION("getSimpleDateTimeFormatByPattern",
132 SimpleDateTimeFormatAddon::GetSimpleDateTimeFormatByPattern),
133 DECLARE_NAPI_FUNCTION("getSimpleDateTimeFormatBySkeleton",
134 SimpleDateTimeFormatAddon::GetSimpleDateTimeFormatBySkeleton),
135 DECLARE_NAPI_FUNCTION("is24HourClock", I18nSystemAddon::Is24HourClock),
136 DECLARE_NAPI_FUNCTION("set24HourClock", I18nSystemAddon::Set24HourClock),
137 DECLARE_NAPI_FUNCTION("getTimeZone", I18nTimeZoneAddon::GetI18nTimeZone),
138 DECLARE_NAPI_PROPERTY("NormalizerMode", I18nNormalizerAddon::CreateI18NNormalizerModeEnum(env)),
139 DECLARE_NAPI_PROPERTY("TemperatureType", CreateTemperatureTypeEnum(env)),
140 DECLARE_NAPI_PROPERTY("WeekDay", CreateWeekDayEnum(env))
141 };
142 initStatus = napi_define_properties(env, exports, sizeof(properties) / sizeof(napi_property_descriptor),
143 properties);
144 if (initStatus != napi_ok) {
145 HILOG_ERROR_I18N("Failed to set properties at init");
146 return nullptr;
147 }
148 return exports;
149 }
150
GetOptionMap(napi_env env,napi_value option,std::map<std::string,std::string> & map)151 void GetOptionMap(napi_env env, napi_value option, std::map<std::string, std::string> &map)
152 {
153 if (VariableConvertor::CheckNapiIsNull(env, option)) {
154 size_t len;
155 napi_get_value_string_utf8(env, option, nullptr, 0, &len);
156 std::vector<char> styleBuf(len + 1);
157 napi_status status = napi_get_value_string_utf8(env, option, styleBuf.data(), len + 1, &len);
158 if (status != napi_ok) {
159 HILOG_ERROR_I18N("GetOptionMap: Failed to get string item");
160 return;
161 }
162 map.insert(std::make_pair("unitDisplay", styleBuf.data()));
163 }
164 }
165
UnitConvert(napi_env env,napi_callback_info info)166 napi_value I18nAddon::UnitConvert(napi_env env, napi_callback_info info)
167 {
168 size_t argc = 5;
169 napi_value argv[5] = { 0 };
170 napi_value thisVar = nullptr;
171 void *data = nullptr;
172 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
173 if (status != napi_ok) {
174 return nullptr;
175 }
176 std::string fromUnit;
177 VariableConvertor::GetOptionValue(env, argv[0], "unit", fromUnit);
178 std::string fromMeasSys;
179 VariableConvertor::GetOptionValue(env, argv[0], "measureSystem", fromMeasSys);
180 std::string toUnit;
181 VariableConvertor::GetOptionValue(env, argv[1], "unit", toUnit);
182 std::string toMeasSys;
183 VariableConvertor::GetOptionValue(env, argv[1], "measureSystem", toMeasSys);
184 double number = 0;
185 napi_get_value_double(env, argv[2], &number); // 2 is the index of value
186 int convertStatus = Convert(number, fromUnit, fromMeasSys, toUnit, toMeasSys);
187 size_t len;
188 napi_get_value_string_utf8(env, argv[3], nullptr, 0, &len); // 3 is the index of value
189 std::vector<char> localeBuf(len + 1);
190 // 3 is the index of value
191 status = napi_get_value_string_utf8(env, argv[3], localeBuf.data(), len + 1, &len);
192 if (status != napi_ok) {
193 return nullptr;
194 }
195 std::vector<std::string> localeTags;
196 localeTags.push_back(localeBuf.data());
197 std::map<std::string, std::string> map = {};
198 map.insert(std::make_pair("style", "unit"));
199 if (!convertStatus) {
200 map.insert(std::make_pair("unit", fromUnit));
201 } else {
202 map.insert(std::make_pair("unit", toUnit));
203 }
204 // 4 is the index of value
205 GetOptionMap(env, argv[4], map);
206 std::unique_ptr<NumberFormat> numberFmt = nullptr;
207 numberFmt = std::make_unique<NumberFormat>(localeTags, map);
208 std::string value = numberFmt->Format(number);
209 napi_value result;
210 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
211 if (status != napi_ok) {
212 HILOG_ERROR_I18N("UnitConvert: Failed to create string item");
213 return nullptr;
214 }
215 return result;
216 }
217
GetDateOrder(napi_env env,napi_callback_info info)218 napi_value I18nAddon::GetDateOrder(napi_env env, napi_callback_info info)
219 {
220 size_t argc = 1;
221 napi_value argv[1] = { 0 };
222 napi_value thisVar = nullptr;
223 void *data = nullptr;
224 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
225 if (status != napi_ok) {
226 return nullptr;
227 }
228 size_t len = 0;
229 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
230 std::vector<char> languageBuf(len + 1);
231 status = napi_get_value_string_utf8(env, argv[0], languageBuf.data(), len + 1, &len);
232 if (status != napi_ok) {
233 HILOG_ERROR_I18N("Failed to get locale string for GetDateOrder");
234 return nullptr;
235 }
236 std::string languageTag = languageBuf.data();
237 std::string value = DateTimeSequence::GetDateOrder(languageTag);
238 napi_value result;
239 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
240 if (status != napi_ok) {
241 HILOG_ERROR_I18N("GetDateOrder Failed to create string item");
242 return nullptr;
243 }
244 return result;
245 }
246
GetTimePeriodName(napi_env env,napi_callback_info info)247 napi_value I18nAddon::GetTimePeriodName(napi_env env, napi_callback_info info)
248 {
249 napi_value result;
250 int32_t hour;
251 std::string localeTag;
252 if (GetParamOfGetTimePeriodName(env, info, localeTag, hour) == -1) {
253 HILOG_ERROR_I18N("GetTimePeriodName param error");
254 napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &result);
255 return result;
256 }
257
258 UErrorCode icuStatus = U_ZERO_ERROR;
259 icu::Locale locale = icu::Locale::forLanguageTag(localeTag.data(), icuStatus);
260 if (U_FAILURE(icuStatus) || !IsValidLocaleTag(locale)) {
261 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", true);
262 return nullptr;
263 }
264 icu::SimpleDateFormat* formatter = dynamic_cast<icu::SimpleDateFormat*>
265 (icu::DateFormat::createDateInstance(icu::DateFormat::EStyle::kDefault, locale));
266 if (!formatter) {
267 HILOG_ERROR_I18N("GetTimePeriodName Failed to create SimpleDateFormat");
268 napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &result);
269 return result;
270 }
271 formatter->applyPattern("B");
272
273 std::string temp;
274 icu::UnicodeString name;
275 icu::Calendar *calendar = icu::Calendar::createInstance(locale, icuStatus);
276 calendar->set(UCalendarDateFields::UCAL_HOUR_OF_DAY, hour);
277 formatter->format(calendar->getTime(icuStatus), name);
278 name.toUTF8String(temp);
279 napi_create_string_utf8(env, PseudoLocalizationProcessor(temp).c_str(), NAPI_AUTO_LENGTH, &result);
280 delete formatter;
281 delete calendar;
282 return result;
283 }
284
GetParamOfGetTimePeriodName(napi_env env,napi_callback_info info,std::string & tag,int32_t & hour)285 int I18nAddon::GetParamOfGetTimePeriodName(napi_env env, napi_callback_info info, std::string &tag, int32_t &hour)
286 {
287 size_t argc = 2;
288 napi_value argv[2] = { 0 };
289 napi_value thisVar = nullptr;
290 void *data = nullptr;
291 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
292 if (status != napi_ok) {
293 HILOG_ERROR_I18N("GetTimePeriodName can't get parameters from getTimePerioudName.");
294 return -1;
295 } else if (argc < 1) {
296 ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "hour", true);
297 return -1;
298 }
299
300 napi_valuetype valueType = napi_valuetype::napi_undefined;
301 napi_typeof(env, argv[0], &valueType);
302 if (valueType != napi_valuetype::napi_number) {
303 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "hour", "number", true);
304 return -1;
305 }
306 status = napi_get_value_int32(env, argv[0], &hour);
307 if (status != napi_ok) {
308 HILOG_ERROR_I18N("GetTimePeriodName can't get number from js param");
309 return -1;
310 }
311
312 valueType = napi_valuetype::napi_undefined;
313 napi_typeof(env, argv[1], &valueType);
314 if (valueType == napi_valuetype::napi_null || valueType == napi_valuetype::napi_undefined) {
315 tag = LocaleConfig::GetSystemLocale();
316 } else if (valueType == napi_valuetype::napi_string) {
317 int code = 0;
318 tag = VariableConvertor::GetString(env, argv[1], code);
319 if (code) {
320 HILOG_ERROR_I18N("GetTimePeriodName can't get string from js param");
321 return -1;
322 }
323 } else {
324 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "string", true);
325 return -1;
326 }
327 return 0;
328 }
329
ProcessJsParamLocale(napi_env env,napi_value argv)330 LocaleInfo* ProcessJsParamLocale(napi_env env, napi_value argv)
331 {
332 int32_t code = 0;
333 std::string localeTag = VariableConvertor::GetString(env, argv, code);
334 if (code != 0) {
335 HILOG_ERROR_I18N("ProcessJsParamLocale: Failed to obtain the parameter.");
336 return nullptr;
337 }
338 UErrorCode icuStatus = U_ZERO_ERROR;
339 icu::Locale locale = icu::Locale::forLanguageTag(localeTag.data(), icuStatus);
340 if (U_FAILURE(icuStatus) || !IsValidLocaleTag(locale)) {
341 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", true);
342 return nullptr;
343 }
344 return new LocaleInfo(localeTag);
345 }
346
ProcessJsParamLocaleList(napi_env env,napi_value argv,std::vector<LocaleInfo * > & candidateLocales,LocaleInfo * requestLocale)347 bool ProcessJsParamLocaleList(napi_env env, napi_value argv, std::vector<LocaleInfo*> &candidateLocales,
348 LocaleInfo *requestLocale)
349 {
350 std::vector<std::string> localeTagList;
351 if (!VariableConvertor::GetStringArrayFromJsParam(env, argv, "localeList", localeTagList)) {
352 HILOG_ERROR_I18N("ProcessJsParamLocaleList: Failed to obtain the parameter.");
353 return false;
354 }
355 if (localeTagList.size() == 0) {
356 return true;
357 }
358 for (auto it = localeTagList.begin(); it != localeTagList.end(); ++it) {
359 UErrorCode icuStatus = U_ZERO_ERROR;
360 icu::Locale locale = icu::Locale::forLanguageTag(it->data(), icuStatus);
361 if (U_FAILURE(icuStatus) || !IsValidLocaleTag(locale)) {
362 HILOG_ERROR_I18N("GetBestMatchLocale param localeList Invalid: %{public}s.", it->data());
363 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale of localeList", "a valid locale", true);
364 return false;
365 }
366 LocaleInfo *temp = new LocaleInfo(*it);
367 if (LocaleMatcher::Match(requestLocale, temp)) {
368 candidateLocales.push_back(temp);
369 } else {
370 delete temp;
371 }
372 }
373 return true;
374 }
375
ReleaseParam(LocaleInfo * locale,std::vector<LocaleInfo * > & candidateLocales)376 void ReleaseParam(LocaleInfo *locale, std::vector<LocaleInfo*> &candidateLocales)
377 {
378 delete locale;
379 for (auto it = candidateLocales.begin(); it != candidateLocales.end(); ++it) {
380 delete *it;
381 }
382 }
383
GetBestMatchLocale(napi_env env,napi_callback_info info)384 napi_value I18nAddon::GetBestMatchLocale(napi_env env, napi_callback_info info)
385 {
386 size_t argc = 2;
387 napi_value argv[2] = { nullptr };
388 napi_value thisVar = nullptr;
389 void *data = nullptr;
390 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
391 if (status != napi_ok || argc < 2) { // 2 is the request param num.
392 ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "locale or localeList", true);
393 return nullptr;
394 }
395 LocaleInfo *requestLocale = ProcessJsParamLocale(env, argv[0]);
396 if (requestLocale == nullptr) {
397 return nullptr;
398 }
399 std::vector<LocaleInfo*> candidateLocales;
400 bool isValidParam = ProcessJsParamLocaleList(env, argv[1], candidateLocales, requestLocale);
401 if (!isValidParam) {
402 ReleaseParam(requestLocale, candidateLocales);
403 return nullptr;
404 }
405 std::string bestMatchLocaleTag = "";
406 if (candidateLocales.size() > 0) {
407 LocaleInfo *bestMatch = candidateLocales[0];
408 for (size_t i = 1; i < candidateLocales.size(); ++i) {
409 if (LocaleMatcher::IsMoreSuitable(bestMatch, candidateLocales[i], requestLocale) < 0) {
410 bestMatch = candidateLocales[i];
411 }
412 }
413 bestMatchLocaleTag = bestMatch->ToString();
414 }
415 ReleaseParam(requestLocale, candidateLocales);
416 napi_value result = nullptr;
417 status = napi_create_string_utf8(env, bestMatchLocaleTag.c_str(), NAPI_AUTO_LENGTH, &result);
418 if (status != napi_ok) {
419 HILOG_ERROR_I18N("Create format stirng failed.");
420 return nullptr;
421 }
422 return result;
423 }
424
GetThreeLetterLanguage(napi_env env,napi_callback_info info)425 napi_value I18nAddon::GetThreeLetterLanguage(napi_env env, napi_callback_info info)
426 {
427 size_t argc = 1;
428 napi_value argv[1] = { 0 };
429 napi_value thisVar = nullptr;
430 void *data = nullptr;
431 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
432 if (status != napi_ok) {
433 HILOG_ERROR_I18N("GetThreeLetterLanguage napi get param error.");
434 return nullptr;
435 } else if (argc < 1) {
436 ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "locale", true);
437 return nullptr;
438 }
439
440 napi_valuetype valueType = napi_valuetype::napi_undefined;
441 napi_typeof(env, argv[0], &valueType);
442 if (valueType != napi_valuetype::napi_string) {
443 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "string", true);
444 return nullptr;
445 }
446
447 int32_t code = 0;
448 std::string languageTag = VariableConvertor::GetString(env, argv[0], code);
449 if (code != 0) {
450 HILOG_ERROR_I18N("GetThreeLetterLanguage: Failed to obtain the parameter.");
451 return nullptr;
452 }
453
454 std::string language = GetISO3Language(languageTag);
455
456 napi_value result;
457 status = napi_create_string_utf8(env, language.c_str(), NAPI_AUTO_LENGTH, &result);
458 if (status != napi_ok || language.empty()) {
459 HILOG_ERROR_I18N("GetThreeLetterLanguage create string fail or empty");
460 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", true);
461 return nullptr;
462 }
463 return result;
464 }
465
GetThreeLetterRegion(napi_env env,napi_callback_info info)466 napi_value I18nAddon::GetThreeLetterRegion(napi_env env, napi_callback_info info)
467 {
468 size_t argc = 1;
469 napi_value argv[1] = { 0 };
470 napi_value thisVar = nullptr;
471 void *data = nullptr;
472 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
473 if (status != napi_ok) {
474 HILOG_ERROR_I18N("GetThreeLetterRegion: Failed to obtain the parameter.");
475 return nullptr;
476 } else if (argc < 1) {
477 ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "locale", true);
478 return nullptr;
479 }
480
481 napi_valuetype valueType = napi_valuetype::napi_undefined;
482 napi_typeof(env, argv[0], &valueType);
483 if (valueType != napi_valuetype::napi_string) {
484 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "string", true);
485 return nullptr;
486 }
487
488 int32_t code = 0;
489 std::string regionTag = VariableConvertor::GetString(env, argv[0], code);
490 if (code != 0) {
491 HILOG_ERROR_I18N("GetThreeLetterRegion: Failed to obtain the parameter.");
492 return nullptr;
493 }
494
495 std::string country = GetISO3Country(regionTag);
496
497 napi_value result;
498 status = napi_create_string_utf8(env, country.c_str(), NAPI_AUTO_LENGTH, &result);
499 if (status != napi_ok || country.empty()) {
500 HILOG_ERROR_I18N("GetThreeLetterRegion create string fail or empty");
501 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", true);
502 return nullptr;
503 }
504 return result;
505 }
506
InitI18nTransliterator(napi_env env,napi_value exports)507 napi_value I18nAddon::InitI18nTransliterator(napi_env env, napi_value exports)
508 {
509 napi_property_descriptor properties[] = {
510 DECLARE_NAPI_FUNCTION("transform", Transform),
511 };
512 napi_value constructor = nullptr;
513 napi_status status = napi_define_class(env, "Transliterator", NAPI_AUTO_LENGTH, I18nTransliteratorConstructor,
514 nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
515 if (status != napi_ok) {
516 HILOG_ERROR_I18N("InitI18nTransliterator: Failed to define transliterator class at Init");
517 return nullptr;
518 }
519 exports = I18nAddon::InitTransliterator(env, exports);
520 g_transConstructor = new (std::nothrow) napi_ref;
521 if (!g_transConstructor) {
522 HILOG_ERROR_I18N("InitI18nTransliterator: Failed to create trans ref at init");
523 return nullptr;
524 }
525 status = napi_create_reference(env, constructor, 1, g_transConstructor);
526 if (status != napi_ok) {
527 HILOG_ERROR_I18N("InitI18nTransliterator: Failed to create trans reference at init");
528 return nullptr;
529 }
530 return exports;
531 }
532
InitTransliterator(napi_env env,napi_value exports)533 napi_value I18nAddon::InitTransliterator(napi_env env, napi_value exports)
534 {
535 napi_property_descriptor properties[] = {
536 DECLARE_NAPI_STATIC_FUNCTION("getAvailableIDs", GetAvailableIDs),
537 DECLARE_NAPI_STATIC_FUNCTION("getInstance", GetTransliteratorInstance)
538 };
539 napi_value constructor = nullptr;
540 napi_status status = napi_define_class(env, "I18nTransliterator", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor,
541 nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
542 if (status != napi_ok) {
543 HILOG_ERROR_I18N("InitTransliterator: Failed to define class Transliterator.");
544 return nullptr;
545 }
546 status = napi_set_named_property(env, exports, "Transliterator", constructor);
547 if (status != napi_ok) {
548 HILOG_ERROR_I18N("InitTransliterator: Set property failed When InitTransliterator.");
549 return nullptr;
550 }
551 return exports;
552 }
553
I18nTransliteratorConstructor(napi_env env,napi_callback_info info)554 napi_value I18nAddon::I18nTransliteratorConstructor(napi_env env, napi_callback_info info)
555 {
556 size_t argc = 1;
557 napi_value argv[1] = { 0 };
558 napi_value thisVar = nullptr;
559 void *data = nullptr;
560 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
561 if (status != napi_ok) {
562 return nullptr;
563 }
564 napi_valuetype valueType = napi_valuetype::napi_undefined;
565 napi_typeof(env, argv[0], &valueType);
566 if (valueType != napi_valuetype::napi_string) {
567 HILOG_ERROR_I18N("I18nTransliteratorConstructor: Parameter type does not match");
568 return nullptr;
569 }
570 int32_t code = 0;
571 std::string idTag = VariableConvertor::GetString(env, argv[0], code);
572 if (code) {
573 return nullptr;
574 }
575 std::unique_ptr<I18nAddon> obj = nullptr;
576 obj = std::make_unique<I18nAddon>();
577 status =
578 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
579 if (status != napi_ok) {
580 HILOG_ERROR_I18N("I18nTransliteratorConstructor: TransliteratorConstructor: Wrap II18nAddon failed");
581 return nullptr;
582 }
583 if (!obj->InitTransliteratorContext(env, info, idTag)) {
584 obj.release();
585 return nullptr;
586 }
587 obj.release();
588 return thisVar;
589 }
590
InitTransliteratorContext(napi_env env,napi_callback_info info,const std::string & idTag)591 bool I18nAddon::InitTransliteratorContext(napi_env env, napi_callback_info info, const std::string &idTag)
592 {
593 UErrorCode status = U_ZERO_ERROR;
594 icu::UnicodeString unistr = icu::UnicodeString::fromUTF8(idTag);
595 icu::Transliterator *trans = icu::Transliterator::createInstance(unistr, UTransDirection::UTRANS_FORWARD, status);
596 if (U_FAILURE(status) || (trans == nullptr)) {
597 return false;
598 }
599 transliterator_ = std::unique_ptr<icu::Transliterator>(trans);
600 return transliterator_ != nullptr;
601 }
602
Transform(napi_env env,napi_callback_info info)603 napi_value I18nAddon::Transform(napi_env env, napi_callback_info info)
604 {
605 size_t argc = 1;
606 napi_value argv[1] = { nullptr };
607 napi_value thisVar = nullptr;
608 void *data = nullptr;
609 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
610 I18nAddon *obj = nullptr;
611 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
612 if (status != napi_ok || !obj || !obj->transliterator_) {
613 HILOG_ERROR_I18N("Get Transliterator object failed");
614 return nullptr;
615 }
616 if (!argv[0]) {
617 return nullptr;
618 }
619 napi_valuetype valueType = napi_valuetype::napi_undefined;
620 napi_typeof(env, argv[0], &valueType);
621 if (valueType != napi_valuetype::napi_string) {
622 HILOG_ERROR_I18N("Transform: Parameter type does not match");
623 return nullptr;
624 }
625 size_t len = 0;
626 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
627 if (status != napi_ok) {
628 HILOG_ERROR_I18N("Transform: Get field length failed napi_get_value_string_utf8");
629 return nullptr;
630 }
631 std::vector<char> buf(len + 1);
632 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
633 if (status != napi_ok) {
634 HILOG_ERROR_I18N("Transform: Get string value failed");
635 return nullptr;
636 }
637 icu::UnicodeString unistr = icu::UnicodeString::fromUTF8(buf.data());
638 obj->transliterator_->transliterate(unistr);
639 std::string temp;
640 unistr.toUTF8String(temp);
641 napi_value value;
642 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &value);
643 if (status != napi_ok) {
644 HILOG_ERROR_I18N("Transform: Get field length failed napi_create_string_utf8");
645 return nullptr;
646 }
647 return value;
648 }
649
GetAvailableIDs(napi_env env,napi_callback_info info)650 napi_value I18nAddon::GetAvailableIDs(napi_env env, napi_callback_info info)
651 {
652 size_t argc = 0;
653 napi_value *argv = nullptr;
654 napi_value thisVar = nullptr;
655 void *data = nullptr;
656 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
657 if (status != napi_ok) {
658 return nullptr;
659 }
660 UErrorCode icuStatus = U_ZERO_ERROR;
661 icu::StringEnumeration *strenum = icu::Transliterator::getAvailableIDs(icuStatus);
662 if (U_FAILURE(icuStatus)) {
663 HILOG_ERROR_I18N("Failed to get available ids");
664 if (strenum) {
665 delete strenum;
666 }
667 return nullptr;
668 }
669
670 napi_value result = nullptr;
671 napi_create_array(env, &result);
672 uint32_t i = 0;
673 const char *temp = nullptr;
674 if (strenum == nullptr) {
675 return nullptr;
676 }
677 while ((temp = strenum->next(nullptr, icuStatus)) != nullptr) {
678 if (U_FAILURE(icuStatus)) {
679 break;
680 }
681 napi_value val = nullptr;
682 napi_create_string_utf8(env, temp, strlen(temp), &val);
683 napi_set_element(env, result, i, val);
684 ++i;
685 }
686 delete strenum;
687 return result;
688 }
689
GetTransliteratorInstance(napi_env env,napi_callback_info info)690 napi_value I18nAddon::GetTransliteratorInstance(napi_env env, napi_callback_info info)
691 {
692 size_t argc = 1; // retrieve 2 arguments
693 napi_value argv[1] = { 0 };
694 napi_value thisVar = nullptr;
695 void *data = nullptr;
696 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
697 napi_value constructor = nullptr;
698 napi_status status = napi_get_reference_value(env, *g_transConstructor, &constructor);
699 if (status != napi_ok) {
700 HILOG_ERROR_I18N("Failed to create reference at GetCalendar");
701 return nullptr;
702 }
703 napi_value result = nullptr;
704 status = napi_new_instance(env, constructor, 1, argv, &result); // 2 arguments
705 if (status != napi_ok) {
706 HILOG_ERROR_I18N("Get Transliterator create instance failed");
707 return nullptr;
708 }
709 return result;
710 }
711
IsRTL(napi_env env,napi_callback_info info)712 napi_value I18nAddon::IsRTL(napi_env env, napi_callback_info info)
713 {
714 size_t argc = 1;
715 napi_value argv[1] = { 0 };
716 napi_value thisVar = nullptr;
717 void *data = nullptr;
718 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
719 if (status != napi_ok) {
720 return nullptr;
721 }
722 size_t len = 0;
723 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
724 std::vector<char> localeBuf(len + 1);
725 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
726 if (status != napi_ok) {
727 HILOG_ERROR_I18N("IsRTL: Failed to get string item");
728 return nullptr;
729 }
730 bool isRTL = LocaleConfig::IsRTL(localeBuf.data());
731 napi_value result = nullptr;
732 status = napi_get_boolean(env, isRTL, &result);
733 if (status != napi_ok) {
734 HILOG_ERROR_I18N("IsRTL failed");
735 return nullptr;
736 }
737 return result;
738 }
739
GetUnicodeWrappedFilePath(napi_env env,napi_callback_info info)740 napi_value I18nAddon::GetUnicodeWrappedFilePath(napi_env env, napi_callback_info info)
741 {
742 size_t argc = 3;
743 napi_value argv[3] = { 0 };
744 napi_value thisVar = nullptr;
745 void *data = nullptr;
746 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
747 if (status != napi_ok) {
748 HILOG_ERROR_I18N("GetUnicodeWrappedFilePath: Get param info failed");
749 return nullptr;
750 }
751 if (argc < 1) {
752 ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "path", true);
753 return nullptr;
754 }
755 VariableConvertor::VerifyType(env, "path", napi_valuetype::napi_string, argv[0]);
756 int32_t code = 0;
757 std::string path = VariableConvertor::GetString(env, argv[0], code);
758 if (code) {
759 HILOG_ERROR_I18N("GetUnicodeWrappedFilePath: Get param string argv[0] failed");
760 return nullptr;
761 }
762 char delimiter = PATH_SEPARATOR;
763 if (argc >= 2) { // 2 is parameter count
764 VariableConvertor::VerifyType(env, "delimiter", napi_valuetype::napi_string, argv[1]);
765 delimiter = GetDelimiter(env, argv[1]);
766 if (delimiter == '\0') {
767 HILOG_ERROR_I18N("GetUnicodeWrappedFilePath: Second param is empty");
768 return nullptr;
769 }
770 }
771 LocaleInfoAddon *obj = nullptr;
772 if (argc == 3) { // 3 is parameter count
773 napi_status status = napi_unwrap(env,
774 argv[2], reinterpret_cast<void **>(&obj)); // 2 is the last parameter index
775 if (status != napi_ok || !obj || !obj->GetLocaleInfo()) {
776 HILOG_ERROR_I18N("GetUnicodeWrappedFilePath: Get Locale object failed");
777 return nullptr;
778 }
779 }
780 std::string errorCode;
781 std::shared_ptr<LocaleInfo> localeInfoPtr = obj == nullptr ? nullptr : obj->GetLocaleInfo();
782 std::string result = LocaleConfig::GetUnicodeWrappedFilePath(path, delimiter,
783 localeInfoPtr, errorCode);
784 if (!errorCode.empty()) {
785 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, errorCode, "valid", true);
786 return nullptr;
787 }
788 return VariableConvertor::CreateString(env, result);
789 }
790
GetDelimiter(napi_env env,napi_value argVal)791 char I18nAddon::GetDelimiter(napi_env env, napi_value argVal)
792 {
793 int32_t code = 0;
794 std::string result = VariableConvertor::GetString(env, argVal, code);
795 if (code) {
796 HILOG_ERROR_I18N("GetDelimiter: Get string failed");
797 return '\0';
798 }
799 if (result.length() != 1) {
800 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "delimiter", "a valid delimiter", true);
801 return '\0';
802 }
803 return result.at(0);
804 }
805
InitPhoneNumberFormat(napi_env env,napi_value exports)806 napi_value I18nAddon::InitPhoneNumberFormat(napi_env env, napi_value exports)
807 {
808 napi_status status = napi_ok;
809 napi_property_descriptor properties[] = {
810 DECLARE_NAPI_FUNCTION("isValidNumber", IsValidPhoneNumber),
811 DECLARE_NAPI_FUNCTION("format", FormatPhoneNumber),
812 DECLARE_NAPI_FUNCTION("getLocationName", GetLocationName)
813 };
814
815 napi_value constructor;
816 status = napi_define_class(env, "PhoneNumberFormat", NAPI_AUTO_LENGTH, PhoneNumberFormatConstructor, nullptr,
817 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
818 if (status != napi_ok) {
819 HILOG_ERROR_I18N("InitPhoneNumberFormat: Define class failed when InitPhoneNumberFormat");
820 return nullptr;
821 }
822
823 status = napi_set_named_property(env, exports, "PhoneNumberFormat", constructor);
824 if (status != napi_ok) {
825 HILOG_ERROR_I18N("Set property failed when InitPhoneNumberFormat");
826 return nullptr;
827 }
828 return exports;
829 }
830
PhoneNumberFormatConstructor(napi_env env,napi_callback_info info)831 napi_value I18nAddon::PhoneNumberFormatConstructor(napi_env env, napi_callback_info info)
832 {
833 size_t argc = 2;
834 napi_value argv[2] = { 0 };
835 napi_value thisVar = nullptr;
836 void *data = nullptr;
837 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
838 if (status != napi_ok) {
839 return nullptr;
840 }
841 napi_valuetype valueType = napi_valuetype::napi_undefined;
842 napi_typeof(env, argv[0], &valueType);
843 if (valueType != napi_valuetype::napi_string) {
844 HILOG_ERROR_I18N("PhoneNumberFormatConstructor: Parameter type does not match");
845 return nullptr;
846 }
847 size_t len = 0;
848 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
849 if (status != napi_ok) {
850 HILOG_ERROR_I18N("PhoneNumberFormatConstructor: Get country tag length failed");
851 return nullptr;
852 }
853 std::vector<char> country (len + 1);
854 status = napi_get_value_string_utf8(env, argv[0], country.data(), len + 1, &len);
855 if (status != napi_ok) {
856 HILOG_ERROR_I18N("Get country tag failed");
857 return nullptr;
858 }
859 std::map<std::string, std::string> options;
860 std::string typeStr;
861 VariableConvertor::GetOptionValue(env, argv[1], "type", typeStr);
862 options.insert(std::make_pair("type", typeStr));
863 std::unique_ptr<I18nAddon> obj = nullptr;
864 obj = std::make_unique<I18nAddon>();
865 status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
866 I18nAddon::Destructor, nullptr, nullptr);
867 if (status != napi_ok) {
868 HILOG_ERROR_I18N("PhoneNumberFormatConstructor: Wrap I18nAddon failed");
869 return nullptr;
870 }
871 if (!obj->InitPhoneNumberFormatContext(env, info, country.data(), options)) {
872 return nullptr;
873 }
874 obj.release();
875 return thisVar;
876 }
877
InitPhoneNumberFormatContext(napi_env env,napi_callback_info info,const std::string & country,const std::map<std::string,std::string> & options)878 bool I18nAddon::InitPhoneNumberFormatContext(napi_env env, napi_callback_info info, const std::string &country,
879 const std::map<std::string, std::string> &options)
880 {
881 napi_value global = nullptr;
882 napi_status status = napi_get_global(env, &global);
883 if (status != napi_ok) {
884 HILOG_ERROR_I18N("InitPhoneNumberFormatContext: Get global failed");
885 return false;
886 }
887 env_ = env;
888 phonenumberfmt_ = PhoneNumberFormat::CreateInstance(country, options);
889
890 return phonenumberfmt_ != nullptr;
891 }
892
IsValidPhoneNumber(napi_env env,napi_callback_info info)893 napi_value I18nAddon::IsValidPhoneNumber(napi_env env, napi_callback_info info)
894 {
895 size_t argc = 1;
896 napi_value argv[1] = { 0 };
897 napi_value thisVar = nullptr;
898 void *data = nullptr;
899 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
900 napi_valuetype valueType = napi_valuetype::napi_undefined;
901 napi_typeof(env, argv[0], &valueType);
902 if (valueType != napi_valuetype::napi_string) {
903 HILOG_ERROR_I18N("IsValidPhoneNumber: Parameter type does not match");
904 return nullptr;
905 }
906
907 size_t len = 0;
908 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
909 if (status != napi_ok) {
910 HILOG_ERROR_I18N("IsValidPhoneNumber: Get phone number length failed");
911 return nullptr;
912 }
913 std::vector<char> buf(len + 1);
914 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
915 if (status != napi_ok) {
916 HILOG_ERROR_I18N("IsValidPhoneNumber: Get phone number failed");
917 return nullptr;
918 }
919
920 I18nAddon *obj = nullptr;
921 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
922 if (status != napi_ok || !obj || !obj->phonenumberfmt_) {
923 HILOG_ERROR_I18N("IsValidPhoneNumber: GetPhoneNumberFormat object failed");
924 return nullptr;
925 }
926
927 bool isValid = obj->phonenumberfmt_->isValidPhoneNumber(buf.data());
928
929 napi_value result = nullptr;
930 status = napi_get_boolean(env, isValid, &result);
931 if (status != napi_ok) {
932 HILOG_ERROR_I18N("IsValidPhoneNumber: Create boolean failed");
933 return nullptr;
934 }
935
936 return result;
937 }
938
GetLocationName(napi_env env,napi_callback_info info)939 napi_value I18nAddon::GetLocationName(napi_env env, napi_callback_info info)
940 {
941 size_t argc = 2;
942 napi_value argv[2] = {0, 0};
943 napi_value thisVar = nullptr;
944 void *data = nullptr;
945 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
946
947 int32_t code = 0;
948 std::string number = VariableConvertor::GetString(env, argv[0], code);
949 if (code) {
950 return nullptr;
951 }
952 std::string language = VariableConvertor::GetString(env, argv[1], code);
953 if (code) {
954 return nullptr;
955 }
956
957 I18nAddon *obj = nullptr;
958 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
959 if (status != napi_ok || !obj || !obj->phonenumberfmt_) {
960 HILOG_ERROR_I18N("GetLocationName: GetPhoneNumberFormat object failed");
961 return nullptr;
962 }
963
964 std::string resStr = obj->phonenumberfmt_->getLocationName(number.data(), language.data());
965 napi_value result = nullptr;
966 status = napi_create_string_utf8(env, resStr.c_str(), NAPI_AUTO_LENGTH, &result);
967 if (status != napi_ok) {
968 HILOG_ERROR_I18N("Create result string failed");
969 return nullptr;
970 }
971
972 return result;
973 }
974
FormatPhoneNumber(napi_env env,napi_callback_info info)975 napi_value I18nAddon::FormatPhoneNumber(napi_env env, napi_callback_info info)
976 {
977 size_t argc = 1;
978 napi_value argv[1] = { 0 };
979 napi_value thisVar = nullptr;
980 void *data = nullptr;
981 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
982 napi_valuetype valueType = napi_valuetype::napi_undefined;
983 napi_typeof(env, argv[0], &valueType);
984 if (valueType != napi_valuetype::napi_string) {
985 HILOG_ERROR_I18N("FormatPhoneNumber: Parameter type does not match");
986 return nullptr;
987 }
988
989 size_t len = 0;
990 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
991 if (status != napi_ok) {
992 HILOG_ERROR_I18N("FormatPhoneNumber: Get phone number length failed");
993 return nullptr;
994 }
995 std::vector<char> buf(len + 1);
996 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
997 if (status != napi_ok) {
998 HILOG_ERROR_I18N("FormatPhoneNumber: Get phone number failed");
999 return nullptr;
1000 }
1001
1002 I18nAddon *obj = nullptr;
1003 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1004 if (status != napi_ok || !obj || !obj->phonenumberfmt_) {
1005 HILOG_ERROR_I18N("Get PhoneNumberFormat object failed");
1006 return nullptr;
1007 }
1008
1009 std::string formattedPhoneNumber = obj->phonenumberfmt_->format(buf.data());
1010
1011 napi_value result = nullptr;
1012 status = napi_create_string_utf8(env, formattedPhoneNumber.c_str(), NAPI_AUTO_LENGTH, &result);
1013 if (status != napi_ok) {
1014 HILOG_ERROR_I18N("Create format phone number failed");
1015 return nullptr;
1016 }
1017 return result;
1018 }
1019
InitI18nIndexUtil(napi_env env,napi_value exports)1020 napi_value I18nAddon::InitI18nIndexUtil(napi_env env, napi_value exports)
1021 {
1022 napi_property_descriptor properties[] = {
1023 DECLARE_NAPI_FUNCTION("getIndexList", GetIndexList),
1024 DECLARE_NAPI_FUNCTION("addLocale", AddLocale),
1025 DECLARE_NAPI_FUNCTION("getIndex", GetIndex)
1026 };
1027
1028 napi_value constructor = nullptr;
1029 napi_status status = napi_define_class(env, "IndexUtil", NAPI_AUTO_LENGTH, I18nIndexUtilConstructor, nullptr,
1030 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1031 if (status != napi_ok) {
1032 HILOG_ERROR_I18N("InitI18nIndexUtil: Define class failed when InitI18nIndexUtil.");
1033 return nullptr;
1034 }
1035 exports = I18nAddon::InitIndexUtil(env, exports);
1036 status = napi_create_reference(env, constructor, 1, &g_indexUtilConstructor);
1037 if (status != napi_ok) {
1038 HILOG_ERROR_I18N("InitI18nIndexUtil: Failed to create reference at init.");
1039 return nullptr;
1040 }
1041 return exports;
1042 }
1043
InitIndexUtil(napi_env env,napi_value exports)1044 napi_value I18nAddon::InitIndexUtil(napi_env env, napi_value exports)
1045 {
1046 napi_property_descriptor properties[] = {};
1047 napi_value constructor = nullptr;
1048 napi_status status = napi_define_class(env, "I18nIndexUtil", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor,
1049 nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1050 if (status != napi_ok) {
1051 HILOG_ERROR_I18N("InitIndexUtil: Failed to define class IndexUtil.");
1052 return nullptr;
1053 }
1054 status = napi_set_named_property(env, exports, "IndexUtil", constructor);
1055 if (status != napi_ok) {
1056 HILOG_ERROR_I18N("InitIndexUtil: Set property failed When InitIndexUtil.");
1057 return nullptr;
1058 }
1059 return exports;
1060 }
1061
I18nBreakIteratorConstructor(napi_env env,napi_callback_info info)1062 napi_value I18nAddon::I18nBreakIteratorConstructor(napi_env env, napi_callback_info info)
1063 {
1064 size_t argc = 1;
1065 napi_value argv[1] = { nullptr };
1066 napi_value thisVar = nullptr;
1067 void *data = nullptr;
1068 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1069 if (status != napi_ok) {
1070 return nullptr;
1071 }
1072 napi_valuetype valueType = napi_valuetype::napi_undefined;
1073 napi_typeof(env, argv[0], &valueType);
1074 if (valueType != napi_valuetype::napi_string) {
1075 HILOG_ERROR_I18N("BreakIteratorConstructor: Parameter type does not match");
1076 return nullptr;
1077 }
1078 int32_t code = 0;
1079 std::string localeTag = VariableConvertor::GetString(env, argv[0], code);
1080 if (code) {
1081 return nullptr;
1082 }
1083 std::unique_ptr<I18nAddon> obj = nullptr;
1084 obj = std::make_unique<I18nAddon>();
1085 status =
1086 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
1087 if (status != napi_ok) {
1088 HILOG_ERROR_I18N("BreakIteratorConstructor: Wrap II18nAddon failed");
1089 return nullptr;
1090 }
1091 obj->brkiter_ = std::make_unique<I18nBreakIterator>(localeTag);
1092 if (!obj->brkiter_) {
1093 HILOG_ERROR_I18N("Wrap BreakIterator failed");
1094 return nullptr;
1095 }
1096 obj.release();
1097 return thisVar;
1098 }
1099
InitI18nBreakIterator(napi_env env,napi_value exports)1100 napi_value I18nAddon::InitI18nBreakIterator(napi_env env, napi_value exports)
1101 {
1102 napi_property_descriptor properties[] = {
1103 DECLARE_NAPI_FUNCTION("current", Current),
1104 DECLARE_NAPI_FUNCTION("first", First),
1105 DECLARE_NAPI_FUNCTION("last", Last),
1106 DECLARE_NAPI_FUNCTION("next", Next),
1107 DECLARE_NAPI_FUNCTION("previous", Previous),
1108 DECLARE_NAPI_FUNCTION("setLineBreakText", SetText),
1109 DECLARE_NAPI_FUNCTION("following", Following),
1110 DECLARE_NAPI_FUNCTION("getLineBreakText", GetText),
1111 DECLARE_NAPI_FUNCTION("isBoundary", IsBoundary)
1112 };
1113 napi_value constructor = nullptr;
1114 napi_status status = napi_define_class(env, "BreakIterator", NAPI_AUTO_LENGTH, I18nBreakIteratorConstructor,
1115 nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1116 if (status != napi_ok) {
1117 HILOG_ERROR_I18N("InitI18nBreakIterator: Failed to define class BreakIterator at Init");
1118 return nullptr;
1119 }
1120 exports = I18nAddon::InitBreakIterator(env, exports);
1121 g_brkConstructor = new (std::nothrow) napi_ref;
1122 if (!g_brkConstructor) {
1123 HILOG_ERROR_I18N("InitI18nBreakIterator: Failed to create brkiterator ref at init");
1124 return nullptr;
1125 }
1126 status = napi_create_reference(env, constructor, 1, g_brkConstructor);
1127 if (status != napi_ok) {
1128 HILOG_ERROR_I18N("InitI18nBreakIterator: Failed to create reference g_brkConstructor at init");
1129 return nullptr;
1130 }
1131 return exports;
1132 }
1133
InitBreakIterator(napi_env env,napi_value exports)1134 napi_value I18nAddon::InitBreakIterator(napi_env env, napi_value exports)
1135 {
1136 napi_property_descriptor properties[] = {};
1137 napi_value constructor = nullptr;
1138 napi_status status = napi_define_class(env, "I18nBreakIterator", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor,
1139 nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1140 if (status != napi_ok) {
1141 HILOG_ERROR_I18N("InitBreakIterator: Failed to define class BreakIterator.");
1142 return nullptr;
1143 }
1144 status = napi_set_named_property(env, exports, "BreakIterator", constructor);
1145 if (status != napi_ok) {
1146 HILOG_ERROR_I18N("InitBreakIterator: Set property failed When InitBreakIterator.");
1147 return nullptr;
1148 }
1149 return exports;
1150 }
1151
GetLineInstance(napi_env env,napi_callback_info info)1152 napi_value I18nAddon::GetLineInstance(napi_env env, napi_callback_info info)
1153 {
1154 size_t argc = 1;
1155 napi_value argv[1] = { nullptr };
1156 napi_value thisVar = nullptr;
1157 void *data = nullptr;
1158 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1159 napi_value constructor = nullptr;
1160 napi_status status = napi_get_reference_value(env, *g_brkConstructor, &constructor);
1161 if (status != napi_ok) {
1162 HILOG_ERROR_I18N("Failed to create reference at GetLineInstance");
1163 return nullptr;
1164 }
1165 if (!argv[0]) {
1166 return nullptr;
1167 }
1168 napi_value result = nullptr;
1169 status = napi_new_instance(env, constructor, 1, argv, &result); // 1 arguments
1170 if (status != napi_ok) {
1171 HILOG_ERROR_I18N("GetLineInstance create instance failed");
1172 return nullptr;
1173 }
1174 return result;
1175 }
1176
Current(napi_env env,napi_callback_info info)1177 napi_value I18nAddon::Current(napi_env env, napi_callback_info info)
1178 {
1179 size_t argc = 0;
1180 napi_value *argv = nullptr;
1181 napi_value thisVar = nullptr;
1182 void *data = nullptr;
1183 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1184 I18nAddon *obj = nullptr;
1185 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1186 if (status != napi_ok || !obj || !obj->brkiter_) {
1187 HILOG_ERROR_I18N("Current: Get BreakIterator object failed");
1188 return nullptr;
1189 }
1190 int value = obj->brkiter_->Current();
1191 napi_value result = nullptr;
1192 status = napi_create_int32(env, value, &result);
1193 if (status != napi_ok) {
1194 HILOG_ERROR_I18N("Current: Create int32_t value failed");
1195 return nullptr;
1196 }
1197 return result;
1198 }
1199
First(napi_env env,napi_callback_info info)1200 napi_value I18nAddon::First(napi_env env, napi_callback_info info)
1201 {
1202 size_t argc = 0;
1203 napi_value *argv = nullptr;
1204 napi_value thisVar = nullptr;
1205 void *data = nullptr;
1206 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1207 I18nAddon *obj = nullptr;
1208 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1209 if (status != napi_ok || !obj || !obj->brkiter_) {
1210 HILOG_ERROR_I18N("First: Get BreakIterator object failed");
1211 return nullptr;
1212 }
1213 int value = obj->brkiter_->First();
1214 napi_value result = nullptr;
1215 status = napi_create_int32(env, value, &result);
1216 if (status != napi_ok) {
1217 HILOG_ERROR_I18N("First: Create int32_t value failed");
1218 return nullptr;
1219 }
1220 return result;
1221 }
1222
Last(napi_env env,napi_callback_info info)1223 napi_value I18nAddon::Last(napi_env env, napi_callback_info info)
1224 {
1225 size_t argc = 0;
1226 napi_value *argv = nullptr;
1227 napi_value thisVar = nullptr;
1228 void *data = nullptr;
1229 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1230 I18nAddon *obj = nullptr;
1231 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1232 if (status != napi_ok || !obj || !obj->brkiter_) {
1233 HILOG_ERROR_I18N("Last: Get BreakIterator object failed");
1234 return nullptr;
1235 }
1236 int value = obj->brkiter_->Last();
1237 napi_value result = nullptr;
1238 status = napi_create_int32(env, value, &result);
1239 if (status != napi_ok) {
1240 HILOG_ERROR_I18N("Last: Create int32_t value failed");
1241 return nullptr;
1242 }
1243 return result;
1244 }
1245
Previous(napi_env env,napi_callback_info info)1246 napi_value I18nAddon::Previous(napi_env env, napi_callback_info info)
1247 {
1248 size_t argc = 0;
1249 napi_value *argv = nullptr;
1250 napi_value thisVar = nullptr;
1251 void *data = nullptr;
1252 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1253 I18nAddon *obj = nullptr;
1254 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1255 if (status != napi_ok || !obj || !obj->brkiter_) {
1256 HILOG_ERROR_I18N("Previous: Get BreakIterator object failed");
1257 return nullptr;
1258 }
1259 int value = obj->brkiter_->Previous();
1260 napi_value result = nullptr;
1261 status = napi_create_int32(env, value, &result);
1262 if (status != napi_ok) {
1263 HILOG_ERROR_I18N("Previous: Create int32_t value failed");
1264 return nullptr;
1265 }
1266 return result;
1267 }
1268
Next(napi_env env,napi_callback_info info)1269 napi_value I18nAddon::Next(napi_env env, napi_callback_info info)
1270 {
1271 size_t argc = 1;
1272 napi_value argv[1] = { nullptr };
1273 napi_value thisVar = nullptr;
1274 void *data = nullptr;
1275 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1276 I18nAddon *obj = nullptr;
1277 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1278 if (status != napi_ok || !obj || !obj->brkiter_) {
1279 HILOG_ERROR_I18N("Next: Get BreakIterator object failed");
1280 return nullptr;
1281 }
1282 int value = 1;
1283 if (VariableConvertor::CheckNapiIsNull(env, argv[0])) {
1284 napi_valuetype valueType = napi_valuetype::napi_undefined;
1285 napi_typeof(env, argv[0], &valueType);
1286 if (valueType != napi_valuetype::napi_number) {
1287 HILOG_ERROR_I18N("Next: Parameter type does not match");
1288 return nullptr;
1289 }
1290 status = napi_get_value_int32(env, argv[0], &value);
1291 if (status != napi_ok) {
1292 HILOG_ERROR_I18N("Next: Retrieve next value failed");
1293 return nullptr;
1294 }
1295 }
1296 value = obj->brkiter_->Next(value);
1297 napi_value result = nullptr;
1298 status = napi_create_int32(env, value, &result);
1299 if (status != napi_ok) {
1300 HILOG_ERROR_I18N("Next: Create int32_t value failed");
1301 return nullptr;
1302 }
1303 return result;
1304 }
1305
SetText(napi_env env,napi_callback_info info)1306 napi_value I18nAddon::SetText(napi_env env, napi_callback_info info)
1307 {
1308 size_t argc = 1;
1309 napi_value argv[1] = { nullptr };
1310 napi_value thisVar = nullptr;
1311 void *data = nullptr;
1312 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1313 I18nAddon *obj = nullptr;
1314 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1315 if (status != napi_ok || !obj || !obj->brkiter_) {
1316 HILOG_ERROR_I18N("SetText: Get BreakIterator object failed");
1317 return nullptr;
1318 }
1319 if (!argv[0]) {
1320 return nullptr;
1321 }
1322 napi_valuetype valueType = napi_valuetype::napi_undefined;
1323 napi_typeof(env, argv[0], &valueType);
1324 if (valueType != napi_valuetype::napi_string) {
1325 HILOG_ERROR_I18N("SetText: Parameter type does not match");
1326 return nullptr;
1327 }
1328 size_t len = 0;
1329 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1330 if (status != napi_ok) {
1331 HILOG_ERROR_I18N("SetText: Get field length failed");
1332 return nullptr;
1333 }
1334 std::vector<char> buf(len + 1);
1335 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1336 if (status != napi_ok) {
1337 HILOG_ERROR_I18N("SetText: Get string value failed");
1338 return nullptr;
1339 }
1340 obj->brkiter_->SetText(buf.data());
1341 return nullptr;
1342 }
1343
GetText(napi_env env,napi_callback_info info)1344 napi_value I18nAddon::GetText(napi_env env, napi_callback_info info)
1345 {
1346 size_t argc = 0;
1347 napi_value *argv = nullptr;
1348 napi_value thisVar = nullptr;
1349 void *data = nullptr;
1350 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1351 I18nAddon *obj = nullptr;
1352 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1353 if (status != napi_ok || !obj || !obj->brkiter_) {
1354 HILOG_ERROR_I18N("GetText: Get BreakIterator object failed");
1355 return nullptr;
1356 }
1357 napi_value value = nullptr;
1358 std::string temp;
1359 obj->brkiter_->GetText(temp);
1360 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &value);
1361 if (status != napi_ok) {
1362 HILOG_ERROR_I18N("GetText: Get field length failed");
1363 return nullptr;
1364 }
1365 return value;
1366 }
1367
Following(napi_env env,napi_callback_info info)1368 napi_value I18nAddon::Following(napi_env env, napi_callback_info info)
1369 {
1370 size_t argc = 1;
1371 napi_value argv[1] = { nullptr };
1372 napi_value thisVar = nullptr;
1373 void *data = nullptr;
1374 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1375 I18nAddon *obj = nullptr;
1376 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1377 if (status != napi_ok || !obj || !obj->brkiter_) {
1378 HILOG_ERROR_I18N("Following: Get BreakIterator object failed");
1379 return nullptr;
1380 }
1381 if (!argv[0]) {
1382 return nullptr;
1383 }
1384 napi_valuetype valueType = napi_valuetype::napi_undefined;
1385 napi_typeof(env, argv[0], &valueType);
1386 if (valueType != napi_valuetype::napi_number) {
1387 HILOG_ERROR_I18N("Following: Parameter type does not match");
1388 return nullptr;
1389 }
1390 int value;
1391 status = napi_get_value_int32(env, argv[0], &value);
1392 if (status != napi_ok) {
1393 HILOG_ERROR_I18N("Following: Retrieve following value failed");
1394 return nullptr;
1395 }
1396 value = obj->brkiter_->Following(value);
1397 napi_value result = nullptr;
1398 status = napi_create_int32(env, value, &result);
1399 if (status != napi_ok) {
1400 HILOG_ERROR_I18N("Following: Create int32_t value failed");
1401 return nullptr;
1402 }
1403 return result;
1404 }
1405
IsBoundary(napi_env env,napi_callback_info info)1406 napi_value I18nAddon::IsBoundary(napi_env env, napi_callback_info info)
1407 {
1408 size_t argc = 1;
1409 napi_value argv[1] = { nullptr };
1410 napi_value thisVar = nullptr;
1411 void *data = nullptr;
1412 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1413 I18nAddon *obj = nullptr;
1414 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1415 if (status != napi_ok || !obj || !obj->brkiter_) {
1416 HILOG_ERROR_I18N("IsBoundary: Get BreakIterator object failed");
1417 return nullptr;
1418 }
1419 if (!argv[0]) {
1420 return nullptr;
1421 }
1422 napi_valuetype valueType = napi_valuetype::napi_undefined;
1423 int value;
1424 napi_typeof(env, argv[0], &valueType);
1425 if (valueType != napi_valuetype::napi_number) {
1426 HILOG_ERROR_I18N("IsBoundary: Parameter type does not match");
1427 return nullptr;
1428 }
1429 status = napi_get_value_int32(env, argv[0], &value);
1430 if (status != napi_ok) {
1431 HILOG_ERROR_I18N("IsBoundary: Retrieve following value failed");
1432 return nullptr;
1433 }
1434 bool boundary = obj->brkiter_->IsBoundary(value);
1435 napi_value result = nullptr;
1436 status = napi_get_boolean(env, boundary, &result);
1437 if (status != napi_ok) {
1438 HILOG_ERROR_I18N("IsBoundary: Create boolean failed");
1439 return nullptr;
1440 }
1441 return result;
1442 }
1443
I18nIndexUtilConstructor(napi_env env,napi_callback_info info)1444 napi_value I18nAddon::I18nIndexUtilConstructor(napi_env env, napi_callback_info info)
1445 {
1446 size_t argc = 1;
1447 napi_value argv[1] = { nullptr };
1448 napi_value thisVar = nullptr;
1449 void *data = nullptr;
1450 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1451 if (status != napi_ok) {
1452 return nullptr;
1453 }
1454 std::string localeTag = "";
1455 if (argc > 0) {
1456 napi_valuetype valueType = napi_valuetype::napi_undefined;
1457 napi_typeof(env, argv[0], &valueType);
1458 if (valueType != napi_valuetype::napi_string) {
1459 HILOG_ERROR_I18N("IndexUtilConstructor: Parameter type does not match");
1460 return nullptr;
1461 }
1462 size_t len = 0;
1463 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1464 if (status != napi_ok) {
1465 HILOG_ERROR_I18N("IndexUtilConstructor: Get locale length failed");
1466 return nullptr;
1467 }
1468 std::vector<char> localeBuf(len + 1);
1469 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
1470 if (status != napi_ok) {
1471 HILOG_ERROR_I18N("IndexUtilConstructor: Get locale failed");
1472 return nullptr;
1473 }
1474 localeTag = localeBuf.data();
1475 }
1476 std::unique_ptr<I18nAddon> obj = nullptr;
1477 obj = std::make_unique<I18nAddon>();
1478 status =
1479 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
1480 if (status != napi_ok) {
1481 HILOG_ERROR_I18N("IndexUtilConstructor: Wrap II18nAddon failed");
1482 return nullptr;
1483 }
1484 if (!obj->InitIndexUtilContext(env, info, localeTag)) {
1485 return nullptr;
1486 }
1487 obj.release();
1488 return thisVar;
1489 }
1490
InitIndexUtilContext(napi_env env,napi_callback_info info,const std::string & localeTag)1491 bool I18nAddon::InitIndexUtilContext(napi_env env, napi_callback_info info, const std::string &localeTag)
1492 {
1493 napi_value global = nullptr;
1494 napi_status status = napi_get_global(env, &global);
1495 if (status != napi_ok) {
1496 HILOG_ERROR_I18N("InitIndexUtilContext: Get global failed");
1497 return false;
1498 }
1499 env_ = env;
1500 indexUtil_ = std::make_unique<IndexUtil>(localeTag);
1501 return indexUtil_ != nullptr;
1502 }
1503
GetIndexUtil(napi_env env,napi_callback_info info)1504 napi_value I18nAddon::GetIndexUtil(napi_env env, napi_callback_info info)
1505 {
1506 size_t argc = 1;
1507 napi_value argv[1] = { 0 };
1508 napi_value thisVar = nullptr;
1509 void *data = nullptr;
1510 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1511 napi_value constructor = nullptr;
1512 napi_status status = napi_get_reference_value(env, g_indexUtilConstructor, &constructor);
1513 if (status != napi_ok) {
1514 HILOG_ERROR_I18N("Failed to create reference at GetIndexUtil");
1515 return nullptr;
1516 }
1517 napi_value result = nullptr;
1518 if (!VariableConvertor::CheckNapiIsNull(env, argv[0])) {
1519 status = napi_new_instance(env, constructor, 0, argv, &result);
1520 } else {
1521 status = napi_new_instance(env, constructor, 1, argv, &result);
1522 }
1523 if (status != napi_ok) {
1524 HILOG_ERROR_I18N("Get calendar create instance failed");
1525 return nullptr;
1526 }
1527 return result;
1528 }
1529
GetIndexList(napi_env env,napi_callback_info info)1530 napi_value I18nAddon::GetIndexList(napi_env env, napi_callback_info info)
1531 {
1532 napi_value thisVar = nullptr;
1533 void *data = nullptr;
1534 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
1535
1536 I18nAddon *obj = nullptr;
1537 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1538 if (status != napi_ok || !obj || !obj->indexUtil_) {
1539 HILOG_ERROR_I18N("GetIndexList: GetPhoneNumberFormat object failed");
1540 return nullptr;
1541 }
1542
1543 std::vector<std::string> indexList = obj->indexUtil_->GetIndexList();
1544 napi_value result = nullptr;
1545 status = napi_create_array_with_length(env, indexList.size(), &result);
1546 if (status != napi_ok) {
1547 HILOG_ERROR_I18N("Failed to create array");
1548 return nullptr;
1549 }
1550 for (size_t i = 0; i < indexList.size(); i++) {
1551 napi_value element = nullptr;
1552 status = napi_create_string_utf8(env, indexList[i].c_str(), NAPI_AUTO_LENGTH, &element);
1553 if (status != napi_ok) {
1554 HILOG_ERROR_I18N("GetIndexList: Failed to create string item");
1555 return nullptr;
1556 }
1557 status = napi_set_element(env, result, i, element);
1558 if (status != napi_ok) {
1559 HILOG_ERROR_I18N("Failed to set array item");
1560 return nullptr;
1561 }
1562 }
1563 return result;
1564 }
1565
AddLocale(napi_env env,napi_callback_info info)1566 napi_value I18nAddon::AddLocale(napi_env env, napi_callback_info info)
1567 {
1568 size_t argc = 1;
1569 napi_value argv[1] = { 0 };
1570 napi_value thisVar = nullptr;
1571 void *data = nullptr;
1572 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1573 napi_valuetype valueType = napi_valuetype::napi_undefined;
1574 napi_typeof(env, argv[0], &valueType);
1575 if (valueType != napi_valuetype::napi_string) {
1576 HILOG_ERROR_I18N("AddLocale: Parameter type does not match");
1577 return nullptr;
1578 }
1579 size_t len = 0;
1580 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1581 if (status != napi_ok) {
1582 HILOG_ERROR_I18N("AddLocale: Get locale length failed");
1583 return nullptr;
1584 }
1585 std::vector<char> buf(len + 1);
1586 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1587 if (status != napi_ok) {
1588 HILOG_ERROR_I18N("AddLocale: Get locale failed");
1589 return nullptr;
1590 }
1591 I18nAddon *obj = nullptr;
1592 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1593 if (status != napi_ok || !obj || !obj->indexUtil_) {
1594 HILOG_ERROR_I18N("AddLocale: Get IndexUtil object failed");
1595 return nullptr;
1596 }
1597 obj->indexUtil_->AddLocale(buf.data());
1598 return nullptr;
1599 }
1600
GetIndex(napi_env env,napi_callback_info info)1601 napi_value I18nAddon::GetIndex(napi_env env, napi_callback_info info)
1602 {
1603 size_t argc = 1;
1604 napi_value argv[1] = { 0 };
1605 napi_value thisVar = nullptr;
1606 void *data = nullptr;
1607 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1608 napi_valuetype valueType = napi_valuetype::napi_undefined;
1609 napi_typeof(env, argv[0], &valueType);
1610 if (valueType != napi_valuetype::napi_string) {
1611 HILOG_ERROR_I18N("GetIndex: Parameter type does not match");
1612 return nullptr;
1613 }
1614 size_t len = 0;
1615 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1616 if (status != napi_ok) {
1617 HILOG_ERROR_I18N("GetIndex: Get String length failed");
1618 return nullptr;
1619 }
1620 std::vector<char> buf(len + 1);
1621 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1622 if (status != napi_ok) {
1623 HILOG_ERROR_I18N("Get String failed");
1624 return nullptr;
1625 }
1626 I18nAddon *obj = nullptr;
1627 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1628 if (status != napi_ok || !obj || !obj->indexUtil_) {
1629 HILOG_ERROR_I18N("GetIndex: Get IndexUtil object failed");
1630 return nullptr;
1631 }
1632 std::string index = obj->indexUtil_->GetIndex(buf.data());
1633 napi_value result = nullptr;
1634 status = napi_create_string_utf8(env, index.c_str(), NAPI_AUTO_LENGTH, &result);
1635 if (status != napi_ok) {
1636 HILOG_ERROR_I18N("GetIndex Failed");
1637 return nullptr;
1638 }
1639 return result;
1640 }
1641
ObjectConstructor(napi_env env,napi_callback_info info)1642 napi_value I18nAddon::ObjectConstructor(napi_env env, napi_callback_info info)
1643 {
1644 napi_value thisVar = nullptr;
1645 void *data = nullptr;
1646 napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
1647 if (status != napi_ok) {
1648 return nullptr;
1649 }
1650 std::unique_ptr<I18nAddon> obj = nullptr;
1651 obj = std::make_unique<I18nAddon>();
1652 status =
1653 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
1654 if (status != napi_ok) {
1655 HILOG_ERROR_I18N("ObjectConstructor: Wrap I18nAddon failed");
1656 return nullptr;
1657 }
1658 obj.release();
1659 return thisVar;
1660 }
1661
InitUtil(napi_env env,napi_value exports)1662 napi_value I18nAddon::InitUtil(napi_env env, napi_value exports)
1663 {
1664 napi_status status = napi_ok;
1665 napi_property_descriptor properties[] = {
1666 DECLARE_NAPI_FUNCTION("unitConvert", UnitConvert)
1667 };
1668
1669 napi_value constructor = nullptr;
1670 status = napi_define_class(env, "Util", NAPI_AUTO_LENGTH, ObjectConstructor, nullptr,
1671 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1672 if (status != napi_ok) {
1673 HILOG_ERROR_I18N("Define class failed when InitUtil");
1674 return nullptr;
1675 }
1676
1677 status = napi_set_named_property(env, exports, "Util", constructor);
1678 if (status != napi_ok) {
1679 HILOG_ERROR_I18N("Set property failed when InitUtil");
1680 return nullptr;
1681 }
1682 return exports;
1683 }
1684
CreateTemperatureTypeEnum(napi_env env)1685 napi_value I18nAddon::CreateTemperatureTypeEnum(napi_env env)
1686 {
1687 napi_value temperatureType = nullptr;
1688 napi_status status = napi_create_object(env, &temperatureType);
1689 if (status != napi_ok) {
1690 HILOG_ERROR_I18N("I18nAddon::CreateTemperatureTypeEnum: Create temperatureType failed.");
1691 return nullptr;
1692 }
1693 for (auto& nameToValue : EnumTemperatureType) {
1694 std::string name = nameToValue.first;
1695 int32_t value = static_cast<int32_t>(nameToValue.second);
1696 status = VariableConvertor::SetEnumValue(env, temperatureType, name, value);
1697 if (status != napi_ok) {
1698 HILOG_ERROR_I18N("I18nAddon::CreateTemperatureTypeEnum: set enum name %{public}s failed.",
1699 name.c_str());
1700 return nullptr;
1701 }
1702 }
1703 return temperatureType;
1704 }
1705
CreateWeekDayEnum(napi_env env)1706 napi_value I18nAddon::CreateWeekDayEnum(napi_env env)
1707 {
1708 napi_value weekDay = nullptr;
1709 napi_status status = napi_create_object(env, &weekDay);
1710 if (status != napi_ok) {
1711 HILOG_ERROR_I18N("I18nAddon::CreateWeekDayEnum: Create weekDay failed.");
1712 return nullptr;
1713 }
1714 for (auto& nameToValue : EnumWeekDay) {
1715 std::string name = nameToValue.first;
1716 int32_t value = static_cast<int32_t>(nameToValue.second);
1717 status = VariableConvertor::SetEnumValue(env, weekDay, name, value);
1718 if (status != napi_ok) {
1719 HILOG_ERROR_I18N("I18nAddon::CreateWeekDayEnum: set enum name %{public}s failed.",
1720 name.c_str());
1721 return nullptr;
1722 }
1723 }
1724 return weekDay;
1725 }
1726
Init(napi_env env,napi_value exports)1727 napi_value Init(napi_env env, napi_value exports)
1728 {
1729 napi_value val = I18nAddon::Init(env, exports);
1730 val = I18nAddon::InitPhoneNumberFormat(env, val);
1731 val = I18nAddon::InitI18nBreakIterator(env, val);
1732 val = I18nCalendarAddon::InitI18nCalendar(env, val);
1733 val = I18nAddon::InitI18nIndexUtil(env, val);
1734 val = I18nAddon::InitI18nUtil(env, val);
1735 val = I18nTimeZoneAddon::InitI18nTimeZone(env, val);
1736 val = I18nAddon::InitI18nTransliterator(env, val);
1737 val = I18nUnicodeAddon::InitCharacter(env, val);
1738 val = I18nUnicodeAddon::InitI18nUnicode(env, val);
1739 val = I18nAddon::InitUtil(env, val);
1740 val = I18nNormalizerAddon::InitI18nNormalizer(env, val);
1741 val = SystemLocaleManagerAddon::InitSystemLocaleManager(env, val);
1742 val = I18nSystemAddon::InitI18nSystem(env, val);
1743 val = HolidayManagerAddon::InitHolidayManager(env, val);
1744 val = EntityRecognizerAddon::InitEntityRecognizer(env, val);
1745 val = SimpleNumberFormatAddon::InitSimpleNumberFormat(env, val);
1746 val = SimpleDateTimeFormatAddon::InitSimpleDateTimeFormat(env, val);
1747 val = StyledNumberFormatAddon::InitStyledNumberFormat(env, val);
1748 return val;
1749 }
1750
1751 static napi_module g_i18nModule = {
1752 .nm_version = 1,
1753 .nm_flags = 0,
1754 .nm_filename = nullptr,
1755 .nm_register_func = Init,
1756 .nm_modname = "i18n",
1757 .nm_priv = nullptr,
1758 .reserved = { 0 }
1759 };
1760
I18nRegister()1761 extern "C" __attribute__((constructor)) void I18nRegister()
1762 {
1763 napi_module_register(&g_i18nModule);
1764 }
1765 } // namespace I18n
1766 } // namespace Global
1767 } // namespace OHOS
1768