• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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