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 "character.h"
16 #include "error_util.h"
17 #include "i18n_hilog.h"
18 #include "i18n_timezone_addon.h"
19 #include "js_utils.h"
20 #include "variable_convertor.h"
21 #include "zone_rules_addon.h"
22
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
26 static thread_local napi_ref* g_timezoneConstructor = nullptr;
27
I18nTimeZoneAddon()28 I18nTimeZoneAddon::I18nTimeZoneAddon() {}
29
~I18nTimeZoneAddon()30 I18nTimeZoneAddon::~I18nTimeZoneAddon() {}
31
Destructor(napi_env env,void * nativeObject,void * hint)32 void I18nTimeZoneAddon::Destructor(napi_env env, void *nativeObject, void *hint)
33 {
34 if (!nativeObject) {
35 return;
36 }
37 delete reinterpret_cast<I18nTimeZoneAddon *>(nativeObject);
38 nativeObject = nullptr;
39 }
40
GetI18nTimeZone(napi_env env,napi_callback_info info)41 napi_value I18nTimeZoneAddon::GetI18nTimeZone(napi_env env, napi_callback_info info)
42 {
43 size_t argc = 1;
44 napi_value argv[1] = { nullptr };
45 napi_value thisVar = nullptr;
46 void *data = nullptr;
47 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
48 if (status != napi_ok) {
49 return nullptr;
50 }
51 if (!VariableConvertor::CheckNapiIsNull(env, argv[0])) {
52 status = napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &argv[0]);
53 if (status != napi_ok) {
54 HILOG_ERROR_I18N("I18nTimeZoneAddon::GetI18nTimeZone: create string failed.");
55 return nullptr;
56 }
57 }
58 return StaticGetTimeZone(env, argv, true);
59 }
60
InitI18nTimeZone(napi_env env,napi_value exports)61 napi_value I18nTimeZoneAddon::InitI18nTimeZone(napi_env env, napi_value exports)
62 {
63 napi_property_descriptor properties[] = {
64 DECLARE_NAPI_FUNCTION("getID", GetID),
65 DECLARE_NAPI_FUNCTION("getDisplayName", GetTimeZoneDisplayName),
66 DECLARE_NAPI_FUNCTION("getRawOffset", GetRawOffset),
67 DECLARE_NAPI_FUNCTION("getOffset", GetOffset),
68 DECLARE_NAPI_FUNCTION("getZoneRules", GetZoneRules),
69 };
70 napi_value constructor = nullptr;
71 napi_status status = napi_define_class(env, "TimeZone", NAPI_AUTO_LENGTH, I18nTimeZoneConstructor, nullptr,
72 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
73 if (status != napi_ok) {
74 HILOG_ERROR_I18N("InitI18nTimeZone: Failed to define class TimeZone at Init");
75 return nullptr;
76 }
77 exports = I18nTimeZoneAddon::InitTimeZone(env, exports);
78 g_timezoneConstructor = new (std::nothrow) napi_ref;
79 if (!g_timezoneConstructor) {
80 HILOG_ERROR_I18N("InitI18nTimeZone: Failed to create TimeZone ref at init");
81 return nullptr;
82 }
83 status = napi_create_reference(env, constructor, 1, g_timezoneConstructor);
84 if (status != napi_ok) {
85 HILOG_ERROR_I18N("InitI18nTimeZone: Failed to create reference g_timezoneConstructor at init");
86 return nullptr;
87 }
88 return exports;
89 }
90
InitTimeZone(napi_env env,napi_value exports)91 napi_value I18nTimeZoneAddon::InitTimeZone(napi_env env, napi_value exports)
92 {
93 napi_property_descriptor properties[] = {
94 DECLARE_NAPI_STATIC_FUNCTION("getAvailableIDs", GetAvailableTimezoneIDs),
95 DECLARE_NAPI_STATIC_FUNCTION("getAvailableZoneCityIDs", GetAvailableZoneCityIDs),
96 DECLARE_NAPI_STATIC_FUNCTION("getCityDisplayName", GetCityDisplayName),
97 DECLARE_NAPI_STATIC_FUNCTION("getTimezoneFromCity", GetTimezoneFromCity),
98 DECLARE_NAPI_STATIC_FUNCTION("getTimezonesByLocation", GetTimezonesByLocation)
99 };
100 napi_value constructor = nullptr;
101 napi_status status = napi_define_class(env, "I18nTimeZone", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor, nullptr,
102 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
103 if (status != napi_ok) {
104 HILOG_ERROR_I18N("InitTimeZone: Failed to define class TimeZone.");
105 return nullptr;
106 }
107 status = napi_set_named_property(env, exports, "TimeZone", constructor);
108 if (status != napi_ok) {
109 HILOG_ERROR_I18N("InitTimeZone: Set property failed When InitTimeZone.");
110 return nullptr;
111 }
112 return exports;
113 }
114
I18nTimeZoneConstructor(napi_env env,napi_callback_info info)115 napi_value I18nTimeZoneAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info info)
116 {
117 size_t argc = 2;
118 napi_value argv[2] = { nullptr };
119 napi_value thisVar = nullptr;
120 void *data = nullptr;
121 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
122 if (status != napi_ok) {
123 return nullptr;
124 }
125 std::string zoneID;
126 napi_valuetype valueType = napi_valuetype::napi_undefined;
127 if (argc > 0) {
128 status = napi_typeof(env, argv[0], &valueType);
129 if (status != napi_ok || valueType != napi_valuetype::napi_string) {
130 return nullptr;
131 }
132 int32_t code = 0;
133 zoneID = VariableConvertor::GetString(env, argv[0], code);
134 if (code != 0) {
135 return nullptr;
136 }
137 }
138 if (argc < FUNC_ARGS_COUNT) {
139 return nullptr;
140 }
141 status = napi_typeof(env, argv[1], &valueType);
142 if (status != napi_ok || valueType != napi_valuetype::napi_boolean) {
143 return nullptr;
144 }
145 bool isZoneID = false;
146 status = napi_get_value_bool(env, argv[1], &isZoneID);
147 if (status != napi_ok) {
148 return nullptr;
149 }
150 std::unique_ptr<I18nTimeZoneAddon> obj = std::make_unique<I18nTimeZoneAddon>();
151 if (obj == nullptr) {
152 return nullptr;
153 }
154 status =
155 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nTimeZoneAddon::Destructor, nullptr, nullptr);
156 if (status != napi_ok) {
157 return nullptr;
158 }
159 obj->timezone_ = I18nTimeZone::CreateInstance(zoneID, isZoneID);
160 if (!obj->timezone_) {
161 return nullptr;
162 }
163 obj.release();
164 return thisVar;
165 }
166
GetAvailableTimezoneIDs(napi_env env,napi_callback_info info)167 napi_value I18nTimeZoneAddon::GetAvailableTimezoneIDs(napi_env env, napi_callback_info info)
168 {
169 I18nErrorCode errorCode = I18nErrorCode::SUCCESS;
170 std::set<std::string> timezoneIDs = I18nTimeZone::GetAvailableIDs(errorCode);
171 if (errorCode != I18nErrorCode::SUCCESS) {
172 return nullptr;
173 }
174 napi_value result = nullptr;
175 napi_status status = napi_create_array_with_length(env, timezoneIDs.size(), &result);
176 if (status != napi_ok) {
177 HILOG_ERROR_I18N("GetAvailableTimezoneIDs: Failed to create array");
178 return nullptr;
179 }
180 size_t index = 0;
181 for (std::set<std::string>::iterator it = timezoneIDs.begin(); it != timezoneIDs.end(); ++it) {
182 napi_value value = nullptr;
183 status = napi_create_string_utf8(env, (*it).c_str(), NAPI_AUTO_LENGTH, &value);
184 if (status != napi_ok) {
185 HILOG_ERROR_I18N("Failed to create string item");
186 return nullptr;
187 }
188 status = napi_set_element(env, result, index, value);
189 if (status != napi_ok) {
190 HILOG_ERROR_I18N("Failed to set array item");
191 return nullptr;
192 }
193 ++index;
194 }
195 return result;
196 }
197
GetAvailableZoneCityIDs(napi_env env,napi_callback_info info)198 napi_value I18nTimeZoneAddon::GetAvailableZoneCityIDs(napi_env env, napi_callback_info info)
199 {
200 std::unordered_set<std::string> cityIDs = I18nTimeZone::GetAvailableZoneCityIDs();
201 napi_value result = nullptr;
202 napi_status status = napi_create_array_with_length(env, cityIDs.size(), &result);
203 if (status != napi_ok) {
204 HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to create array");
205 return nullptr;
206 }
207 size_t index = 0;
208 for (auto it = cityIDs.begin(); it != cityIDs.end(); ++it) {
209 napi_value value = nullptr;
210 status = napi_create_string_utf8(env, (*it).c_str(), NAPI_AUTO_LENGTH, &value);
211 if (status != napi_ok) {
212 HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to create string item");
213 return nullptr;
214 }
215 status = napi_set_element(env, result, index, value);
216 if (status != napi_ok) {
217 HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to set array item");
218 return nullptr;
219 }
220 ++index;
221 }
222 return result;
223 }
224
GetCityDisplayName(napi_env env,napi_callback_info info)225 napi_value I18nTimeZoneAddon::GetCityDisplayName(napi_env env, napi_callback_info info)
226 {
227 size_t argc = 2;
228 napi_value argv[2] = { 0 };
229 napi_value thisVar = nullptr;
230 void *data = nullptr;
231 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
232 if (status != napi_ok) {
233 return nullptr;
234 }
235 if (argc < FUNC_ARGS_COUNT) {
236 return nullptr;
237 }
238 napi_valuetype valueType = napi_valuetype::napi_undefined;
239 status = napi_typeof(env, argv[0], &valueType);
240 if (status != napi_ok) {
241 return nullptr;
242 }
243 if (valueType != napi_valuetype::napi_string) {
244 HILOG_ERROR_I18N("GetCityDisplayName: Invalid parameter type");
245 return nullptr;
246 }
247 int32_t code = 0;
248 std::string cityID = VariableConvertor::GetString(env, argv[0], code);
249 if (code != 0) {
250 return nullptr;
251 }
252 std::string locale = VariableConvertor::GetString(env, argv[1], code);
253 if (code != 0) {
254 return nullptr;
255 }
256 std::string name = I18nTimeZone::GetCityDisplayName(cityID, locale);
257 napi_value result = nullptr;
258 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result);
259 if (status != napi_ok) {
260 return nullptr;
261 }
262 return result;
263 }
264
GetTimezoneFromCity(napi_env env,napi_callback_info info)265 napi_value I18nTimeZoneAddon::GetTimezoneFromCity(napi_env env, napi_callback_info info)
266 {
267 size_t argc = 1;
268 napi_value argv[1] = { nullptr };
269 napi_value thisVar = nullptr;
270 void *data = nullptr;
271 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
272 if (status != napi_ok) {
273 return nullptr;
274 }
275 return StaticGetTimeZone(env, argv, false);
276 }
277
GetTimezonesByLocation(napi_env env,napi_callback_info info)278 napi_value I18nTimeZoneAddon::GetTimezonesByLocation(napi_env env, napi_callback_info info)
279 {
280 size_t argc = 2;
281 napi_value argv[2] = {0, 0};
282 napi_value thisVar = nullptr;
283 void *data = nullptr;
284 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
285 if (status != napi_ok) {
286 return nullptr;
287 }
288 if (argc < FUNC_ARGS_COUNT) {
289 HILOG_ERROR_I18N("GetTimezonesByLocation: Missing parameter");
290 ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "longitude or latitude", true);
291 return nullptr;
292 }
293 double x;
294 double y;
295 VariableConvertor::VerifyType(env, "longitude", napi_valuetype::napi_number, argv[0]);
296 VariableConvertor::VerifyType(env, "latitude", napi_valuetype::napi_number, argv[1]);
297 if (!CheckLongitudeTypeAndScope(env, argv[0], x) ||
298 !CheckLatitudeTypeAndScope(env, argv[1], y)) {
299 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "longitude or latitude", "a valid value", true);
300 return nullptr;
301 }
302 napi_value timezoneList = nullptr;
303 status = napi_create_array(env, &timezoneList);
304 if (status != napi_ok) {
305 return nullptr;
306 }
307 std::vector<std::string> tempList = I18nTimeZone::GetTimezoneIdByLocation(x, y);
308 for (size_t i = 0; i < tempList.size(); i++) {
309 napi_value timezoneId = nullptr;
310 status = napi_create_string_utf8(env, tempList[i].c_str(), NAPI_AUTO_LENGTH, &timezoneId);
311 if (status != napi_ok) {
312 return nullptr;
313 }
314 napi_value argTimeZoneId[1] = { timezoneId };
315 napi_value timezone = StaticGetTimeZone(env, argTimeZoneId, true);
316 status = napi_set_element(env, timezoneList, i, timezone);
317 if (status != napi_ok) {
318 return nullptr;
319 }
320 }
321
322 return timezoneList;
323 }
324
CheckLongitudeTypeAndScope(napi_env env,napi_value argv,double & x)325 bool I18nTimeZoneAddon::CheckLongitudeTypeAndScope(napi_env env, napi_value argv, double &x)
326 {
327 napi_status status = napi_get_value_double(env, argv, &x);
328 if (status != napi_ok) {
329 HILOG_ERROR_I18N("GetTimezonesByLocation: Parse first argument x failed");
330 return false;
331 }
332 // -180 and 179.9 is the scope of longitude
333 if (x < -180 || x > 179.9) {
334 HILOG_ERROR_I18N("GetTimezonesByLocation: Args x exceed it's scope.");
335 return false;
336 }
337 return true;
338 }
339
CheckLatitudeTypeAndScope(napi_env env,napi_value argv,double & y)340 bool I18nTimeZoneAddon::CheckLatitudeTypeAndScope(napi_env env, napi_value argv, double &y)
341 {
342 napi_status status = napi_get_value_double(env, argv, &y);
343 if (status != napi_ok) {
344 HILOG_ERROR_I18N("GetTimezonesByLocation: Parse second argument y failed");
345 return false;
346 }
347 // -90 and 89.9 is the scope of latitude
348 if (y < -90 || y > 89.9) {
349 HILOG_ERROR_I18N("GetTimezonesByLocation: Args y exceed it's scope.");
350 return false;
351 }
352 return true;
353 }
354
GetID(napi_env env,napi_callback_info info)355 napi_value I18nTimeZoneAddon::GetID(napi_env env, napi_callback_info info)
356 {
357 size_t argc = 0;
358 napi_value *argv = nullptr;
359 napi_value thisVar = nullptr;
360 void *data = nullptr;
361 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
362 if (status != napi_ok) {
363 return nullptr;
364 }
365 I18nTimeZoneAddon *obj = nullptr;
366 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
367 if (status != napi_ok || !obj || !obj->timezone_) {
368 HILOG_ERROR_I18N("GetID: Get TimeZone object failed");
369 return nullptr;
370 }
371 std::string result = obj->timezone_->GetID();
372 napi_value value = nullptr;
373 status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
374 if (status != napi_ok) {
375 HILOG_ERROR_I18N("GetID: Create result failed");
376 return nullptr;
377 }
378 return value;
379 }
380
GetTimeZoneDisplayName(napi_env env,napi_callback_info info)381 napi_value I18nTimeZoneAddon::GetTimeZoneDisplayName(napi_env env, napi_callback_info info)
382 {
383 size_t argc = 2;
384 napi_value argv[2] = { 0 };
385 napi_value thisVar = nullptr;
386 void *data = nullptr;
387 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
388 if (status != napi_ok) {
389 return nullptr;
390 }
391
392 I18nTimeZoneAddon *obj = nullptr;
393 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
394 if (status != napi_ok || !obj || !obj->timezone_) {
395 HILOG_ERROR_I18N("GetTimeZoneDisplayName: Get TimeZone object failed");
396 return nullptr;
397 }
398
399 std::string locale;
400 bool isDST = false;
401 int32_t parameterStatus = GetParameter(env, argv, locale, isDST);
402
403 std::string result;
404 if (parameterStatus == -1) { // -1 represents Invalid parameter.
405 HILOG_ERROR_I18N("GetTimeZoneDisplayName: Parameter type does not match");
406 return nullptr;
407 } else if (parameterStatus == 0) {
408 result = obj->timezone_->GetDisplayName();
409 } else if (parameterStatus == 1) { // 1 represents one string parameter.
410 result = obj->timezone_->GetDisplayName(locale);
411 } else if (parameterStatus == 2) { // 2 represents one boolean parameter.
412 result = obj->timezone_->GetDisplayName(isDST);
413 } else {
414 result = obj->timezone_->GetDisplayName(locale, isDST);
415 }
416
417 napi_value value = nullptr;
418 status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
419 if (status != napi_ok) {
420 HILOG_ERROR_I18N("GetTimeZoneDisplayName: Create result failed");
421 return nullptr;
422 }
423 return value;
424 }
425
GetRawOffset(napi_env env,napi_callback_info info)426 napi_value I18nTimeZoneAddon::GetRawOffset(napi_env env, napi_callback_info info)
427 {
428 size_t argc = 0;
429 napi_value *argv = nullptr;
430 napi_value thisVar = nullptr;
431 void *data = nullptr;
432 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
433 if (status != napi_ok) {
434 return nullptr;
435 }
436 I18nTimeZoneAddon *obj = nullptr;
437 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
438 if (status != napi_ok || !obj || !obj->timezone_) {
439 HILOG_ERROR_I18N("GetRawOffset: Get TimeZone object failed");
440 return nullptr;
441 }
442 int32_t result = obj->timezone_->GetRawOffset();
443 napi_value value = nullptr;
444 status = napi_create_int32(env, result, &value);
445 if (status != napi_ok) {
446 HILOG_ERROR_I18N("GetRawOffset: Create result failed");
447 return nullptr;
448 }
449 return value;
450 }
451
GetOffset(napi_env env,napi_callback_info info)452 napi_value I18nTimeZoneAddon::GetOffset(napi_env env, napi_callback_info info)
453 {
454 size_t argc = 1;
455 napi_value argv[1] = { 0 };
456 napi_value thisVar = nullptr;
457 void *data = nullptr;
458 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
459 if (status != napi_ok) {
460 return nullptr;
461 }
462
463 double date = 0;
464 if (VariableConvertor::CheckNapiIsNull(env, argv[0])) {
465 napi_valuetype valueType = napi_valuetype::napi_undefined;
466 status = napi_typeof(env, argv[0], &valueType);
467 if (status != napi_ok) {
468 return nullptr;
469 }
470 if (valueType != napi_valuetype::napi_number) {
471 HILOG_ERROR_I18N("GetOffset: Invalid parameter type");
472 return nullptr;
473 }
474 status = napi_get_value_double(env, argv[0], &date);
475 if (status != napi_ok) {
476 HILOG_ERROR_I18N("Get parameter date failed");
477 return nullptr;
478 }
479 } else {
480 auto time = std::chrono::system_clock::now();
481 auto since_epoch = time.time_since_epoch();
482 auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch);
483 date = (double)millis.count();
484 }
485
486 I18nTimeZoneAddon *obj = nullptr;
487 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
488 if (status != napi_ok || !obj || !obj->timezone_) {
489 HILOG_ERROR_I18N("GetOffset: Get TimeZone object failed");
490 return nullptr;
491 }
492 int32_t result = obj->timezone_->GetOffset(date);
493 napi_value value = nullptr;
494 status = napi_create_int32(env, result, &value);
495 if (status != napi_ok) {
496 HILOG_ERROR_I18N("GetOffset: Create result failed");
497 return nullptr;
498 }
499 return value;
500 }
501
GetZoneRules(napi_env env,napi_callback_info info)502 napi_value I18nTimeZoneAddon::GetZoneRules(napi_env env, napi_callback_info info)
503 {
504 size_t argc = 1;
505 napi_value argv[1] = { nullptr };
506 napi_value thisVar = nullptr;
507 void *data = nullptr;
508 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
509 if (status != napi_ok) {
510 HILOG_ERROR_I18N("GetZoneRules: Get param info failed");
511 return nullptr;
512 }
513 I18nTimeZoneAddon *obj = nullptr;
514 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
515 if (status != napi_ok || !obj || !obj->timezone_) {
516 HILOG_ERROR_I18N("GetZoneRules: Get TimeZone object failed");
517 return nullptr;
518 }
519 std::string tzid = obj->timezone_->GetID();
520 return ZoneRulesAddon::GetZoneRulesObject(env, tzid);
521 }
522
StaticGetTimeZone(napi_env env,napi_value * argv,bool isZoneID)523 napi_value I18nTimeZoneAddon::StaticGetTimeZone(napi_env env, napi_value *argv, bool isZoneID)
524 {
525 napi_value constructor = nullptr;
526 if (g_timezoneConstructor == nullptr) {
527 HILOG_ERROR_I18N("Failed to create g_timezoneConstructor");
528 return nullptr;
529 }
530 napi_status status = napi_get_reference_value(env, *g_timezoneConstructor, &constructor);
531 if (status != napi_ok) {
532 HILOG_ERROR_I18N("Failed to create reference at StaticGetTimeZone");
533 return nullptr;
534 }
535 napi_value newArgv[2] = { 0 };
536 newArgv[0] = argv[0];
537 status = napi_get_boolean(env, isZoneID, &newArgv[1]);
538 if (status != napi_ok) {
539 return nullptr;
540 }
541 napi_value result = nullptr;
542 status = napi_new_instance(env, constructor, 2, newArgv, &result); // 2 is parameter num
543 if (status != napi_ok) {
544 HILOG_ERROR_I18N("StaticGetTimeZone create instance failed");
545 return nullptr;
546 }
547 return result;
548 }
549
GetParameter(napi_env env,napi_value * argv,std::string & localeStr,bool & isDST)550 int32_t I18nTimeZoneAddon::GetParameter(napi_env env, napi_value *argv, std::string &localeStr, bool &isDST)
551 {
552 if (VariableConvertor::CheckNapiIsNull(env, argv[1])) {
553 napi_valuetype valueType0 = napi_valuetype::napi_undefined;
554 napi_valuetype valueType1 = napi_valuetype::napi_undefined;
555 napi_status status = napi_typeof(env, argv[0], &valueType0); // 0 represents first parameter
556 if (status != napi_ok) {
557 return -1;
558 }
559 status = napi_typeof(env, argv[1], &valueType1); // 1 represents second parameter
560 if (status != napi_ok) {
561 return -1;
562 }
563 bool firstParamFlag = VariableConvertor::CheckNapiIsNull(env, argv[0]);
564 if (valueType1 == napi_valuetype::napi_boolean) {
565 status = napi_get_value_bool(env, argv[1], &isDST);
566 if (status != napi_ok) {
567 return -1; // -1 represents Invalid parameter.
568 } else if (!firstParamFlag) {
569 return 2; // 2 represents one boolean parameter.
570 }
571 if (valueType0 == napi_valuetype::napi_string &&
572 GetStringFromJS(env, argv[0], localeStr)) {
573 return 3; // 3 represents one string parameter and one bool parameter.
574 }
575 }
576 return -1; // -1 represents Invalid parameter.
577 }
578 return GetFirstParameter(env, argv[0], localeStr, isDST);
579 }
580
GetStringFromJS(napi_env env,napi_value argv,std::string & jsString)581 bool I18nTimeZoneAddon::GetStringFromJS(napi_env env, napi_value argv, std::string &jsString)
582 {
583 size_t len = 0;
584 napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
585 if (status != napi_ok) {
586 HILOG_ERROR_I18N("Failed to get string length");
587 return false;
588 }
589 std::vector<char> argvBuf(len + 1);
590 status = napi_get_value_string_utf8(env, argv, argvBuf.data(), len + 1, &len);
591 if (status != napi_ok) {
592 HILOG_ERROR_I18N("Failed to get string item");
593 return false;
594 }
595 jsString = argvBuf.data();
596 return true;
597 }
598
GetFirstParameter(napi_env env,napi_value value,std::string & localeStr,bool & isDST)599 int32_t I18nTimeZoneAddon::GetFirstParameter(napi_env env, napi_value value, std::string &localeStr, bool &isDST)
600 {
601 if (!VariableConvertor::CheckNapiIsNull(env, value)) {
602 return 0; // 0 represents no parameter.
603 } else {
604 napi_valuetype valueType = napi_valuetype::napi_undefined;
605 napi_status status = napi_typeof(env, value, &valueType);
606 if (status != napi_ok) {
607 return -1;
608 }
609 if (valueType == napi_valuetype::napi_string) {
610 bool valid = GetStringFromJS(env, value, localeStr);
611 // -1 represents Invalid parameter.
612 // 1 represents one string parameter.
613 return !valid ? -1 : 1;
614 } else if (valueType == napi_valuetype::napi_boolean) {
615 status = napi_get_value_bool(env, value, &isDST);
616 // -1 represents Invalid parameter.
617 // 2 represents one boolean parameter.
618 return (status != napi_ok) ? -1 : 2;
619 }
620 return -1; // -1 represents Invalid parameter.
621 }
622 }
623 } // namespace I18n
624 } // namespace Global
625 } // namespace OHOS