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 <chrono>
16 #include <unordered_map>
17 #include <vector>
18
19 #include "character.h"
20 #include "hilog/log.h"
21 #include "i18n_calendar.h"
22 #include "unicode/locid.h"
23 #include "unicode/datefmt.h"
24 #include "unicode/smpdtfmt.h"
25 #include "unicode/translit.h"
26 #include "node_api.h"
27
28 #include "error_util.h"
29 #include "i18n_addon.h"
30
31 namespace OHOS {
32 namespace Global {
33 namespace I18n {
34 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001E00, "I18nJs" };
35 static thread_local napi_ref* g_constructor = nullptr;
36 static thread_local napi_ref* g_brkConstructor = nullptr;
37 static thread_local napi_ref* g_timezoneConstructor = nullptr;
38 static thread_local napi_ref g_indexUtilConstructor = nullptr;
39 static thread_local napi_ref* g_transConstructor = nullptr;
40 static std::unordered_map<std::string, UCalendarDateFields> g_fieldsMap {
41 { "era", UCAL_ERA },
42 { "year", UCAL_YEAR },
43 { "month", UCAL_MONTH },
44 { "week_of_year", UCAL_WEEK_OF_YEAR },
45 { "week_of_month", UCAL_WEEK_OF_MONTH },
46 { "date", UCAL_DATE },
47 { "day_of_year", UCAL_DAY_OF_YEAR },
48 { "day_of_week", UCAL_DAY_OF_WEEK },
49 { "day_of_week_in_month", UCAL_DAY_OF_WEEK_IN_MONTH },
50 { "ap_pm", UCAL_AM_PM },
51 { "hour", UCAL_HOUR },
52 { "hour_of_day", UCAL_HOUR_OF_DAY },
53 { "minute", UCAL_MINUTE },
54 { "second", UCAL_SECOND },
55 { "millisecond", UCAL_MILLISECOND },
56 { "zone_offset", UCAL_ZONE_OFFSET },
57 { "dst_offset", UCAL_DST_OFFSET },
58 { "year_woy", UCAL_YEAR_WOY },
59 { "dow_local", UCAL_DOW_LOCAL },
60 { "extended_year", UCAL_EXTENDED_YEAR },
61 { "julian_day", UCAL_JULIAN_DAY },
62 { "milliseconds_in_day", UCAL_MILLISECONDS_IN_DAY },
63 { "is_leap_month", UCAL_IS_LEAP_MONTH },
64 };
65 static std::unordered_map<std::string, CalendarType> g_typeMap {
66 { "buddhist", CalendarType::BUDDHIST },
67 { "chinese", CalendarType::CHINESE },
68 { "coptic", CalendarType::COPTIC },
69 { "ethiopic", CalendarType::ETHIOPIC },
70 { "hebrew", CalendarType::HEBREW },
71 { "gregory", CalendarType::GREGORY },
72 { "indian", CalendarType::INDIAN },
73 { "islamic_civil", CalendarType::ISLAMIC_CIVIL },
74 { "islamic_tbla", CalendarType::ISLAMIC_TBLA },
75 { "islamic_umalqura", CalendarType::ISLAMIC_UMALQURA },
76 { "japanese", CalendarType::JAPANESE },
77 { "persion", CalendarType::PERSIAN },
78 };
79 using namespace OHOS::HiviewDFX;
80
I18nAddon()81 I18nAddon::I18nAddon() : env_(nullptr) {}
82
~I18nAddon()83 I18nAddon::~I18nAddon()
84 {
85 }
86
Destructor(napi_env env,void * nativeObject,void * hint)87 void I18nAddon::Destructor(napi_env env, void *nativeObject, void *hint)
88 {
89 if (!nativeObject) {
90 return;
91 }
92 delete reinterpret_cast<I18nAddon *>(nativeObject);
93 nativeObject = nullptr;
94 }
95
CreateUnicodeObject(napi_env env)96 napi_value I18nAddon::CreateUnicodeObject(napi_env env)
97 {
98 napi_status status = napi_ok;
99 napi_value character = nullptr;
100 status = napi_create_object(env, &character);
101 if (status != napi_ok) {
102 HiLog::Error(LABEL, "Failed to create character object at init");
103 return nullptr;
104 }
105 napi_property_descriptor characterProperties[] = {
106 DECLARE_NAPI_FUNCTION("isDigit", IsDigitAddon),
107 DECLARE_NAPI_FUNCTION("isSpaceChar", IsSpaceCharAddon),
108 DECLARE_NAPI_FUNCTION("isWhitespace", IsWhiteSpaceAddon),
109 DECLARE_NAPI_FUNCTION("isRTL", IsRTLCharacterAddon),
110 DECLARE_NAPI_FUNCTION("isIdeograph", IsIdeoGraphicAddon),
111 DECLARE_NAPI_FUNCTION("isLetter", IsLetterAddon),
112 DECLARE_NAPI_FUNCTION("isLowerCase", IsLowerCaseAddon),
113 DECLARE_NAPI_FUNCTION("isUpperCase", IsUpperCaseAddon),
114 DECLARE_NAPI_FUNCTION("getType", GetTypeAddon),
115 };
116 status = napi_define_properties(env, character,
117 sizeof(characterProperties) / sizeof(napi_property_descriptor),
118 characterProperties);
119 if (status != napi_ok) {
120 HiLog::Error(LABEL, "Failed to set properties of character at init");
121 return nullptr;
122 }
123 return character;
124 }
125
CreateInitProperties(napi_property_descriptor * properties)126 void I18nAddon::CreateInitProperties(napi_property_descriptor *properties)
127 {
128 properties[0] = DECLARE_NAPI_FUNCTION("getSystemLanguages", GetSystemLanguages); // 0 is properties index
129 properties[1] = DECLARE_NAPI_FUNCTION("getSystemCountries", GetSystemCountries); // 1 is properties index
130 properties[2] = DECLARE_NAPI_FUNCTION("isSuggested", IsSuggested); // 2 is properties index
131 properties[3] = DECLARE_NAPI_FUNCTION("getDisplayLanguage", GetDisplayLanguage); // 3 is properties index
132 properties[4] = DECLARE_NAPI_FUNCTION("getDisplayCountry", GetDisplayCountry); // 4 is properties index
133 properties[5] = DECLARE_NAPI_FUNCTION("getSystemLanguage", GetSystemLanguage); // 5 is properties index
134 properties[6] = DECLARE_NAPI_FUNCTION("getSystemRegion", GetSystemRegion); // 6 is properties index
135 properties[7] = DECLARE_NAPI_FUNCTION("getSystemLocale", GetSystemLocale); // 7 is properties index
136 properties[8] = DECLARE_NAPI_FUNCTION("setSystemLanguage", SetSystemLanguage); // 8 is properties index
137 properties[9] = DECLARE_NAPI_FUNCTION("setSystemRegion", SetSystemRegion); // 9 is properties index
138 properties[10] = DECLARE_NAPI_FUNCTION("setSystemLocale", SetSystemLocale); // 10 is properties index
139 properties[11] = DECLARE_NAPI_FUNCTION("getCalendar", GetCalendar); // 11 is properties index
140 properties[12] = DECLARE_NAPI_FUNCTION("isRTL", IsRTL); // 12 is properties index
141 properties[14] = DECLARE_NAPI_FUNCTION("getLineInstance", GetLineInstance); // 14 is properties index
142 properties[15] = DECLARE_NAPI_FUNCTION("getInstance", GetIndexUtil); // 15 is properties index
143 properties[17] = DECLARE_NAPI_FUNCTION("addPreferredLanguage", AddPreferredLanguage); // 17 is properties index
144 // 18 is properties index
145 properties[18] = DECLARE_NAPI_FUNCTION("removePreferredLanguage", RemovePreferredLanguage);
146 // 19 is properties index
147 properties[19] = DECLARE_NAPI_FUNCTION("getPreferredLanguageList", GetPreferredLanguageList);
148 // 20 is properties index
149 properties[20] = DECLARE_NAPI_FUNCTION("getFirstPreferredLanguage", GetFirstPreferredLanguage);
150 // 21 is properties index
151 properties[21] = DECLARE_NAPI_FUNCTION("is24HourClock", Is24HourClock);
152 // 22 is properties index
153 properties[22] = DECLARE_NAPI_FUNCTION("set24HourClock", Set24HourClock);
154 // 23 is properties index
155 properties[23] = DECLARE_NAPI_FUNCTION("getTimeZone", GetI18nTimeZone);
156 // 25 is properties index
157 properties[25] = DECLARE_NAPI_FUNCTION("setUsingLocalDigit", SetUsingLocalDigitAddon);
158 // 26 is properties index
159 properties[26] = DECLARE_NAPI_FUNCTION("getUsingLocalDigit", GetUsingLocalDigitAddon);
160 // 28 is properties index
161 properties[28] = DECLARE_NAPI_FUNCTION("getAppPreferredLanguage", GetFirstPreferredLanguage);
162 }
163
Init(napi_env env,napi_value exports)164 napi_value I18nAddon::Init(napi_env env, napi_value exports)
165 {
166 napi_status status = napi_ok;
167 napi_value i18nUtil = nullptr;
168 status = napi_create_object(env, &i18nUtil);
169 if (status != napi_ok) {
170 HiLog::Error(LABEL, "Failed to create util object at init");
171 return nullptr;
172 }
173 napi_property_descriptor i18nUtilProperties[] = {
174 DECLARE_NAPI_FUNCTION("unitConvert", UnitConvert),
175 DECLARE_NAPI_FUNCTION("getDateOrder", GetDateOrder)
176 };
177 status = napi_define_properties(env, i18nUtil,
178 sizeof(i18nUtilProperties) / sizeof(napi_property_descriptor),
179 i18nUtilProperties);
180 if (status != napi_ok) {
181 HiLog::Error(LABEL, "Failed to set properties of i18nUtil at init");
182 return nullptr;
183 }
184 napi_value unicode = CreateUnicodeObject(env);
185 if (!unicode) {
186 return nullptr;
187 }
188 napi_value transliterator = CreateTransliteratorObject(env);
189 if (!transliterator) {
190 return nullptr;
191 }
192 napi_value timezone = CreateTimeZoneObject(env);
193 if (!timezone) {
194 return nullptr;
195 }
196 napi_value system = CreateSystemObject(env);
197 if (!system) {
198 return nullptr;
199 }
200 size_t propertiesNums = 30;
201 napi_property_descriptor properties[propertiesNums];
202 CreateInitProperties(properties);
203 properties[13] = DECLARE_NAPI_PROPERTY("I18NUtil", i18nUtil); // 13 is properties index
204 properties[16] = DECLARE_NAPI_PROPERTY("Unicode", unicode); // 16 is properties index
205 properties[24] = DECLARE_NAPI_PROPERTY("Transliterator", transliterator); // 24 is properties index
206 properties[27] = DECLARE_NAPI_PROPERTY("TimeZone", timezone); // 27 is properties index
207 properties[29] = DECLARE_NAPI_PROPERTY("System", system); // 29 is properties index
208 status = napi_define_properties(env, exports, propertiesNums, properties);
209 if (status != napi_ok) {
210 HiLog::Error(LABEL, "Failed to set properties at init");
211 return nullptr;
212 }
213 return exports;
214 }
215
GetOptionValue(napi_env env,napi_value options,const std::string & optionName,std::string & value)216 void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
217 std::string &value)
218 {
219 napi_value optionValue = nullptr;
220 napi_valuetype type = napi_undefined;
221 napi_status status = napi_typeof(env, options, &type);
222 if (status != napi_ok && type != napi_object) {
223 HiLog::Error(LABEL, "Get option failed, option is not an object");
224 return;
225 }
226 bool hasProperty = false;
227 napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
228 if (propStatus == napi_ok && hasProperty) {
229 status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
230 if (status == napi_ok) {
231 size_t len;
232 napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
233 std::vector<char> optionBuf(len + 1);
234 status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
235 if (status != napi_ok) {
236 HiLog::Error(LABEL, "Failed to get string item");
237 return;
238 }
239 value = optionBuf.data();
240 }
241 }
242 }
243
GetOptionMap(napi_env env,napi_value option,std::map<std::string,std::string> & map)244 void GetOptionMap(napi_env env, napi_value option, std::map<std::string, std::string> &map)
245 {
246 if (option != nullptr) {
247 size_t len;
248 napi_get_value_string_utf8(env, option, nullptr, 0, &len);
249 std::vector<char> styleBuf(len + 1);
250 napi_status status = napi_get_value_string_utf8(env, option, styleBuf.data(), len + 1, &len);
251 if (status != napi_ok) {
252 HiLog::Error(LABEL, "Failed to get string item");
253 return;
254 }
255 map.insert(std::make_pair("unitDisplay", styleBuf.data()));
256 }
257 }
258
UnitConvert(napi_env env,napi_callback_info info)259 napi_value I18nAddon::UnitConvert(napi_env env, napi_callback_info info)
260 {
261 size_t argc = 5;
262 napi_value argv[5] = { 0 };
263 napi_value thisVar = nullptr;
264 void *data = nullptr;
265 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
266 if (status != napi_ok) {
267 return nullptr;
268 }
269 std::string fromUnit;
270 GetOptionValue(env, argv[0], "unit", fromUnit);
271 std::string fromMeasSys;
272 GetOptionValue(env, argv[0], "measureSystem", fromMeasSys);
273 std::string toUnit;
274 GetOptionValue(env, argv[1], "unit", toUnit);
275 std::string toMeasSys;
276 GetOptionValue(env, argv[1], "measureSystem", toMeasSys);
277 double number = 0;
278 napi_get_value_double(env, argv[2], &number); // 2 is the index of value
279 int convertStatus = Convert(number, fromUnit, fromMeasSys, toUnit, toMeasSys);
280 size_t len;
281 napi_get_value_string_utf8(env, argv[3], nullptr, 0, &len); // 3 is the index of value
282 std::vector<char> localeBuf(len + 1);
283 // 3 is the index of value
284 status = napi_get_value_string_utf8(env, argv[3], localeBuf.data(), len + 1, &len);
285 if (status != napi_ok) {
286 return nullptr;
287 }
288 std::vector<std::string> localeTags;
289 localeTags.push_back(localeBuf.data());
290 std::map<std::string, std::string> map = {};
291 map.insert(std::make_pair("style", "unit"));
292 if (!convertStatus) {
293 map.insert(std::make_pair("unit", fromUnit));
294 } else {
295 map.insert(std::make_pair("unit", toUnit));
296 }
297 // 4 is the index of value
298 GetOptionMap(env, argv[4], map);
299 std::unique_ptr<NumberFormat> numberFmt = nullptr;
300 numberFmt = std::make_unique<NumberFormat>(localeTags, map);
301 std::string value = numberFmt->Format(number);
302 napi_value result;
303 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
304 if (status != napi_ok) {
305 HiLog::Error(LABEL, "Failed to create string item");
306 return nullptr;
307 }
308 return result;
309 }
310
GetDateOrder(napi_env env,napi_callback_info info)311 napi_value I18nAddon::GetDateOrder(napi_env env, napi_callback_info info)
312 {
313 size_t argc = 1;
314 napi_value argv[1] = { 0 };
315 napi_value thisVar = nullptr;
316 void *data = nullptr;
317 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
318 if (status != napi_ok) {
319 return nullptr;
320 }
321 size_t len = 0;
322 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
323 std::vector<char> languageBuf(len + 1);
324 status = napi_get_value_string_utf8(env, argv[0], languageBuf.data(), len + 1, &len);
325 if (status != napi_ok) {
326 HiLog::Error(LABEL, "Failed to get locale string for GetDateOrder");
327 return nullptr;
328 }
329 UErrorCode icuStatus = U_ZERO_ERROR;
330 icu::Locale locale = icu::Locale::forLanguageTag(languageBuf.data(), icuStatus);
331 if (icuStatus != U_ZERO_ERROR) {
332 HiLog::Error(LABEL, "Failed to create locale for GetDateOrder");
333 return nullptr;
334 }
335 icu::SimpleDateFormat* formatter = dynamic_cast<icu::SimpleDateFormat*>
336 (icu::DateFormat::createDateInstance(icu::DateFormat::EStyle::kDefault, locale));
337 if (icuStatus != U_ZERO_ERROR || formatter == nullptr) {
338 HiLog::Error(LABEL, "Failed to create SimpleDateFormat");
339 return nullptr;
340 }
341 std::string tempValue;
342 icu::UnicodeString unistr;
343 formatter->toPattern(unistr);
344 unistr.toUTF8String<std::string>(tempValue);
345 std::string value = ModifyOrder(tempValue);
346 napi_value result;
347 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
348 if (status != napi_ok) {
349 HiLog::Error(LABEL, "Failed to create string item");
350 return nullptr;
351 }
352 return result;
353 }
354
ModifyOrder(std::string & pattern)355 std::string I18nAddon::ModifyOrder(std::string &pattern)
356 {
357 int order[3] = { 0 }; // total 3 elements 'y', 'M'/'L', 'd'
358 int lengths[4] = { 0 }; // first elements is the currently found elememnts, thus 4 elements totally.
359 size_t len = pattern.length();
360 for (size_t i = 0; i < len; ++i) {
361 char ch = pattern[i];
362 if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) {
363 ProcessNormal(ch, order, 3, lengths, 4); // 3, 4 are lengths of these arrays
364 } else if (ch == '\'') {
365 ++i;
366 while ((i < len) && pattern[i] != '\'') {
367 ++i;
368 }
369 }
370 }
371 std::string ret;
372 for (int i = 0; i < 3; ++i) { // 3 is the size of orders
373 switch (order[i]) {
374 case 'y': {
375 if ((lengths[1] <= 0) || (lengths[1] > 6)) { // 6 is the max length of a filed
376 break;
377 }
378 ret.append(lengths[1], order[i]);
379 break;
380 }
381 case 'L': {
382 if ((lengths[2] <= 0) || (lengths[2] > 6)) { // 6 is the max length of a filed, 2 is the index
383 break;
384 }
385 ret.append(lengths[2], order[i]); // 2 is the index of 'L'
386 break;
387 }
388 case 'd': {
389 if ((lengths[3] <= 0) || (lengths[3] > 6)) { // 6 is the max length of a filed, 3 is the index
390 break;
391 }
392 ret.append(lengths[3], order[i]); // 3 is the index of 'y'
393 break;
394 }
395 default: {
396 break;
397 }
398 }
399 if ((i < 2) && (order[i] != 0)) { // 2 is the index of 'L'
400 ret.append(1, '-');
401 }
402 }
403 return ret;
404 }
405
ProcessNormal(char ch,int * order,size_t orderSize,int * lengths,size_t lengsSize)406 void I18nAddon::ProcessNormal(char ch, int *order, size_t orderSize, int *lengths, size_t lengsSize)
407 {
408 char adjust;
409 int index = -1;
410 if (ch == 'd') {
411 adjust = 'd';
412 index = 3; // 3 is the index of 'd'
413 } else if ((ch == 'L') || (ch == 'M')) {
414 adjust = 'L';
415 index = 2; // 2 is the index of 'L'
416 } else if (ch == 'y') {
417 adjust = 'y';
418 index = 1;
419 } else {
420 return;
421 }
422 if ((index < 0) || (index >= static_cast<int>(lengsSize))) {
423 return;
424 }
425 if (lengths[index] == 0) {
426 if (lengths[0] >= 3) { // 3 is the index of order
427 return;
428 }
429 order[lengths[0]] = (int) adjust;
430 ++lengths[0];
431 lengths[index] = 1;
432 } else {
433 ++lengths[index];
434 }
435 }
436
InitTransliterator(napi_env env,napi_value exports)437 napi_value I18nAddon::InitTransliterator(napi_env env, napi_value exports)
438 {
439 napi_status status = napi_ok;
440 napi_property_descriptor properties[] = {
441 DECLARE_NAPI_FUNCTION("transform", Transform),
442 };
443 napi_value constructor = nullptr;
444 status = napi_define_class(env, "Transliterator", NAPI_AUTO_LENGTH, TransliteratorConstructor, nullptr,
445 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
446 if (status != napi_ok) {
447 HiLog::Error(LABEL, "Failed to define transliterator class at Init");
448 return nullptr;
449 }
450 g_transConstructor = new (std::nothrow) napi_ref;
451 if (!g_transConstructor) {
452 HiLog::Error(LABEL, "Failed to create trans ref at init");
453 return nullptr;
454 }
455 status = napi_create_reference(env, constructor, 1, g_transConstructor);
456 if (status != napi_ok) {
457 HiLog::Error(LABEL, "Failed to create trans reference at init");
458 return nullptr;
459 }
460 return exports;
461 }
462
TransliteratorConstructor(napi_env env,napi_callback_info info)463 napi_value I18nAddon::TransliteratorConstructor(napi_env env, napi_callback_info info)
464 {
465 size_t argc = 1;
466 napi_value argv[1] = { 0 };
467 napi_value thisVar = nullptr;
468 void *data = nullptr;
469 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
470 if (status != napi_ok) {
471 return nullptr;
472 }
473 napi_valuetype valueType = napi_valuetype::napi_undefined;
474 napi_typeof(env, argv[0], &valueType);
475 if (valueType != napi_valuetype::napi_string) {
476 napi_throw_type_error(env, nullptr, "Parameter type does not match");
477 return nullptr;
478 }
479 int32_t code = 0;
480 std::string idTag = GetString(env, argv[0], code);
481 if (code) {
482 return nullptr;
483 }
484 std::unique_ptr<I18nAddon> obj = nullptr;
485 obj = std::make_unique<I18nAddon>();
486 status =
487 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
488 if (status != napi_ok) {
489 HiLog::Error(LABEL, "TransliteratorConstructor: Wrap II18nAddon failed");
490 return nullptr;
491 }
492 if (!obj->InitTransliteratorContext(env, info, idTag)) {
493 obj.release();
494 return nullptr;
495 }
496 obj.release();
497 return thisVar;
498 }
499
InitTransliteratorContext(napi_env env,napi_callback_info info,const std::string & idTag)500 bool I18nAddon::InitTransliteratorContext(napi_env env, napi_callback_info info, const std::string &idTag)
501 {
502 UErrorCode status = U_ZERO_ERROR;
503 icu::UnicodeString unistr = icu::UnicodeString::fromUTF8(idTag);
504 icu::Transliterator *trans = icu::Transliterator::createInstance(unistr, UTransDirection::UTRANS_FORWARD, status);
505 if ((status != U_ZERO_ERROR) || (trans == nullptr)) {
506 return false;
507 }
508 transliterator_ = std::unique_ptr<icu::Transliterator>(trans);
509 return transliterator_ != nullptr;
510 }
511
CreateTransliteratorObject(napi_env env)512 napi_value I18nAddon::CreateTransliteratorObject(napi_env env)
513 {
514 napi_status status = napi_ok;
515 napi_value transliterator = nullptr;
516 status = napi_create_object(env, &transliterator);
517 if (status != napi_ok) {
518 HiLog::Error(LABEL, "Failed to create transliterator object at init");
519 return nullptr;
520 }
521 napi_property_descriptor transProperties[] = {
522 DECLARE_NAPI_FUNCTION("getAvailableIDs", GetAvailableIDs),
523 DECLARE_NAPI_FUNCTION("getInstance", GetTransliteratorInstance)
524 };
525 status = napi_define_properties(env, transliterator,
526 sizeof(transProperties) / sizeof(napi_property_descriptor),
527 transProperties);
528 if (status != napi_ok) {
529 HiLog::Error(LABEL, "Failed to set properties of transliterator at init");
530 return nullptr;
531 }
532 return transliterator;
533 }
534
Transform(napi_env env,napi_callback_info info)535 napi_value I18nAddon::Transform(napi_env env, napi_callback_info info)
536 {
537 size_t argc = 1;
538 napi_value argv[1] = { nullptr };
539 napi_value thisVar = nullptr;
540 void *data = nullptr;
541 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
542 I18nAddon *obj = nullptr;
543 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
544 if (status != napi_ok || !obj || !obj->transliterator_) {
545 HiLog::Error(LABEL, "Get Transliterator object failed");
546 return nullptr;
547 }
548 if (!argv[0]) {
549 return nullptr;
550 }
551 napi_valuetype valueType = napi_valuetype::napi_undefined;
552 napi_typeof(env, argv[0], &valueType);
553 if (valueType != napi_valuetype::napi_string) {
554 napi_throw_type_error(env, nullptr, "Parameter type does not match");
555 return nullptr;
556 }
557 size_t len = 0;
558 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
559 if (status != napi_ok) {
560 HiLog::Error(LABEL, "Get field length failed");
561 return nullptr;
562 }
563 std::vector<char> buf(len + 1);
564 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
565 if (status != napi_ok) {
566 HiLog::Error(LABEL, "Get string value failed");
567 return nullptr;
568 }
569 icu::UnicodeString unistr = icu::UnicodeString::fromUTF8(buf.data());
570 obj->transliterator_->transliterate(unistr);
571 std::string temp;
572 unistr.toUTF8String(temp);
573 napi_value value;
574 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &value);
575 if (status != napi_ok) {
576 HiLog::Error(LABEL, "Get field length failed");
577 return nullptr;
578 }
579 return value;
580 }
581
GetAvailableIDs(napi_env env,napi_callback_info info)582 napi_value I18nAddon::GetAvailableIDs(napi_env env, napi_callback_info info)
583 {
584 size_t argc = 0;
585 napi_value *argv = nullptr;
586 napi_value thisVar = nullptr;
587 void *data = nullptr;
588 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
589 if (status != napi_ok) {
590 return nullptr;
591 }
592 UErrorCode icuStatus = U_ZERO_ERROR;
593 icu::StringEnumeration *strenum = icu::Transliterator::getAvailableIDs(icuStatus);
594 if (icuStatus != U_ZERO_ERROR) {
595 HiLog::Error(LABEL, "Failed to get available ids");
596 if (strenum) {
597 delete strenum;
598 }
599 return nullptr;
600 }
601
602 napi_value result = nullptr;
603 napi_create_array(env, &result);
604 uint32_t i = 0;
605 const char *temp = nullptr;
606 if (strenum == nullptr) {
607 return nullptr;
608 }
609 while ((temp = strenum->next(nullptr, icuStatus)) != nullptr) {
610 if (icuStatus != U_ZERO_ERROR) {
611 break;
612 }
613 napi_value val = nullptr;
614 napi_create_string_utf8(env, temp, strlen(temp), &val);
615 napi_set_element(env, result, i, val);
616 ++i;
617 }
618 delete strenum;
619 return result;
620 }
621
GetTransliteratorInstance(napi_env env,napi_callback_info info)622 napi_value I18nAddon::GetTransliteratorInstance(napi_env env, napi_callback_info info)
623 {
624 size_t argc = 1; // retrieve 2 arguments
625 napi_value argv[1] = { 0 };
626 napi_value thisVar = nullptr;
627 void *data = nullptr;
628 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
629 napi_value constructor = nullptr;
630 napi_status status = napi_get_reference_value(env, *g_transConstructor, &constructor);
631 if (status != napi_ok) {
632 HiLog::Error(LABEL, "Failed to create reference at GetCalendar");
633 return nullptr;
634 }
635 napi_value result = nullptr;
636 status = napi_new_instance(env, constructor, 1, argv, &result); // 2 arguments
637 if (status != napi_ok) {
638 HiLog::Error(LABEL, "Get Transliterator create instance failed");
639 return nullptr;
640 }
641 return result;
642 }
643
IsDigitAddon(napi_env env,napi_callback_info info)644 napi_value I18nAddon::IsDigitAddon(napi_env env, napi_callback_info info)
645 {
646 size_t argc = 1;
647 napi_value argv[1] = { 0 };
648 napi_value thisVar = nullptr;
649 void *data = nullptr;
650 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
651 if (status != napi_ok) {
652 return nullptr;
653 }
654 napi_valuetype valueType = napi_valuetype::napi_undefined;
655 napi_typeof(env, argv[0], &valueType);
656 if (valueType != napi_valuetype::napi_string) {
657 napi_throw_type_error(env, nullptr, "Parameter type does not match");
658 return nullptr;
659 }
660 int32_t code = 0;
661 std::string character = GetString(env, argv[0], code);
662 if (code) {
663 return nullptr;
664 }
665 bool isDigit = IsDigit(character);
666 napi_value result = nullptr;
667 status = napi_get_boolean(env, isDigit, &result);
668 if (status != napi_ok) {
669 HiLog::Error(LABEL, "Create isDigit boolean value failed");
670 return nullptr;
671 }
672 return result;
673 }
674
IsSpaceCharAddon(napi_env env,napi_callback_info info)675 napi_value I18nAddon::IsSpaceCharAddon(napi_env env, napi_callback_info info)
676 {
677 size_t argc = 1;
678 napi_value argv[1] = { 0 };
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 napi_valuetype valueType = napi_valuetype::napi_undefined;
686 napi_typeof(env, argv[0], &valueType);
687 if (valueType != napi_valuetype::napi_string) {
688 napi_throw_type_error(env, nullptr, "Parameter type does not match");
689 return nullptr;
690 }
691 int32_t code = 0;
692 std::string character = GetString(env, argv[0], code);
693 if (code) {
694 return nullptr;
695 }
696 bool isSpaceChar = IsSpaceChar(character);
697 napi_value result = nullptr;
698 status = napi_get_boolean(env, isSpaceChar, &result);
699 if (status != napi_ok) {
700 HiLog::Error(LABEL, "Create isSpaceChar boolean value failed");
701 return nullptr;
702 }
703 return result;
704 }
705
IsWhiteSpaceAddon(napi_env env,napi_callback_info info)706 napi_value I18nAddon::IsWhiteSpaceAddon(napi_env env, napi_callback_info info)
707 {
708 size_t argc = 1;
709 napi_value argv[1] = { 0 };
710 napi_value thisVar = nullptr;
711 void *data = nullptr;
712 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
713 if (status != napi_ok) {
714 return nullptr;
715 }
716 napi_valuetype valueType = napi_valuetype::napi_undefined;
717 napi_typeof(env, argv[0], &valueType);
718 if (valueType != napi_valuetype::napi_string) {
719 napi_throw_type_error(env, nullptr, "Parameter type does not match");
720 return nullptr;
721 }
722 int32_t code = 0;
723 std::string character = GetString(env, argv[0], code);
724 if (code) {
725 return nullptr;
726 }
727 bool isWhiteSpace = IsWhiteSpace(character);
728 napi_value result = nullptr;
729 status = napi_get_boolean(env, isWhiteSpace, &result);
730 if (status != napi_ok) {
731 HiLog::Error(LABEL, "Create isWhiteSpace boolean value failed");
732 return nullptr;
733 }
734 return result;
735 }
736
IsRTLCharacterAddon(napi_env env,napi_callback_info info)737 napi_value I18nAddon::IsRTLCharacterAddon(napi_env env, napi_callback_info info)
738 {
739 size_t argc = 1;
740 napi_value argv[1] = { 0 };
741 napi_value thisVar = nullptr;
742 void *data = nullptr;
743 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
744 if (status != napi_ok) {
745 return nullptr;
746 }
747 napi_valuetype valueType = napi_valuetype::napi_undefined;
748 napi_typeof(env, argv[0], &valueType);
749 if (valueType != napi_valuetype::napi_string) {
750 napi_throw_type_error(env, nullptr, "Parameter type does not match");
751 return nullptr;
752 }
753 int32_t code = 0;
754 std::string character = GetString(env, argv[0], code);
755 if (code) {
756 return nullptr;
757 }
758 bool isRTLCharacter = IsRTLCharacter(character);
759 napi_value result = nullptr;
760 status = napi_get_boolean(env, isRTLCharacter, &result);
761 if (status != napi_ok) {
762 HiLog::Error(LABEL, "Create isRTLCharacter boolean value failed");
763 return nullptr;
764 }
765 return result;
766 }
767
IsIdeoGraphicAddon(napi_env env,napi_callback_info info)768 napi_value I18nAddon::IsIdeoGraphicAddon(napi_env env, napi_callback_info info)
769 {
770 size_t argc = 1;
771 napi_value argv[1] = { 0 };
772 napi_value thisVar = nullptr;
773 void *data = nullptr;
774 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
775 if (status != napi_ok) {
776 return nullptr;
777 }
778 napi_valuetype valueType = napi_valuetype::napi_undefined;
779 napi_typeof(env, argv[0], &valueType);
780 if (valueType != napi_valuetype::napi_string) {
781 napi_throw_type_error(env, nullptr, "Parameter type does not match");
782 return nullptr;
783 }
784 int32_t code = 0;
785 std::string character = GetString(env, argv[0], code);
786 if (code) {
787 return nullptr;
788 }
789 bool isIdeoGraphic = IsIdeoGraphic(character);
790 napi_value result = nullptr;
791 status = napi_get_boolean(env, isIdeoGraphic, &result);
792 if (status != napi_ok) {
793 HiLog::Error(LABEL, "Create isIdeoGraphic boolean value failed");
794 return nullptr;
795 }
796 return result;
797 }
798
IsLetterAddon(napi_env env,napi_callback_info info)799 napi_value I18nAddon::IsLetterAddon(napi_env env, napi_callback_info info)
800 {
801 size_t argc = 1;
802 napi_value argv[1] = { 0 };
803 napi_value thisVar = nullptr;
804 void *data = nullptr;
805 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
806 if (status != napi_ok) {
807 return nullptr;
808 }
809 napi_valuetype valueType = napi_valuetype::napi_undefined;
810 napi_typeof(env, argv[0], &valueType);
811 if (valueType != napi_valuetype::napi_string) {
812 napi_throw_type_error(env, nullptr, "Parameter type does not match");
813 return nullptr;
814 }
815 int32_t code = 0;
816 std::string character = GetString(env, argv[0], code);
817 if (code) {
818 return nullptr;
819 }
820 bool isLetter = IsLetter(character);
821 napi_value result = nullptr;
822 status = napi_get_boolean(env, isLetter, &result);
823 if (status != napi_ok) {
824 HiLog::Error(LABEL, "Create isLetter boolean value failed");
825 return nullptr;
826 }
827 return result;
828 }
829
IsLowerCaseAddon(napi_env env,napi_callback_info info)830 napi_value I18nAddon::IsLowerCaseAddon(napi_env env, napi_callback_info info)
831 {
832 size_t argc = 1;
833 napi_value argv[1] = { 0 };
834 napi_value thisVar = nullptr;
835 void *data = nullptr;
836 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
837 if (status != napi_ok) {
838 return nullptr;
839 }
840 napi_valuetype valueType = napi_valuetype::napi_undefined;
841 napi_typeof(env, argv[0], &valueType);
842 if (valueType != napi_valuetype::napi_string) {
843 napi_throw_type_error(env, nullptr, "Parameter type does not match");
844 return nullptr;
845 }
846 int32_t code = 0;
847 std::string character = GetString(env, argv[0], code);
848 if (code) {
849 return nullptr;
850 }
851 bool isLowerCase = IsLowerCase(character);
852 napi_value result = nullptr;
853 status = napi_get_boolean(env, isLowerCase, &result);
854 if (status != napi_ok) {
855 HiLog::Error(LABEL, "Create isLowerCase boolean value failed");
856 return nullptr;
857 }
858 return result;
859 }
860
IsUpperCaseAddon(napi_env env,napi_callback_info info)861 napi_value I18nAddon::IsUpperCaseAddon(napi_env env, napi_callback_info info)
862 {
863 size_t argc = 1;
864 napi_value argv[1] = { 0 };
865 napi_value thisVar = nullptr;
866 void *data = nullptr;
867 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
868 if (status != napi_ok) {
869 return nullptr;
870 }
871 napi_valuetype valueType = napi_valuetype::napi_undefined;
872 napi_typeof(env, argv[0], &valueType);
873 if (valueType != napi_valuetype::napi_string) {
874 napi_throw_type_error(env, nullptr, "Parameter type does not match");
875 return nullptr;
876 }
877 int32_t code = 0;
878 std::string character = GetString(env, argv[0], code);
879 if (code) {
880 return nullptr;
881 }
882 bool isUpperCase = IsUpperCase(character);
883 napi_value result = nullptr;
884 status = napi_get_boolean(env, isUpperCase, &result);
885 if (status != napi_ok) {
886 HiLog::Error(LABEL, "Create isUpperCase boolean value failed");
887 return nullptr;
888 }
889 return result;
890 }
891
GetTypeAddon(napi_env env,napi_callback_info info)892 napi_value I18nAddon::GetTypeAddon(napi_env env, napi_callback_info info)
893 {
894 size_t argc = 1;
895 napi_value argv[1] = { 0 };
896 napi_value thisVar = nullptr;
897 void *data = nullptr;
898 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
899 if (status != napi_ok) {
900 return nullptr;
901 }
902 napi_valuetype valueType = napi_valuetype::napi_undefined;
903 napi_typeof(env, argv[0], &valueType);
904 if (valueType != napi_valuetype::napi_string) {
905 napi_throw_type_error(env, nullptr, "Parameter type does not match");
906 return nullptr;
907 }
908 int32_t code = 0;
909 std::string character = GetString(env, argv[0], code);
910 if (code) {
911 return nullptr;
912 }
913 std::string type = GetType(character);
914 napi_value result = nullptr;
915 status = napi_create_string_utf8(env, type.c_str(), NAPI_AUTO_LENGTH, &result);
916 if (status != napi_ok) {
917 HiLog::Error(LABEL, "Create getType string value failed");
918 return nullptr;
919 }
920 return result;
921 }
922
GetSystemLanguages(napi_env env,napi_callback_info info)923 napi_value I18nAddon::GetSystemLanguages(napi_env env, napi_callback_info info)
924 {
925 std::vector<std::string> systemLanguages;
926 LocaleConfig::GetSystemLanguages(systemLanguages);
927 napi_value result = nullptr;
928 napi_status status = napi_create_array_with_length(env, systemLanguages.size(), &result);
929 if (status != napi_ok) {
930 HiLog::Error(LABEL, "Failed to create array");
931 return nullptr;
932 }
933 for (size_t i = 0; i < systemLanguages.size(); i++) {
934 napi_value value = nullptr;
935 status = napi_create_string_utf8(env, systemLanguages[i].c_str(), NAPI_AUTO_LENGTH, &value);
936 if (status != napi_ok) {
937 HiLog::Error(LABEL, "GetSystemLanguages: Failed to create string item");
938 return nullptr;
939 }
940 status = napi_set_element(env, result, i, value);
941 if (status != napi_ok) {
942 HiLog::Error(LABEL, "GetSystemLanguages: Failed to set array item");
943 return nullptr;
944 }
945 }
946 return result;
947 }
948
GetSystemCountries(napi_env env,napi_callback_info info)949 napi_value I18nAddon::GetSystemCountries(napi_env env, napi_callback_info info)
950 {
951 return I18nAddon::GetSystemCountriesImpl(env, info, false);
952 }
953
GetSystemCountriesWithError(napi_env env,napi_callback_info info)954 napi_value I18nAddon::GetSystemCountriesWithError(napi_env env, napi_callback_info info)
955 {
956 return I18nAddon::GetSystemCountriesImpl(env, info, true);
957 }
958
GetSystemCountriesImpl(napi_env env,napi_callback_info info,bool throwError)959 napi_value I18nAddon::GetSystemCountriesImpl(napi_env env, napi_callback_info info, bool throwError)
960 {
961 size_t argc = 1;
962 napi_value argv[1] = { 0 };
963 napi_value thisVar = nullptr;
964 void *data = nullptr;
965 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
966 if (status != napi_ok) {
967 return nullptr;
968 }
969 if (argv[0] == nullptr) {
970 HiLog::Error(LABEL, "Missing parameter");
971 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
972 return nullptr;
973 }
974 size_t len = 0;
975 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
976 std::vector<char> localeBuf(len + 1);
977 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
978 if (status != napi_ok) {
979 HiLog::Error(LABEL, "Failed to get string item");
980 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
981 return nullptr;
982 }
983 std::vector<std::string> systemCountries;
984 LocaleConfig::GetSystemCountries(systemCountries);
985 napi_value result = nullptr;
986 status = napi_create_array_with_length(env, systemCountries.size(), &result);
987 if (status != napi_ok) {
988 HiLog::Error(LABEL, "Failed to create array");
989 return nullptr;
990 }
991 for (size_t i = 0; i < systemCountries.size(); i++) {
992 napi_value value = nullptr;
993 status = napi_create_string_utf8(env, systemCountries[i].c_str(), NAPI_AUTO_LENGTH, &value);
994 if (status != napi_ok) {
995 HiLog::Error(LABEL, "GetSystemCountries: Failed to create string item");
996 return nullptr;
997 }
998 status = napi_set_element(env, result, i, value);
999 if (status != napi_ok) {
1000 HiLog::Error(LABEL, "GetSystemCountries: Failed to set array item");
1001 return nullptr;
1002 }
1003 }
1004 return result;
1005 }
1006
GetSystemLanguage(napi_env env,napi_callback_info info)1007 napi_value I18nAddon::GetSystemLanguage(napi_env env, napi_callback_info info)
1008 {
1009 std::string value = LocaleConfig::GetSystemLanguage();
1010 napi_value result = nullptr;
1011 napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
1012 if (status != napi_ok) {
1013 HiLog::Error(LABEL, "Failed to create string item");
1014 return nullptr;
1015 }
1016 return result;
1017 }
1018
GetSystemRegion(napi_env env,napi_callback_info info)1019 napi_value I18nAddon::GetSystemRegion(napi_env env, napi_callback_info info)
1020 {
1021 std::string value = LocaleConfig::GetSystemRegion();
1022 napi_value result = nullptr;
1023 napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
1024 if (status != napi_ok) {
1025 HiLog::Error(LABEL, "Failed to create string item");
1026 return nullptr;
1027 }
1028 return result;
1029 }
1030
GetSystemLocale(napi_env env,napi_callback_info info)1031 napi_value I18nAddon::GetSystemLocale(napi_env env, napi_callback_info info)
1032 {
1033 std::string value = LocaleConfig::GetSystemLocale();
1034 napi_value result = nullptr;
1035 napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
1036 if (status != napi_ok) {
1037 HiLog::Error(LABEL, "Failed to create string item");
1038 return nullptr;
1039 }
1040 return result;
1041 }
1042
GetDisplayLanguage(napi_env env,napi_callback_info info)1043 napi_value I18nAddon::GetDisplayLanguage(napi_env env, napi_callback_info info)
1044 {
1045 return I18nAddon::GetDisplayLanguageImpl(env, info, false);
1046 }
1047
GetDisplayLanguageWithError(napi_env env,napi_callback_info info)1048 napi_value I18nAddon::GetDisplayLanguageWithError(napi_env env, napi_callback_info info)
1049 {
1050 return I18nAddon::GetDisplayLanguageImpl(env, info, true);
1051 }
1052
GetDisplayLanguageImpl(napi_env env,napi_callback_info info,bool throwError)1053 napi_value I18nAddon::GetDisplayLanguageImpl(napi_env env, napi_callback_info info, bool throwError)
1054 {
1055 // Need to get three parameters to get the display Language.
1056 size_t argc = 3;
1057 napi_value argv[3] = { 0 };
1058 napi_value thisVar = nullptr;
1059 void *data = nullptr;
1060 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1061 if (status != napi_ok) {
1062 return nullptr;
1063 }
1064 if (argv[1] == nullptr) {
1065 HiLog::Error(LABEL, "Missing parameter");
1066 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
1067 return nullptr;
1068 }
1069 size_t len = 0;
1070 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1071 std::vector<char> localeBuf(len + 1);
1072 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
1073 if (status != napi_ok) {
1074 HiLog::Error(LABEL, "Failed to get string item");
1075 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1076 return nullptr;
1077 }
1078 napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
1079 std::vector<char> displayLocaleBuf(len + 1);
1080 status = napi_get_value_string_utf8(env, argv[1], displayLocaleBuf.data(), len + 1, &len);
1081 if (status != napi_ok) {
1082 HiLog::Error(LABEL, "Failed to get string item");
1083 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1084 return nullptr;
1085 }
1086 bool sentenceCase = true;
1087 int sentenceCaseIndex = 2;
1088 if (argv[sentenceCaseIndex] != nullptr) {
1089 napi_get_value_bool(env, argv[sentenceCaseIndex], &sentenceCase);
1090 }
1091
1092 std::string value = LocaleConfig::GetDisplayLanguage(localeBuf.data(), displayLocaleBuf.data(), sentenceCase);
1093 if (value.length() == 0) {
1094 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1095 }
1096 napi_value result = nullptr;
1097 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
1098 if (status != napi_ok) {
1099 HiLog::Error(LABEL, "Failed to create string item");
1100 return nullptr;
1101 }
1102 return result;
1103 }
1104
GetDisplayCountry(napi_env env,napi_callback_info info)1105 napi_value I18nAddon::GetDisplayCountry(napi_env env, napi_callback_info info)
1106 {
1107 return I18nAddon::GetDisplayCountryImpl(env, info, false);
1108 }
1109
GetDisplayCountryWithError(napi_env env,napi_callback_info info)1110 napi_value I18nAddon::GetDisplayCountryWithError(napi_env env, napi_callback_info info)
1111 {
1112 return I18nAddon::GetDisplayCountryImpl(env, info, true);
1113 }
1114
GetDisplayCountryImpl(napi_env env,napi_callback_info info,bool throwError)1115 napi_value I18nAddon::GetDisplayCountryImpl(napi_env env, napi_callback_info info, bool throwError)
1116 {
1117 // Need to get three parameters to get the display country.
1118 size_t argc = 3;
1119 napi_value argv[3] = { 0 };
1120 napi_value thisVar = nullptr;
1121 void *data = nullptr;
1122 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1123 if (status != napi_ok) {
1124 return nullptr;
1125 }
1126 if (argv[1] == nullptr) {
1127 HiLog::Error(LABEL, "Missing parameter");
1128 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
1129 return nullptr;
1130 }
1131 size_t len = 0;
1132 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1133 std::vector<char> localeBuf(len + 1);
1134 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
1135 if (status != napi_ok) {
1136 HiLog::Error(LABEL, "Failed to get string item");
1137 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1138 return nullptr;
1139 }
1140 napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
1141 std::vector<char> displayLocaleBuf(len + 1);
1142 status = napi_get_value_string_utf8(env, argv[1], displayLocaleBuf.data(), len + 1, &len);
1143 if (status != napi_ok) {
1144 HiLog::Error(LABEL, "Failed to get string item");
1145 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1146 return nullptr;
1147 }
1148 bool sentenceCase = true;
1149 int sentenceCaseIndex = 2;
1150 if (argv[sentenceCaseIndex] != nullptr) {
1151 napi_get_value_bool(env, argv[sentenceCaseIndex], &sentenceCase);
1152 }
1153 std::string value = LocaleConfig::GetDisplayRegion(localeBuf.data(), displayLocaleBuf.data(), sentenceCase);
1154 if (value.length() == 0) {
1155 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1156 }
1157 napi_value result = nullptr;
1158 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
1159 if (status != napi_ok) {
1160 HiLog::Error(LABEL, "Failed to create string item");
1161 return nullptr;
1162 }
1163 return result;
1164 }
1165
IsSuggested(napi_env env,napi_callback_info info)1166 napi_value I18nAddon::IsSuggested(napi_env env, napi_callback_info info)
1167 {
1168 return I18nAddon::IsSuggestedImpl(env, info, false);
1169 }
1170
IsSuggestedWithError(napi_env env,napi_callback_info info)1171 napi_value I18nAddon::IsSuggestedWithError(napi_env env, napi_callback_info info)
1172 {
1173 return I18nAddon::IsSuggestedImpl(env, info, true);
1174 }
1175
IsSuggestedImpl(napi_env env,napi_callback_info info,bool throwError)1176 napi_value I18nAddon::IsSuggestedImpl(napi_env env, napi_callback_info info, bool throwError)
1177 {
1178 // Need to get two parameters to check is suggested or not.
1179 size_t argc = 2;
1180 napi_value argv[2] = { 0 };
1181 napi_value thisVar = nullptr;
1182 void *data = nullptr;
1183 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1184 if (status != napi_ok) {
1185 return nullptr;
1186 }
1187 if (argv[0] == nullptr) {
1188 HiLog::Error(LABEL, "Missing parameter");
1189 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
1190 return nullptr;
1191 }
1192 size_t len = 0;
1193 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1194 std::vector<char> languageBuf(len + 1);
1195 status = napi_get_value_string_utf8(env, argv[0], languageBuf.data(), len + 1, &len);
1196 if (status != napi_ok) {
1197 HiLog::Error(LABEL, "Failed to get string item");
1198 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1199 return nullptr;
1200 }
1201 bool isSuggested = false;
1202 if (argv[1] != nullptr) {
1203 napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
1204 std::vector<char> regionBuf(len + 1);
1205 status = napi_get_value_string_utf8(env, argv[1], regionBuf.data(), len + 1, &len);
1206 if (status != napi_ok) {
1207 HiLog::Error(LABEL, "Failed to get string item");
1208 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1209 return nullptr;
1210 }
1211 isSuggested = LocaleConfig::IsSuggested(languageBuf.data(), regionBuf.data());
1212 } else {
1213 isSuggested = LocaleConfig::IsSuggested(languageBuf.data());
1214 }
1215 napi_value result = nullptr;
1216 status = napi_get_boolean(env, isSuggested, &result);
1217 if (status != napi_ok) {
1218 HiLog::Error(LABEL, "Create case first boolean value failed");
1219 return nullptr;
1220 }
1221 return result;
1222 }
1223
SetSystemLanguage(napi_env env,napi_callback_info info)1224 napi_value I18nAddon::SetSystemLanguage(napi_env env, napi_callback_info info)
1225 {
1226 return I18nAddon::SetSystemLanguageImpl(env, info, false);
1227 }
1228
SetSystemLanguageWithError(napi_env env,napi_callback_info info)1229 napi_value I18nAddon::SetSystemLanguageWithError(napi_env env, napi_callback_info info)
1230 {
1231 return I18nAddon::SetSystemLanguageImpl(env, info, true);
1232 }
1233
SetSystemLanguageImpl(napi_env env,napi_callback_info info,bool throwError)1234 napi_value I18nAddon::SetSystemLanguageImpl(napi_env env, napi_callback_info info, bool throwError)
1235 {
1236 size_t argc = 1;
1237 napi_value argv[1] = { 0 };
1238 napi_value thisVar = nullptr;
1239 void *data = nullptr;
1240 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1241 if (status != napi_ok) {
1242 return nullptr;
1243 }
1244 if (argv[0] == nullptr) {
1245 HiLog::Error(LABEL, "Missing parameter");
1246 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
1247 return nullptr;
1248 }
1249 size_t len = 0;
1250 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1251 std::vector<char> languageBuf(len + 1);
1252 status = napi_get_value_string_utf8(env, argv[0], languageBuf.data(), len + 1, &len);
1253 if (status != napi_ok) {
1254 HiLog::Error(LABEL, "Failed to get string item");
1255 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1256 return nullptr;
1257 }
1258 bool success = LocaleConfig::SetSystemLanguage(languageBuf.data());
1259 if (throwError) {
1260 if (!success) {
1261 ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, throwError);
1262 }
1263 return nullptr;
1264 }
1265 napi_value result = nullptr;
1266 status = napi_get_boolean(env, success, &result);
1267 if (status != napi_ok) {
1268 HiLog::Error(LABEL, "Create set system language boolean value failed");
1269 return nullptr;
1270 }
1271 return result;
1272 }
1273
SetSystemRegion(napi_env env,napi_callback_info info)1274 napi_value I18nAddon::SetSystemRegion(napi_env env, napi_callback_info info)
1275 {
1276 return I18nAddon::SetSystemRegionImpl(env, info, false);
1277 }
1278
SetSystemRegionWithError(napi_env env,napi_callback_info info)1279 napi_value I18nAddon::SetSystemRegionWithError(napi_env env, napi_callback_info info)
1280 {
1281 return I18nAddon::SetSystemRegionImpl(env, info, true);
1282 }
1283
SetSystemRegionImpl(napi_env env,napi_callback_info info,bool throwError)1284 napi_value I18nAddon::SetSystemRegionImpl(napi_env env, napi_callback_info info, bool throwError)
1285 {
1286 size_t argc = 1;
1287 napi_value argv[1] = { 0 };
1288 napi_value thisVar = nullptr;
1289 void *data = nullptr;
1290 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1291 if (status != napi_ok) {
1292 return nullptr;
1293 }
1294 if (argv[0] == nullptr) {
1295 HiLog::Error(LABEL, "Missing parameter");
1296 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
1297 return nullptr;
1298 }
1299 size_t len = 0;
1300 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1301 std::vector<char> regionBuf(len + 1);
1302 status = napi_get_value_string_utf8(env, argv[0], regionBuf.data(), len + 1, &len);
1303 if (status != napi_ok) {
1304 HiLog::Error(LABEL, "Failed to get string item");
1305 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1306 return nullptr;
1307 }
1308 bool success = LocaleConfig::SetSystemRegion(regionBuf.data());
1309 if (throwError) {
1310 if (!success) {
1311 ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, throwError);
1312 }
1313 return nullptr;
1314 }
1315 napi_value result = nullptr;
1316 status = napi_get_boolean(env, success, &result);
1317 if (status != napi_ok) {
1318 HiLog::Error(LABEL, "Create set system language boolean value failed");
1319 return nullptr;
1320 }
1321 return result;
1322 }
1323
SetSystemLocale(napi_env env,napi_callback_info info)1324 napi_value I18nAddon::SetSystemLocale(napi_env env, napi_callback_info info)
1325 {
1326 return I18nAddon::SetSystemLocaleImpl(env, info, false);
1327 }
1328
SetSystemLocaleWithError(napi_env env,napi_callback_info info)1329 napi_value I18nAddon::SetSystemLocaleWithError(napi_env env, napi_callback_info info)
1330 {
1331 return I18nAddon::SetSystemLocaleImpl(env, info, true);
1332 }
1333
SetSystemLocaleImpl(napi_env env,napi_callback_info info,bool throwError)1334 napi_value I18nAddon::SetSystemLocaleImpl(napi_env env, napi_callback_info info, bool throwError)
1335 {
1336 size_t argc = 1;
1337 napi_value argv[1] = { 0 };
1338 napi_value thisVar = nullptr;
1339 void *data = nullptr;
1340 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1341 if (status != napi_ok) {
1342 return nullptr;
1343 }
1344 if (argv[0] == nullptr) {
1345 HiLog::Error(LABEL, "Missing parameter");
1346 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
1347 return nullptr;
1348 }
1349 size_t len = 0;
1350 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1351 std::vector<char> localeBuf(len + 1);
1352 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
1353 if (status != napi_ok) {
1354 HiLog::Error(LABEL, "Failed to get string item");
1355 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
1356 return nullptr;
1357 }
1358 bool success = LocaleConfig::SetSystemLocale(localeBuf.data());
1359 if (throwError) {
1360 if (!success) {
1361 ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, throwError);
1362 }
1363 return nullptr;
1364 }
1365 napi_value result = nullptr;
1366 status = napi_get_boolean(env, success, &result);
1367 if (status != napi_ok) {
1368 HiLog::Error(LABEL, "Create set system language boolean value failed");
1369 return nullptr;
1370 }
1371 return result;
1372 }
1373
IsRTL(napi_env env,napi_callback_info info)1374 napi_value I18nAddon::IsRTL(napi_env env, napi_callback_info info)
1375 {
1376 size_t argc = 1;
1377 napi_value argv[1] = { 0 };
1378 napi_value thisVar = nullptr;
1379 void *data = nullptr;
1380 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1381 if (status != napi_ok) {
1382 return nullptr;
1383 }
1384 size_t len = 0;
1385 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1386 std::vector<char> localeBuf(len + 1);
1387 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
1388 if (status != napi_ok) {
1389 HiLog::Error(LABEL, "Failed to get string item");
1390 return nullptr;
1391 }
1392 bool isRTL = LocaleConfig::IsRTL(localeBuf.data());
1393 napi_value result = nullptr;
1394 status = napi_get_boolean(env, isRTL, &result);
1395 if (status != napi_ok) {
1396 HiLog::Error(LABEL, "IsRTL failed");
1397 return nullptr;
1398 }
1399 return result;
1400 }
1401
InitPhoneNumberFormat(napi_env env,napi_value exports)1402 napi_value I18nAddon::InitPhoneNumberFormat(napi_env env, napi_value exports)
1403 {
1404 napi_status status = napi_ok;
1405 napi_property_descriptor properties[] = {
1406 DECLARE_NAPI_FUNCTION("isValidNumber", IsValidPhoneNumber),
1407 DECLARE_NAPI_FUNCTION("format", FormatPhoneNumber),
1408 DECLARE_NAPI_FUNCTION("getLocationName", GetLocationName)
1409 };
1410
1411 napi_value constructor;
1412 status = napi_define_class(env, "PhoneNumberFormat", NAPI_AUTO_LENGTH, PhoneNumberFormatConstructor, nullptr,
1413 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1414 if (status != napi_ok) {
1415 HiLog::Error(LABEL, "Define class failed when InitPhoneNumberFormat");
1416 return nullptr;
1417 }
1418
1419 status = napi_set_named_property(env, exports, "PhoneNumberFormat", constructor);
1420 if (status != napi_ok) {
1421 HiLog::Error(LABEL, "Set property failed when InitPhoneNumberFormat");
1422 return nullptr;
1423 }
1424 return exports;
1425 }
1426
GetOptionValue(napi_env env,napi_value options,const std::string & optionName,std::map<std::string,std::string> & map)1427 void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
1428 std::map<std::string, std::string> &map)
1429 {
1430 napi_value optionValue = nullptr;
1431 napi_valuetype type = napi_undefined;
1432 napi_status status = napi_typeof(env, options, &type);
1433 if (status != napi_ok && type != napi_object) {
1434 HiLog::Error(LABEL, "Get option failed, option is not an object");
1435 return;
1436 }
1437 bool hasProperty = false;
1438 napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
1439 if (propStatus == napi_ok && hasProperty) {
1440 status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
1441 if (status == napi_ok) {
1442 size_t len = 0;
1443 napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
1444 std::vector<char> optionBuf(len + 1);
1445 status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
1446 if (status != napi_ok) {
1447 return;
1448 }
1449 map.insert(make_pair(optionName, optionBuf.data()));
1450 }
1451 }
1452 }
1453
PhoneNumberFormatConstructor(napi_env env,napi_callback_info info)1454 napi_value I18nAddon::PhoneNumberFormatConstructor(napi_env env, napi_callback_info info)
1455 {
1456 size_t argc = 2;
1457 napi_value argv[2] = { 0 };
1458 napi_value thisVar = nullptr;
1459 void *data = nullptr;
1460 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1461 if (status != napi_ok) {
1462 return nullptr;
1463 }
1464 napi_valuetype valueType = napi_valuetype::napi_undefined;
1465 napi_typeof(env, argv[0], &valueType);
1466 if (valueType != napi_valuetype::napi_string) {
1467 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1468 return nullptr;
1469 }
1470 size_t len = 0;
1471 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1472 if (status != napi_ok) {
1473 HiLog::Error(LABEL, "Get country tag length failed");
1474 return nullptr;
1475 }
1476 std::vector<char> country (len + 1);
1477 status = napi_get_value_string_utf8(env, argv[0], country.data(), len + 1, &len);
1478 if (status != napi_ok) {
1479 HiLog::Error(LABEL, "Get country tag failed");
1480 return nullptr;
1481 }
1482 std::map<std::string, std::string> options;
1483 GetOptionValue(env, argv[1], "type", options);
1484 std::unique_ptr<I18nAddon> obj = nullptr;
1485 obj = std::make_unique<I18nAddon>();
1486 status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
1487 I18nAddon::Destructor, nullptr, nullptr);
1488 if (status != napi_ok) {
1489 HiLog::Error(LABEL, "Wrap I18nAddon failed");
1490 return nullptr;
1491 }
1492 if (!obj->InitPhoneNumberFormatContext(env, info, country.data(), options)) {
1493 return nullptr;
1494 }
1495 obj.release();
1496 return thisVar;
1497 }
1498
InitPhoneNumberFormatContext(napi_env env,napi_callback_info info,const std::string & country,const std::map<std::string,std::string> & options)1499 bool I18nAddon::InitPhoneNumberFormatContext(napi_env env, napi_callback_info info, const std::string &country,
1500 const std::map<std::string, std::string> &options)
1501 {
1502 napi_value global = nullptr;
1503 napi_status status = napi_get_global(env, &global);
1504 if (status != napi_ok) {
1505 HiLog::Error(LABEL, "Get global failed");
1506 return false;
1507 }
1508 env_ = env;
1509 phonenumberfmt_ = PhoneNumberFormat::CreateInstance(country, options);
1510
1511 return phonenumberfmt_ != nullptr;
1512 }
1513
IsValidPhoneNumber(napi_env env,napi_callback_info info)1514 napi_value I18nAddon::IsValidPhoneNumber(napi_env env, napi_callback_info info)
1515 {
1516 size_t argc = 1;
1517 napi_value argv[1] = { 0 };
1518 napi_value thisVar = nullptr;
1519 void *data = nullptr;
1520 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1521 napi_valuetype valueType = napi_valuetype::napi_undefined;
1522 napi_typeof(env, argv[0], &valueType);
1523 if (valueType != napi_valuetype::napi_string) {
1524 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1525 return nullptr;
1526 }
1527
1528 size_t len = 0;
1529 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1530 if (status != napi_ok) {
1531 HiLog::Error(LABEL, "Get phone number length failed");
1532 return nullptr;
1533 }
1534 std::vector<char> buf(len + 1);
1535 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1536 if (status != napi_ok) {
1537 HiLog::Error(LABEL, "Get phone number failed");
1538 return nullptr;
1539 }
1540
1541 I18nAddon *obj = nullptr;
1542 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1543 if (status != napi_ok || !obj || !obj->phonenumberfmt_) {
1544 HiLog::Error(LABEL, "GetPhoneNumberFormat object failed");
1545 return nullptr;
1546 }
1547
1548 bool isValid = obj->phonenumberfmt_->isValidPhoneNumber(buf.data());
1549
1550 napi_value result = nullptr;
1551 status = napi_get_boolean(env, isValid, &result);
1552 if (status != napi_ok) {
1553 HiLog::Error(LABEL, "Create boolean failed");
1554 return nullptr;
1555 }
1556
1557 return result;
1558 }
1559
GetLocationName(napi_env env,napi_callback_info info)1560 napi_value I18nAddon::GetLocationName(napi_env env, napi_callback_info info)
1561 {
1562 size_t argc = 2;
1563 napi_value argv[2] = {0, 0};
1564 napi_value thisVar = nullptr;
1565 void *data = nullptr;
1566 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1567
1568 int32_t code = 0;
1569 std::string number = GetString(env, argv[0], code);
1570 if (code) {
1571 return nullptr;
1572 }
1573 std::string language = GetString(env, argv[1], code);
1574 if (code) {
1575 return nullptr;
1576 }
1577
1578 I18nAddon *obj = nullptr;
1579 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1580 if (status != napi_ok || !obj || !obj->phonenumberfmt_) {
1581 HiLog::Error(LABEL, "GetPhoneNumberFormat object failed");
1582 return nullptr;
1583 }
1584
1585 std::string resStr = obj->phonenumberfmt_->getLocationName(number.data(), language.data());
1586 napi_value result = nullptr;
1587 status = napi_create_string_utf8(env, resStr.c_str(), NAPI_AUTO_LENGTH, &result);
1588 if (status != napi_ok) {
1589 HiLog::Error(LABEL, "Create result string failed");
1590 return nullptr;
1591 }
1592
1593 return result;
1594 }
1595
FormatPhoneNumber(napi_env env,napi_callback_info info)1596 napi_value I18nAddon::FormatPhoneNumber(napi_env env, napi_callback_info info)
1597 {
1598 size_t argc = 1;
1599 napi_value argv[1] = { 0 };
1600 napi_value thisVar = nullptr;
1601 void *data = nullptr;
1602 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1603 napi_valuetype valueType = napi_valuetype::napi_undefined;
1604 napi_typeof(env, argv[0], &valueType);
1605 if (valueType != napi_valuetype::napi_string) {
1606 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1607 return nullptr;
1608 }
1609
1610 size_t len = 0;
1611 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1612 if (status != napi_ok) {
1613 HiLog::Error(LABEL, "Get phone number length failed");
1614 return nullptr;
1615 }
1616 std::vector<char> buf(len + 1);
1617 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1618 if (status != napi_ok) {
1619 HiLog::Error(LABEL, "Get phone number failed");
1620 return nullptr;
1621 }
1622
1623 I18nAddon *obj = nullptr;
1624 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1625 if (status != napi_ok || !obj || !obj->phonenumberfmt_) {
1626 HiLog::Error(LABEL, "Get PhoneNumberFormat object failed");
1627 return nullptr;
1628 }
1629
1630 std::string formattedPhoneNumber = obj->phonenumberfmt_->format(buf.data());
1631
1632 napi_value result = nullptr;
1633 status = napi_create_string_utf8(env, formattedPhoneNumber.c_str(), NAPI_AUTO_LENGTH, &result);
1634 if (status != napi_ok) {
1635 HiLog::Error(LABEL, "Create format phone number failed");
1636 return nullptr;
1637 }
1638 return result;
1639 }
1640
GetString(napi_env & env,napi_value & value,int32_t & code)1641 std::string I18nAddon::GetString(napi_env &env, napi_value &value, int32_t &code)
1642 {
1643 size_t len = 0;
1644 napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
1645 if (status != napi_ok) {
1646 HiLog::Error(LABEL, "Get string failed");
1647 code = 1;
1648 return "";
1649 }
1650 std::vector<char> buf(len + 1);
1651 status = napi_get_value_string_utf8(env, value, buf.data(), len + 1, &len);
1652 if (status != napi_ok) {
1653 HiLog::Error(LABEL, "Create string failed");
1654 code = 1;
1655 return "";
1656 }
1657 return buf.data();
1658 }
1659
InitI18nCalendar(napi_env env,napi_value exports)1660 napi_value I18nAddon::InitI18nCalendar(napi_env env, napi_value exports)
1661 {
1662 napi_status status = napi_ok;
1663 napi_property_descriptor properties[] = {
1664 DECLARE_NAPI_FUNCTION("setTime", SetTime),
1665 DECLARE_NAPI_FUNCTION("set", Set),
1666 DECLARE_NAPI_FUNCTION("getTimeZone", GetTimeZone),
1667 DECLARE_NAPI_FUNCTION("setTimeZone", SetTimeZone),
1668 DECLARE_NAPI_FUNCTION("getFirstDayOfWeek", GetFirstDayOfWeek),
1669 DECLARE_NAPI_FUNCTION("setFirstDayOfWeek", SetFirstDayOfWeek),
1670 DECLARE_NAPI_FUNCTION("getMinimalDaysInFirstWeek", GetMinimalDaysInFirstWeek),
1671 DECLARE_NAPI_FUNCTION("setMinimalDaysInFirstWeek", SetMinimalDaysInFirstWeek),
1672 DECLARE_NAPI_FUNCTION("get", Get),
1673 DECLARE_NAPI_FUNCTION("getDisplayName", GetDisplayName),
1674 DECLARE_NAPI_FUNCTION("isWeekend", IsWeekend)
1675 };
1676 napi_value constructor = nullptr;
1677 status = napi_define_class(env, "I18nCalendar", NAPI_AUTO_LENGTH, CalendarConstructor, nullptr,
1678 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1679 if (status != napi_ok) {
1680 HiLog::Error(LABEL, "Failed to define class at Init");
1681 return nullptr;
1682 }
1683 g_constructor = new (std::nothrow) napi_ref;
1684 if (!g_constructor) {
1685 HiLog::Error(LABEL, "Failed to create ref at init");
1686 return nullptr;
1687 }
1688 status = napi_create_reference(env, constructor, 1, g_constructor);
1689 if (status != napi_ok) {
1690 HiLog::Error(LABEL, "Failed to create reference at init");
1691 return nullptr;
1692 }
1693 return exports;
1694 }
1695
CalendarConstructor(napi_env env,napi_callback_info info)1696 napi_value I18nAddon::CalendarConstructor(napi_env env, napi_callback_info info)
1697 {
1698 size_t argc = 2;
1699 napi_value argv[2] = { 0 };
1700 argv[0] = nullptr;
1701 argv[1] = nullptr;
1702 napi_value thisVar = nullptr;
1703 void *data = nullptr;
1704 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1705 if (status != napi_ok) {
1706 return nullptr;
1707 }
1708 napi_valuetype valueType = napi_valuetype::napi_undefined;
1709 napi_typeof(env, argv[0], &valueType);
1710 if (valueType != napi_valuetype::napi_string) {
1711 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1712 return nullptr;
1713 }
1714 int32_t code = 0;
1715 std::string localeTag = GetString(env, argv[0], code);
1716 if (code) {
1717 return nullptr;
1718 }
1719 CalendarType type = GetCalendarType(env, argv[1]);
1720 std::unique_ptr<I18nAddon> obj = nullptr;
1721 obj = std::make_unique<I18nAddon>();
1722 status =
1723 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
1724 if (status != napi_ok) {
1725 HiLog::Error(LABEL, "CalendarConstructor: Wrap II18nAddon failed");
1726 return nullptr;
1727 }
1728 if (!obj->InitCalendarContext(env, info, localeTag, type)) {
1729 return nullptr;
1730 }
1731 obj.release();
1732 return thisVar;
1733 }
1734
GetCalendarType(napi_env env,napi_value value)1735 CalendarType I18nAddon::GetCalendarType(napi_env env, napi_value value)
1736 {
1737 CalendarType type = CalendarType::UNDEFINED;
1738 if (value != nullptr) {
1739 napi_valuetype valueType = napi_valuetype::napi_undefined;
1740 napi_typeof(env, value, &valueType);
1741 if (valueType != napi_valuetype::napi_string) {
1742 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1743 return type;
1744 }
1745 int32_t code = 0;
1746 std::string calendarType = GetString(env, value, code);
1747 if (code) {
1748 return type;
1749 }
1750 if (g_typeMap.find(calendarType) != g_typeMap.end()) {
1751 type = g_typeMap[calendarType];
1752 }
1753 }
1754 return type;
1755 }
1756
InitCalendarContext(napi_env env,napi_callback_info info,const std::string & localeTag,CalendarType type)1757 bool I18nAddon::InitCalendarContext(napi_env env, napi_callback_info info, const std::string &localeTag,
1758 CalendarType type)
1759 {
1760 calendar_ = std::make_unique<I18nCalendar>(localeTag, type);
1761 return calendar_ != nullptr;
1762 }
1763
GetCalendar(napi_env env,napi_callback_info info)1764 napi_value I18nAddon::GetCalendar(napi_env env, napi_callback_info info)
1765 {
1766 size_t argc = 2; // retrieve 2 arguments
1767 napi_value argv[2] = { 0 };
1768 argv[0] = nullptr;
1769 argv[1] = nullptr;
1770 napi_value thisVar = nullptr;
1771 void *data = nullptr;
1772 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1773 napi_value constructor = nullptr;
1774 napi_status status = napi_get_reference_value(env, *g_constructor, &constructor);
1775 if (status != napi_ok) {
1776 HiLog::Error(LABEL, "Failed to create reference at GetCalendar");
1777 return nullptr;
1778 }
1779 if (!argv[1]) {
1780 status = napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, argv + 1);
1781 if (status != napi_ok) {
1782 return nullptr;
1783 }
1784 }
1785 napi_value result = nullptr;
1786 status = napi_new_instance(env, constructor, 2, argv, &result); // 2 arguments
1787 if (status != napi_ok) {
1788 HiLog::Error(LABEL, "Get calendar create instance failed");
1789 return nullptr;
1790 }
1791 return result;
1792 }
1793
GetDate(napi_env env,napi_value value)1794 napi_value I18nAddon::GetDate(napi_env env, napi_value value)
1795 {
1796 if (!value) {
1797 return nullptr;
1798 }
1799 napi_value funcGetDateInfo = nullptr;
1800 napi_status status = napi_get_named_property(env, value, "valueOf", &funcGetDateInfo);
1801 if (status != napi_ok) {
1802 HiLog::Error(LABEL, "Get method valueOf failed");
1803 return nullptr;
1804 }
1805 napi_value ret_value = nullptr;
1806 status = napi_call_function(env, value, funcGetDateInfo, 0, nullptr, &ret_value);
1807 if (status != napi_ok) {
1808 HiLog::Error(LABEL, "Get milliseconds failed");
1809 return nullptr;
1810 }
1811 return ret_value;
1812 }
1813
SetMilliseconds(napi_env env,napi_value value)1814 void I18nAddon::SetMilliseconds(napi_env env, napi_value value)
1815 {
1816 if (!value) {
1817 return;
1818 }
1819 double milliseconds = 0;
1820 napi_valuetype valueType = napi_valuetype::napi_undefined;
1821 napi_typeof(env, value, &valueType);
1822 if (valueType != napi_valuetype::napi_number) {
1823 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1824 return;
1825 }
1826 napi_status status = napi_get_value_double(env, value, &milliseconds);
1827 if (status != napi_ok) {
1828 HiLog::Error(LABEL, "Retrieve milliseconds failed");
1829 return;
1830 }
1831 if (calendar_ != nullptr) {
1832 calendar_->SetTime(milliseconds);
1833 }
1834 }
1835
Set(napi_env env,napi_callback_info info)1836 napi_value I18nAddon::Set(napi_env env, napi_callback_info info)
1837 {
1838 size_t argc = 6; // Set may have 6 arguments
1839 napi_value argv[6] = { 0 };
1840 for (size_t i = 0; i < argc; ++i) {
1841 argv[i] = nullptr;
1842 }
1843 napi_value thisVar = nullptr;
1844 void *data = nullptr;
1845 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1846 napi_valuetype valueType = napi_valuetype::napi_undefined;
1847 napi_status status = napi_ok;
1848 int32_t times[3] = { 0 }; // There are at least 3 arguments.
1849 for (int i = 0; i < 3; ++i) { // There are at least 3 arguments.
1850 napi_typeof(env, argv[i], &valueType);
1851 if (valueType != napi_valuetype::napi_number) {
1852 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1853 return nullptr;
1854 }
1855 status = napi_get_value_int32(env, argv[i], times + i);
1856 if (status != napi_ok) {
1857 HiLog::Error(LABEL, "Retrieve time value failed");
1858 return nullptr;
1859 }
1860 }
1861 I18nAddon *obj = nullptr;
1862 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1863 if (status != napi_ok || !obj || !obj->calendar_) {
1864 HiLog::Error(LABEL, "Get calendar object failed");
1865 return nullptr;
1866 }
1867 obj->calendar_->Set(times[0], times[1], times[2]); // 2 is the index of date
1868 obj->SetField(env, argv[3], UCalendarDateFields::UCAL_HOUR_OF_DAY); // 3 is the index of hour
1869 obj->SetField(env, argv[4], UCalendarDateFields::UCAL_MINUTE); // 4 is the index of minute
1870 obj->SetField(env, argv[5], UCalendarDateFields::UCAL_SECOND); // 5 is the index of second
1871 return nullptr;
1872 }
1873
SetTime(napi_env env,napi_callback_info info)1874 napi_value I18nAddon::SetTime(napi_env env, napi_callback_info info)
1875 {
1876 size_t argc = 1;
1877 napi_value argv[1] = { 0 };
1878 argv[0] = nullptr;
1879 napi_value thisVar = nullptr;
1880 void *data = nullptr;
1881 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1882 if (!argv[0]) {
1883 return nullptr;
1884 }
1885 I18nAddon *obj = nullptr;
1886 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1887 if (status != napi_ok || !obj || !obj->calendar_) {
1888 HiLog::Error(LABEL, "Get calendar object failed");
1889 return nullptr;
1890 }
1891 napi_valuetype type = napi_valuetype::napi_undefined;
1892 status = napi_typeof(env, argv[0], &type);
1893 if (status != napi_ok) {
1894 return nullptr;
1895 }
1896 if (type == napi_valuetype::napi_number) {
1897 obj->SetMilliseconds(env, argv[0]);
1898 return nullptr;
1899 } else {
1900 napi_value val = GetDate(env, argv[0]);
1901 if (!val) {
1902 return nullptr;
1903 }
1904 obj->SetMilliseconds(env, val);
1905 return nullptr;
1906 }
1907 }
1908
SetField(napi_env env,napi_value value,UCalendarDateFields field)1909 void I18nAddon::SetField(napi_env env, napi_value value, UCalendarDateFields field)
1910 {
1911 if (!value) {
1912 return;
1913 }
1914 int32_t val = 0;
1915 napi_valuetype valueType = napi_valuetype::napi_undefined;
1916 napi_typeof(env, value, &valueType);
1917 if (valueType != napi_valuetype::napi_number) {
1918 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1919 return;
1920 }
1921 napi_status status = napi_get_value_int32(env, value, &val);
1922 if (status != napi_ok) {
1923 HiLog::Error(LABEL, "Retrieve field failed");
1924 return;
1925 }
1926 if (calendar_ != nullptr) {
1927 calendar_->Set(field, val);
1928 }
1929 }
1930
SetTimeZone(napi_env env,napi_callback_info info)1931 napi_value I18nAddon::SetTimeZone(napi_env env, napi_callback_info info)
1932 {
1933 size_t argc = 1;
1934 napi_value argv[1] = { 0 };
1935 argv[0] = nullptr;
1936 napi_value thisVar = nullptr;
1937 void *data = nullptr;
1938 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1939 napi_valuetype valueType = napi_valuetype::napi_undefined;
1940 napi_typeof(env, argv[0], &valueType);
1941 if (valueType != napi_valuetype::napi_string) {
1942 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1943 return nullptr;
1944 }
1945 size_t len = 0;
1946 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1947 if (status != napi_ok) {
1948 HiLog::Error(LABEL, "Get timezone length failed");
1949 return nullptr;
1950 }
1951 std::vector<char> buf(len + 1);
1952 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1953 if (status != napi_ok) {
1954 HiLog::Error(LABEL, "Get timezone failed");
1955 return nullptr;
1956 }
1957 std::string timezone(buf.data());
1958 I18nAddon *obj = nullptr;
1959 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1960 if (status != napi_ok || !obj || !obj->calendar_) {
1961 HiLog::Error(LABEL, "Get calendar object failed");
1962 return nullptr;
1963 }
1964 obj->calendar_->SetTimeZone(timezone);
1965 return nullptr;
1966 }
1967
GetTimeZone(napi_env env,napi_callback_info info)1968 napi_value I18nAddon::GetTimeZone(napi_env env, napi_callback_info info)
1969 {
1970 size_t argc = 0;
1971 napi_value *argv = nullptr;
1972 napi_value thisVar = nullptr;
1973 void *data = nullptr;
1974 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1975 I18nAddon *obj = nullptr;
1976 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1977 if (status != napi_ok || !obj || !obj->calendar_) {
1978 HiLog::Error(LABEL, "Get calendar object failed");
1979 return nullptr;
1980 }
1981 std::string temp = obj->calendar_->GetTimeZone();
1982 napi_value result = nullptr;
1983 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &result);
1984 if (status != napi_ok) {
1985 HiLog::Error(LABEL, "Create timezone string failed");
1986 return nullptr;
1987 }
1988 return result;
1989 }
1990
GetFirstDayOfWeek(napi_env env,napi_callback_info info)1991 napi_value I18nAddon::GetFirstDayOfWeek(napi_env env, napi_callback_info info)
1992 {
1993 size_t argc = 0;
1994 napi_value *argv = nullptr;
1995 napi_value thisVar = nullptr;
1996 void *data = nullptr;
1997 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1998 I18nAddon *obj = nullptr;
1999 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2000 if (status != napi_ok || !obj || !obj->calendar_) {
2001 HiLog::Error(LABEL, "Get calendar object failed");
2002 return nullptr;
2003 }
2004 int32_t temp = obj->calendar_->GetFirstDayOfWeek();
2005 napi_value result = nullptr;
2006 status = napi_create_int32(env, temp, &result);
2007 if (status != napi_ok) {
2008 HiLog::Error(LABEL, "Create int32 failed");
2009 return nullptr;
2010 }
2011 return result;
2012 }
2013
GetMinimalDaysInFirstWeek(napi_env env,napi_callback_info info)2014 napi_value I18nAddon::GetMinimalDaysInFirstWeek(napi_env env, napi_callback_info info)
2015 {
2016 size_t argc = 0;
2017 napi_value *argv = nullptr;
2018 napi_value thisVar = nullptr;
2019 void *data = nullptr;
2020 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2021 I18nAddon *obj = nullptr;
2022 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2023 if (status != napi_ok || !obj || !obj->calendar_) {
2024 HiLog::Error(LABEL, "Get calendar object failed");
2025 return nullptr;
2026 }
2027 int32_t temp = obj->calendar_->GetMinimalDaysInFirstWeek();
2028 napi_value result = nullptr;
2029 status = napi_create_int32(env, temp, &result);
2030 if (status != napi_ok) {
2031 HiLog::Error(LABEL, "Create int32 failed");
2032 return nullptr;
2033 }
2034 return result;
2035 }
2036
SetFirstDayOfWeek(napi_env env,napi_callback_info info)2037 napi_value I18nAddon::SetFirstDayOfWeek(napi_env env, napi_callback_info info)
2038 {
2039 size_t argc = 1;
2040 napi_value argv[1] = { 0 };
2041 argv[0] = nullptr;
2042 napi_value thisVar = nullptr;
2043 void *data = nullptr;
2044 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2045 napi_valuetype valueType = napi_valuetype::napi_undefined;
2046 napi_typeof(env, argv[0], &valueType);
2047 if (valueType != napi_valuetype::napi_number) {
2048 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2049 return nullptr;
2050 }
2051 int32_t value = 0;
2052 napi_status status = napi_get_value_int32(env, argv[0], &value);
2053 if (status != napi_ok) {
2054 HiLog::Error(LABEL, "Get int32 failed");
2055 return nullptr;
2056 }
2057 I18nAddon *obj = nullptr;
2058 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2059 if (status != napi_ok || !obj || !obj->calendar_) {
2060 HiLog::Error(LABEL, "Get calendar object failed");
2061 return nullptr;
2062 }
2063 obj->calendar_->SetFirstDayOfWeek(value);
2064 return nullptr;
2065 }
2066
SetMinimalDaysInFirstWeek(napi_env env,napi_callback_info info)2067 napi_value I18nAddon::SetMinimalDaysInFirstWeek(napi_env env, napi_callback_info info)
2068 {
2069 size_t argc = 1;
2070 napi_value argv[1] = { 0 };
2071 argv[0] = nullptr;
2072 napi_value thisVar = nullptr;
2073 void *data = nullptr;
2074 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2075 napi_valuetype valueType = napi_valuetype::napi_undefined;
2076 napi_typeof(env, argv[0], &valueType);
2077 if (valueType != napi_valuetype::napi_number) {
2078 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2079 return nullptr;
2080 }
2081 int32_t value = 0;
2082 napi_status status = napi_get_value_int32(env, argv[0], &value);
2083 if (status != napi_ok) {
2084 HiLog::Error(LABEL, "Get int32 failed");
2085 return nullptr;
2086 }
2087 I18nAddon *obj = nullptr;
2088 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2089 if (status != napi_ok || !obj || !obj->calendar_) {
2090 HiLog::Error(LABEL, "Get calendar object failed");
2091 return nullptr;
2092 }
2093 obj->calendar_->SetMinimalDaysInFirstWeek(value);
2094 return nullptr;
2095 }
2096
Get(napi_env env,napi_callback_info info)2097 napi_value I18nAddon::Get(napi_env env, napi_callback_info info)
2098 {
2099 size_t argc = 1;
2100 napi_value argv[1] = { 0 };
2101 argv[0] = nullptr;
2102 napi_value thisVar = nullptr;
2103 void *data = nullptr;
2104 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2105 napi_valuetype valueType = napi_valuetype::napi_undefined;
2106 napi_typeof(env, argv[0], &valueType);
2107 if (valueType != napi_valuetype::napi_string) {
2108 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2109 return nullptr;
2110 }
2111 size_t len = 0;
2112 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2113 if (status != napi_ok) {
2114 HiLog::Error(LABEL, "Get field length failed");
2115 return nullptr;
2116 }
2117 std::vector<char> buf(len + 1);
2118 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
2119 if (status != napi_ok) {
2120 HiLog::Error(LABEL, "Get field failed");
2121 return nullptr;
2122 }
2123 std::string field(buf.data());
2124 if (g_fieldsMap.find(field) == g_fieldsMap.end()) {
2125 HiLog::Error(LABEL, "Invalid field");
2126 return nullptr;
2127 }
2128 I18nAddon *obj = nullptr;
2129 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2130 if (status != napi_ok || !obj || !obj->calendar_) {
2131 HiLog::Error(LABEL, "Get calendar object failed");
2132 return nullptr;
2133 }
2134 int32_t value = obj->calendar_->Get(g_fieldsMap[field]);
2135 napi_value result = nullptr;
2136 status = napi_create_int32(env, value, &result);
2137 if (status != napi_ok) {
2138 HiLog::Error(LABEL, "Create int32 failed");
2139 return nullptr;
2140 }
2141 return result;
2142 }
2143
IsWeekend(napi_env env,napi_callback_info info)2144 napi_value I18nAddon::IsWeekend(napi_env env, napi_callback_info info)
2145 {
2146 size_t argc = 1;
2147 napi_value argv[1] = { 0 };
2148 argv[0] = nullptr;
2149 napi_value thisVar = nullptr;
2150 void *data = nullptr;
2151 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2152 I18nAddon *obj = nullptr;
2153 bool isWeekEnd = false;
2154 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2155 do {
2156 if (status != napi_ok || !obj || !obj->calendar_) {
2157 HiLog::Error(LABEL, "Get calendar object failed");
2158 break;
2159 }
2160 if (!argv[0]) {
2161 isWeekEnd = obj->calendar_->IsWeekend();
2162 } else {
2163 napi_value funcGetDateInfo = nullptr;
2164 status = napi_get_named_property(env, argv[0], "valueOf", &funcGetDateInfo);
2165 if (status != napi_ok) {
2166 HiLog::Error(LABEL, "Get method now failed");
2167 break;
2168 }
2169 napi_value value = nullptr;
2170 status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &value);
2171 if (status != napi_ok) {
2172 HiLog::Error(LABEL, "Get milliseconds failed");
2173 break;
2174 }
2175 double milliseconds = 0;
2176 status = napi_get_value_double(env, value, &milliseconds);
2177 if (status != napi_ok) {
2178 HiLog::Error(LABEL, "Retrieve milliseconds failed");
2179 break;
2180 }
2181 UErrorCode error = U_ZERO_ERROR;
2182 isWeekEnd = obj->calendar_->IsWeekend(milliseconds, error);
2183 }
2184 } while (false);
2185 napi_value result = nullptr;
2186 status = napi_get_boolean(env, isWeekEnd, &result);
2187 if (status != napi_ok) {
2188 HiLog::Error(LABEL, "Create boolean failed");
2189 return nullptr;
2190 }
2191 return result;
2192 }
2193
GetDisplayName(napi_env env,napi_callback_info info)2194 napi_value I18nAddon::GetDisplayName(napi_env env, napi_callback_info info)
2195 {
2196 size_t argc = 1;
2197 napi_value argv[1] = { 0 };
2198 argv[0] = nullptr;
2199 napi_value thisVar = nullptr;
2200 void *data = nullptr;
2201 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2202 napi_valuetype valueType = napi_valuetype::napi_undefined;
2203 napi_typeof(env, argv[0], &valueType);
2204 if (valueType != napi_valuetype::napi_string) {
2205 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2206 return nullptr;
2207 }
2208 int32_t code = 0;
2209 std::string localeTag = GetString(env, argv[0], code);
2210 if (code) {
2211 return nullptr;
2212 }
2213 I18nAddon *obj = nullptr;
2214 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2215 if (status != napi_ok || !obj || !obj->calendar_) {
2216 HiLog::Error(LABEL, "Get calendar object failed");
2217 return nullptr;
2218 }
2219 if (!obj->calendar_) {
2220 return nullptr;
2221 }
2222 std::string name = obj->calendar_->GetDisplayName(localeTag);
2223 napi_value result = nullptr;
2224 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result);
2225 if (status != napi_ok) {
2226 HiLog::Error(LABEL, "Create calendar name string failed");
2227 return nullptr;
2228 }
2229 return result;
2230 }
2231
InitIndexUtil(napi_env env,napi_value exports)2232 napi_value I18nAddon::InitIndexUtil(napi_env env, napi_value exports)
2233 {
2234 napi_property_descriptor properties[] = {
2235 DECLARE_NAPI_FUNCTION("getIndexList", GetIndexList),
2236 DECLARE_NAPI_FUNCTION("addLocale", AddLocale),
2237 DECLARE_NAPI_FUNCTION("getIndex", GetIndex)
2238 };
2239
2240 napi_value constructor = nullptr;
2241 napi_status status = napi_define_class(env, "IndexUtil", NAPI_AUTO_LENGTH, IndexUtilConstructor, nullptr,
2242 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
2243 if (status != napi_ok) {
2244 HiLog::Error(LABEL, "Define class failed when InitPhoneNumberFormat");
2245 return nullptr;
2246 }
2247
2248 status = napi_create_reference(env, constructor, 1, &g_indexUtilConstructor);
2249 if (status != napi_ok) {
2250 HiLog::Error(LABEL, "Failed to create reference at init");
2251 return nullptr;
2252 }
2253 return exports;
2254 }
2255
BreakIteratorConstructor(napi_env env,napi_callback_info info)2256 napi_value I18nAddon::BreakIteratorConstructor(napi_env env, napi_callback_info info)
2257 {
2258 size_t argc = 1;
2259 napi_value argv[1] = { nullptr };
2260 napi_value thisVar = nullptr;
2261 void *data = nullptr;
2262 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2263 if (status != napi_ok) {
2264 return nullptr;
2265 }
2266 napi_valuetype valueType = napi_valuetype::napi_undefined;
2267 napi_typeof(env, argv[0], &valueType);
2268 if (valueType != napi_valuetype::napi_string) {
2269 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2270 return nullptr;
2271 }
2272 int32_t code = 0;
2273 std::string localeTag = GetString(env, argv[0], code);
2274 if (code) {
2275 return nullptr;
2276 }
2277 std::unique_ptr<I18nAddon> obj = nullptr;
2278 obj = std::make_unique<I18nAddon>();
2279 status =
2280 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
2281 if (status != napi_ok) {
2282 HiLog::Error(LABEL, "BreakIteratorConstructor: Wrap II18nAddon failed");
2283 return nullptr;
2284 }
2285 obj->brkiter_ = std::make_unique<I18nBreakIterator>(localeTag);
2286 if (!obj->brkiter_) {
2287 HiLog::Error(LABEL, "Wrap BreakIterator failed");
2288 return nullptr;
2289 }
2290 obj.release();
2291 return thisVar;
2292 }
2293
InitBreakIterator(napi_env env,napi_value exports)2294 napi_value I18nAddon::InitBreakIterator(napi_env env, napi_value exports)
2295 {
2296 napi_status status = napi_ok;
2297 napi_property_descriptor properties[] = {
2298 DECLARE_NAPI_FUNCTION("current", Current),
2299 DECLARE_NAPI_FUNCTION("first", First),
2300 DECLARE_NAPI_FUNCTION("last", Last),
2301 DECLARE_NAPI_FUNCTION("next", Next),
2302 DECLARE_NAPI_FUNCTION("previous", Previous),
2303 DECLARE_NAPI_FUNCTION("setLineBreakText", SetText),
2304 DECLARE_NAPI_FUNCTION("following", Following),
2305 DECLARE_NAPI_FUNCTION("getLineBreakText", GetText),
2306 DECLARE_NAPI_FUNCTION("isBoundary", IsBoundary),
2307 };
2308 napi_value constructor = nullptr;
2309 status = napi_define_class(env, "BreakIterator", NAPI_AUTO_LENGTH, BreakIteratorConstructor, nullptr,
2310 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
2311 if (status != napi_ok) {
2312 HiLog::Error(LABEL, "Failed to define class BreakIterator at Init");
2313 return nullptr;
2314 }
2315 g_brkConstructor = new (std::nothrow) napi_ref;
2316 if (!g_brkConstructor) {
2317 HiLog::Error(LABEL, "Failed to create brkiterator ref at init");
2318 return nullptr;
2319 }
2320 status = napi_create_reference(env, constructor, 1, g_brkConstructor);
2321 if (status != napi_ok) {
2322 HiLog::Error(LABEL, "Failed to create reference g_brkConstructor at init");
2323 return nullptr;
2324 }
2325 return exports;
2326 }
2327
GetLineInstance(napi_env env,napi_callback_info info)2328 napi_value I18nAddon::GetLineInstance(napi_env env, napi_callback_info info)
2329 {
2330 size_t argc = 1;
2331 napi_value argv[1] = { nullptr };
2332 napi_value thisVar = nullptr;
2333 void *data = nullptr;
2334 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2335 napi_value constructor = nullptr;
2336 napi_status status = napi_get_reference_value(env, *g_brkConstructor, &constructor);
2337 if (status != napi_ok) {
2338 HiLog::Error(LABEL, "Failed to create reference at GetLineInstance");
2339 return nullptr;
2340 }
2341 if (!argv[0]) {
2342 return nullptr;
2343 }
2344 napi_value result = nullptr;
2345 status = napi_new_instance(env, constructor, 1, argv, &result); // 1 arguments
2346 if (status != napi_ok) {
2347 HiLog::Error(LABEL, "GetLineInstance create instance failed");
2348 return nullptr;
2349 }
2350 return result;
2351 }
2352
Current(napi_env env,napi_callback_info info)2353 napi_value I18nAddon::Current(napi_env env, napi_callback_info info)
2354 {
2355 size_t argc = 0;
2356 napi_value *argv = nullptr;
2357 napi_value thisVar = nullptr;
2358 void *data = nullptr;
2359 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2360 I18nAddon *obj = nullptr;
2361 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2362 if (status != napi_ok || !obj || !obj->brkiter_) {
2363 HiLog::Error(LABEL, "Get BreakIterator object failed");
2364 return nullptr;
2365 }
2366 int value = obj->brkiter_->current();
2367 napi_value result = nullptr;
2368 status = napi_create_int32(env, value, &result);
2369 if (status != napi_ok) {
2370 HiLog::Error(LABEL, "Create int32_t value failed");
2371 return nullptr;
2372 }
2373 return result;
2374 }
2375
First(napi_env env,napi_callback_info info)2376 napi_value I18nAddon::First(napi_env env, napi_callback_info info)
2377 {
2378 size_t argc = 0;
2379 napi_value *argv = nullptr;
2380 napi_value thisVar = nullptr;
2381 void *data = nullptr;
2382 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2383 I18nAddon *obj = nullptr;
2384 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2385 if (status != napi_ok || !obj || !obj->brkiter_) {
2386 HiLog::Error(LABEL, "Get BreakIterator object failed");
2387 return nullptr;
2388 }
2389 int value = obj->brkiter_->first();
2390 napi_value result = nullptr;
2391 status = napi_create_int32(env, value, &result);
2392 if (status != napi_ok) {
2393 HiLog::Error(LABEL, "Create int32_t value failed");
2394 return nullptr;
2395 }
2396 return result;
2397 }
2398
Last(napi_env env,napi_callback_info info)2399 napi_value I18nAddon::Last(napi_env env, napi_callback_info info)
2400 {
2401 size_t argc = 0;
2402 napi_value *argv = nullptr;
2403 napi_value thisVar = nullptr;
2404 void *data = nullptr;
2405 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2406 I18nAddon *obj = nullptr;
2407 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2408 if (status != napi_ok || !obj || !obj->brkiter_) {
2409 HiLog::Error(LABEL, "Get BreakIterator object failed");
2410 return nullptr;
2411 }
2412 int value = obj->brkiter_->last();
2413 napi_value result = nullptr;
2414 status = napi_create_int32(env, value, &result);
2415 if (status != napi_ok) {
2416 HiLog::Error(LABEL, "Create int32_t value failed");
2417 return nullptr;
2418 }
2419 return result;
2420 }
2421
Previous(napi_env env,napi_callback_info info)2422 napi_value I18nAddon::Previous(napi_env env, napi_callback_info info)
2423 {
2424 size_t argc = 0;
2425 napi_value *argv = nullptr;
2426 napi_value thisVar = nullptr;
2427 void *data = nullptr;
2428 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2429 I18nAddon *obj = nullptr;
2430 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2431 if (status != napi_ok || !obj || !obj->brkiter_) {
2432 HiLog::Error(LABEL, "Get BreakIterator object failed");
2433 return nullptr;
2434 }
2435 int value = obj->brkiter_->previous();
2436 napi_value result = nullptr;
2437 status = napi_create_int32(env, value, &result);
2438 if (status != napi_ok) {
2439 HiLog::Error(LABEL, "Create int32_t value failed");
2440 return nullptr;
2441 }
2442 return result;
2443 }
2444
Next(napi_env env,napi_callback_info info)2445 napi_value I18nAddon::Next(napi_env env, napi_callback_info info)
2446 {
2447 size_t argc = 1;
2448 napi_value argv[1] = { nullptr };
2449 napi_value thisVar = nullptr;
2450 void *data = nullptr;
2451 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2452 I18nAddon *obj = nullptr;
2453 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2454 if (status != napi_ok || !obj || !obj->brkiter_) {
2455 HiLog::Error(LABEL, "Get BreakIterator object failed");
2456 return nullptr;
2457 }
2458 int value = 1;
2459 if (argv[0] != nullptr) {
2460 napi_valuetype valueType = napi_valuetype::napi_undefined;
2461 napi_typeof(env, argv[0], &valueType);
2462 if (valueType != napi_valuetype::napi_number) {
2463 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2464 return nullptr;
2465 }
2466 status = napi_get_value_int32(env, argv[0], &value);
2467 if (status != napi_ok) {
2468 HiLog::Error(LABEL, "Retrieve next value failed");
2469 return nullptr;
2470 }
2471 }
2472 value = obj->brkiter_->next(value);
2473 napi_value result = nullptr;
2474 status = napi_create_int32(env, value, &result);
2475 if (status != napi_ok) {
2476 HiLog::Error(LABEL, "Create int32_t value failed");
2477 return nullptr;
2478 }
2479 return result;
2480 }
2481
SetText(napi_env env,napi_callback_info info)2482 napi_value I18nAddon::SetText(napi_env env, napi_callback_info info)
2483 {
2484 size_t argc = 1;
2485 napi_value argv[1] = { nullptr };
2486 napi_value thisVar = nullptr;
2487 void *data = nullptr;
2488 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2489 I18nAddon *obj = nullptr;
2490 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2491 if (status != napi_ok || !obj || !obj->brkiter_) {
2492 HiLog::Error(LABEL, "Get BreakIterator object failed");
2493 return nullptr;
2494 }
2495 if (!argv[0]) {
2496 return nullptr;
2497 }
2498 napi_valuetype valueType = napi_valuetype::napi_undefined;
2499 napi_typeof(env, argv[0], &valueType);
2500 if (valueType != napi_valuetype::napi_string) {
2501 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2502 return nullptr;
2503 }
2504 size_t len = 0;
2505 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2506 if (status != napi_ok) {
2507 HiLog::Error(LABEL, "Get field length failed");
2508 return nullptr;
2509 }
2510 std::vector<char> buf(len + 1);
2511 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
2512 if (status != napi_ok) {
2513 HiLog::Error(LABEL, "Get string value failed");
2514 return nullptr;
2515 }
2516 obj->brkiter_->setText(buf.data());
2517 return nullptr;
2518 }
2519
GetText(napi_env env,napi_callback_info info)2520 napi_value I18nAddon::GetText(napi_env env, napi_callback_info info)
2521 {
2522 size_t argc = 0;
2523 napi_value *argv = nullptr;
2524 napi_value thisVar = nullptr;
2525 void *data = nullptr;
2526 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2527 I18nAddon *obj = nullptr;
2528 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2529 if (status != napi_ok || !obj || !obj->brkiter_) {
2530 HiLog::Error(LABEL, "Get BreakIterator object failed");
2531 return nullptr;
2532 }
2533 napi_value value = nullptr;
2534 std::string temp;
2535 obj->brkiter_->getText(temp);
2536 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &value);
2537 if (status != napi_ok) {
2538 HiLog::Error(LABEL, "Get field length failed");
2539 return nullptr;
2540 }
2541 return value;
2542 }
2543
Following(napi_env env,napi_callback_info info)2544 napi_value I18nAddon::Following(napi_env env, napi_callback_info info)
2545 {
2546 size_t argc = 1;
2547 napi_value argv[1] = { nullptr };
2548 napi_value thisVar = nullptr;
2549 void *data = nullptr;
2550 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2551 I18nAddon *obj = nullptr;
2552 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2553 if (status != napi_ok || !obj || !obj->brkiter_) {
2554 HiLog::Error(LABEL, "Get BreakIterator object failed");
2555 return nullptr;
2556 }
2557 if (!argv[0]) {
2558 return nullptr;
2559 }
2560 napi_valuetype valueType = napi_valuetype::napi_undefined;
2561 napi_typeof(env, argv[0], &valueType);
2562 if (valueType != napi_valuetype::napi_number) {
2563 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2564 return nullptr;
2565 }
2566 int value;
2567 status = napi_get_value_int32(env, argv[0], &value);
2568 if (status != napi_ok) {
2569 HiLog::Error(LABEL, "Retrieve following value failed");
2570 return nullptr;
2571 }
2572 value = obj->brkiter_->following(value);
2573 napi_value result = nullptr;
2574 status = napi_create_int32(env, value, &result);
2575 if (status != napi_ok) {
2576 HiLog::Error(LABEL, "Create int32_t value failed");
2577 return nullptr;
2578 }
2579 return result;
2580 }
2581
IsBoundary(napi_env env,napi_callback_info info)2582 napi_value I18nAddon::IsBoundary(napi_env env, napi_callback_info info)
2583 {
2584 size_t argc = 1;
2585 napi_value argv[1] = { nullptr };
2586 napi_value thisVar = nullptr;
2587 void *data = nullptr;
2588 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2589 I18nAddon *obj = nullptr;
2590 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2591 if (status != napi_ok || !obj || !obj->brkiter_) {
2592 HiLog::Error(LABEL, "Get BreakIterator object failed");
2593 return nullptr;
2594 }
2595 if (!argv[0]) {
2596 return nullptr;
2597 }
2598 napi_valuetype valueType = napi_valuetype::napi_undefined;
2599 int value;
2600 napi_typeof(env, argv[0], &valueType);
2601 if (valueType != napi_valuetype::napi_number) {
2602 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2603 return nullptr;
2604 }
2605 status = napi_get_value_int32(env, argv[0], &value);
2606 if (status != napi_ok) {
2607 HiLog::Error(LABEL, "Retrieve following value failed");
2608 return nullptr;
2609 }
2610 bool boundary = obj->brkiter_->isBoundary(value);
2611 napi_value result = nullptr;
2612 status = napi_get_boolean(env, boundary, &result);
2613 if (status != napi_ok) {
2614 HiLog::Error(LABEL, "Create boolean failed");
2615 return nullptr;
2616 }
2617 return result;
2618 }
2619
IndexUtilConstructor(napi_env env,napi_callback_info info)2620 napi_value I18nAddon::IndexUtilConstructor(napi_env env, napi_callback_info info)
2621 {
2622 size_t argc = 1;
2623 napi_value argv[1] = { 0 };
2624 napi_value thisVar = nullptr;
2625 void *data = nullptr;
2626 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2627 if (status != napi_ok) {
2628 return nullptr;
2629 }
2630 std::string localeTag = "";
2631 if (argv[0] != nullptr) {
2632 napi_valuetype valueType = napi_valuetype::napi_undefined;
2633 napi_typeof(env, argv[0], &valueType);
2634 if (valueType != napi_valuetype::napi_string) {
2635 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2636 return nullptr;
2637 }
2638 size_t len = 0;
2639 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2640 if (status != napi_ok) {
2641 HiLog::Error(LABEL, "Get locale length failed");
2642 return nullptr;
2643 }
2644 std::vector<char> localeBuf(len + 1);
2645 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
2646 if (status != napi_ok) {
2647 HiLog::Error(LABEL, "Get locale failed");
2648 return nullptr;
2649 }
2650 localeTag = localeBuf.data();
2651 }
2652 std::unique_ptr<I18nAddon> obj = nullptr;
2653 obj = std::make_unique<I18nAddon>();
2654 status =
2655 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
2656 if (status != napi_ok) {
2657 HiLog::Error(LABEL, "IndexUtilConstructor: Wrap II18nAddon failed");
2658 return nullptr;
2659 }
2660 if (!obj->InitIndexUtilContext(env, info, localeTag)) {
2661 return nullptr;
2662 }
2663 obj.release();
2664 return thisVar;
2665 }
2666
InitIndexUtilContext(napi_env env,napi_callback_info info,const std::string & localeTag)2667 bool I18nAddon::InitIndexUtilContext(napi_env env, napi_callback_info info, const std::string &localeTag)
2668 {
2669 napi_value global = nullptr;
2670 napi_status status = napi_get_global(env, &global);
2671 if (status != napi_ok) {
2672 HiLog::Error(LABEL, "Get global failed");
2673 return false;
2674 }
2675 env_ = env;
2676 indexUtil_ = std::make_unique<IndexUtil>(localeTag);
2677 return indexUtil_ != nullptr;
2678 }
2679
GetIndexUtil(napi_env env,napi_callback_info info)2680 napi_value I18nAddon::GetIndexUtil(napi_env env, napi_callback_info info)
2681 {
2682 size_t argc = 1;
2683 napi_value argv[1] = { 0 };
2684 napi_value thisVar = nullptr;
2685 void *data = nullptr;
2686 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2687 napi_value constructor = nullptr;
2688 napi_status status = napi_get_reference_value(env, g_indexUtilConstructor, &constructor);
2689 if (status != napi_ok) {
2690 HiLog::Error(LABEL, "Failed to create reference at GetIndexUtil");
2691 return nullptr;
2692 }
2693 napi_value result = nullptr;
2694 if (!argv[0]) {
2695 status = napi_new_instance(env, constructor, 0, argv, &result);
2696 } else {
2697 status = napi_new_instance(env, constructor, 1, argv, &result);
2698 }
2699 if (status != napi_ok) {
2700 HiLog::Error(LABEL, "Get calendar create instance failed");
2701 return nullptr;
2702 }
2703 return result;
2704 }
2705
GetIndexList(napi_env env,napi_callback_info info)2706 napi_value I18nAddon::GetIndexList(napi_env env, napi_callback_info info)
2707 {
2708 size_t argc = 0;
2709 napi_value argv[0];
2710 napi_value thisVar = nullptr;
2711 void *data = nullptr;
2712 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2713
2714 I18nAddon *obj = nullptr;
2715 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2716 if (status != napi_ok || !obj || !obj->indexUtil_) {
2717 HiLog::Error(LABEL, "GetPhoneNumberFormat object failed");
2718 return nullptr;
2719 }
2720
2721 std::vector<std::string> indexList = obj->indexUtil_->GetIndexList();
2722 napi_value result = nullptr;
2723 status = napi_create_array_with_length(env, indexList.size(), &result);
2724 if (status != napi_ok) {
2725 HiLog::Error(LABEL, "Failed to create array");
2726 return nullptr;
2727 }
2728 for (size_t i = 0; i < indexList.size(); i++) {
2729 napi_value element = nullptr;
2730 status = napi_create_string_utf8(env, indexList[i].c_str(), NAPI_AUTO_LENGTH, &element);
2731 if (status != napi_ok) {
2732 HiLog::Error(LABEL, "Failed to create string item");
2733 return nullptr;
2734 }
2735 status = napi_set_element(env, result, i, element);
2736 if (status != napi_ok) {
2737 HiLog::Error(LABEL, "Failed to set array item");
2738 return nullptr;
2739 }
2740 }
2741 return result;
2742 }
2743
AddLocale(napi_env env,napi_callback_info info)2744 napi_value I18nAddon::AddLocale(napi_env env, napi_callback_info info)
2745 {
2746 size_t argc = 1;
2747 napi_value argv[1] = { 0 };
2748 napi_value thisVar = nullptr;
2749 void *data = nullptr;
2750 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2751 napi_valuetype valueType = napi_valuetype::napi_undefined;
2752 napi_typeof(env, argv[0], &valueType);
2753 if (valueType != napi_valuetype::napi_string) {
2754 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2755 return nullptr;
2756 }
2757 size_t len = 0;
2758 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2759 if (status != napi_ok) {
2760 HiLog::Error(LABEL, "Get locale length failed");
2761 return nullptr;
2762 }
2763 std::vector<char> buf(len + 1);
2764 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
2765 if (status != napi_ok) {
2766 HiLog::Error(LABEL, "Get locale failed");
2767 return nullptr;
2768 }
2769 I18nAddon *obj = nullptr;
2770 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2771 if (status != napi_ok || !obj || !obj->indexUtil_) {
2772 HiLog::Error(LABEL, "Get IndexUtil object failed");
2773 return nullptr;
2774 }
2775 obj->indexUtil_->AddLocale(buf.data());
2776 return nullptr;
2777 }
2778
GetIndex(napi_env env,napi_callback_info info)2779 napi_value I18nAddon::GetIndex(napi_env env, napi_callback_info info)
2780 {
2781 size_t argc = 1;
2782 napi_value argv[1] = { 0 };
2783 napi_value thisVar = nullptr;
2784 void *data = nullptr;
2785 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2786 napi_valuetype valueType = napi_valuetype::napi_undefined;
2787 napi_typeof(env, argv[0], &valueType);
2788 if (valueType != napi_valuetype::napi_string) {
2789 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2790 return nullptr;
2791 }
2792 size_t len = 0;
2793 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2794 if (status != napi_ok) {
2795 HiLog::Error(LABEL, "Get String length failed");
2796 return nullptr;
2797 }
2798 std::vector<char> buf(len + 1);
2799 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
2800 if (status != napi_ok) {
2801 HiLog::Error(LABEL, "Get String failed");
2802 return nullptr;
2803 }
2804 I18nAddon *obj = nullptr;
2805 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2806 if (status != napi_ok || !obj || !obj->indexUtil_) {
2807 HiLog::Error(LABEL, "Get IndexUtil object failed");
2808 return nullptr;
2809 }
2810 std::string index = obj->indexUtil_->GetIndex(buf.data());
2811 napi_value result = nullptr;
2812 status = napi_create_string_utf8(env, index.c_str(), NAPI_AUTO_LENGTH, &result);
2813 if (status != napi_ok) {
2814 HiLog::Error(LABEL, "GetIndex Failed");
2815 return nullptr;
2816 }
2817 return result;
2818 }
2819
Is24HourClock(napi_env env,napi_callback_info info)2820 napi_value I18nAddon::Is24HourClock(napi_env env, napi_callback_info info)
2821 {
2822 bool is24HourClock = LocaleConfig::Is24HourClock();
2823 napi_value result = nullptr;
2824 napi_status status = napi_get_boolean(env, is24HourClock, &result);
2825 if (status != napi_ok) {
2826 HiLog::Error(LABEL, "Failed to create boolean item");
2827 return nullptr;
2828 }
2829 return result;
2830 }
2831
Set24HourClock(napi_env env,napi_callback_info info)2832 napi_value I18nAddon::Set24HourClock(napi_env env, napi_callback_info info)
2833 {
2834 return I18nAddon::Set24HourClockImpl(env, info, false);
2835 }
2836
Set24HourClockWithError(napi_env env,napi_callback_info info)2837 napi_value I18nAddon::Set24HourClockWithError(napi_env env, napi_callback_info info)
2838 {
2839 return I18nAddon::Set24HourClockImpl(env, info, true);
2840 }
2841
Set24HourClockImpl(napi_env env,napi_callback_info info,bool throwError)2842 napi_value I18nAddon::Set24HourClockImpl(napi_env env, napi_callback_info info, bool throwError)
2843 {
2844 size_t argc = 1;
2845 napi_value argv[1] = { 0 };
2846 napi_value thisVar = nullptr;
2847 void *data = nullptr;
2848 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2849 if (status != napi_ok) {
2850 return nullptr;
2851 }
2852 if (argv[0] == nullptr) {
2853 HiLog::Error(LABEL, "Missing parameter");
2854 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
2855 return nullptr;
2856 }
2857
2858 bool option = false;
2859 status = napi_get_value_bool(env, argv[0], &option);
2860 if (status != napi_ok) {
2861 HiLog::Error(LABEL, "Failed to get boolean item");
2862 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
2863 return nullptr;
2864 }
2865 bool success = LocaleConfig::Set24HourClock(option);
2866 if (throwError) {
2867 if (!success) {
2868 ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, throwError);
2869 }
2870 return nullptr;
2871 }
2872 napi_value result = nullptr;
2873 status = napi_get_boolean(env, success, &result);
2874 if (status != napi_ok) {
2875 HiLog::Error(LABEL, "Create set 24HourClock boolean value failed");
2876 return nullptr;
2877 }
2878 return result;
2879 }
2880
AddPreferredLanguage(napi_env env,napi_callback_info info)2881 napi_value I18nAddon::AddPreferredLanguage(napi_env env, napi_callback_info info)
2882 {
2883 return I18nAddon::AddPreferredLanguageImpl(env, info, false);
2884 }
2885
AddPreferredLanguageWithError(napi_env env,napi_callback_info info)2886 napi_value I18nAddon::AddPreferredLanguageWithError(napi_env env, napi_callback_info info)
2887 {
2888 return I18nAddon::AddPreferredLanguageImpl(env, info, true);
2889 }
2890
ParseStringParam(napi_env env,napi_value argv,bool throwError,std::string & strParam)2891 bool I18nAddon::ParseStringParam(napi_env env, napi_value argv, bool throwError, std::string &strParam)
2892 {
2893 if (argv == nullptr) {
2894 HiLog::Error(LABEL, "Missing parameter");
2895 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
2896 return false;
2897 }
2898 napi_valuetype valueType = napi_valuetype::napi_undefined;
2899 napi_typeof(env, argv, &valueType);
2900 if (valueType != napi_valuetype::napi_string) {
2901 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
2902 return false;
2903 }
2904 size_t len = 0;
2905 napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
2906 if (status != napi_ok) {
2907 HiLog::Error(LABEL, "get string parameter length failed");
2908 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
2909 return false;
2910 }
2911 std::vector<char> res(len + 1);
2912 status = napi_get_value_string_utf8(env, argv, res.data(), len + 1, &len);
2913 if (status != napi_ok) {
2914 HiLog::Error(LABEL, "get string parameter failed");
2915 return false;
2916 }
2917 strParam = res.data();
2918 return true;
2919 }
2920
AddPreferredLanguageImpl(napi_env env,napi_callback_info info,bool throwError)2921 napi_value I18nAddon::AddPreferredLanguageImpl(napi_env env, napi_callback_info info, bool throwError)
2922 {
2923 size_t argc = 2;
2924 napi_value argv[2] = { 0 };
2925 napi_value thisVar = nullptr;
2926 void *data = nullptr;
2927 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2928 if (status != napi_ok) {
2929 return nullptr;
2930 }
2931
2932 std::string language;
2933 if (!ParseStringParam(env, argv[0], throwError, language)) {
2934 return nullptr;
2935 }
2936
2937 int index = 1000000;
2938 if (argv[1] != nullptr) {
2939 status = napi_get_value_int32(env, argv[1], &index);
2940 }
2941 if (status != napi_ok) {
2942 HiLog::Error(LABEL, "addPreferrdLanguage: get index failed");
2943 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
2944 return nullptr;
2945 }
2946 bool success = PreferredLanguage::AddPreferredLanguage(language.data(), index);
2947 if (throwError) {
2948 if (!success) {
2949 ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, throwError);
2950 }
2951 return nullptr;
2952 }
2953 napi_value result = nullptr;
2954 status = napi_get_boolean(env, success, &result);
2955 if (status != napi_ok) {
2956 HiLog::Error(LABEL, "addPreferrdLanguage: create boolean result failed");
2957 return nullptr;
2958 }
2959 return result;
2960 }
2961
RemovePreferredLanguage(napi_env env,napi_callback_info info)2962 napi_value I18nAddon::RemovePreferredLanguage(napi_env env, napi_callback_info info)
2963 {
2964 return I18nAddon::RemovePreferredLanguageImpl(env, info, false);
2965 }
2966
RemovePreferredLanguageWithError(napi_env env,napi_callback_info info)2967 napi_value I18nAddon::RemovePreferredLanguageWithError(napi_env env, napi_callback_info info)
2968 {
2969 return I18nAddon::RemovePreferredLanguageImpl(env, info, true);
2970 }
2971
RemovePreferredLanguageImpl(napi_env env,napi_callback_info info,bool throwError)2972 napi_value I18nAddon::RemovePreferredLanguageImpl(napi_env env, napi_callback_info info, bool throwError)
2973 {
2974 size_t argc = 1;
2975 napi_value argv[1] = { 0 };
2976 napi_value thisVar = nullptr;
2977 void *data = nullptr;
2978 int len = 0;
2979 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2980 if (status != napi_ok) {
2981 return nullptr;
2982 }
2983 if (argv[0] == nullptr) {
2984 HiLog::Error(LABEL, "Missing parameter");
2985 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
2986 return nullptr;
2987 }
2988
2989 napi_valuetype valueType = napi_valuetype::napi_undefined;
2990 napi_typeof(env, argv[0], &valueType);
2991 if (valueType != napi_valuetype::napi_number) {
2992 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
2993 return nullptr;
2994 }
2995 int index = 1000000;
2996 status = napi_get_value_int32(env, argv[0], &index);
2997 if (status != napi_ok) {
2998 HiLog::Error(LABEL, "removePreferrdLanguage: get index failed");
2999 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
3000 return nullptr;
3001 }
3002 len = static_cast<int>(PreferredLanguage::GetPreferredLanguageList().size());
3003 if ((index < 0 || index > len - 1) && throwError) {
3004 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
3005 return nullptr;
3006 }
3007 bool success = PreferredLanguage::RemovePreferredLanguage(index);
3008
3009 if (throwError) {
3010 if (!success) {
3011 ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, throwError);
3012 }
3013 return nullptr;
3014 }
3015 napi_value result = nullptr;
3016 status = napi_get_boolean(env, success, &result);
3017 if (status != napi_ok) {
3018 HiLog::Error(LABEL, "removePreferrdLanguage: create boolean result failed");
3019 return nullptr;
3020 }
3021 return result;
3022 }
3023
GetPreferredLanguageList(napi_env env,napi_callback_info info)3024 napi_value I18nAddon::GetPreferredLanguageList(napi_env env, napi_callback_info info)
3025 {
3026 std::vector<std::string> languageList = PreferredLanguage::GetPreferredLanguageList();
3027 napi_value result = nullptr;
3028 napi_status status = napi_ok;
3029 status = napi_create_array_with_length(env, languageList.size(), &result);
3030 if (status != napi_ok) {
3031 HiLog::Error(LABEL, "getPreferrdLanguageList: create array failed");
3032 return nullptr;
3033 }
3034 for (size_t i = 0; i < languageList.size(); i++) {
3035 napi_value value = nullptr;
3036 status = napi_create_string_utf8(env, languageList[i].c_str(), NAPI_AUTO_LENGTH, &value);
3037 if (status != napi_ok) {
3038 HiLog::Error(LABEL, "getPreferrdLanguageList: create string failed");
3039 return nullptr;
3040 }
3041 status = napi_set_element(env, result, i, value);
3042 if (status != napi_ok) {
3043 HiLog::Error(LABEL, "GetPreferredLanguageList: set array item failed");
3044 return nullptr;
3045 }
3046 }
3047 return result;
3048 }
3049
GetFirstPreferredLanguage(napi_env env,napi_callback_info info)3050 napi_value I18nAddon::GetFirstPreferredLanguage(napi_env env, napi_callback_info info)
3051 {
3052 std::string language = PreferredLanguage::GetFirstPreferredLanguage();
3053 napi_value result = nullptr;
3054 napi_status status = napi_ok;
3055 status = napi_create_string_utf8(env, language.c_str(), NAPI_AUTO_LENGTH, &result);
3056 if (status != napi_ok) {
3057 HiLog::Error(LABEL, "getFirstPreferrdLanguage: create string result failed");
3058 return nullptr;
3059 }
3060 return result;
3061 }
3062
InitI18nTimeZone(napi_env env,napi_value exports)3063 napi_value I18nAddon::InitI18nTimeZone(napi_env env, napi_value exports)
3064 {
3065 napi_status status = napi_ok;
3066 napi_property_descriptor properties[] = {
3067 DECLARE_NAPI_FUNCTION("getID", GetID),
3068 DECLARE_NAPI_FUNCTION("getDisplayName", GetTimeZoneDisplayName),
3069 DECLARE_NAPI_FUNCTION("getRawOffset", GetRawOffset),
3070 DECLARE_NAPI_FUNCTION("getOffset", GetOffset),
3071 };
3072 napi_value constructor = nullptr;
3073 status = napi_define_class(env, "TimeZone", NAPI_AUTO_LENGTH, I18nTimeZoneConstructor, nullptr,
3074 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
3075 if (status != napi_ok) {
3076 HiLog::Error(LABEL, "Failed to define class TimeZone at Init");
3077 return nullptr;
3078 }
3079 g_timezoneConstructor = new (std::nothrow) napi_ref;
3080 if (!g_timezoneConstructor) {
3081 HiLog::Error(LABEL, "Failed to create TimeZone ref at init");
3082 return nullptr;
3083 }
3084 status = napi_create_reference(env, constructor, 1, g_timezoneConstructor);
3085 if (status != napi_ok) {
3086 HiLog::Error(LABEL, "Failed to create reference g_timezoneConstructor at init");
3087 return nullptr;
3088 }
3089 return exports;
3090 }
3091
I18nTimeZoneConstructor(napi_env env,napi_callback_info info)3092 napi_value I18nAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info info)
3093 {
3094 size_t argc = 2;
3095 napi_value argv[2] = { nullptr };
3096 napi_value thisVar = nullptr;
3097 void *data = nullptr;
3098 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3099 if (status != napi_ok) {
3100 return nullptr;
3101 }
3102 std::string zoneID = "";
3103 napi_valuetype valueType = napi_valuetype::napi_undefined;
3104 if (argv[0] != nullptr) {
3105 napi_typeof(env, argv[0], &valueType);
3106 if (valueType != napi_valuetype::napi_string) {
3107 return nullptr;
3108 }
3109 int32_t code = 0;
3110 zoneID = GetString(env, argv[0], code);
3111 if (code != 0) {
3112 return nullptr;
3113 }
3114 }
3115 if (argv[1] == nullptr) {
3116 return nullptr;
3117 }
3118 napi_typeof(env, argv[1], &valueType);
3119 if (valueType != napi_valuetype::napi_boolean) {
3120 return nullptr;
3121 }
3122 bool isZoneID = false;
3123 status = napi_get_value_bool(env, argv[1], &isZoneID);
3124 if (status != napi_ok) {
3125 return nullptr;
3126 }
3127 std::unique_ptr<I18nAddon> obj = std::make_unique<I18nAddon>();
3128 status =
3129 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
3130 if (status != napi_ok) {
3131 return nullptr;
3132 }
3133 obj->timezone_ = I18nTimeZone::CreateInstance(zoneID, isZoneID);
3134 if (!obj->timezone_) {
3135 return nullptr;
3136 }
3137 obj.release();
3138 return thisVar;
3139 }
3140
GetI18nTimeZone(napi_env env,napi_callback_info info)3141 napi_value I18nAddon::GetI18nTimeZone(napi_env env, napi_callback_info info)
3142 {
3143 size_t argc = 1;
3144 napi_value argv[1] = { nullptr };
3145 napi_value thisVar = nullptr;
3146 void *data = nullptr;
3147 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3148 if (argv[0] == nullptr) {
3149 napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &argv[0]);
3150 }
3151 return StaticGetTimeZone(env, argv, true);
3152 }
3153
GetID(napi_env env,napi_callback_info info)3154 napi_value I18nAddon::GetID(napi_env env, napi_callback_info info)
3155 {
3156 size_t argc = 0;
3157 napi_value *argv = nullptr;
3158 napi_value thisVar = nullptr;
3159 void *data = nullptr;
3160 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3161 I18nAddon *obj = nullptr;
3162 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
3163 if (status != napi_ok || !obj || !obj->timezone_) {
3164 HiLog::Error(LABEL, "Get TimeZone object failed");
3165 return nullptr;
3166 }
3167 std::string result = obj->timezone_->GetID();
3168 napi_value value = nullptr;
3169 status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
3170 if (status != napi_ok) {
3171 HiLog::Error(LABEL, "Create result failed");
3172 return nullptr;
3173 }
3174 return value;
3175 }
3176
GetStringFromJS(napi_env env,napi_value argv,std::string & jsString)3177 bool I18nAddon::GetStringFromJS(napi_env env, napi_value argv, std::string &jsString)
3178 {
3179 size_t len = 0;
3180 napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
3181 if (status != napi_ok) {
3182 HiLog::Error(LABEL, "Failed to get string length");
3183 return false;
3184 }
3185 std::vector<char> argvBuf(len + 1);
3186 status = napi_get_value_string_utf8(env, argv, argvBuf.data(), len + 1, &len);
3187 if (status != napi_ok) {
3188 HiLog::Error(LABEL, "Failed to get string item");
3189 return false;
3190 }
3191 jsString = argvBuf.data();
3192 return true;
3193 }
3194
GetParameter(napi_env env,napi_value * argv,std::string & localeStr,bool & isDST)3195 int32_t I18nAddon::GetParameter(napi_env env, napi_value *argv, std::string &localeStr, bool &isDST)
3196 {
3197 if (!argv[0]) {
3198 return 0; // 0 represents no parameter.
3199 }
3200 napi_status status = napi_ok;
3201 if (!argv[1]) {
3202 napi_valuetype valueType = napi_valuetype::napi_undefined;
3203 napi_typeof(env, argv[0], &valueType);
3204 if (valueType == napi_valuetype::napi_string) {
3205 bool valid = GetStringFromJS(env, argv[0], localeStr);
3206 if (!valid) {
3207 return -1; // -1 represents Invalid parameter.
3208 }
3209 return 1; // 1 represents one string parameter.
3210 } else if (valueType == napi_valuetype::napi_boolean) {
3211 status = napi_get_value_bool(env, argv[0], &isDST);
3212 if (status != napi_ok) {
3213 return -1; // -1 represents Invalid parameter.
3214 }
3215 return 2; // 2 represents one boolean parameter.
3216 } else {
3217 return -1; // -1 represents Invalid parameter.
3218 }
3219 }
3220 napi_valuetype valueType0 = napi_valuetype::napi_undefined;
3221 napi_valuetype valueType1 = napi_valuetype::napi_undefined;
3222 napi_typeof(env, argv[0], &valueType0); // 0 represents first parameter
3223 napi_typeof(env, argv[1], &valueType1); // 0 represents second parameter
3224 if (valueType0 != napi_valuetype::napi_string || valueType1 != napi_valuetype::napi_boolean) {
3225 return -1; // -1 represents Invalid parameter.
3226 }
3227 bool valid = GetStringFromJS(env, argv[0], localeStr);
3228 if (!valid) {
3229 return -1; // -1 represents Invalid parameter.
3230 }
3231 status = napi_get_value_bool(env, argv[1], &isDST);
3232 if (status != napi_ok) {
3233 return -1; // -1 represents Invalid parameter.
3234 }
3235 return 3; // 3 represents one string parameter and one bool parameter.
3236 }
3237
GetTimeZoneDisplayName(napi_env env,napi_callback_info info)3238 napi_value I18nAddon::GetTimeZoneDisplayName(napi_env env, napi_callback_info info)
3239 {
3240 size_t argc = 2;
3241 napi_value argv[2] = { 0 };
3242 napi_value thisVar = nullptr;
3243 void *data = nullptr;
3244 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3245 if (status != napi_ok) {
3246 return nullptr;
3247 }
3248
3249 I18nAddon *obj = nullptr;
3250 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
3251 if (status != napi_ok || !obj || !obj->timezone_) {
3252 HiLog::Error(LABEL, "Get TimeZone object failed");
3253 return nullptr;
3254 }
3255
3256 std::string locale;
3257 bool isDST = false;
3258 int32_t parameterStatus = GetParameter(env, argv, locale, isDST);
3259
3260 std::string result;
3261 if (parameterStatus == -1) { // -1 represents Invalid parameter.
3262 napi_throw_type_error(env, nullptr, "Parameter type does not match");
3263 return nullptr;
3264 } else if (parameterStatus == 0) {
3265 result = obj->timezone_->GetDisplayName();
3266 } else if (parameterStatus == 1) { // 1 represents one string parameter.
3267 result = obj->timezone_->GetDisplayName(locale);
3268 } else if (parameterStatus == 2) { // 2 represents one boolean parameter.
3269 result = obj->timezone_->GetDisplayName(isDST);
3270 } else {
3271 result = obj->timezone_->GetDisplayName(locale, isDST);
3272 }
3273
3274 napi_value value = nullptr;
3275 status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
3276 if (status != napi_ok) {
3277 HiLog::Error(LABEL, "Create result failed");
3278 return nullptr;
3279 }
3280 return value;
3281 }
3282
GetOffset(napi_env env,napi_callback_info info)3283 napi_value I18nAddon::GetOffset(napi_env env, napi_callback_info info)
3284 {
3285 size_t argc = 1;
3286 napi_value argv[1] = { 0 };
3287 napi_value thisVar = nullptr;
3288 void *data = nullptr;
3289 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3290 if (status != napi_ok) {
3291 return nullptr;
3292 }
3293
3294 double date = 0;
3295 if (argv[0]) {
3296 napi_valuetype valueType = napi_valuetype::napi_undefined;
3297 napi_typeof(env, argv[0], &valueType);
3298 if (valueType != napi_valuetype::napi_number) {
3299 HiLog::Error(LABEL, "Invalid parameter type");
3300 return nullptr;
3301 }
3302 status = napi_get_value_double(env, argv[0], &date);
3303 if (status != napi_ok) {
3304 HiLog::Error(LABEL, "Get parameter date failed");
3305 return nullptr;
3306 }
3307 } else {
3308 auto time = std::chrono::system_clock::now();
3309 auto since_epoch = time.time_since_epoch();
3310 auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch);
3311 date = (double)millis.count();
3312 }
3313
3314 I18nAddon *obj = nullptr;
3315 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
3316 if (status != napi_ok || !obj || !obj->timezone_) {
3317 HiLog::Error(LABEL, "Get TimeZone object failed");
3318 return nullptr;
3319 }
3320 int32_t result = obj->timezone_->GetOffset(date);
3321 napi_value value = nullptr;
3322 status = napi_create_int32(env, result, &value);
3323 if (status != napi_ok) {
3324 HiLog::Error(LABEL, "Create result failed");
3325 return nullptr;
3326 }
3327 return value;
3328 }
3329
GetRawOffset(napi_env env,napi_callback_info info)3330 napi_value I18nAddon::GetRawOffset(napi_env env, napi_callback_info info)
3331 {
3332 size_t argc = 0;
3333 napi_value *argv = nullptr;
3334 napi_value thisVar = nullptr;
3335 void *data = nullptr;
3336 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3337 I18nAddon *obj = nullptr;
3338 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
3339 if (status != napi_ok || !obj || !obj->timezone_) {
3340 HiLog::Error(LABEL, "Get TimeZone object failed");
3341 return nullptr;
3342 }
3343 int32_t result = obj->timezone_->GetRawOffset();
3344 napi_value value = nullptr;
3345 status = napi_create_int32(env, result, &value);
3346 if (status != napi_ok) {
3347 HiLog::Error(LABEL, "Create result failed");
3348 return nullptr;
3349 }
3350 return value;
3351 }
3352
SetUsingLocalDigitAddon(napi_env env,napi_callback_info info)3353 napi_value I18nAddon::SetUsingLocalDigitAddon(napi_env env, napi_callback_info info)
3354 {
3355 return I18nAddon::SetUsingLocalDigitAddonImpl(env, info, false);
3356 }
3357
SetUsingLocalDigitAddonWithError(napi_env env,napi_callback_info info)3358 napi_value I18nAddon::SetUsingLocalDigitAddonWithError(napi_env env, napi_callback_info info)
3359 {
3360 return I18nAddon::SetUsingLocalDigitAddonImpl(env, info, true);
3361 }
3362
SetUsingLocalDigitAddonImpl(napi_env env,napi_callback_info info,bool throwError)3363 napi_value I18nAddon::SetUsingLocalDigitAddonImpl(napi_env env, napi_callback_info info, bool throwError)
3364 {
3365 size_t argc = 1;
3366 napi_value argv[1] = { 0 };
3367 napi_value thisVar = nullptr;
3368 void *data = nullptr;
3369 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3370
3371 if (argv[0] == nullptr) {
3372 HiLog::Error(LABEL, "Invalid parameter nullptr");
3373 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, throwError);
3374 return nullptr;
3375 }
3376 napi_valuetype valueType = napi_valuetype::napi_undefined;
3377 napi_typeof(env, argv[0], &valueType);
3378 if (valueType != napi_valuetype::napi_boolean) {
3379 HiLog::Error(LABEL, "Invalid parameter type");
3380 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, throwError);
3381 return nullptr;
3382 }
3383 bool flag = false;
3384 napi_status status = napi_get_value_bool(env, argv[0], &flag);
3385 if (status != napi_ok) {
3386 HiLog::Error(LABEL, "Get parameter flag failed");
3387 return nullptr;
3388 }
3389
3390 bool res = LocaleConfig::SetUsingLocalDigit(flag);
3391 if (throwError) {
3392 if (!res) {
3393 ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, throwError);
3394 }
3395 return nullptr;
3396 }
3397 napi_value value = nullptr;
3398 status = napi_get_boolean(env, res, &value);
3399 if (status != napi_ok) {
3400 HiLog::Error(LABEL, "Invalid result");
3401 return nullptr;
3402 }
3403 return value;
3404 }
3405
GetUsingLocalDigitAddon(napi_env env,napi_callback_info info)3406 napi_value I18nAddon::GetUsingLocalDigitAddon(napi_env env, napi_callback_info info)
3407 {
3408 bool res = LocaleConfig::GetUsingLocalDigit();
3409 napi_value value = nullptr;
3410 napi_status status = napi_get_boolean(env, res, &value);
3411 if (status != napi_ok) {
3412 return nullptr;
3413 }
3414 return value;
3415 }
3416
CreateTimeZoneObject(napi_env env)3417 napi_value I18nAddon::CreateTimeZoneObject(napi_env env)
3418 {
3419 napi_status status = napi_ok;
3420 napi_value timezone = nullptr;
3421 status = napi_create_object(env, &timezone);
3422 if (status != napi_ok) {
3423 HiLog::Error(LABEL, "Failed to create timezone object at init");
3424 return nullptr;
3425 }
3426 napi_property_descriptor timezoneProperties[] = {
3427 DECLARE_NAPI_FUNCTION("getAvailableIDs", GetAvailableTimezoneIDs),
3428 DECLARE_NAPI_FUNCTION("getAvailableZoneCityIDs", GetAvailableZoneCityIDs),
3429 DECLARE_NAPI_FUNCTION("getCityDisplayName", GetCityDisplayName),
3430 DECLARE_NAPI_FUNCTION("getTimezoneFromCity", GetTimezoneFromCity)
3431 };
3432 status = napi_define_properties(env, timezone,
3433 sizeof(timezoneProperties) / sizeof(napi_property_descriptor),
3434 timezoneProperties);
3435 if (status != napi_ok) {
3436 HiLog::Error(LABEL, "Failed to set properties of timezone at init");
3437 return nullptr;
3438 }
3439 return timezone;
3440 }
3441
CreateSystemObject(napi_env env)3442 napi_value I18nAddon::CreateSystemObject(napi_env env)
3443 {
3444 napi_status status = napi_ok;
3445 napi_value system = nullptr;
3446 status = napi_create_object(env, &system);
3447 if (status != napi_ok) {
3448 HiLog::Error(LABEL, "Failed to create system object at init");
3449 return nullptr;
3450 }
3451 napi_property_descriptor systemProperties[] = {
3452 DECLARE_NAPI_FUNCTION("getDisplayCountry", GetDisplayCountryWithError),
3453 DECLARE_NAPI_FUNCTION("getDisplayLanguage", GetDisplayLanguageWithError),
3454 DECLARE_NAPI_FUNCTION("getSystemLanguages", GetSystemLanguages),
3455 DECLARE_NAPI_FUNCTION("getSystemCountries", GetSystemCountriesWithError),
3456 DECLARE_NAPI_FUNCTION("isSuggested", IsSuggestedWithError),
3457 DECLARE_NAPI_FUNCTION("getSystemLanguage", GetSystemLanguage),
3458 DECLARE_NAPI_FUNCTION("setSystemLanguage", SetSystemLanguageWithError),
3459 DECLARE_NAPI_FUNCTION("getSystemRegion", GetSystemRegion),
3460 DECLARE_NAPI_FUNCTION("setSystemRegion", SetSystemRegionWithError),
3461 DECLARE_NAPI_FUNCTION("getSystemLocale", GetSystemLocale),
3462 DECLARE_NAPI_FUNCTION("setSystemLocale", SetSystemLocaleWithError),
3463 DECLARE_NAPI_FUNCTION("is24HourClock", Is24HourClock),
3464 DECLARE_NAPI_FUNCTION("set24HourClock", Set24HourClockWithError),
3465 DECLARE_NAPI_FUNCTION("addPreferredLanguage", AddPreferredLanguageWithError),
3466 DECLARE_NAPI_FUNCTION("removePreferredLanguage", RemovePreferredLanguageWithError),
3467 DECLARE_NAPI_FUNCTION("getPreferredLanguageList", GetPreferredLanguageList),
3468 DECLARE_NAPI_FUNCTION("getFirstPreferredLanguage", GetFirstPreferredLanguage),
3469 DECLARE_NAPI_FUNCTION("getAppPreferredLanguage", GetFirstPreferredLanguage),
3470 DECLARE_NAPI_FUNCTION("setUsingLocalDigit", SetUsingLocalDigitAddonWithError),
3471 DECLARE_NAPI_FUNCTION("getUsingLocalDigit", GetUsingLocalDigitAddon),
3472 };
3473 status = napi_define_properties(env, system,
3474 sizeof(systemProperties) / sizeof(napi_property_descriptor),
3475 systemProperties);
3476 if (status != napi_ok) {
3477 HiLog::Error(LABEL, "Failed to set properties of system at init");
3478 return nullptr;
3479 }
3480 return system;
3481 }
3482
GetAvailableTimezoneIDs(napi_env env,napi_callback_info info)3483 napi_value I18nAddon::GetAvailableTimezoneIDs(napi_env env, napi_callback_info info)
3484 {
3485 std::set<std::string> timezoneIDs = I18nTimeZone::GetAvailableIDs();
3486 napi_value result = nullptr;
3487 napi_status status = napi_create_array_with_length(env, timezoneIDs.size(), &result);
3488 if (status != napi_ok) {
3489 HiLog::Error(LABEL, "Failed to create array");
3490 return nullptr;
3491 }
3492 size_t index = 0;
3493 for (std::set<std::string>::iterator it = timezoneIDs.begin(); it != timezoneIDs.end(); ++it) {
3494 napi_value value = nullptr;
3495 status = napi_create_string_utf8(env, (*it).c_str(), NAPI_AUTO_LENGTH, &value);
3496 if (status != napi_ok) {
3497 HiLog::Error(LABEL, "Failed to create string item");
3498 return nullptr;
3499 }
3500 status = napi_set_element(env, result, index, value);
3501 if (status != napi_ok) {
3502 HiLog::Error(LABEL, "Failed to set array item");
3503 return nullptr;
3504 }
3505 ++index;
3506 }
3507 return result;
3508 }
3509
GetAvailableZoneCityIDs(napi_env env,napi_callback_info info)3510 napi_value I18nAddon::GetAvailableZoneCityIDs(napi_env env, napi_callback_info info)
3511 {
3512 std::vector<std::string> cityIDs = I18nTimeZone::GetAvailableZoneCityIDs();
3513 napi_value result = nullptr;
3514 napi_status status = napi_create_array_with_length(env, cityIDs.size(), &result);
3515 if (status != napi_ok) {
3516 HiLog::Error(LABEL, "Failed to create array");
3517 return nullptr;
3518 }
3519 for (size_t i = 0; i < cityIDs.size(); ++i) {
3520 napi_value value = nullptr;
3521 status = napi_create_string_utf8(env, cityIDs[i].c_str(), NAPI_AUTO_LENGTH, &value);
3522 if (status != napi_ok) {
3523 HiLog::Error(LABEL, "GetAvailableZoneCityIDs: Failed to create string item");
3524 return nullptr;
3525 }
3526 status = napi_set_element(env, result, i, value);
3527 if (status != napi_ok) {
3528 HiLog::Error(LABEL, "GetAvailableZoneCityIDs: Failed to set array item");
3529 return nullptr;
3530 }
3531 }
3532 return result;
3533 }
3534
GetCityDisplayName(napi_env env,napi_callback_info info)3535 napi_value I18nAddon::GetCityDisplayName(napi_env env, napi_callback_info info)
3536 {
3537 size_t argc = 2;
3538 napi_value argv[2] = { 0 };
3539 napi_value thisVar = nullptr;
3540 void *data = nullptr;
3541 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3542 if (status != napi_ok) {
3543 return nullptr;
3544 }
3545 if (argv[0] == nullptr || argv[1] == nullptr) {
3546 return nullptr;
3547 }
3548 napi_valuetype valueType = napi_valuetype::napi_undefined;
3549 napi_typeof(env, argv[0], &valueType);
3550 if (valueType != napi_valuetype::napi_string) {
3551 HiLog::Error(LABEL, "Invalid parameter type");
3552 return nullptr;
3553 }
3554 int32_t code = 0;
3555 std::string cityID = GetString(env, argv[0], code);
3556 if (code != 0) {
3557 return nullptr;
3558 }
3559 std::string locale = GetString(env, argv[1], code);
3560 if (code != 0) {
3561 return nullptr;
3562 }
3563 std::string name = I18nTimeZone::GetCityDisplayName(cityID, locale);
3564 napi_value result = nullptr;
3565 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result);
3566 if (status != napi_ok) {
3567 return nullptr;
3568 }
3569 return result;
3570 }
3571
StaticGetTimeZone(napi_env env,napi_value * argv,bool isZoneID)3572 napi_value I18nAddon::StaticGetTimeZone(napi_env env, napi_value *argv, bool isZoneID)
3573 {
3574 napi_value constructor = nullptr;
3575 napi_status status = napi_get_reference_value(env, *g_timezoneConstructor, &constructor);
3576 if (status != napi_ok) {
3577 HiLog::Error(LABEL, "Failed to create reference at StaticGetTimeZone");
3578 return nullptr;
3579 }
3580 napi_value newArgv[2] = { 0 };
3581 newArgv[0] = argv[0];
3582 status = napi_get_boolean(env, isZoneID, &newArgv[1]);
3583 if (status != napi_ok) {
3584 return nullptr;
3585 }
3586 napi_value result = nullptr;
3587 status = napi_new_instance(env, constructor, 2, newArgv, &result); // 2 is parameter num
3588 if (status != napi_ok) {
3589 HiLog::Error(LABEL, "StaticGetTimeZone create instance failed");
3590 return nullptr;
3591 }
3592 return result;
3593 }
3594
GetTimezoneFromCity(napi_env env,napi_callback_info info)3595 napi_value I18nAddon::GetTimezoneFromCity(napi_env env, napi_callback_info info)
3596 {
3597 size_t argc = 1;
3598 napi_value argv[1] = { nullptr };
3599 napi_value thisVar = nullptr;
3600 void *data = nullptr;
3601 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3602 return StaticGetTimeZone(env, argv, false);
3603 }
3604
InitCharacter(napi_env env,napi_value exports)3605 napi_value I18nAddon::InitCharacter(napi_env env, napi_value exports)
3606 {
3607 napi_status status = napi_ok;
3608 napi_property_descriptor properties[] = {
3609 DECLARE_NAPI_FUNCTION("isDigit", IsDigitAddon),
3610 DECLARE_NAPI_FUNCTION("isSpaceChar", IsSpaceCharAddon),
3611 DECLARE_NAPI_FUNCTION("isWhitespace", IsWhiteSpaceAddon),
3612 DECLARE_NAPI_FUNCTION("isRTL", IsRTLCharacterAddon),
3613 DECLARE_NAPI_FUNCTION("isIdeograph", IsIdeoGraphicAddon),
3614 DECLARE_NAPI_FUNCTION("isLetter", IsLetterAddon),
3615 DECLARE_NAPI_FUNCTION("isLowerCase", IsLowerCaseAddon),
3616 DECLARE_NAPI_FUNCTION("isUpperCase", IsUpperCaseAddon),
3617 DECLARE_NAPI_FUNCTION("getType", GetTypeAddon)
3618 };
3619
3620 napi_value constructor = nullptr;
3621 status = napi_define_class(env, "Character", NAPI_AUTO_LENGTH, ObjectConstructor, nullptr,
3622 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
3623 if (status != napi_ok) {
3624 HiLog::Error(LABEL, "Define class failed when InitCharacter");
3625 return nullptr;
3626 }
3627
3628 status = napi_set_named_property(env, exports, "Character", constructor);
3629 if (status != napi_ok) {
3630 HiLog::Error(LABEL, "Set property failed when InitCharacter");
3631 return nullptr;
3632 }
3633 return exports;
3634 }
3635
ObjectConstructor(napi_env env,napi_callback_info info)3636 napi_value I18nAddon::ObjectConstructor(napi_env env, napi_callback_info info)
3637 {
3638 size_t argc = 0;
3639 napi_value argv[0];
3640 napi_value thisVar = nullptr;
3641 void *data = nullptr;
3642 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3643 if (status != napi_ok) {
3644 return nullptr;
3645 }
3646 std::unique_ptr<I18nAddon> obj = nullptr;
3647 obj = std::make_unique<I18nAddon>();
3648 status =
3649 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, nullptr);
3650 if (status != napi_ok) {
3651 HiLog::Error(LABEL, "Wrap I18nAddon failed");
3652 return nullptr;
3653 }
3654 obj.release();
3655 return thisVar;
3656 }
3657
InitUtil(napi_env env,napi_value exports)3658 napi_value I18nAddon::InitUtil(napi_env env, napi_value exports)
3659 {
3660 napi_status status = napi_ok;
3661 napi_property_descriptor properties[] = {
3662 DECLARE_NAPI_FUNCTION("unitConvert", UnitConvert)
3663 };
3664
3665 napi_value constructor = nullptr;
3666 status = napi_define_class(env, "Util", NAPI_AUTO_LENGTH, ObjectConstructor, nullptr,
3667 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
3668 if (status != napi_ok) {
3669 HiLog::Error(LABEL, "Define class failed when InitUtil");
3670 return nullptr;
3671 }
3672
3673 status = napi_set_named_property(env, exports, "Util", constructor);
3674 if (status != napi_ok) {
3675 HiLog::Error(LABEL, "Set property failed when InitUtil");
3676 return nullptr;
3677 }
3678 return exports;
3679 }
3680
Init(napi_env env,napi_value exports)3681 napi_value Init(napi_env env, napi_value exports)
3682 {
3683 napi_value val = I18nAddon::Init(env, exports);
3684 val = I18nAddon::InitPhoneNumberFormat(env, val);
3685 val = I18nAddon::InitBreakIterator(env, val);
3686 val = I18nAddon::InitI18nCalendar(env, val);
3687 val = I18nAddon::InitIndexUtil(env, val);
3688 val = I18nAddon::InitI18nTimeZone(env, val);
3689 val = I18nAddon::InitTransliterator(env, val);
3690 val = I18nAddon::InitCharacter(env, val);
3691 val = I18nAddon::InitUtil(env, val);
3692 return val;
3693 }
3694
3695 static napi_module g_i18nModule = {
3696 .nm_version = 1,
3697 .nm_flags = 0,
3698 .nm_filename = nullptr,
3699 .nm_register_func = Init,
3700 .nm_modname = "i18n",
3701 .nm_priv = nullptr,
3702 .reserved = { 0 }
3703 };
3704
I18nRegister()3705 extern "C" __attribute__((constructor)) void I18nRegister()
3706 {
3707 napi_module_register(&g_i18nModule);
3708 }
3709 } // namespace I18n
3710 } // namespace Global
3711 } // namespace OHOS
3712