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