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