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