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 #include "character.h"
19 #include "hilog/log.h"
20 #include "i18n_calendar.h"
21 #include "node_api.h"
22 #include "i18n_addon.h"
23
24 namespace OHOS {
25 namespace Global {
26 namespace I18n {
27 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001E00, "I18nJs" };
28 static thread_local napi_ref* g_constructor = nullptr;
29 static thread_local napi_ref* g_brkConstructor = nullptr;
30 static thread_local napi_ref* g_timezoneConstructor = nullptr;
31 static thread_local napi_ref g_indexUtilConstructor = nullptr;
32 static std::unordered_map<std::string, UCalendarDateFields> g_fieldsMap {
33 { "era", UCAL_ERA },
34 { "year", UCAL_YEAR },
35 { "month", UCAL_MONTH },
36 { "week_of_year", UCAL_WEEK_OF_YEAR },
37 { "week_of_month", UCAL_WEEK_OF_MONTH },
38 { "date", UCAL_DATE },
39 { "day_of_year", UCAL_DAY_OF_YEAR },
40 { "day_of_week", UCAL_DAY_OF_WEEK },
41 { "day_of_week_in_month", UCAL_DAY_OF_WEEK_IN_MONTH },
42 { "ap_pm", UCAL_AM_PM },
43 { "hour", UCAL_HOUR },
44 { "hour_of_day", UCAL_HOUR_OF_DAY },
45 { "minute", UCAL_MINUTE },
46 { "second", UCAL_SECOND },
47 { "millisecond", UCAL_MILLISECOND },
48 { "zone_offset", UCAL_ZONE_OFFSET },
49 { "dst_offset", UCAL_DST_OFFSET },
50 { "year_woy", UCAL_YEAR_WOY },
51 { "dow_local", UCAL_DOW_LOCAL },
52 { "extended_year", UCAL_EXTENDED_YEAR },
53 { "julian_day", UCAL_JULIAN_DAY },
54 { "milliseconds_in_day", UCAL_MILLISECONDS_IN_DAY },
55 { "is_leap_month", UCAL_IS_LEAP_MONTH },
56 };
57 static std::unordered_map<std::string, CalendarType> g_typeMap {
58 { "buddhist", CalendarType::BUDDHIST },
59 { "chinese", CalendarType::CHINESE },
60 { "coptic", CalendarType::COPTIC },
61 { "ethiopic", CalendarType::ETHIOPIC },
62 { "hebrew", CalendarType::HEBREW },
63 { "gregory", CalendarType::GREGORY },
64 { "indian", CalendarType::INDIAN },
65 { "islamic_civil", CalendarType::ISLAMIC_CIVIL },
66 { "islamic_tbla", CalendarType::ISLAMIC_TBLA },
67 { "islamic_umalqura", CalendarType::ISLAMIC_UMALQURA },
68 { "japanese", CalendarType::JAPANESE },
69 { "persion", CalendarType::PERSIAN },
70 };
71 using namespace OHOS::HiviewDFX;
72
I18nAddon()73 I18nAddon::I18nAddon() : env_(nullptr), wrapper_(nullptr) {}
74
~I18nAddon()75 I18nAddon::~I18nAddon()
76 {
77 napi_delete_reference(env_, wrapper_);
78 }
79
Destructor(napi_env env,void * nativeObject,void * hint)80 void I18nAddon::Destructor(napi_env env, void *nativeObject, void *hint)
81 {
82 if (!nativeObject) {
83 return;
84 }
85 reinterpret_cast<I18nAddon *>(nativeObject)->~I18nAddon();
86 }
87
CreateCharacterObject(napi_env env)88 napi_value I18nAddon::CreateCharacterObject(napi_env env)
89 {
90 napi_status status = napi_ok;
91 napi_value character = nullptr;
92 status = napi_create_object(env, &character);
93 if (status != napi_ok) {
94 HiLog::Error(LABEL, "Failed to create character object at init");
95 return nullptr;
96 }
97 napi_property_descriptor characterProperties[] = {
98 DECLARE_NAPI_FUNCTION("isDigit", IsDigitAddon),
99 DECLARE_NAPI_FUNCTION("isSpaceChar", IsSpaceCharAddon),
100 DECLARE_NAPI_FUNCTION("isWhitespace", IsWhiteSpaceAddon),
101 DECLARE_NAPI_FUNCTION("isRTL", IsRTLCharacterAddon),
102 DECLARE_NAPI_FUNCTION("isIdeograph", IsIdeoGraphicAddon),
103 DECLARE_NAPI_FUNCTION("isLetter", IsLetterAddon),
104 DECLARE_NAPI_FUNCTION("isLowerCase", IsLowerCaseAddon),
105 DECLARE_NAPI_FUNCTION("isUpperCase", IsUpperCaseAddon),
106 DECLARE_NAPI_FUNCTION("getType", GetTypeAddon),
107 };
108 status = napi_define_properties(env, character,
109 sizeof(characterProperties) / sizeof(napi_property_descriptor),
110 characterProperties);
111 if (status != napi_ok) {
112 HiLog::Error(LABEL, "Failed to set properties of character at init");
113 return nullptr;
114 }
115 return character;
116 }
117
CreateInitProperties(napi_property_descriptor * properties)118 void I18nAddon::CreateInitProperties(napi_property_descriptor *properties)
119 {
120 properties[0] = DECLARE_NAPI_FUNCTION("getSystemLanguages", GetSystemLanguages); // 0 is properties index
121 properties[1] = DECLARE_NAPI_FUNCTION("getSystemCountries", GetSystemCountries); // 1 is properties index
122 properties[2] = DECLARE_NAPI_FUNCTION("isSuggested", IsSuggested); // 2 is properties index
123 properties[3] = DECLARE_NAPI_FUNCTION("getDisplayLanguage", GetDisplayLanguage); // 3 is properties index
124 properties[4] = DECLARE_NAPI_FUNCTION("getDisplayCountry", GetDisplayCountry); // 4 is properties index
125 properties[5] = DECLARE_NAPI_FUNCTION("getSystemLanguage", GetSystemLanguage); // 5 is properties index
126 properties[6] = DECLARE_NAPI_FUNCTION("getSystemRegion", GetSystemRegion); // 6 is properties index
127 properties[7] = DECLARE_NAPI_FUNCTION("getSystemLocale", GetSystemLocale); // 7 is properties index
128 properties[8] = DECLARE_NAPI_FUNCTION("setSystemLanguage", SetSystemLanguage); // 8 is properties index
129 properties[9] = DECLARE_NAPI_FUNCTION("setSystemRegion", SetSystemRegion); // 9 is properties index
130 properties[10] = DECLARE_NAPI_FUNCTION("setSystemLocale", SetSystemLocale); // 10 is properties index
131 properties[11] = DECLARE_NAPI_FUNCTION("getCalendar", GetCalendar); // 11 is properties index
132 properties[12] = DECLARE_NAPI_FUNCTION("isRTL", IsRTL); // 12 is properties index
133 properties[14] = DECLARE_NAPI_FUNCTION("getLineInstance", GetLineInstance); // 14 is properties index
134 properties[15] = DECLARE_NAPI_FUNCTION("getInstance", GetIndexUtil); // 15 is properties index
135 properties[17] = DECLARE_NAPI_FUNCTION("addPreferredLanguage", AddPreferredLanguage); // 17 is properties index
136 // 18 is properties index
137 properties[18] = DECLARE_NAPI_FUNCTION("removePreferredLanguage", RemovePreferredLanguage);
138 // 19 is properties index
139 properties[19] = DECLARE_NAPI_FUNCTION("getPreferredLanguageList", GetPreferredLanguageList);
140 // 20 is properties index
141 properties[20] = DECLARE_NAPI_FUNCTION("getFirstPreferredLanguage", GetFirstPreferredLanguage);
142 // 21 is properties index
143 properties[21] = DECLARE_NAPI_FUNCTION("is24HourClock", Is24HourClock);
144 // 22 is properties index
145 properties[22] = DECLARE_NAPI_FUNCTION("set24HourClock", Set24HourClock);
146 // 23 is properties index
147 properties[23] = DECLARE_NAPI_FUNCTION("getTimeZone", GetI18nTimeZone);
148 }
149
Init(napi_env env,napi_value exports)150 napi_value I18nAddon::Init(napi_env env, napi_value exports)
151 {
152 napi_status status = napi_ok;
153 napi_value util = nullptr;
154 status = napi_create_object(env, &util);
155 if (status != napi_ok) {
156 HiLog::Error(LABEL, "Failed to create util object at init");
157 return nullptr;
158 }
159 napi_property_descriptor utilProperties[] = {
160 DECLARE_NAPI_FUNCTION("unitConvert", UnitConvert),
161 };
162 status = napi_define_properties(env, util,
163 sizeof(utilProperties) / sizeof(napi_property_descriptor),
164 utilProperties);
165 if (status != napi_ok) {
166 HiLog::Error(LABEL, "Failed to set properties of util at init");
167 return nullptr;
168 }
169 napi_value character = CreateCharacterObject(env);
170 if (!character) {
171 return nullptr;
172 }
173 size_t propertiesNums = 24;
174 napi_property_descriptor properties[propertiesNums];
175 CreateInitProperties(properties);
176 properties[13] = DECLARE_NAPI_PROPERTY("Util", util); // 13 is properties index
177 properties[16] = DECLARE_NAPI_PROPERTY("Character", character); // 16 is properties index
178 status = napi_define_properties(env, exports, propertiesNums, properties);
179 if (status != napi_ok) {
180 HiLog::Error(LABEL, "Failed to set properties at init");
181 return nullptr;
182 }
183 return exports;
184 }
185
GetOptionValue(napi_env env,napi_value options,const std::string & optionName,std::string & value)186 void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
187 std::string &value)
188 {
189 napi_value optionValue = nullptr;
190 napi_valuetype type = napi_undefined;
191 napi_status status = napi_typeof(env, options, &type);
192 if (status != napi_ok && type != napi_object) {
193 HiLog::Error(LABEL, "Get option failed, option is not an object");
194 return;
195 }
196 bool hasProperty = false;
197 napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
198 if (propStatus == napi_ok && hasProperty) {
199 status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
200 if (status == napi_ok) {
201 size_t len;
202 napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
203 std::vector<char> optionBuf(len + 1);
204 status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
205 if (status != napi_ok) {
206 HiLog::Error(LABEL, "Failed to get string item");
207 return;
208 }
209 value = optionBuf.data();
210 }
211 }
212 }
213
GetOptionMap(napi_env env,napi_value option,std::map<std::string,std::string> & map)214 void GetOptionMap(napi_env env, napi_value option, std::map<std::string, std::string> &map)
215 {
216 if (option != nullptr) {
217 size_t len;
218 napi_get_value_string_utf8(env, option, nullptr, 0, &len);
219 std::vector<char> styleBuf(len + 1);
220 napi_status status = napi_get_value_string_utf8(env, option, styleBuf.data(), len + 1, &len);
221 if (status != napi_ok) {
222 HiLog::Error(LABEL, "Failed to get string item");
223 return;
224 }
225 map.insert(std::make_pair("unitDisplay", styleBuf.data()));
226 }
227 }
228
UnitConvert(napi_env env,napi_callback_info info)229 napi_value I18nAddon::UnitConvert(napi_env env, napi_callback_info info)
230 {
231 size_t argc = 5;
232 napi_value argv[5] = { 0 };
233 napi_value thisVar = nullptr;
234 void *data = nullptr;
235 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
236 std::string fromUnit;
237 GetOptionValue(env, argv[0], "unit", fromUnit);
238 std::string fromMeasSys;
239 GetOptionValue(env, argv[0], "measureSystem", fromMeasSys);
240 std::string toUnit;
241 GetOptionValue(env, argv[1], "unit", toUnit);
242 std::string toMeasSys;
243 GetOptionValue(env, argv[1], "measureSystem", toMeasSys);
244 double number = 0;
245 napi_get_value_double(env, argv[2], &number); // 2 is the index of value
246 int convertStatus = Convert(number, fromUnit, fromMeasSys, toUnit, toMeasSys);
247 size_t len;
248 napi_get_value_string_utf8(env, argv[3], nullptr, 0, &len); // 3 is the index of value
249 std::vector<char> localeBuf(len + 1);
250 // 3 is the index of value
251 status = napi_get_value_string_utf8(env, argv[3], localeBuf.data(), len + 1, &len);
252 if (status != napi_ok) {
253 HiLog::Error(LABEL, "Failed to get string item");
254 return nullptr;
255 }
256 std::vector<std::string> localeTags;
257 localeTags.push_back(localeBuf.data());
258 std::map<std::string, std::string> map = {};
259 map.insert(std::make_pair("style", "unit"));
260 if (!convertStatus) {
261 HiLog::Error(LABEL, "Do not support the conversion");
262 map.insert(std::make_pair("unit", fromUnit));
263 } else {
264 map.insert(std::make_pair("unit", toUnit));
265 }
266 // 4 is the index of value
267 GetOptionMap(env, argv[4], map);
268 std::unique_ptr<NumberFormat> numberFmt = nullptr;
269 numberFmt = std::make_unique<NumberFormat>(localeTags, map);
270 std::string value = numberFmt->Format(number);
271 napi_value result;
272 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
273 if (status != napi_ok) {
274 HiLog::Error(LABEL, "Failed to create string item");
275 return nullptr;
276 }
277 return result;
278 }
279
IsDigitAddon(napi_env env,napi_callback_info info)280 napi_value I18nAddon::IsDigitAddon(napi_env env, napi_callback_info info)
281 {
282 size_t argc = 1;
283 napi_value argv[1] = { 0 };
284 napi_value thisVar = nullptr;
285 void *data = nullptr;
286 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
287 napi_valuetype valueType = napi_valuetype::napi_undefined;
288 napi_typeof(env, argv[0], &valueType);
289 if (valueType != napi_valuetype::napi_string) {
290 napi_throw_type_error(env, nullptr, "Parameter type does not match");
291 return nullptr;
292 }
293 int32_t code = 0;
294 std::string character = GetString(env, argv[0], code);
295 if (code) {
296 return nullptr;
297 }
298 bool isDigit = IsDigit(character);
299 napi_value result = nullptr;
300 status = napi_get_boolean(env, isDigit, &result);
301 if (status != napi_ok) {
302 HiLog::Error(LABEL, "Create isDigit boolean value failed");
303 return nullptr;
304 }
305 return result;
306 }
307
IsSpaceCharAddon(napi_env env,napi_callback_info info)308 napi_value I18nAddon::IsSpaceCharAddon(napi_env env, napi_callback_info info)
309 {
310 size_t argc = 1;
311 napi_value argv[1] = { 0 };
312 napi_value thisVar = nullptr;
313 void *data = nullptr;
314 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
315 napi_valuetype valueType = napi_valuetype::napi_undefined;
316 napi_typeof(env, argv[0], &valueType);
317 if (valueType != napi_valuetype::napi_string) {
318 napi_throw_type_error(env, nullptr, "Parameter type does not match");
319 return nullptr;
320 }
321 int32_t code = 0;
322 std::string character = GetString(env, argv[0], code);
323 if (code) {
324 return nullptr;
325 }
326 bool isSpaceChar = IsSpaceChar(character);
327 napi_value result = nullptr;
328 status = napi_get_boolean(env, isSpaceChar, &result);
329 if (status != napi_ok) {
330 HiLog::Error(LABEL, "Create isSpaceChar boolean value failed");
331 return nullptr;
332 }
333 return result;
334 }
335
IsWhiteSpaceAddon(napi_env env,napi_callback_info info)336 napi_value I18nAddon::IsWhiteSpaceAddon(napi_env env, napi_callback_info info)
337 {
338 size_t argc = 1;
339 napi_value argv[1] = { 0 };
340 napi_value thisVar = nullptr;
341 void *data = nullptr;
342 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
343 napi_valuetype valueType = napi_valuetype::napi_undefined;
344 napi_typeof(env, argv[0], &valueType);
345 if (valueType != napi_valuetype::napi_string) {
346 napi_throw_type_error(env, nullptr, "Parameter type does not match");
347 return nullptr;
348 }
349 int32_t code = 0;
350 std::string character = GetString(env, argv[0], code);
351 if (code) {
352 return nullptr;
353 }
354 bool isWhiteSpace = IsWhiteSpace(character);
355 napi_value result = nullptr;
356 status = napi_get_boolean(env, isWhiteSpace, &result);
357 if (status != napi_ok) {
358 HiLog::Error(LABEL, "Create isWhiteSpace boolean value failed");
359 return nullptr;
360 }
361 return result;
362 }
363
IsRTLCharacterAddon(napi_env env,napi_callback_info info)364 napi_value I18nAddon::IsRTLCharacterAddon(napi_env env, napi_callback_info info)
365 {
366 size_t argc = 1;
367 napi_value argv[1] = { 0 };
368 napi_value thisVar = nullptr;
369 void *data = nullptr;
370 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
371 napi_valuetype valueType = napi_valuetype::napi_undefined;
372 napi_typeof(env, argv[0], &valueType);
373 if (valueType != napi_valuetype::napi_string) {
374 napi_throw_type_error(env, nullptr, "Parameter type does not match");
375 return nullptr;
376 }
377 int32_t code = 0;
378 std::string character = GetString(env, argv[0], code);
379 if (code) {
380 return nullptr;
381 }
382 bool isRTLCharacter = IsRTLCharacter(character);
383 napi_value result = nullptr;
384 status = napi_get_boolean(env, isRTLCharacter, &result);
385 if (status != napi_ok) {
386 HiLog::Error(LABEL, "Create isRTLCharacter boolean value failed");
387 return nullptr;
388 }
389 return result;
390 }
391
IsIdeoGraphicAddon(napi_env env,napi_callback_info info)392 napi_value I18nAddon::IsIdeoGraphicAddon(napi_env env, napi_callback_info info)
393 {
394 size_t argc = 1;
395 napi_value argv[1] = { 0 };
396 napi_value thisVar = nullptr;
397 void *data = nullptr;
398 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
399 napi_valuetype valueType = napi_valuetype::napi_undefined;
400 napi_typeof(env, argv[0], &valueType);
401 if (valueType != napi_valuetype::napi_string) {
402 napi_throw_type_error(env, nullptr, "Parameter type does not match");
403 return nullptr;
404 }
405 int32_t code = 0;
406 std::string character = GetString(env, argv[0], code);
407 if (code) {
408 return nullptr;
409 }
410 bool isIdeoGraphic = IsIdeoGraphic(character);
411 napi_value result = nullptr;
412 status = napi_get_boolean(env, isIdeoGraphic, &result);
413 if (status != napi_ok) {
414 HiLog::Error(LABEL, "Create isIdeoGraphic boolean value failed");
415 return nullptr;
416 }
417 return result;
418 }
419
IsLetterAddon(napi_env env,napi_callback_info info)420 napi_value I18nAddon::IsLetterAddon(napi_env env, napi_callback_info info)
421 {
422 size_t argc = 1;
423 napi_value argv[1] = { 0 };
424 napi_value thisVar = nullptr;
425 void *data = nullptr;
426 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
427 napi_valuetype valueType = napi_valuetype::napi_undefined;
428 napi_typeof(env, argv[0], &valueType);
429 if (valueType != napi_valuetype::napi_string) {
430 napi_throw_type_error(env, nullptr, "Parameter type does not match");
431 return nullptr;
432 }
433 int32_t code = 0;
434 std::string character = GetString(env, argv[0], code);
435 if (code) {
436 return nullptr;
437 }
438 bool isLetter = IsLetter(character);
439 napi_value result = nullptr;
440 status = napi_get_boolean(env, isLetter, &result);
441 if (status != napi_ok) {
442 HiLog::Error(LABEL, "Create isLetter boolean value failed");
443 return nullptr;
444 }
445 return result;
446 }
447
IsLowerCaseAddon(napi_env env,napi_callback_info info)448 napi_value I18nAddon::IsLowerCaseAddon(napi_env env, napi_callback_info info)
449 {
450 size_t argc = 1;
451 napi_value argv[1] = { 0 };
452 napi_value thisVar = nullptr;
453 void *data = nullptr;
454 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
455 napi_valuetype valueType = napi_valuetype::napi_undefined;
456 napi_typeof(env, argv[0], &valueType);
457 if (valueType != napi_valuetype::napi_string) {
458 napi_throw_type_error(env, nullptr, "Parameter type does not match");
459 return nullptr;
460 }
461 int32_t code = 0;
462 std::string character = GetString(env, argv[0], code);
463 if (code) {
464 return nullptr;
465 }
466 bool isLowerCase = IsLowerCase(character);
467 napi_value result = nullptr;
468 status = napi_get_boolean(env, isLowerCase, &result);
469 if (status != napi_ok) {
470 HiLog::Error(LABEL, "Create isLowerCase boolean value failed");
471 return nullptr;
472 }
473 return result;
474 }
475
IsUpperCaseAddon(napi_env env,napi_callback_info info)476 napi_value I18nAddon::IsUpperCaseAddon(napi_env env, napi_callback_info info)
477 {
478 size_t argc = 1;
479 napi_value argv[1] = { 0 };
480 napi_value thisVar = nullptr;
481 void *data = nullptr;
482 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
483 napi_valuetype valueType = napi_valuetype::napi_undefined;
484 napi_typeof(env, argv[0], &valueType);
485 if (valueType != napi_valuetype::napi_string) {
486 napi_throw_type_error(env, nullptr, "Parameter type does not match");
487 return nullptr;
488 }
489 int32_t code = 0;
490 std::string character = GetString(env, argv[0], code);
491 if (code) {
492 return nullptr;
493 }
494 bool isUpperCase = IsUpperCase(character);
495 napi_value result = nullptr;
496 status = napi_get_boolean(env, isUpperCase, &result);
497 if (status != napi_ok) {
498 HiLog::Error(LABEL, "Create isUpperCase boolean value failed");
499 return nullptr;
500 }
501 return result;
502 }
503
GetTypeAddon(napi_env env,napi_callback_info info)504 napi_value I18nAddon::GetTypeAddon(napi_env env, napi_callback_info info)
505 {
506 size_t argc = 1;
507 napi_value argv[1] = { 0 };
508 napi_value thisVar = nullptr;
509 void *data = nullptr;
510 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
511 napi_valuetype valueType = napi_valuetype::napi_undefined;
512 napi_typeof(env, argv[0], &valueType);
513 if (valueType != napi_valuetype::napi_string) {
514 napi_throw_type_error(env, nullptr, "Parameter type does not match");
515 return nullptr;
516 }
517 int32_t code = 0;
518 std::string character = GetString(env, argv[0], code);
519 if (code) {
520 return nullptr;
521 }
522 std::string type = GetType(character);
523 napi_value result = nullptr;
524 status = napi_create_string_utf8(env, type.c_str(), NAPI_AUTO_LENGTH, &result);
525 if (status != napi_ok) {
526 HiLog::Error(LABEL, "Create getType string value failed");
527 return nullptr;
528 }
529 return result;
530 }
531
GetSystemLanguages(napi_env env,napi_callback_info info)532 napi_value I18nAddon::GetSystemLanguages(napi_env env, napi_callback_info info)
533 {
534 std::vector<std::string> systemLanguages;
535 LocaleConfig::GetSystemLanguages(systemLanguages);
536 napi_value result = nullptr;
537 napi_status status = napi_create_array_with_length(env, systemLanguages.size(), &result);
538 if (status != napi_ok) {
539 HiLog::Error(LABEL, "Failed to create array");
540 return nullptr;
541 }
542 for (size_t i = 0; i < systemLanguages.size(); i++) {
543 napi_value value = nullptr;
544 status = napi_create_string_utf8(env, systemLanguages[i].c_str(), NAPI_AUTO_LENGTH, &value);
545 if (status != napi_ok) {
546 HiLog::Error(LABEL, "Failed to create string item");
547 return nullptr;
548 }
549 status = napi_set_element(env, result, i, value);
550 if (status != napi_ok) {
551 HiLog::Error(LABEL, "Failed to set array item");
552 return nullptr;
553 }
554 }
555 return result;
556 }
557
GetSystemCountries(napi_env env,napi_callback_info info)558 napi_value I18nAddon::GetSystemCountries(napi_env env, napi_callback_info info)
559 {
560 size_t argc = 1;
561 napi_value argv[1] = { 0 };
562 napi_value thisVar = nullptr;
563 void *data = nullptr;
564 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
565 size_t len = 0;
566 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
567 std::vector<char> localeBuf(len + 1);
568 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
569 if (status != napi_ok) {
570 HiLog::Error(LABEL, "Failed to get string item");
571 return nullptr;
572 }
573 std::vector<std::string> systemCountries;
574 LocaleConfig::GetSystemCountries(systemCountries);
575 napi_value result = nullptr;
576 status = napi_create_array_with_length(env, systemCountries.size(), &result);
577 if (status != napi_ok) {
578 HiLog::Error(LABEL, "Failed to create array");
579 return nullptr;
580 }
581 for (size_t i = 0; i < systemCountries.size(); i++) {
582 napi_value value = nullptr;
583 status = napi_create_string_utf8(env, systemCountries[i].c_str(), NAPI_AUTO_LENGTH, &value);
584 if (status != napi_ok) {
585 HiLog::Error(LABEL, "Failed to create string item");
586 return nullptr;
587 }
588 status = napi_set_element(env, result, i, value);
589 if (status != napi_ok) {
590 HiLog::Error(LABEL, "Failed to set array item");
591 return nullptr;
592 }
593 }
594 return result;
595 }
596
GetSystemLanguage(napi_env env,napi_callback_info info)597 napi_value I18nAddon::GetSystemLanguage(napi_env env, napi_callback_info info)
598 {
599 std::string value = LocaleConfig::GetSystemLanguage();
600 napi_value result = nullptr;
601 napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
602 if (status != napi_ok) {
603 HiLog::Error(LABEL, "Failed to create string item");
604 return nullptr;
605 }
606 return result;
607 }
608
GetSystemRegion(napi_env env,napi_callback_info info)609 napi_value I18nAddon::GetSystemRegion(napi_env env, napi_callback_info info)
610 {
611 std::string value = LocaleConfig::GetSystemRegion();
612 napi_value result = nullptr;
613 napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
614 if (status != napi_ok) {
615 HiLog::Error(LABEL, "Failed to create string item");
616 return nullptr;
617 }
618 return result;
619 }
620
GetSystemLocale(napi_env env,napi_callback_info info)621 napi_value I18nAddon::GetSystemLocale(napi_env env, napi_callback_info info)
622 {
623 std::string value = LocaleConfig::GetSystemLocale();
624 napi_value result = nullptr;
625 napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
626 if (status != napi_ok) {
627 HiLog::Error(LABEL, "Failed to create string item");
628 return nullptr;
629 }
630 return result;
631 }
632
GetDisplayLanguage(napi_env env,napi_callback_info info)633 napi_value I18nAddon::GetDisplayLanguage(napi_env env, napi_callback_info info)
634 {
635 // Need to get three parameters to get the display Language.
636 size_t argc = 3;
637 napi_value argv[3] = { 0 };
638 napi_value thisVar = nullptr;
639 void *data = nullptr;
640 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
641 size_t len = 0;
642 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
643 std::vector<char> localeBuf(len + 1);
644 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
645 if (status != napi_ok) {
646 HiLog::Error(LABEL, "Failed to get string item");
647 return nullptr;
648 }
649 napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
650 std::vector<char> displayLocaleBuf(len + 1);
651 status = napi_get_value_string_utf8(env, argv[1], displayLocaleBuf.data(), len + 1, &len);
652 if (status != napi_ok) {
653 HiLog::Error(LABEL, "Failed to get string item");
654 return nullptr;
655 }
656 bool sentenceCase = true;
657 int sentenceCaseIndex = 2;
658 if (argv[sentenceCaseIndex] != nullptr) {
659 napi_get_value_bool(env, argv[sentenceCaseIndex], &sentenceCase);
660 }
661
662 std::string value = LocaleConfig::GetDisplayLanguage(localeBuf.data(), displayLocaleBuf.data(), sentenceCase);
663 napi_value result = nullptr;
664 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
665 if (status != napi_ok) {
666 HiLog::Error(LABEL, "Failed to create string item");
667 return nullptr;
668 }
669 return result;
670 }
671
GetDisplayCountry(napi_env env,napi_callback_info info)672 napi_value I18nAddon::GetDisplayCountry(napi_env env, napi_callback_info info)
673 {
674 // Need to get three parameters to get the display country.
675 size_t argc = 3;
676 napi_value argv[3] = { 0 };
677 napi_value thisVar = nullptr;
678 void *data = nullptr;
679 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
680 size_t len = 0;
681 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
682 std::vector<char> localeBuf(len + 1);
683 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
684 if (status != napi_ok) {
685 HiLog::Error(LABEL, "Failed to get string item");
686 return nullptr;
687 }
688 napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
689 std::vector<char> displayLocaleBuf(len + 1);
690 status = napi_get_value_string_utf8(env, argv[1], displayLocaleBuf.data(), len + 1, &len);
691 if (status != napi_ok) {
692 HiLog::Error(LABEL, "Failed to get string item");
693 return nullptr;
694 }
695 bool sentenceCase = true;
696 int sentenceCaseIndex = 2;
697 if (argv[sentenceCaseIndex] != nullptr) {
698 napi_get_value_bool(env, argv[sentenceCaseIndex], &sentenceCase);
699 }
700 std::string value = LocaleConfig::GetDisplayRegion(localeBuf.data(), displayLocaleBuf.data(), sentenceCase);
701 napi_value result = nullptr;
702 status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
703 if (status != napi_ok) {
704 HiLog::Error(LABEL, "Failed to create string item");
705 return nullptr;
706 }
707 return result;
708 }
709
IsSuggested(napi_env env,napi_callback_info info)710 napi_value I18nAddon::IsSuggested(napi_env env, napi_callback_info info)
711 {
712 // Need to get two parameters to check is suggested or not.
713 size_t argc = 2;
714 napi_value argv[2] = { 0 };
715 napi_value thisVar = nullptr;
716 void *data = nullptr;
717 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
718 size_t len = 0;
719 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
720 std::vector<char> languageBuf(len + 1);
721 status = napi_get_value_string_utf8(env, argv[0], languageBuf.data(), len + 1, &len);
722 if (status != napi_ok) {
723 HiLog::Error(LABEL, "Failed to get string item");
724 return nullptr;
725 }
726 bool isSuggested = false;
727 if (argv[1] != nullptr) {
728 napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
729 std::vector<char> regionBuf(len + 1);
730 status = napi_get_value_string_utf8(env, argv[1], regionBuf.data(), len + 1, &len);
731 if (status != napi_ok) {
732 HiLog::Error(LABEL, "Failed to get string item");
733 return nullptr;
734 }
735 isSuggested = LocaleConfig::IsSuggested(languageBuf.data(), regionBuf.data());
736 } else {
737 isSuggested = LocaleConfig::IsSuggested(languageBuf.data());
738 }
739 napi_value result = nullptr;
740 status = napi_get_boolean(env, isSuggested, &result);
741 if (status != napi_ok) {
742 HiLog::Error(LABEL, "Create case first boolean value failed");
743 return nullptr;
744 }
745 return result;
746 }
747
SetSystemLanguage(napi_env env,napi_callback_info info)748 napi_value I18nAddon::SetSystemLanguage(napi_env env, napi_callback_info info)
749 {
750 size_t argc = 1;
751 napi_value argv[1] = { 0 };
752 napi_value thisVar = nullptr;
753 void *data = nullptr;
754 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
755 size_t len = 0;
756 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
757 std::vector<char> languageBuf(len + 1);
758 status = napi_get_value_string_utf8(env, argv[0], languageBuf.data(), len + 1, &len);
759 if (status != napi_ok) {
760 HiLog::Error(LABEL, "Failed to get string item");
761 return nullptr;
762 }
763 bool success = LocaleConfig::SetSystemLanguage(languageBuf.data());
764 napi_value result = nullptr;
765 status = napi_get_boolean(env, success, &result);
766 if (status != napi_ok) {
767 HiLog::Error(LABEL, "Create set system language boolean value failed");
768 return nullptr;
769 }
770 return result;
771 }
772
SetSystemRegion(napi_env env,napi_callback_info info)773 napi_value I18nAddon::SetSystemRegion(napi_env env, napi_callback_info info)
774 {
775 size_t argc = 1;
776 napi_value argv[1] = { 0 };
777 napi_value thisVar = nullptr;
778 void *data = nullptr;
779 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
780 size_t len = 0;
781 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
782 std::vector<char> regionBuf(len + 1);
783 status = napi_get_value_string_utf8(env, argv[0], regionBuf.data(), len + 1, &len);
784 if (status != napi_ok) {
785 HiLog::Error(LABEL, "Failed to get string item");
786 return nullptr;
787 }
788 bool success = LocaleConfig::SetSystemRegion(regionBuf.data());
789 napi_value result = nullptr;
790 status = napi_get_boolean(env, success, &result);
791 if (status != napi_ok) {
792 HiLog::Error(LABEL, "Create set system language boolean value failed");
793 return nullptr;
794 }
795 return result;
796 }
797
SetSystemLocale(napi_env env,napi_callback_info info)798 napi_value I18nAddon::SetSystemLocale(napi_env env, napi_callback_info info)
799 {
800 size_t argc = 1;
801 napi_value argv[1] = { 0 };
802 napi_value thisVar = nullptr;
803 void *data = nullptr;
804 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
805 size_t len = 0;
806 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
807 std::vector<char> localeBuf(len + 1);
808 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
809 if (status != napi_ok) {
810 HiLog::Error(LABEL, "Failed to get string item");
811 return nullptr;
812 }
813 bool success = LocaleConfig::SetSystemLocale(localeBuf.data());
814 napi_value result = nullptr;
815 status = napi_get_boolean(env, success, &result);
816 if (status != napi_ok) {
817 HiLog::Error(LABEL, "Create set system language boolean value failed");
818 return nullptr;
819 }
820 return result;
821 }
822
IsRTL(napi_env env,napi_callback_info info)823 napi_value I18nAddon::IsRTL(napi_env env, napi_callback_info info)
824 {
825 size_t argc = 1;
826 napi_value argv[1] = { 0 };
827 napi_value thisVar = nullptr;
828 void *data = nullptr;
829 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
830 size_t len = 0;
831 napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
832 std::vector<char> localeBuf(len + 1);
833 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
834 if (status != napi_ok) {
835 HiLog::Error(LABEL, "Failed to get string item");
836 return nullptr;
837 }
838 bool isRTL = LocaleConfig::IsRTL(localeBuf.data());
839 napi_value result = nullptr;
840 status = napi_get_boolean(env, isRTL, &result);
841 if (status != napi_ok) {
842 HiLog::Error(LABEL, "IsRTL failed");
843 return nullptr;
844 }
845 return result;
846 }
847
InitPhoneNumberFormat(napi_env env,napi_value exports)848 napi_value I18nAddon::InitPhoneNumberFormat(napi_env env, napi_value exports)
849 {
850 napi_status status = napi_ok;
851 napi_property_descriptor properties[] = {
852 DECLARE_NAPI_FUNCTION("isValidNumber", IsValidPhoneNumber),
853 DECLARE_NAPI_FUNCTION("format", FormatPhoneNumber)
854 };
855
856 napi_value constructor;
857 status = napi_define_class(env, "PhoneNumberFormat", NAPI_AUTO_LENGTH, PhoneNumberFormatConstructor, nullptr,
858 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
859 if (status != napi_ok) {
860 HiLog::Error(LABEL, "Define class failed when InitPhoneNumberFormat");
861 return nullptr;
862 }
863
864 status = napi_set_named_property(env, exports, "PhoneNumberFormat", constructor);
865 if (status != napi_ok) {
866 HiLog::Error(LABEL, "Set property failed when InitPhoneNumberFormat");
867 return nullptr;
868 }
869 return exports;
870 }
871
GetOptionValue(napi_env env,napi_value options,const std::string & optionName,std::map<std::string,std::string> & map)872 void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
873 std::map<std::string, std::string> &map)
874 {
875 napi_value optionValue = nullptr;
876 napi_valuetype type = napi_undefined;
877 napi_status status = napi_typeof(env, options, &type);
878 if (status != napi_ok && type != napi_object) {
879 HiLog::Error(LABEL, "Get option failed, option is not an object");
880 return;
881 }
882 bool hasProperty = false;
883 napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
884 if (propStatus == napi_ok && hasProperty) {
885 status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
886 if (status == napi_ok) {
887 size_t len = 0;
888 napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
889 std::vector<char> optionBuf(len + 1);
890 status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
891 map.insert(make_pair(optionName, optionBuf.data()));
892 }
893 }
894 }
895
PhoneNumberFormatConstructor(napi_env env,napi_callback_info info)896 napi_value I18nAddon::PhoneNumberFormatConstructor(napi_env env, napi_callback_info info)
897 {
898 size_t argc = 2;
899 napi_value argv[2] = { 0 };
900 napi_value thisVar = nullptr;
901 void *data = nullptr;
902 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
903
904 napi_valuetype valueType = napi_valuetype::napi_undefined;
905 napi_typeof(env, argv[0], &valueType);
906 if (valueType != napi_valuetype::napi_string) {
907 napi_throw_type_error(env, nullptr, "Parameter type does not match");
908 return nullptr;
909 }
910
911 size_t len = 0;
912 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
913 if (status != napi_ok) {
914 HiLog::Error(LABEL, "Get country tag length failed");
915 return nullptr;
916 }
917
918 std::vector<char> country (len + 1);
919 status = napi_get_value_string_utf8(env, argv[0], country.data(), len + 1, &len);
920 if (status != napi_ok) {
921 HiLog::Error(LABEL, "Get country tag failed");
922 return nullptr;
923 }
924
925 std::map<std::string, std::string> options;
926 GetOptionValue(env, argv[1], "type", options);
927
928 std::unique_ptr<I18nAddon> obj = nullptr;
929 obj = std::make_unique<I18nAddon>();
930 if (!obj) {
931 HiLog::Error(LABEL, "Create I18nAddon failed");
932 return nullptr;
933 }
934
935 status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
936 I18nAddon::Destructor, nullptr, &obj->wrapper_);
937 if (status != napi_ok) {
938 HiLog::Error(LABEL, "Wrap I18nAddon failed");
939 return nullptr;
940 }
941
942 if (!obj->InitPhoneNumberFormatContext(env, info, country.data(), options)) {
943 return nullptr;
944 }
945
946 obj.release();
947
948 return thisVar;
949 }
950
InitPhoneNumberFormatContext(napi_env env,napi_callback_info info,const std::string & country,const std::map<std::string,std::string> & options)951 bool I18nAddon::InitPhoneNumberFormatContext(napi_env env, napi_callback_info info, const std::string &country,
952 const std::map<std::string, std::string> &options)
953 {
954 napi_value global = nullptr;
955 napi_status status = napi_get_global(env, &global);
956 if (status != napi_ok) {
957 HiLog::Error(LABEL, "Get global failed");
958 return false;
959 }
960 env_ = env;
961 phonenumberfmt_ = std::make_unique<PhoneNumberFormat>(country, options);
962
963 return phonenumberfmt_ != nullptr;
964 }
965
IsValidPhoneNumber(napi_env env,napi_callback_info info)966 napi_value I18nAddon::IsValidPhoneNumber(napi_env env, napi_callback_info info)
967 {
968 size_t argc = 1;
969 napi_value argv[1] = { 0 };
970 napi_value thisVar = nullptr;
971 void *data = nullptr;
972 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
973 napi_valuetype valueType = napi_valuetype::napi_undefined;
974 napi_typeof(env, argv[0], &valueType);
975 if (valueType != napi_valuetype::napi_string) {
976 napi_throw_type_error(env, nullptr, "Parameter type does not match");
977 return nullptr;
978 }
979
980 size_t len = 0;
981 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
982 if (status != napi_ok) {
983 HiLog::Error(LABEL, "Get phone number length failed");
984 return nullptr;
985 }
986 std::vector<char> buf(len + 1);
987 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
988 if (status != napi_ok) {
989 HiLog::Error(LABEL, "Get phone number failed");
990 return nullptr;
991 }
992
993 I18nAddon *obj = nullptr;
994 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
995 if (status != napi_ok || !obj || !obj->phonenumberfmt_) {
996 HiLog::Error(LABEL, "GetPhoneNumberFormat object failed");
997 return nullptr;
998 }
999
1000 bool isValid = obj->phonenumberfmt_->isValidPhoneNumber(buf.data());
1001
1002 napi_value result = nullptr;
1003 status = napi_get_boolean(env, isValid, &result);
1004 if (status != napi_ok) {
1005 HiLog::Error(LABEL, "Create boolean failed");
1006 return nullptr;
1007 }
1008
1009 return result;
1010 }
1011
FormatPhoneNumber(napi_env env,napi_callback_info info)1012 napi_value I18nAddon::FormatPhoneNumber(napi_env env, napi_callback_info info)
1013 {
1014 size_t argc = 1;
1015 napi_value argv[1] = { 0 };
1016 napi_value thisVar = nullptr;
1017 void *data = nullptr;
1018 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1019 napi_valuetype valueType = napi_valuetype::napi_undefined;
1020 napi_typeof(env, argv[0], &valueType);
1021 if (valueType != napi_valuetype::napi_string) {
1022 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1023 return nullptr;
1024 }
1025
1026 size_t len = 0;
1027 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1028 if (status != napi_ok) {
1029 HiLog::Error(LABEL, "Get phone number length failed");
1030 return nullptr;
1031 }
1032 std::vector<char> buf(len + 1);
1033 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1034 if (status != napi_ok) {
1035 HiLog::Error(LABEL, "Get phone number failed");
1036 return nullptr;
1037 }
1038
1039 I18nAddon *obj = nullptr;
1040 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1041 if (status != napi_ok || !obj || !obj->phonenumberfmt_) {
1042 HiLog::Error(LABEL, "Get PhoneNumberFormat object failed");
1043 return nullptr;
1044 }
1045
1046 std::string formattedPhoneNumber = obj->phonenumberfmt_->format(buf.data());
1047
1048 napi_value result = nullptr;
1049 status = napi_create_string_utf8(env, formattedPhoneNumber.c_str(), NAPI_AUTO_LENGTH, &result);
1050 if (status != napi_ok) {
1051 HiLog::Error(LABEL, "Create format phone number failed");
1052 return nullptr;
1053 }
1054 return result;
1055 }
1056
GetString(napi_env & env,napi_value & value,int32_t & code)1057 std::string I18nAddon::GetString(napi_env &env, napi_value &value, int32_t &code)
1058 {
1059 size_t len = 0;
1060 napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
1061 if (status != napi_ok) {
1062 HiLog::Error(LABEL, "Get string failed");
1063 code = 1;
1064 return "";
1065 }
1066 std::vector<char> buf(len + 1);
1067 status = napi_get_value_string_utf8(env, value, buf.data(), len + 1, &len);
1068 if (status != napi_ok) {
1069 HiLog::Error(LABEL, "Create string failed");
1070 code = 1;
1071 return "";
1072 }
1073 return buf.data();
1074 }
1075
InitI18nCalendar(napi_env env,napi_value exports)1076 napi_value I18nAddon::InitI18nCalendar(napi_env env, napi_value exports)
1077 {
1078 napi_status status = napi_ok;
1079 napi_property_descriptor properties[] = {
1080 DECLARE_NAPI_FUNCTION("setTime", SetTime),
1081 DECLARE_NAPI_FUNCTION("set", Set),
1082 DECLARE_NAPI_FUNCTION("getTimeZone", GetTimeZone),
1083 DECLARE_NAPI_FUNCTION("setTimeZone", SetTimeZone),
1084 DECLARE_NAPI_FUNCTION("getFirstDayOfWeek", GetFirstDayOfWeek),
1085 DECLARE_NAPI_FUNCTION("setFirstDayOfWeek", SetFirstDayOfWeek),
1086 DECLARE_NAPI_FUNCTION("getMinimalDaysInFirstWeek", GetMinimalDaysInFirstWeek),
1087 DECLARE_NAPI_FUNCTION("setMinimalDaysInFirstWeek", SetMinimalDaysInFirstWeek),
1088 DECLARE_NAPI_FUNCTION("get", Get),
1089 DECLARE_NAPI_FUNCTION("getDisplayName", GetDisplayName),
1090 DECLARE_NAPI_FUNCTION("isWeekend", IsWeekend)
1091 };
1092 napi_value constructor = nullptr;
1093 status = napi_define_class(env, "I18nCalendar", NAPI_AUTO_LENGTH, CalendarConstructor, nullptr,
1094 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1095 if (status != napi_ok) {
1096 HiLog::Error(LABEL, "Failed to define class at Init");
1097 return nullptr;
1098 }
1099 g_constructor = new (std::nothrow) napi_ref;
1100 if (!g_constructor) {
1101 HiLog::Error(LABEL, "Failed to create ref at init");
1102 return nullptr;
1103 }
1104 status = napi_create_reference(env, constructor, 1, g_constructor);
1105 if (status != napi_ok) {
1106 HiLog::Error(LABEL, "Failed to create reference at init");
1107 return nullptr;
1108 }
1109 return exports;
1110 }
1111
CalendarConstructor(napi_env env,napi_callback_info info)1112 napi_value I18nAddon::CalendarConstructor(napi_env env, napi_callback_info info)
1113 {
1114 size_t argc = 2;
1115 napi_value argv[2] = { 0 };
1116 argv[0] = nullptr;
1117 argv[1] = nullptr;
1118 napi_value thisVar = nullptr;
1119 void *data = nullptr;
1120 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1121 if (status != napi_ok) {
1122 return nullptr;
1123 }
1124 napi_valuetype valueType = napi_valuetype::napi_undefined;
1125 napi_typeof(env, argv[0], &valueType);
1126 if (valueType != napi_valuetype::napi_string) {
1127 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1128 return nullptr;
1129 }
1130 int32_t code = 0;
1131 std::string localeTag = GetString(env, argv[0], code);
1132 if (code) {
1133 return nullptr;
1134 }
1135 CalendarType type = GetCalendarType(env, argv[1]);
1136 std::unique_ptr<I18nAddon> obj = nullptr;
1137 obj = std::make_unique<I18nAddon>();
1138 if (!obj) {
1139 HiLog::Error(LABEL, "Create I18nAddon failed");
1140 return nullptr;
1141 }
1142 status =
1143 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, &obj->wrapper_);
1144 if (status != napi_ok) {
1145 HiLog::Error(LABEL, "Wrap II18nAddon failed");
1146 return nullptr;
1147 }
1148 if (!obj->InitCalendarContext(env, info, localeTag, type)) {
1149 return nullptr;
1150 }
1151 obj.release();
1152 return thisVar;
1153 }
1154
GetCalendarType(napi_env env,napi_value value)1155 CalendarType I18nAddon::GetCalendarType(napi_env env, napi_value value)
1156 {
1157 CalendarType type = CalendarType::UNDEFINED;
1158 if (value != nullptr) {
1159 napi_valuetype valueType = napi_valuetype::napi_undefined;
1160 napi_typeof(env, value, &valueType);
1161 if (valueType != napi_valuetype::napi_string) {
1162 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1163 return type;
1164 }
1165 int32_t code = 0;
1166 std::string calendarType = GetString(env, value, code);
1167 if (code) {
1168 return type;
1169 }
1170 if (g_typeMap.find(calendarType) != g_typeMap.end()) {
1171 type = g_typeMap[calendarType];
1172 }
1173 }
1174 return type;
1175 }
1176
InitCalendarContext(napi_env env,napi_callback_info info,const std::string & localeTag,CalendarType type)1177 bool I18nAddon::InitCalendarContext(napi_env env, napi_callback_info info, const std::string &localeTag,
1178 CalendarType type)
1179 {
1180 calendar_ = std::make_unique<I18nCalendar>(localeTag, type);
1181 return calendar_ != nullptr;
1182 }
1183
GetCalendar(napi_env env,napi_callback_info info)1184 napi_value I18nAddon::GetCalendar(napi_env env, napi_callback_info info)
1185 {
1186 size_t argc = 2; // retrieve 2 arguments
1187 napi_value argv[2] = { 0 };
1188 argv[0] = nullptr;
1189 argv[1] = nullptr;
1190 napi_value thisVar = nullptr;
1191 void *data = nullptr;
1192 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1193 napi_value constructor = nullptr;
1194 napi_status status = napi_get_reference_value(env, *g_constructor, &constructor);
1195 if (status != napi_ok) {
1196 HiLog::Error(LABEL, "Failed to create reference at GetCalendar");
1197 return nullptr;
1198 }
1199 if (!argv[1]) {
1200 status = napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, argv + 1);
1201 if (status != napi_ok) {
1202 return nullptr;
1203 }
1204 }
1205 napi_value result = nullptr;
1206 status = napi_new_instance(env, constructor, 2, argv, &result); // 2 arguments
1207 if (status != napi_ok) {
1208 HiLog::Error(LABEL, "Get calendar create instance failed");
1209 return nullptr;
1210 }
1211 return result;
1212 }
1213
GetDate(napi_env env,napi_value value)1214 napi_value I18nAddon::GetDate(napi_env env, napi_value value)
1215 {
1216 if (!value) {
1217 return nullptr;
1218 }
1219 napi_value funcGetDateInfo = nullptr;
1220 napi_status status = napi_get_named_property(env, value, "valueOf", &funcGetDateInfo);
1221 if (status != napi_ok) {
1222 HiLog::Error(LABEL, "Get method valueOf failed");
1223 return nullptr;
1224 }
1225 napi_value ret_value = nullptr;
1226 status = napi_call_function(env, value, funcGetDateInfo, 0, nullptr, &ret_value);
1227 if (status != napi_ok) {
1228 HiLog::Error(LABEL, "Get milliseconds failed");
1229 return nullptr;
1230 }
1231 return ret_value;
1232 }
1233
SetMilliseconds(napi_env env,napi_value value)1234 void I18nAddon::SetMilliseconds(napi_env env, napi_value value)
1235 {
1236 if (!value) {
1237 return;
1238 }
1239 double milliseconds = 0;
1240 napi_valuetype valueType = napi_valuetype::napi_undefined;
1241 napi_typeof(env, value, &valueType);
1242 if (valueType != napi_valuetype::napi_number) {
1243 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1244 return;
1245 }
1246 napi_status status = napi_get_value_double(env, value, &milliseconds);
1247 if (status != napi_ok) {
1248 HiLog::Error(LABEL, "Retrieve milliseconds failed");
1249 return;
1250 }
1251 if (calendar_ != nullptr) {
1252 calendar_->SetTime(milliseconds);
1253 }
1254 }
1255
Set(napi_env env,napi_callback_info info)1256 napi_value I18nAddon::Set(napi_env env, napi_callback_info info)
1257 {
1258 size_t argc = 6; // Set may have 6 arguments
1259 napi_value argv[6] = { 0 };
1260 for (size_t i = 0; i < argc; ++i) {
1261 argv[i] = nullptr;
1262 }
1263 napi_value thisVar = nullptr;
1264 void *data = nullptr;
1265 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1266 napi_valuetype valueType = napi_valuetype::napi_undefined;
1267 napi_status status = napi_ok;
1268 int32_t times[3] = { 0 }; // There are at least 3 arguments.
1269 for (int i = 0; i < 3; ++i) { // There are at least 3 arguments.
1270 napi_typeof(env, argv[i], &valueType);
1271 if (valueType != napi_valuetype::napi_number) {
1272 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1273 return nullptr;
1274 }
1275 status = napi_get_value_int32(env, argv[i], times + i);
1276 if (status != napi_ok) {
1277 HiLog::Error(LABEL, "Retrieve time value failed");
1278 return nullptr;
1279 }
1280 }
1281 I18nAddon *obj = nullptr;
1282 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1283 if (status != napi_ok || !obj || !obj->calendar_) {
1284 HiLog::Error(LABEL, "Get calendar object failed");
1285 return nullptr;
1286 }
1287 obj->calendar_->Set(times[0], times[1], times[2]); // 2 is the index of date
1288 obj->SetField(env, argv[3], UCalendarDateFields::UCAL_HOUR_OF_DAY); // 3 is the index of hour
1289 obj->SetField(env, argv[4], UCalendarDateFields::UCAL_MINUTE); // 4 is the index of minute
1290 obj->SetField(env, argv[5], UCalendarDateFields::UCAL_SECOND); // 5 is the index of second
1291 return nullptr;
1292 }
1293
SetTime(napi_env env,napi_callback_info info)1294 napi_value I18nAddon::SetTime(napi_env env, napi_callback_info info)
1295 {
1296 size_t argc = 1;
1297 napi_value argv[1] = { 0 };
1298 argv[0] = nullptr;
1299 napi_value thisVar = nullptr;
1300 void *data = nullptr;
1301 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1302 if (!argv[0]) {
1303 return nullptr;
1304 }
1305 I18nAddon *obj = nullptr;
1306 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1307 if (status != napi_ok || !obj || !obj->calendar_) {
1308 HiLog::Error(LABEL, "Get calendar object failed");
1309 return nullptr;
1310 }
1311 napi_valuetype type = napi_valuetype::napi_undefined;
1312 status = napi_typeof(env, argv[0], &type);
1313 if (status != napi_ok) {
1314 return nullptr;
1315 }
1316 if (type == napi_valuetype::napi_number) {
1317 obj->SetMilliseconds(env, argv[0]);
1318 return nullptr;
1319 } else {
1320 napi_value val = GetDate(env, argv[0]);
1321 if (!val) {
1322 return nullptr;
1323 }
1324 obj->SetMilliseconds(env, val);
1325 return nullptr;
1326 }
1327 }
1328
SetField(napi_env env,napi_value value,UCalendarDateFields field)1329 void I18nAddon::SetField(napi_env env, napi_value value, UCalendarDateFields field)
1330 {
1331 if (!value) {
1332 return;
1333 }
1334 int32_t val = 0;
1335 napi_valuetype valueType = napi_valuetype::napi_undefined;
1336 napi_typeof(env, value, &valueType);
1337 if (valueType != napi_valuetype::napi_number) {
1338 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1339 return;
1340 }
1341 napi_status status = napi_get_value_int32(env, value, &val);
1342 if (status != napi_ok) {
1343 HiLog::Error(LABEL, "Retrieve field failed");
1344 return;
1345 }
1346 if (calendar_ != nullptr) {
1347 calendar_->Set(field, val);
1348 }
1349 }
1350
SetTimeZone(napi_env env,napi_callback_info info)1351 napi_value I18nAddon::SetTimeZone(napi_env env, napi_callback_info info)
1352 {
1353 size_t argc = 1;
1354 napi_value argv[1] = { 0 };
1355 argv[0] = nullptr;
1356 napi_value thisVar = nullptr;
1357 void *data = nullptr;
1358 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1359 napi_valuetype valueType = napi_valuetype::napi_undefined;
1360 napi_typeof(env, argv[0], &valueType);
1361 if (valueType != napi_valuetype::napi_string) {
1362 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1363 return nullptr;
1364 }
1365 size_t len = 0;
1366 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1367 if (status != napi_ok) {
1368 HiLog::Error(LABEL, "Get timezone length failed");
1369 return nullptr;
1370 }
1371 std::vector<char> buf(len + 1);
1372 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1373 if (status != napi_ok) {
1374 HiLog::Error(LABEL, "Get timezone failed");
1375 return nullptr;
1376 }
1377 std::string timezone(buf.data());
1378 I18nAddon *obj = nullptr;
1379 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1380 if (status != napi_ok || !obj || !obj->calendar_) {
1381 HiLog::Error(LABEL, "Get calendar object failed");
1382 return nullptr;
1383 }
1384 obj->calendar_->SetTimeZone(timezone);
1385 return nullptr;
1386 }
1387
GetTimeZone(napi_env env,napi_callback_info info)1388 napi_value I18nAddon::GetTimeZone(napi_env env, napi_callback_info info)
1389 {
1390 size_t argc = 0;
1391 napi_value *argv = nullptr;
1392 napi_value thisVar = nullptr;
1393 void *data = nullptr;
1394 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1395 I18nAddon *obj = nullptr;
1396 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1397 if (status != napi_ok || !obj || !obj->calendar_) {
1398 HiLog::Error(LABEL, "Get calendar object failed");
1399 return nullptr;
1400 }
1401 std::string temp = obj->calendar_->GetTimeZone();
1402 napi_value result = nullptr;
1403 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &result);
1404 if (status != napi_ok) {
1405 HiLog::Error(LABEL, "Create timezone string failed");
1406 return nullptr;
1407 }
1408 return result;
1409 }
1410
GetFirstDayOfWeek(napi_env env,napi_callback_info info)1411 napi_value I18nAddon::GetFirstDayOfWeek(napi_env env, napi_callback_info info)
1412 {
1413 size_t argc = 0;
1414 napi_value *argv = nullptr;
1415 napi_value thisVar = nullptr;
1416 void *data = nullptr;
1417 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1418 I18nAddon *obj = nullptr;
1419 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1420 if (status != napi_ok || !obj || !obj->calendar_) {
1421 HiLog::Error(LABEL, "Get calendar object failed");
1422 return nullptr;
1423 }
1424 int32_t temp = obj->calendar_->GetFirstDayOfWeek();
1425 napi_value result = nullptr;
1426 status = napi_create_int32(env, temp, &result);
1427 if (status != napi_ok) {
1428 HiLog::Error(LABEL, "Create int32 failed");
1429 return nullptr;
1430 }
1431 return result;
1432 }
1433
GetMinimalDaysInFirstWeek(napi_env env,napi_callback_info info)1434 napi_value I18nAddon::GetMinimalDaysInFirstWeek(napi_env env, napi_callback_info info)
1435 {
1436 size_t argc = 0;
1437 napi_value *argv = nullptr;
1438 napi_value thisVar = nullptr;
1439 void *data = nullptr;
1440 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1441 I18nAddon *obj = nullptr;
1442 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1443 if (status != napi_ok || !obj || !obj->calendar_) {
1444 HiLog::Error(LABEL, "Get calendar object failed");
1445 return nullptr;
1446 }
1447 int32_t temp = obj->calendar_->GetMinimalDaysInFirstWeek();
1448 napi_value result = nullptr;
1449 status = napi_create_int32(env, temp, &result);
1450 if (status != napi_ok) {
1451 HiLog::Error(LABEL, "Create int32 failed");
1452 return nullptr;
1453 }
1454 return result;
1455 }
1456
SetFirstDayOfWeek(napi_env env,napi_callback_info info)1457 napi_value I18nAddon::SetFirstDayOfWeek(napi_env env, napi_callback_info info)
1458 {
1459 size_t argc = 1;
1460 napi_value argv[1] = { 0 };
1461 argv[0] = nullptr;
1462 napi_value thisVar = nullptr;
1463 void *data = nullptr;
1464 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1465 napi_valuetype valueType = napi_valuetype::napi_undefined;
1466 napi_typeof(env, argv[0], &valueType);
1467 if (valueType != napi_valuetype::napi_number) {
1468 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1469 return nullptr;
1470 }
1471 int32_t value = 0;
1472 napi_status status = napi_get_value_int32(env, argv[0], &value);
1473 if (status != napi_ok) {
1474 HiLog::Error(LABEL, "Get int32 failed");
1475 return nullptr;
1476 }
1477 I18nAddon *obj = nullptr;
1478 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1479 if (status != napi_ok || !obj || !obj->calendar_) {
1480 HiLog::Error(LABEL, "Get calendar object failed");
1481 return nullptr;
1482 }
1483 obj->calendar_->SetFirstDayOfWeek(value);
1484 return nullptr;
1485 }
1486
SetMinimalDaysInFirstWeek(napi_env env,napi_callback_info info)1487 napi_value I18nAddon::SetMinimalDaysInFirstWeek(napi_env env, napi_callback_info info)
1488 {
1489 size_t argc = 1;
1490 napi_value argv[1] = { 0 };
1491 argv[0] = nullptr;
1492 napi_value thisVar = nullptr;
1493 void *data = nullptr;
1494 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1495 napi_valuetype valueType = napi_valuetype::napi_undefined;
1496 napi_typeof(env, argv[0], &valueType);
1497 if (valueType != napi_valuetype::napi_number) {
1498 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1499 return nullptr;
1500 }
1501 int32_t value = 0;
1502 napi_status status = napi_get_value_int32(env, argv[0], &value);
1503 if (status != napi_ok) {
1504 HiLog::Error(LABEL, "Get int32 failed");
1505 return nullptr;
1506 }
1507 I18nAddon *obj = nullptr;
1508 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1509 if (status != napi_ok || !obj || !obj->calendar_) {
1510 HiLog::Error(LABEL, "Get calendar object failed");
1511 return nullptr;
1512 }
1513 obj->calendar_->SetMinimalDaysInFirstWeek(value);
1514 return nullptr;
1515 }
1516
Get(napi_env env,napi_callback_info info)1517 napi_value I18nAddon::Get(napi_env env, napi_callback_info info)
1518 {
1519 size_t argc = 1;
1520 napi_value argv[1] = { 0 };
1521 argv[0] = nullptr;
1522 napi_value thisVar = nullptr;
1523 void *data = nullptr;
1524 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1525 napi_valuetype valueType = napi_valuetype::napi_undefined;
1526 napi_typeof(env, argv[0], &valueType);
1527 if (valueType != napi_valuetype::napi_string) {
1528 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1529 return nullptr;
1530 }
1531 size_t len = 0;
1532 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1533 if (status != napi_ok) {
1534 HiLog::Error(LABEL, "Get field length failed");
1535 return nullptr;
1536 }
1537 std::vector<char> buf(len + 1);
1538 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1539 if (status != napi_ok) {
1540 HiLog::Error(LABEL, "Get field failed");
1541 return nullptr;
1542 }
1543 std::string field(buf.data());
1544 if (g_fieldsMap.find(field) == g_fieldsMap.end()) {
1545 HiLog::Error(LABEL, "Invalid field");
1546 return nullptr;
1547 }
1548 I18nAddon *obj = nullptr;
1549 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1550 if (status != napi_ok || !obj || !obj->calendar_) {
1551 HiLog::Error(LABEL, "Get calendar object failed");
1552 return nullptr;
1553 }
1554 int32_t value = obj->calendar_->Get(g_fieldsMap[field]);
1555 napi_value result = nullptr;
1556 status = napi_create_int32(env, value, &result);
1557 if (status != napi_ok) {
1558 HiLog::Error(LABEL, "Create int32 failed");
1559 return nullptr;
1560 }
1561 return result;
1562 }
1563
IsWeekend(napi_env env,napi_callback_info info)1564 napi_value I18nAddon::IsWeekend(napi_env env, napi_callback_info info)
1565 {
1566 size_t argc = 1;
1567 napi_value argv[1] = { 0 };
1568 argv[0] = nullptr;
1569 napi_value thisVar = nullptr;
1570 void *data = nullptr;
1571 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1572 I18nAddon *obj = nullptr;
1573 bool isWeekEnd = false;
1574 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1575 do {
1576 if (status != napi_ok || !obj || !obj->calendar_) {
1577 HiLog::Error(LABEL, "Get calendar object failed");
1578 break;
1579 }
1580 if (!argv[0]) {
1581 isWeekEnd = obj->calendar_->IsWeekend();
1582 } else {
1583 napi_value funcGetDateInfo = nullptr;
1584 status = napi_get_named_property(env, argv[0], "valueOf", &funcGetDateInfo);
1585 if (status != napi_ok) {
1586 HiLog::Error(LABEL, "Get method now failed");
1587 break;
1588 }
1589 napi_value value = nullptr;
1590 status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &value);
1591 if (status != napi_ok) {
1592 HiLog::Error(LABEL, "Get milliseconds failed");
1593 break;
1594 }
1595 double milliseconds = 0;
1596 status = napi_get_value_double(env, value, &milliseconds);
1597 if (status != napi_ok) {
1598 HiLog::Error(LABEL, "Retrieve milliseconds failed");
1599 break;
1600 }
1601 UErrorCode error = U_ZERO_ERROR;
1602 isWeekEnd = obj->calendar_->IsWeekend(milliseconds, error);
1603 }
1604 } while (false);
1605 napi_value result = nullptr;
1606 status = napi_get_boolean(env, isWeekEnd, &result);
1607 if (status != napi_ok) {
1608 HiLog::Error(LABEL, "Create boolean failed");
1609 return nullptr;
1610 }
1611 return result;
1612 }
1613
GetDisplayName(napi_env env,napi_callback_info info)1614 napi_value I18nAddon::GetDisplayName(napi_env env, napi_callback_info info)
1615 {
1616 size_t argc = 1;
1617 napi_value argv[1] = { 0 };
1618 argv[0] = nullptr;
1619 napi_value thisVar = nullptr;
1620 void *data = nullptr;
1621 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1622 napi_valuetype valueType = napi_valuetype::napi_undefined;
1623 napi_typeof(env, argv[0], &valueType);
1624 if (valueType != napi_valuetype::napi_string) {
1625 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1626 return nullptr;
1627 }
1628 int32_t code = 0;
1629 std::string localeTag = GetString(env, argv[0], code);
1630 if (code) {
1631 return nullptr;
1632 }
1633 I18nAddon *obj = nullptr;
1634 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1635 if (status != napi_ok || !obj || !obj->calendar_) {
1636 HiLog::Error(LABEL, "Get calendar object failed");
1637 return nullptr;
1638 }
1639 if (!obj->calendar_) {
1640 return nullptr;
1641 }
1642 std::string name = obj->calendar_->GetDisplayName(localeTag);
1643 napi_value result = nullptr;
1644 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result);
1645 if (status != napi_ok) {
1646 HiLog::Error(LABEL, "Create calendar name string failed");
1647 return nullptr;
1648 }
1649 return result;
1650 }
1651
InitIndexUtil(napi_env env,napi_value exports)1652 napi_value I18nAddon::InitIndexUtil(napi_env env, napi_value exports)
1653 {
1654 napi_property_descriptor properties[] = {
1655 DECLARE_NAPI_FUNCTION("getIndexList", GetIndexList),
1656 DECLARE_NAPI_FUNCTION("addLocale", AddLocale),
1657 DECLARE_NAPI_FUNCTION("getIndex", GetIndex)
1658 };
1659
1660 napi_value constructor = nullptr;
1661 napi_status status = napi_define_class(env, "IndexUtil", NAPI_AUTO_LENGTH, IndexUtilConstructor, nullptr,
1662 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1663 if (status != napi_ok) {
1664 HiLog::Error(LABEL, "Define class failed when InitPhoneNumberFormat");
1665 return nullptr;
1666 }
1667
1668 status = napi_create_reference(env, constructor, 1, &g_indexUtilConstructor);
1669 if (status != napi_ok) {
1670 HiLog::Error(LABEL, "Failed to create reference at init");
1671 return nullptr;
1672 }
1673 return exports;
1674 }
1675
BreakIteratorConstructor(napi_env env,napi_callback_info info)1676 napi_value I18nAddon::BreakIteratorConstructor(napi_env env, napi_callback_info info)
1677 {
1678 size_t argc = 1;
1679 napi_value argv[1] = { nullptr };
1680 napi_value thisVar = nullptr;
1681 void *data = nullptr;
1682 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1683 if (status != napi_ok) {
1684 return nullptr;
1685 }
1686 napi_valuetype valueType = napi_valuetype::napi_undefined;
1687 napi_typeof(env, argv[0], &valueType);
1688 if (valueType != napi_valuetype::napi_string) {
1689 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1690 return nullptr;
1691 }
1692 int32_t code = 0;
1693 std::string localeTag = GetString(env, argv[0], code);
1694 if (code) {
1695 return nullptr;
1696 }
1697 std::unique_ptr<I18nAddon> obj = nullptr;
1698 obj = std::make_unique<I18nAddon>();
1699 if (!obj) {
1700 HiLog::Error(LABEL, "Create I18nAddon failed");
1701 return nullptr;
1702 }
1703 status =
1704 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, &obj->wrapper_);
1705 if (status != napi_ok) {
1706 HiLog::Error(LABEL, "Wrap II18nAddon failed");
1707 return nullptr;
1708 }
1709 obj->brkiter_ = std::make_unique<I18nBreakIterator>(localeTag);
1710 if (!obj->brkiter_) {
1711 HiLog::Error(LABEL, "Wrap BreakIterator failed");
1712 return nullptr;
1713 }
1714 obj.release();
1715 return thisVar;
1716 }
1717
InitBreakIterator(napi_env env,napi_value exports)1718 napi_value I18nAddon::InitBreakIterator(napi_env env, napi_value exports)
1719 {
1720 napi_status status = napi_ok;
1721 napi_property_descriptor properties[] = {
1722 DECLARE_NAPI_FUNCTION("current", Current),
1723 DECLARE_NAPI_FUNCTION("first", First),
1724 DECLARE_NAPI_FUNCTION("last", Last),
1725 DECLARE_NAPI_FUNCTION("next", Next),
1726 DECLARE_NAPI_FUNCTION("previous", Previous),
1727 DECLARE_NAPI_FUNCTION("setLineBreakText", SetText),
1728 DECLARE_NAPI_FUNCTION("following", Following),
1729 DECLARE_NAPI_FUNCTION("getLineBreakText", GetText),
1730 DECLARE_NAPI_FUNCTION("isBoundary", IsBoundary),
1731 };
1732 napi_value constructor = nullptr;
1733 status = napi_define_class(env, "BreakIterator", NAPI_AUTO_LENGTH, BreakIteratorConstructor, nullptr,
1734 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1735 if (status != napi_ok) {
1736 HiLog::Error(LABEL, "Failed to define class BreakIterator at Init");
1737 return nullptr;
1738 }
1739 g_brkConstructor = new (std::nothrow) napi_ref;
1740 if (!g_brkConstructor) {
1741 HiLog::Error(LABEL, "Failed to create brkiterator ref at init");
1742 return nullptr;
1743 }
1744 status = napi_create_reference(env, constructor, 1, g_brkConstructor);
1745 if (status != napi_ok) {
1746 HiLog::Error(LABEL, "Failed to create reference g_brkConstructor at init");
1747 return nullptr;
1748 }
1749 return exports;
1750 }
1751
GetLineInstance(napi_env env,napi_callback_info info)1752 napi_value I18nAddon::GetLineInstance(napi_env env, napi_callback_info info)
1753 {
1754 size_t argc = 1;
1755 napi_value argv[1] = { nullptr };
1756 napi_value thisVar = nullptr;
1757 void *data = nullptr;
1758 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1759 napi_value constructor = nullptr;
1760 napi_status status = napi_get_reference_value(env, *g_brkConstructor, &constructor);
1761 if (status != napi_ok) {
1762 HiLog::Error(LABEL, "Failed to create reference at GetLineInstance");
1763 return nullptr;
1764 }
1765 if (!argv[0]) {
1766 return nullptr;
1767 }
1768 napi_value result = nullptr;
1769 status = napi_new_instance(env, constructor, 1, argv, &result); // 1 arguments
1770 if (status != napi_ok) {
1771 HiLog::Error(LABEL, "GetLineInstance create instance failed");
1772 return nullptr;
1773 }
1774 return result;
1775 }
1776
Current(napi_env env,napi_callback_info info)1777 napi_value I18nAddon::Current(napi_env env, napi_callback_info info)
1778 {
1779 size_t argc = 0;
1780 napi_value *argv = nullptr;
1781 napi_value thisVar = nullptr;
1782 void *data = nullptr;
1783 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1784 I18nAddon *obj = nullptr;
1785 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1786 if (status != napi_ok || !obj || !obj->brkiter_) {
1787 HiLog::Error(LABEL, "Get BreakIterator object failed");
1788 return nullptr;
1789 }
1790 int value = obj->brkiter_->current();
1791 napi_value result = nullptr;
1792 status = napi_create_int32(env, value, &result);
1793 if (status != napi_ok) {
1794 HiLog::Error(LABEL, "Create int32_t value failed");
1795 return nullptr;
1796 }
1797 return result;
1798 }
1799
First(napi_env env,napi_callback_info info)1800 napi_value I18nAddon::First(napi_env env, napi_callback_info info)
1801 {
1802 size_t argc = 0;
1803 napi_value *argv = nullptr;
1804 napi_value thisVar = nullptr;
1805 void *data = nullptr;
1806 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1807 I18nAddon *obj = nullptr;
1808 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1809 if (status != napi_ok || !obj || !obj->brkiter_) {
1810 HiLog::Error(LABEL, "Get BreakIterator object failed");
1811 return nullptr;
1812 }
1813 int value = obj->brkiter_->first();
1814 napi_value result = nullptr;
1815 status = napi_create_int32(env, value, &result);
1816 if (status != napi_ok) {
1817 HiLog::Error(LABEL, "Create int32_t value failed");
1818 return nullptr;
1819 }
1820 return result;
1821 }
1822
Last(napi_env env,napi_callback_info info)1823 napi_value I18nAddon::Last(napi_env env, napi_callback_info info)
1824 {
1825 size_t argc = 0;
1826 napi_value *argv = nullptr;
1827 napi_value thisVar = nullptr;
1828 void *data = nullptr;
1829 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1830 I18nAddon *obj = nullptr;
1831 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1832 if (status != napi_ok || !obj || !obj->brkiter_) {
1833 HiLog::Error(LABEL, "Get BreakIterator object failed");
1834 return nullptr;
1835 }
1836 int value = obj->brkiter_->last();
1837 napi_value result = nullptr;
1838 status = napi_create_int32(env, value, &result);
1839 if (status != napi_ok) {
1840 HiLog::Error(LABEL, "Create int32_t value failed");
1841 return nullptr;
1842 }
1843 return result;
1844 }
1845
Previous(napi_env env,napi_callback_info info)1846 napi_value I18nAddon::Previous(napi_env env, napi_callback_info info)
1847 {
1848 size_t argc = 0;
1849 napi_value *argv = nullptr;
1850 napi_value thisVar = nullptr;
1851 void *data = nullptr;
1852 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1853 I18nAddon *obj = nullptr;
1854 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1855 if (status != napi_ok || !obj || !obj->brkiter_) {
1856 HiLog::Error(LABEL, "Get BreakIterator object failed");
1857 return nullptr;
1858 }
1859 int value = obj->brkiter_->previous();
1860 napi_value result = nullptr;
1861 status = napi_create_int32(env, value, &result);
1862 if (status != napi_ok) {
1863 HiLog::Error(LABEL, "Create int32_t value failed");
1864 return nullptr;
1865 }
1866 return result;
1867 }
1868
Next(napi_env env,napi_callback_info info)1869 napi_value I18nAddon::Next(napi_env env, napi_callback_info info)
1870 {
1871 size_t argc = 1;
1872 napi_value argv[1] = { nullptr };
1873 napi_value thisVar = nullptr;
1874 void *data = nullptr;
1875 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1876 I18nAddon *obj = nullptr;
1877 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1878 if (status != napi_ok || !obj || !obj->brkiter_) {
1879 HiLog::Error(LABEL, "Get BreakIterator object failed");
1880 return nullptr;
1881 }
1882 int value = 1;
1883 if (argv[0] != nullptr) {
1884 napi_valuetype valueType = napi_valuetype::napi_undefined;
1885 napi_typeof(env, argv[0], &valueType);
1886 if (valueType != napi_valuetype::napi_number) {
1887 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1888 return nullptr;
1889 }
1890 status = napi_get_value_int32(env, argv[0], &value);
1891 if (status != napi_ok) {
1892 HiLog::Error(LABEL, "Retrieve next value failed");
1893 return nullptr;
1894 }
1895 }
1896 value = obj->brkiter_->next(value);
1897 napi_value result = nullptr;
1898 status = napi_create_int32(env, value, &result);
1899 if (status != napi_ok) {
1900 HiLog::Error(LABEL, "Create int32_t value failed");
1901 return nullptr;
1902 }
1903 return result;
1904 }
1905
SetText(napi_env env,napi_callback_info info)1906 napi_value I18nAddon::SetText(napi_env env, napi_callback_info info)
1907 {
1908 size_t argc = 1;
1909 napi_value argv[1] = { nullptr };
1910 napi_value thisVar = nullptr;
1911 void *data = nullptr;
1912 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1913 I18nAddon *obj = nullptr;
1914 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1915 if (status != napi_ok || !obj || !obj->brkiter_) {
1916 HiLog::Error(LABEL, "Get BreakIterator object failed");
1917 return nullptr;
1918 }
1919 if (!argv[0]) {
1920 return nullptr;
1921 }
1922 napi_valuetype valueType = napi_valuetype::napi_undefined;
1923 napi_typeof(env, argv[0], &valueType);
1924 if (valueType != napi_valuetype::napi_string) {
1925 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1926 return nullptr;
1927 }
1928 size_t len = 0;
1929 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
1930 if (status != napi_ok) {
1931 HiLog::Error(LABEL, "Get field length failed");
1932 return nullptr;
1933 }
1934 std::vector<char> buf(len + 1);
1935 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
1936 if (status != napi_ok) {
1937 HiLog::Error(LABEL, "Get string value failed");
1938 return nullptr;
1939 }
1940 obj->brkiter_->setText(buf.data());
1941 return nullptr;
1942 }
1943
GetText(napi_env env,napi_callback_info info)1944 napi_value I18nAddon::GetText(napi_env env, napi_callback_info info)
1945 {
1946 size_t argc = 0;
1947 napi_value *argv = nullptr;
1948 napi_value thisVar = nullptr;
1949 void *data = nullptr;
1950 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1951 I18nAddon *obj = nullptr;
1952 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1953 if (status != napi_ok || !obj || !obj->brkiter_) {
1954 HiLog::Error(LABEL, "Get BreakIterator object failed");
1955 return nullptr;
1956 }
1957 napi_value value = nullptr;
1958 std::string temp;
1959 obj->brkiter_->getText(temp);
1960 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &value);
1961 if (status != napi_ok) {
1962 HiLog::Error(LABEL, "Get field length failed");
1963 return nullptr;
1964 }
1965 return value;
1966 }
1967
Following(napi_env env,napi_callback_info info)1968 napi_value I18nAddon::Following(napi_env env, napi_callback_info info)
1969 {
1970 size_t argc = 1;
1971 napi_value argv[1] = { nullptr };
1972 napi_value thisVar = nullptr;
1973 void *data = nullptr;
1974 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1975 I18nAddon *obj = nullptr;
1976 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
1977 if (status != napi_ok || !obj || !obj->brkiter_) {
1978 HiLog::Error(LABEL, "Get BreakIterator object failed");
1979 return nullptr;
1980 }
1981 if (!argv[0]) {
1982 return nullptr;
1983 }
1984 napi_valuetype valueType = napi_valuetype::napi_undefined;
1985 napi_typeof(env, argv[0], &valueType);
1986 if (valueType != napi_valuetype::napi_number) {
1987 napi_throw_type_error(env, nullptr, "Parameter type does not match");
1988 return nullptr;
1989 }
1990 int value;
1991 status = napi_get_value_int32(env, argv[0], &value);
1992 if (status != napi_ok) {
1993 HiLog::Error(LABEL, "Retrieve following value failed");
1994 return nullptr;
1995 }
1996 value = obj->brkiter_->following(value);
1997 napi_value result = nullptr;
1998 status = napi_create_int32(env, value, &result);
1999 if (status != napi_ok) {
2000 HiLog::Error(LABEL, "Create int32_t value failed");
2001 return nullptr;
2002 }
2003 return result;
2004 }
2005
IsBoundary(napi_env env,napi_callback_info info)2006 napi_value I18nAddon::IsBoundary(napi_env env, napi_callback_info info)
2007 {
2008 size_t argc = 1;
2009 napi_value argv[1] = { nullptr };
2010 napi_value thisVar = nullptr;
2011 void *data = nullptr;
2012 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2013 I18nAddon *obj = nullptr;
2014 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2015 if (status != napi_ok || !obj || !obj->brkiter_) {
2016 HiLog::Error(LABEL, "Get BreakIterator object failed");
2017 return nullptr;
2018 }
2019 if (!argv[0]) {
2020 return nullptr;
2021 }
2022 napi_valuetype valueType = napi_valuetype::napi_undefined;
2023 int value;
2024 napi_typeof(env, argv[0], &valueType);
2025 if (valueType != napi_valuetype::napi_number) {
2026 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2027 return nullptr;
2028 }
2029 status = napi_get_value_int32(env, argv[0], &value);
2030 if (status != napi_ok) {
2031 HiLog::Error(LABEL, "Retrieve following value failed");
2032 return nullptr;
2033 }
2034 bool boundary = obj->brkiter_->isBoundary(value);
2035 napi_value result = nullptr;
2036 status = napi_get_boolean(env, boundary, &result);
2037 if (status != napi_ok) {
2038 HiLog::Error(LABEL, "Create boolean failed");
2039 return nullptr;
2040 }
2041 return result;
2042 }
2043
IndexUtilConstructor(napi_env env,napi_callback_info info)2044 napi_value I18nAddon::IndexUtilConstructor(napi_env env, napi_callback_info info)
2045 {
2046 size_t argc = 1;
2047 napi_value argv[1] = { 0 };
2048 napi_value thisVar = nullptr;
2049 void *data = nullptr;
2050 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2051 std::string localeTag = "";
2052 if (argv[0] != nullptr) {
2053 napi_valuetype valueType = napi_valuetype::napi_undefined;
2054 napi_typeof(env, argv[0], &valueType);
2055 if (valueType != napi_valuetype::napi_string) {
2056 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2057 return nullptr;
2058 }
2059 size_t len = 0;
2060 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2061 if (status != napi_ok) {
2062 HiLog::Error(LABEL, "Get locale length failed");
2063 return nullptr;
2064 }
2065 std::vector<char> localeBuf(len + 1);
2066 status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
2067 if (status != napi_ok) {
2068 HiLog::Error(LABEL, "Get locale failed");
2069 return nullptr;
2070 }
2071 localeTag = localeBuf.data();
2072 }
2073 std::unique_ptr<I18nAddon> obj = nullptr;
2074 obj = std::make_unique<I18nAddon>();
2075 if (!obj) {
2076 HiLog::Error(LABEL, "Create I18nAddon failed");
2077 return nullptr;
2078 }
2079 status =
2080 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, &obj->wrapper_);
2081 if (status != napi_ok) {
2082 HiLog::Error(LABEL, "Wrap II18nAddon failed");
2083 return nullptr;
2084 }
2085 if (!obj->InitIndexUtilContext(env, info, localeTag)) {
2086 return nullptr;
2087 }
2088 obj.release();
2089 return thisVar;
2090 }
2091
InitIndexUtilContext(napi_env env,napi_callback_info info,const std::string & localeTag)2092 bool I18nAddon::InitIndexUtilContext(napi_env env, napi_callback_info info, const std::string &localeTag)
2093 {
2094 napi_value global = nullptr;
2095 napi_status status = napi_get_global(env, &global);
2096 if (status != napi_ok) {
2097 HiLog::Error(LABEL, "Get global failed");
2098 return false;
2099 }
2100 env_ = env;
2101 indexUtil_ = std::make_unique<IndexUtil>(localeTag);
2102 return indexUtil_ != nullptr;
2103 }
2104
GetIndexUtil(napi_env env,napi_callback_info info)2105 napi_value I18nAddon::GetIndexUtil(napi_env env, napi_callback_info info)
2106 {
2107 size_t argc = 1;
2108 napi_value argv[1] = { 0 };
2109 napi_value thisVar = nullptr;
2110 void *data = nullptr;
2111 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2112 napi_value constructor = nullptr;
2113 napi_status status = napi_get_reference_value(env, g_indexUtilConstructor, &constructor);
2114 if (status != napi_ok) {
2115 HiLog::Error(LABEL, "Failed to create reference at GetIndexUtil");
2116 return nullptr;
2117 }
2118 napi_value result = nullptr;
2119 if (!argv[0]) {
2120 status = napi_new_instance(env, constructor, 0, argv, &result);
2121 } else {
2122 status = napi_new_instance(env, constructor, 1, argv, &result);
2123 }
2124 if (status != napi_ok) {
2125 HiLog::Error(LABEL, "Get calendar create instance failed");
2126 return nullptr;
2127 }
2128 return result;
2129 }
2130
GetIndexList(napi_env env,napi_callback_info info)2131 napi_value I18nAddon::GetIndexList(napi_env env, napi_callback_info info)
2132 {
2133 size_t argc = 0;
2134 napi_value argv[0];
2135 napi_value thisVar = nullptr;
2136 void *data = nullptr;
2137 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2138
2139 I18nAddon *obj = nullptr;
2140 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2141 if (status != napi_ok || !obj || !obj->indexUtil_) {
2142 HiLog::Error(LABEL, "GetPhoneNumberFormat object failed");
2143 return nullptr;
2144 }
2145
2146 std::vector<std::string> indexList = obj->indexUtil_->GetIndexList();
2147 napi_value result = nullptr;
2148 status = napi_create_array_with_length(env, indexList.size(), &result);
2149 if (status != napi_ok) {
2150 HiLog::Error(LABEL, "Failed to create array");
2151 return nullptr;
2152 }
2153 for (size_t i = 0; i < indexList.size(); i++) {
2154 napi_value element = nullptr;
2155 status = napi_create_string_utf8(env, indexList[i].c_str(), NAPI_AUTO_LENGTH, &element);
2156 if (status != napi_ok) {
2157 HiLog::Error(LABEL, "Failed to create string item");
2158 return nullptr;
2159 }
2160 status = napi_set_element(env, result, i, element);
2161 if (status != napi_ok) {
2162 HiLog::Error(LABEL, "Failed to set array item");
2163 return nullptr;
2164 }
2165 }
2166 return result;
2167 }
2168
AddLocale(napi_env env,napi_callback_info info)2169 napi_value I18nAddon::AddLocale(napi_env env, napi_callback_info info)
2170 {
2171 size_t argc = 1;
2172 napi_value argv[1] = { 0 };
2173 napi_value thisVar = nullptr;
2174 void *data = nullptr;
2175 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2176 napi_valuetype valueType = napi_valuetype::napi_undefined;
2177 napi_typeof(env, argv[0], &valueType);
2178 if (valueType != napi_valuetype::napi_string) {
2179 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2180 return nullptr;
2181 }
2182 size_t len = 0;
2183 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2184 if (status != napi_ok) {
2185 HiLog::Error(LABEL, "Get locale length failed");
2186 return nullptr;
2187 }
2188 std::vector<char> buf(len + 1);
2189 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
2190 if (status != napi_ok) {
2191 HiLog::Error(LABEL, "Get locale failed");
2192 return nullptr;
2193 }
2194 I18nAddon *obj = nullptr;
2195 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2196 if (status != napi_ok || !obj || !obj->indexUtil_) {
2197 HiLog::Error(LABEL, "Get IndexUtil object failed");
2198 return nullptr;
2199 }
2200 obj->indexUtil_->AddLocale(buf.data());
2201 return nullptr;
2202 }
2203
GetIndex(napi_env env,napi_callback_info info)2204 napi_value I18nAddon::GetIndex(napi_env env, napi_callback_info info)
2205 {
2206 size_t argc = 1;
2207 napi_value argv[1] = { 0 };
2208 napi_value thisVar = nullptr;
2209 void *data = nullptr;
2210 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2211 napi_valuetype valueType = napi_valuetype::napi_undefined;
2212 napi_typeof(env, argv[0], &valueType);
2213 if (valueType != napi_valuetype::napi_string) {
2214 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2215 return nullptr;
2216 }
2217 size_t len = 0;
2218 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2219 if (status != napi_ok) {
2220 HiLog::Error(LABEL, "Get String length failed");
2221 return nullptr;
2222 }
2223 std::vector<char> buf(len + 1);
2224 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
2225 if (status != napi_ok) {
2226 HiLog::Error(LABEL, "Get String failed");
2227 return nullptr;
2228 }
2229 I18nAddon *obj = nullptr;
2230 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2231 if (status != napi_ok || !obj || !obj->indexUtil_) {
2232 HiLog::Error(LABEL, "Get IndexUtil object failed");
2233 return nullptr;
2234 }
2235 std::string index = obj->indexUtil_->GetIndex(buf.data());
2236 napi_value result = nullptr;
2237 status = napi_create_string_utf8(env, index.c_str(), NAPI_AUTO_LENGTH, &result);
2238 if (status != napi_ok) {
2239 HiLog::Error(LABEL, "GetIndex Failed");
2240 return nullptr;
2241 }
2242 return result;
2243 }
2244
Is24HourClock(napi_env env,napi_callback_info info)2245 napi_value I18nAddon::Is24HourClock(napi_env env, napi_callback_info info)
2246 {
2247 bool is24HourClock = LocaleConfig::Is24HourClock();
2248 napi_value result = nullptr;
2249 napi_status status = napi_get_boolean(env, is24HourClock, &result);
2250 if (status != napi_ok) {
2251 HiLog::Error(LABEL, "Failed to create boolean item");
2252 return nullptr;
2253 }
2254 return result;
2255 }
2256
Set24HourClock(napi_env env,napi_callback_info info)2257 napi_value I18nAddon::Set24HourClock(napi_env env, napi_callback_info info)
2258 {
2259 size_t argc = 1;
2260 napi_value argv[1] = { 0 };
2261 napi_value thisVar = nullptr;
2262 void *data = nullptr;
2263 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2264
2265 bool option = false;
2266 status = napi_get_value_bool(env, argv[0], &option);
2267 if (status != napi_ok) {
2268 HiLog::Error(LABEL, "Failed to get boolean item");
2269 return nullptr;
2270 }
2271 bool success = LocaleConfig::Set24HourClock(option);
2272 napi_value result = nullptr;
2273 status = napi_get_boolean(env, success, &result);
2274 if (status != napi_ok) {
2275 HiLog::Error(LABEL, "Create set 24HourClock boolean value failed");
2276 return nullptr;
2277 }
2278 return result;
2279 }
2280
AddPreferredLanguage(napi_env env,napi_callback_info info)2281 napi_value I18nAddon::AddPreferredLanguage(napi_env env, napi_callback_info info)
2282 {
2283 size_t argc = 2;
2284 napi_value argv[2] = { 0 };
2285 napi_value thisVar = nullptr;
2286 void *data = nullptr;
2287 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2288
2289 napi_valuetype valueType = napi_valuetype::napi_undefined;
2290 napi_typeof(env, argv[0], &valueType);
2291 if (valueType != napi_valuetype::napi_string) {
2292 napi_throw_type_error(env, nullptr, "addPreferredLanguage: first parameter type does not match");
2293 return nullptr;
2294 }
2295 size_t len = 0;
2296 status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
2297 if (status != napi_ok) {
2298 HiLog::Error(LABEL, "addPreferredLanguage: get language length failed");
2299 return nullptr;
2300 }
2301 std::vector<char> language(len + 1);
2302 status = napi_get_value_string_utf8(env, argv[0], language.data(), len + 1, &len);
2303 if (status != napi_ok) {
2304 HiLog::Error(LABEL, "addPreferrdLanguage: get language failed");
2305 return nullptr;
2306 }
2307 int index = 1000000;
2308 if (argv[1] != nullptr) {
2309 status = napi_get_value_int32(env, argv[1], &index);
2310 }
2311 if (status != napi_ok) {
2312 HiLog::Error(LABEL, "addPreferrdLanguage: get index failed");
2313 return nullptr;
2314 }
2315 bool success = PreferredLanguage::AddPreferredLanguage(language.data(), index);
2316 napi_value result = nullptr;
2317 status = napi_get_boolean(env, success, &result);
2318 if (status != napi_ok) {
2319 HiLog::Error(LABEL, "addPreferrdLanguage: create boolean result failed");
2320 return nullptr;
2321 }
2322 return result;
2323 }
2324
RemovePreferredLanguage(napi_env env,napi_callback_info info)2325 napi_value I18nAddon::RemovePreferredLanguage(napi_env env, napi_callback_info info)
2326 {
2327 size_t argc = 1;
2328 napi_value argv[1] = { 0 };
2329 napi_value thisVar = nullptr;
2330 void *data = nullptr;
2331 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2332
2333 napi_valuetype valueType = napi_valuetype::napi_undefined;
2334 napi_typeof(env, argv[0], &valueType);
2335 if (valueType != napi_valuetype::napi_number) {
2336 napi_throw_type_error(env, nullptr, "removePreferredLanguage: parameter type does not match");
2337 return nullptr;
2338 }
2339 int index = 1000000;
2340 status = napi_get_value_int32(env, argv[0], &index);
2341 if (status != napi_ok) {
2342 HiLog::Error(LABEL, "removePreferrdLanguage: get index failed");
2343 return nullptr;
2344 }
2345 bool success = PreferredLanguage::RemovePreferredLanguage(index);
2346 napi_value result = nullptr;
2347 status = napi_get_boolean(env, success, &result);
2348 if (status != napi_ok) {
2349 HiLog::Error(LABEL, "removePreferrdLanguage: create boolean result failed");
2350 return nullptr;
2351 }
2352 return result;
2353 }
2354
GetPreferredLanguageList(napi_env env,napi_callback_info info)2355 napi_value I18nAddon::GetPreferredLanguageList(napi_env env, napi_callback_info info)
2356 {
2357 std::vector<std::string> languageList = PreferredLanguage::GetPreferredLanguageList();
2358 napi_value result = nullptr;
2359 napi_status status = napi_ok;
2360 status = napi_create_array_with_length(env, languageList.size(), &result);
2361 if (status != napi_ok) {
2362 HiLog::Error(LABEL, "getPreferrdLanguageList: create array failed");
2363 return nullptr;
2364 }
2365 for (size_t i = 0; i < languageList.size(); i++) {
2366 napi_value value = nullptr;
2367 status = napi_create_string_utf8(env, languageList[i].c_str(), NAPI_AUTO_LENGTH, &value);
2368 if (status != napi_ok) {
2369 HiLog::Error(LABEL, "getPreferrdLanguageList: create string failed");
2370 return nullptr;
2371 }
2372 status = napi_set_element(env, result, i, value);
2373 if (status != napi_ok) {
2374 HiLog::Error(LABEL, "GetPreferredLanguageList: set array item failed");
2375 return nullptr;
2376 }
2377 }
2378 return result;
2379 }
2380
GetFirstPreferredLanguage(napi_env env,napi_callback_info info)2381 napi_value I18nAddon::GetFirstPreferredLanguage(napi_env env, napi_callback_info info)
2382 {
2383 std::string language = PreferredLanguage::GetFirstPreferredLanguage();
2384 napi_value result = nullptr;
2385 napi_status status = napi_ok;
2386 status = napi_create_string_utf8(env, language.c_str(), NAPI_AUTO_LENGTH, &result);
2387 if (status != napi_ok) {
2388 HiLog::Error(LABEL, "getFirstPreferrdLanguage: create string result failed");
2389 return nullptr;
2390 }
2391 return result;
2392 }
2393
InitI18nTimeZone(napi_env env,napi_value exports)2394 napi_value I18nAddon::InitI18nTimeZone(napi_env env, napi_value exports)
2395 {
2396 napi_status status = napi_ok;
2397 napi_property_descriptor properties[] = {
2398 DECLARE_NAPI_FUNCTION("getID", GetID),
2399 DECLARE_NAPI_FUNCTION("getDisplayName", GetTimeZoneDisplayName),
2400 DECLARE_NAPI_FUNCTION("getRawOffset", GetRawOffset),
2401 DECLARE_NAPI_FUNCTION("getOffset", GetOffset),
2402 };
2403 napi_value constructor = nullptr;
2404 status = napi_define_class(env, "TimeZone", NAPI_AUTO_LENGTH, I18nTimeZoneConstructor, nullptr,
2405 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
2406 if (status != napi_ok) {
2407 HiLog::Error(LABEL, "Failed to define class TimeZone at Init");
2408 return nullptr;
2409 }
2410 g_timezoneConstructor = new (std::nothrow) napi_ref;
2411 if (!g_timezoneConstructor) {
2412 HiLog::Error(LABEL, "Failed to create TimeZone ref at init");
2413 return nullptr;
2414 }
2415 status = napi_create_reference(env, constructor, 1, g_timezoneConstructor);
2416 if (status != napi_ok) {
2417 HiLog::Error(LABEL, "Failed to create reference g_timezoneConstructor at init");
2418 return nullptr;
2419 }
2420 return exports;
2421 }
2422
I18nTimeZoneConstructor(napi_env env,napi_callback_info info)2423 napi_value I18nAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info info)
2424 {
2425 size_t argc = 1;
2426 napi_value argv[1] = { nullptr };
2427 napi_value thisVar = nullptr;
2428 void *data = nullptr;
2429 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2430 if (status != napi_ok) {
2431 return nullptr;
2432 }
2433 std::string zoneID = "";
2434 if (argv[0] != nullptr) {
2435 napi_valuetype valueType = napi_valuetype::napi_undefined;
2436 napi_typeof(env, argv[0], &valueType);
2437 if (valueType != napi_valuetype::napi_string) {
2438 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2439 return nullptr;
2440 }
2441 int32_t code = 0;
2442 zoneID = GetString(env, argv[0], code);
2443 if (code != 0) {
2444 return nullptr;
2445 }
2446 }
2447 std::unique_ptr<I18nAddon> obj = nullptr;
2448 obj = std::make_unique<I18nAddon>();
2449 if (!obj) {
2450 HiLog::Error(LABEL, "Create I18nAddon failed");
2451 return nullptr;
2452 }
2453 status =
2454 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nAddon::Destructor, nullptr, &obj->wrapper_);
2455 if (status != napi_ok) {
2456 HiLog::Error(LABEL, "Wrap II18nAddon failed");
2457 return nullptr;
2458 }
2459 obj->timezone_ = std::make_unique<I18nTimeZone>(zoneID);
2460 if (!obj->timezone_) {
2461 HiLog::Error(LABEL, "Wrap TimeZone failed");
2462 return nullptr;
2463 }
2464 obj.release();
2465 return thisVar;
2466 }
2467
GetI18nTimeZone(napi_env env,napi_callback_info info)2468 napi_value I18nAddon::GetI18nTimeZone(napi_env env, napi_callback_info info)
2469 {
2470 size_t argc = 1;
2471 napi_value argv[1] = { nullptr };
2472 napi_value thisVar = nullptr;
2473 void *data = nullptr;
2474 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2475 napi_value constructor = nullptr;
2476 napi_status status = napi_get_reference_value(env, *g_timezoneConstructor, &constructor);
2477 if (status != napi_ok) {
2478 HiLog::Error(LABEL, "Failed to create reference at GetTimeZoneInstance");
2479 return nullptr;
2480 }
2481
2482 napi_value result = nullptr;
2483 if (!argv[0]) {
2484 status = napi_new_instance(env, constructor, 0, nullptr, &result); // 1 arguments
2485 } else {
2486 status = napi_new_instance(env, constructor, 1, argv, &result); // 1 arguments
2487 }
2488 if (status != napi_ok) {
2489 HiLog::Error(LABEL, "GetTimeZone create instance failed");
2490 return nullptr;
2491 }
2492 return result;
2493 }
2494
GetID(napi_env env,napi_callback_info info)2495 napi_value I18nAddon::GetID(napi_env env, napi_callback_info info)
2496 {
2497 size_t argc = 0;
2498 napi_value *argv = nullptr;
2499 napi_value thisVar = nullptr;
2500 void *data = nullptr;
2501 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2502 I18nAddon *obj = nullptr;
2503 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2504 if (status != napi_ok || !obj || !obj->timezone_) {
2505 HiLog::Error(LABEL, "Get TimeZone object failed");
2506 return nullptr;
2507 }
2508 std::string result = obj->timezone_->GetID();
2509 napi_value value = nullptr;
2510 status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
2511 if (status != napi_ok) {
2512 HiLog::Error(LABEL, "Create result failed");
2513 return nullptr;
2514 }
2515 return value;
2516 }
2517
GetStringFromJS(napi_env env,napi_value argv,std::string & jsString)2518 bool I18nAddon::GetStringFromJS(napi_env env, napi_value argv, std::string &jsString)
2519 {
2520 size_t len = 0;
2521 napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
2522 if (status != napi_ok) {
2523 HiLog::Error(LABEL, "Failed to get string length");
2524 return false;
2525 }
2526 std::vector<char> argvBuf(len + 1);
2527 status = napi_get_value_string_utf8(env, argv, argvBuf.data(), len + 1, &len);
2528 if (status != napi_ok) {
2529 HiLog::Error(LABEL, "Failed to get string item");
2530 return false;
2531 }
2532 jsString = argvBuf.data();
2533 return true;
2534 }
2535
GetParameter(napi_env env,napi_value * argv,std::string & localeStr,bool & isDST)2536 int32_t I18nAddon::GetParameter(napi_env env, napi_value *argv, std::string &localeStr, bool &isDST)
2537 {
2538 if (!argv[0]) {
2539 return 0; // 0 represents no parameter.
2540 }
2541 napi_status status = napi_ok;
2542 if (!argv[1]) {
2543 napi_valuetype valueType = napi_valuetype::napi_undefined;
2544 napi_typeof(env, argv[0], &valueType);
2545 if (valueType == napi_valuetype::napi_string) {
2546 bool valid = GetStringFromJS(env, argv[0], localeStr);
2547 if (!valid) {
2548 return -1; // -1 represents Invalid parameter.
2549 }
2550 return 1; // 1 represents one string parameter.
2551 } else if (valueType == napi_valuetype::napi_boolean) {
2552 status = napi_get_value_bool(env, argv[0], &isDST);
2553 if (status != napi_ok) {
2554 return -1; // -1 represents Invalid parameter.
2555 }
2556 return 2; // 2 represents one boolean parameter.
2557 } else {
2558 return -1; // -1 represents Invalid parameter.
2559 }
2560 }
2561 napi_valuetype valueType0 = napi_valuetype::napi_undefined;
2562 napi_valuetype valueType1 = napi_valuetype::napi_undefined;
2563 napi_typeof(env, argv[0], &valueType0); // 0 represents first parameter
2564 napi_typeof(env, argv[1], &valueType1); // 0 represents second parameter
2565 if (valueType0 != napi_valuetype::napi_string || valueType1 != napi_valuetype::napi_boolean) {
2566 return -1; // -1 represents Invalid parameter.
2567 }
2568 bool valid = GetStringFromJS(env, argv[0], localeStr);
2569 if (!valid) {
2570 return -1; // -1 represents Invalid parameter.
2571 }
2572 status = napi_get_value_bool(env, argv[1], &isDST);
2573 if (status != napi_ok) {
2574 return -1; // -1 represents Invalid parameter.
2575 }
2576 return 3; // 3 represents one string parameter and one bool parameter.
2577 }
2578
GetTimeZoneDisplayName(napi_env env,napi_callback_info info)2579 napi_value I18nAddon::GetTimeZoneDisplayName(napi_env env, napi_callback_info info)
2580 {
2581 size_t argc = 2;
2582 napi_value argv[2] = { 0 };
2583 napi_value thisVar = nullptr;
2584 void *data = nullptr;
2585 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2586
2587 I18nAddon *obj = nullptr;
2588 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2589 if (status != napi_ok || !obj || !obj->timezone_) {
2590 HiLog::Error(LABEL, "Get TimeZone object failed");
2591 return nullptr;
2592 }
2593
2594 std::string locale;
2595 bool isDST = false;
2596 int32_t parameterStatus = GetParameter(env, argv, locale, isDST);
2597
2598 std::string result;
2599 if (parameterStatus == -1) { // -1 represents Invalid parameter.
2600 napi_throw_type_error(env, nullptr, "Parameter type does not match");
2601 return nullptr;
2602 } else if (parameterStatus == 0) {
2603 result = obj->timezone_->GetDisplayName();
2604 } else if (parameterStatus == 1) { // 1 represents one string parameter.
2605 result = obj->timezone_->GetDisplayName(locale);
2606 } else if (parameterStatus == 2) { // 2 represents one boolean parameter.
2607 result = obj->timezone_->GetDisplayName(isDST);
2608 } else {
2609 result = obj->timezone_->GetDisplayName(locale, isDST);
2610 }
2611
2612 napi_value value = nullptr;
2613 status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
2614 if (status != napi_ok) {
2615 HiLog::Error(LABEL, "Create result failed");
2616 return nullptr;
2617 }
2618 return value;
2619 }
2620
GetOffset(napi_env env,napi_callback_info info)2621 napi_value I18nAddon::GetOffset(napi_env env, napi_callback_info info)
2622 {
2623 size_t argc = 1;
2624 napi_value argv[1] = { 0 };
2625 napi_value thisVar = nullptr;
2626 void *data = nullptr;
2627 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2628
2629 double date = 0;
2630 if (argv[0]) {
2631 napi_valuetype valueType = napi_valuetype::napi_undefined;
2632 napi_typeof(env, argv[0], &valueType);
2633 if (valueType != napi_valuetype::napi_number) {
2634 HiLog::Error(LABEL, "Invalid parameter type");
2635 return nullptr;
2636 }
2637 status = napi_get_value_double(env, argv[0], &date);
2638 if (status != napi_ok) {
2639 HiLog::Error(LABEL, "Get parameter date failed");
2640 return nullptr;
2641 }
2642 } else {
2643 auto time = std::chrono::system_clock::now();
2644 auto since_epoch = time.time_since_epoch();
2645 auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch);
2646 date = (double)millis.count();
2647 }
2648
2649 I18nAddon *obj = nullptr;
2650 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2651 if (status != napi_ok || !obj || !obj->timezone_) {
2652 HiLog::Error(LABEL, "Get TimeZone object failed");
2653 return nullptr;
2654 }
2655 int32_t result = obj->timezone_->GetOffset(date);
2656 napi_value value = nullptr;
2657 status = napi_create_int32(env, result, &value);
2658 if (status != napi_ok) {
2659 HiLog::Error(LABEL, "Create result failed");
2660 return nullptr;
2661 }
2662 return value;
2663 }
2664
GetRawOffset(napi_env env,napi_callback_info info)2665 napi_value I18nAddon::GetRawOffset(napi_env env, napi_callback_info info)
2666 {
2667 size_t argc = 0;
2668 napi_value *argv = nullptr;
2669 napi_value thisVar = nullptr;
2670 void *data = nullptr;
2671 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2672 I18nAddon *obj = nullptr;
2673 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
2674 if (status != napi_ok || !obj || !obj->timezone_) {
2675 HiLog::Error(LABEL, "Get TimeZone object failed");
2676 return nullptr;
2677 }
2678 int32_t result = obj->timezone_->GetRawOffset();
2679 napi_value value = nullptr;
2680 status = napi_create_int32(env, result, &value);
2681 if (status != napi_ok) {
2682 HiLog::Error(LABEL, "Create result failed");
2683 return nullptr;
2684 }
2685 return value;
2686 }
2687
Init(napi_env env,napi_value exports)2688 napi_value Init(napi_env env, napi_value exports)
2689 {
2690 napi_value val = I18nAddon::Init(env, exports);
2691 val = I18nAddon::InitPhoneNumberFormat(env, val);
2692 val = I18nAddon::InitBreakIterator(env, val);
2693 val = I18nAddon::InitI18nCalendar(env, val);
2694 val = I18nAddon::InitIndexUtil(env, val);
2695 return I18nAddon::InitI18nTimeZone(env, val);
2696 }
2697
2698 static napi_module g_i18nModule = {
2699 .nm_version = 1,
2700 .nm_flags = 0,
2701 .nm_filename = nullptr,
2702 .nm_register_func = Init,
2703 .nm_modname = "i18n",
2704 .nm_priv = ((void *)0),
2705 .reserved = { 0 }
2706 };
2707
I18nRegister()2708 extern "C" __attribute__((constructor)) void I18nRegister()
2709 {
2710 napi_module_register(&g_i18nModule);
2711 }
2712 } // namespace I18n
2713 } // namespace Global
2714 } // namespace OHOS
2715