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