1 /*
2 * Copyright (c) 2023 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
16 #include <unordered_map>
17 #include <unordered_set>
18
19 #include "error_util.h"
20 #include "i18n_hilog.h"
21 #include "i18n_calendar_addon.h"
22 #include "js_utils.h"
23 #include "variable_convertor.h"
24
25 namespace OHOS {
26 namespace Global {
27 namespace I18n {
28 static thread_local napi_ref* g_constructor = nullptr;
29 static std::unordered_map<std::string, UCalendarDateFields> g_fieldsMap {
30 { "era", UCAL_ERA },
31 { "year", UCAL_YEAR },
32 { "month", UCAL_MONTH },
33 { "week_of_year", UCAL_WEEK_OF_YEAR },
34 { "week_of_month", UCAL_WEEK_OF_MONTH },
35 { "date", UCAL_DATE },
36 { "day_of_year", UCAL_DAY_OF_YEAR },
37 { "day_of_week", UCAL_DAY_OF_WEEK },
38 { "day_of_week_in_month", UCAL_DAY_OF_WEEK_IN_MONTH },
39 { "ap_pm", UCAL_AM_PM },
40 { "hour", UCAL_HOUR },
41 { "hour_of_day", UCAL_HOUR_OF_DAY },
42 { "minute", UCAL_MINUTE },
43 { "second", UCAL_SECOND },
44 { "millisecond", UCAL_MILLISECOND },
45 { "zone_offset", UCAL_ZONE_OFFSET },
46 { "dst_offset", UCAL_DST_OFFSET },
47 { "year_woy", UCAL_YEAR_WOY },
48 { "dow_local", UCAL_DOW_LOCAL },
49 { "extended_year", UCAL_EXTENDED_YEAR },
50 { "julian_day", UCAL_JULIAN_DAY },
51 { "milliseconds_in_day", UCAL_MILLISECONDS_IN_DAY },
52 { "is_leap_month", UCAL_IS_LEAP_MONTH },
53 };
54 static std::unordered_set<std::string> g_fieldsInFunctionAdd {
55 "year", "month", "date", "hour", "minute", "second", "millisecond",
56 "week_of_year", "week_of_month", "day_of_year", "day_of_week",
57 "day_of_week_in_month", "hour_of_day", "milliseconds_in_day",
58 };
59 static std::unordered_map<std::string, CalendarType> g_typeMap {
60 { "buddhist", CalendarType::BUDDHIST },
61 { "chinese", CalendarType::CHINESE },
62 { "coptic", CalendarType::COPTIC },
63 { "ethiopic", CalendarType::ETHIOPIC },
64 { "hebrew", CalendarType::HEBREW },
65 { "gregory", CalendarType::GREGORY },
66 { "indian", CalendarType::INDIAN },
67 { "islamic_civil", CalendarType::ISLAMIC_CIVIL },
68 { "islamic_tbla", CalendarType::ISLAMIC_TBLA },
69 { "islamic_umalqura", CalendarType::ISLAMIC_UMALQURA },
70 { "japanese", CalendarType::JAPANESE },
71 { "persion", CalendarType::PERSIAN },
72 };
73
I18nCalendarAddon()74 I18nCalendarAddon::I18nCalendarAddon() {}
75
~I18nCalendarAddon()76 I18nCalendarAddon::~I18nCalendarAddon() {}
77
Destructor(napi_env env,void * nativeObject,void * hint)78 void I18nCalendarAddon::Destructor(napi_env env, void *nativeObject, void *hint)
79 {
80 if (!nativeObject) {
81 return;
82 }
83 delete reinterpret_cast<I18nCalendarAddon *>(nativeObject);
84 nativeObject = nullptr;
85 }
86
InitI18nCalendar(napi_env env,napi_value exports)87 napi_value I18nCalendarAddon::InitI18nCalendar(napi_env env, napi_value exports)
88 {
89 napi_property_descriptor properties[] = {
90 DECLARE_NAPI_FUNCTION("setTime", SetTime),
91 DECLARE_NAPI_FUNCTION("set", Set),
92 DECLARE_NAPI_FUNCTION("getTimeZone", GetTimeZone),
93 DECLARE_NAPI_FUNCTION("setTimeZone", SetTimeZone),
94 DECLARE_NAPI_FUNCTION("getFirstDayOfWeek", GetFirstDayOfWeek),
95 DECLARE_NAPI_FUNCTION("setFirstDayOfWeek", SetFirstDayOfWeek),
96 DECLARE_NAPI_FUNCTION("getMinimalDaysInFirstWeek", GetMinimalDaysInFirstWeek),
97 DECLARE_NAPI_FUNCTION("setMinimalDaysInFirstWeek", SetMinimalDaysInFirstWeek),
98 DECLARE_NAPI_FUNCTION("get", Get),
99 DECLARE_NAPI_FUNCTION("add", Add),
100 DECLARE_NAPI_FUNCTION("getDisplayName", GetDisplayName),
101 DECLARE_NAPI_FUNCTION("getTimeInMillis", GetTimeInMillis),
102 DECLARE_NAPI_FUNCTION("isWeekend", IsWeekend),
103 DECLARE_NAPI_FUNCTION("compareDays", CompareDays)
104 };
105 napi_value constructor = nullptr;
106 napi_status status = napi_define_class(env, "Calendar", NAPI_AUTO_LENGTH, I18nCalendarConstructor, nullptr,
107 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
108 if (status != napi_ok) {
109 HILOG_ERROR_I18N("Failed to define class at Init");
110 return nullptr;
111 }
112 exports = I18nCalendarAddon::InitCalendar(env, exports);
113 g_constructor = new (std::nothrow) napi_ref;
114 if (!g_constructor) {
115 HILOG_ERROR_I18N("Failed to create ref at init");
116 return nullptr;
117 }
118 status = napi_create_reference(env, constructor, 1, g_constructor);
119 if (status != napi_ok) {
120 HILOG_ERROR_I18N("Failed to create reference at init");
121 return nullptr;
122 }
123 return exports;
124 }
125
InitCalendar(napi_env env,napi_value exports)126 napi_value I18nCalendarAddon::InitCalendar(napi_env env, napi_value exports)
127 {
128 napi_property_descriptor properties[] = {};
129 napi_value constructor = nullptr;
130 napi_status status = napi_define_class(env, "I18nCalendar", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor, nullptr,
131 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
132 if (status != napi_ok) {
133 HILOG_ERROR_I18N("InitCalendar: Failed to define class Calendar.");
134 return nullptr;
135 }
136 status = napi_set_named_property(env, exports, "Calendar", constructor);
137 if (status != napi_ok) {
138 HILOG_ERROR_I18N("InitCalendar: Set property failed When InitCalendar.");
139 return nullptr;
140 }
141 return exports;
142 }
143
GetCalendar(napi_env env,napi_callback_info info)144 napi_value I18nCalendarAddon::GetCalendar(napi_env env, napi_callback_info info)
145 {
146 size_t argc = 2; // retrieve 2 arguments
147 napi_value argv[2] = { 0 };
148 argv[0] = nullptr;
149 argv[1] = nullptr;
150 napi_value thisVar = nullptr;
151 void *data = nullptr;
152 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
153 napi_value constructor = nullptr;
154 napi_status status = napi_get_reference_value(env, *g_constructor, &constructor);
155 if (status != napi_ok) {
156 HILOG_ERROR_I18N("Failed to create reference at GetCalendar");
157 return nullptr;
158 }
159 napi_valuetype valueType = napi_valuetype::napi_undefined;
160 napi_typeof(env, argv[1], &valueType);
161 if (valueType != napi_valuetype::napi_string) {
162 status = napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, argv + 1);
163 if (status != napi_ok) {
164 return nullptr;
165 }
166 }
167 napi_value result = nullptr;
168 status = napi_new_instance(env, constructor, 2, argv, &result); // 2 arguments
169 if (status != napi_ok) {
170 HILOG_ERROR_I18N("Get calendar create instance failed");
171 return nullptr;
172 }
173 return result;
174 }
175
I18nCalendarConstructor(napi_env env,napi_callback_info info)176 napi_value I18nCalendarAddon::I18nCalendarConstructor(napi_env env, napi_callback_info info)
177 {
178 size_t argc = 2;
179 napi_value argv[2] = { 0 };
180 argv[0] = nullptr;
181 argv[1] = nullptr;
182 napi_value thisVar = nullptr;
183 void *data = nullptr;
184 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
185 if (status != napi_ok) {
186 return nullptr;
187 }
188 napi_valuetype valueType = napi_valuetype::napi_undefined;
189 napi_typeof(env, argv[0], &valueType);
190 if (valueType != napi_valuetype::napi_string) {
191 HILOG_ERROR_I18N("CalendarConstructor: Parameter type does not match");
192 return nullptr;
193 }
194 int32_t code = 0;
195 std::string localeTag = VariableConvertor::GetString(env, argv[0], code);
196 if (code) {
197 return nullptr;
198 }
199 CalendarType type = GetCalendarType(env, argv[1]);
200 std::unique_ptr<I18nCalendarAddon> obj = nullptr;
201 obj = std::make_unique<I18nCalendarAddon>();
202 status =
203 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nCalendarAddon::Destructor, nullptr, nullptr);
204 if (status != napi_ok) {
205 HILOG_ERROR_I18N("CalendarConstructor: Wrap II18nAddon failed");
206 return nullptr;
207 }
208 if (!obj->InitCalendarContext(env, info, localeTag, type)) {
209 return nullptr;
210 }
211 obj.release();
212 return thisVar;
213 }
214
SetTime(napi_env env,napi_callback_info info)215 napi_value I18nCalendarAddon::SetTime(napi_env env, napi_callback_info info)
216 {
217 size_t argc = 1;
218 napi_value argv[1] = { 0 };
219 argv[0] = nullptr;
220 napi_value thisVar = nullptr;
221 void *data = nullptr;
222 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
223 if (!argv[0]) {
224 return nullptr;
225 }
226 I18nCalendarAddon *obj = nullptr;
227 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
228 if (status != napi_ok || !obj || !obj->calendar_) {
229 HILOG_ERROR_I18N("SetTime: Get calendar object failed");
230 return nullptr;
231 }
232 napi_valuetype type = napi_valuetype::napi_undefined;
233 status = napi_typeof(env, argv[0], &type);
234 if (status != napi_ok) {
235 return nullptr;
236 }
237 if (type == napi_valuetype::napi_number) {
238 obj->SetMilliseconds(env, argv[0]);
239 return nullptr;
240 } else {
241 napi_value val = GetDate(env, argv[0]);
242 if (!val) {
243 return nullptr;
244 }
245 obj->SetMilliseconds(env, val);
246 return nullptr;
247 }
248 }
249
Set(napi_env env,napi_callback_info info)250 napi_value I18nCalendarAddon::Set(napi_env env, napi_callback_info info)
251 {
252 size_t argc = 6; // Set may have 6 arguments
253 napi_value argv[6] = { 0 };
254 for (size_t i = 0; i < argc; ++i) {
255 argv[i] = nullptr;
256 }
257 napi_value thisVar = nullptr;
258 void *data = nullptr;
259 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
260 napi_valuetype valueType = napi_valuetype::napi_undefined;
261 napi_status status = napi_ok;
262 int32_t times[3] = { 0 }; // There are at least 3 arguments.
263 for (int i = 0; i < 3; ++i) { // There are at least 3 arguments.
264 napi_typeof(env, argv[i], &valueType);
265 if (valueType != napi_valuetype::napi_number) {
266 HILOG_ERROR_I18N("Set: Parameter type does not match");
267 return nullptr;
268 }
269 status = napi_get_value_int32(env, argv[i], times + i);
270 if (status != napi_ok) {
271 HILOG_ERROR_I18N("Set: Retrieve time value failed");
272 return nullptr;
273 }
274 }
275 I18nCalendarAddon *obj = nullptr;
276 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
277 if (status != napi_ok || !obj || !obj->calendar_) {
278 HILOG_ERROR_I18N("Set: Get calendar object failed");
279 return nullptr;
280 }
281 obj->calendar_->Set(times[0], times[1], times[2]); // 2 is the index of date
282 obj->SetField(env, argv[3], UCalendarDateFields::UCAL_HOUR_OF_DAY); // 3 is the index of hour
283 obj->SetField(env, argv[4], UCalendarDateFields::UCAL_MINUTE); // 4 is the index of minute
284 obj->SetField(env, argv[5], UCalendarDateFields::UCAL_SECOND); // 5 is the index of second
285 return nullptr;
286 }
287
GetTimeZone(napi_env env,napi_callback_info info)288 napi_value I18nCalendarAddon::GetTimeZone(napi_env env, napi_callback_info info)
289 {
290 size_t argc = 0;
291 napi_value *argv = nullptr;
292 napi_value thisVar = nullptr;
293 void *data = nullptr;
294 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
295 I18nCalendarAddon *obj = nullptr;
296 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
297 if (status != napi_ok || !obj || !obj->calendar_) {
298 HILOG_ERROR_I18N("GetTimeZone: Get calendar object failed");
299 return nullptr;
300 }
301 std::string temp = obj->calendar_->GetTimeZone();
302 napi_value result = nullptr;
303 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &result);
304 if (status != napi_ok) {
305 HILOG_ERROR_I18N("Create timezone string failed");
306 return nullptr;
307 }
308 return result;
309 }
310
SetTimeZone(napi_env env,napi_callback_info info)311 napi_value I18nCalendarAddon::SetTimeZone(napi_env env, napi_callback_info info)
312 {
313 size_t argc = 1;
314 napi_value argv[1] = { 0 };
315 argv[0] = nullptr;
316 napi_value thisVar = nullptr;
317 void *data = nullptr;
318 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
319 napi_valuetype valueType = napi_valuetype::napi_undefined;
320 napi_typeof(env, argv[0], &valueType);
321 if (valueType != napi_valuetype::napi_string) {
322 HILOG_ERROR_I18N("SetTimeZone: Parameter type does not match");
323 return nullptr;
324 }
325 size_t len = 0;
326 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
327 if (status != napi_ok) {
328 HILOG_ERROR_I18N("SetTimeZone: Get timezone length failed");
329 return nullptr;
330 }
331 std::vector<char> buf(len + 1);
332 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
333 if (status != napi_ok) {
334 HILOG_ERROR_I18N("SetTimeZone: Get timezone failed");
335 return nullptr;
336 }
337 std::string timezone(buf.data());
338 I18nCalendarAddon *obj = nullptr;
339 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
340 if (status != napi_ok || !obj || !obj->calendar_) {
341 HILOG_ERROR_I18N("SetTimeZone: Get calendar object failed");
342 return nullptr;
343 }
344 obj->calendar_->SetTimeZone(timezone);
345 return nullptr;
346 }
347
GetFirstDayOfWeek(napi_env env,napi_callback_info info)348 napi_value I18nCalendarAddon::GetFirstDayOfWeek(napi_env env, napi_callback_info info)
349 {
350 size_t argc = 0;
351 napi_value *argv = nullptr;
352 napi_value thisVar = nullptr;
353 void *data = nullptr;
354 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
355 I18nCalendarAddon *obj = nullptr;
356 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
357 if (status != napi_ok || !obj || !obj->calendar_) {
358 HILOG_ERROR_I18N("GetFirstDayOfWeek: Get calendar object failed");
359 return nullptr;
360 }
361 int32_t temp = obj->calendar_->GetFirstDayOfWeek();
362 napi_value result = nullptr;
363 status = napi_create_int32(env, temp, &result);
364 if (status != napi_ok) {
365 HILOG_ERROR_I18N("GetFirstDayOfWeek: Create int32 failed");
366 return nullptr;
367 }
368 return result;
369 }
370
SetFirstDayOfWeek(napi_env env,napi_callback_info info)371 napi_value I18nCalendarAddon::SetFirstDayOfWeek(napi_env env, napi_callback_info info)
372 {
373 size_t argc = 1;
374 napi_value argv[1] = { 0 };
375 argv[0] = nullptr;
376 napi_value thisVar = nullptr;
377 void *data = nullptr;
378 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
379 napi_valuetype valueType = napi_valuetype::napi_undefined;
380 napi_typeof(env, argv[0], &valueType);
381 if (valueType != napi_valuetype::napi_number) {
382 HILOG_ERROR_I18N("SetFirstDayOfWeek: Parameter type does not match");
383 return nullptr;
384 }
385 int32_t value = 0;
386 napi_status status = napi_get_value_int32(env, argv[0], &value);
387 if (status != napi_ok) {
388 HILOG_ERROR_I18N("SetFirstDayOfWeek: Get int32 failed");
389 return nullptr;
390 }
391 I18nCalendarAddon *obj = nullptr;
392 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
393 if (status != napi_ok || !obj || !obj->calendar_) {
394 HILOG_ERROR_I18N("SetFirstDayOfWeek: Get calendar object failed");
395 return nullptr;
396 }
397 obj->calendar_->SetFirstDayOfWeek(value);
398 return nullptr;
399 }
400
GetMinimalDaysInFirstWeek(napi_env env,napi_callback_info info)401 napi_value I18nCalendarAddon::GetMinimalDaysInFirstWeek(napi_env env, napi_callback_info info)
402 {
403 size_t argc = 0;
404 napi_value *argv = nullptr;
405 napi_value thisVar = nullptr;
406 void *data = nullptr;
407 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
408 I18nCalendarAddon *obj = nullptr;
409 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
410 if (status != napi_ok || !obj || !obj->calendar_) {
411 HILOG_ERROR_I18N("GetMinimalDaysInFirstWeek: Get calendar object failed");
412 return nullptr;
413 }
414 int32_t temp = obj->calendar_->GetMinimalDaysInFirstWeek();
415 napi_value result = nullptr;
416 status = napi_create_int32(env, temp, &result);
417 if (status != napi_ok) {
418 HILOG_ERROR_I18N("GetMinimalDaysInFirstWeek: Create int32 failed");
419 return nullptr;
420 }
421 return result;
422 }
423
SetMinimalDaysInFirstWeek(napi_env env,napi_callback_info info)424 napi_value I18nCalendarAddon::SetMinimalDaysInFirstWeek(napi_env env, napi_callback_info info)
425 {
426 size_t argc = 1;
427 napi_value argv[1] = { 0 };
428 argv[0] = nullptr;
429 napi_value thisVar = nullptr;
430 void *data = nullptr;
431 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
432 napi_valuetype valueType = napi_valuetype::napi_undefined;
433 napi_typeof(env, argv[0], &valueType);
434 if (valueType != napi_valuetype::napi_number) {
435 HILOG_ERROR_I18N("SetMinimalDaysInFirstWeek: Parameter type does not match");
436 return nullptr;
437 }
438 int32_t value = 0;
439 napi_status status = napi_get_value_int32(env, argv[0], &value);
440 if (status != napi_ok) {
441 HILOG_ERROR_I18N("SetMinimalDaysInFirstWeek: Get int32 failed");
442 return nullptr;
443 }
444 I18nCalendarAddon *obj = nullptr;
445 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
446 if (status != napi_ok || !obj || !obj->calendar_) {
447 HILOG_ERROR_I18N("SetMinimalDaysInFirstWeek: Get calendar object failed");
448 return nullptr;
449 }
450 obj->calendar_->SetMinimalDaysInFirstWeek(value);
451 return nullptr;
452 }
453
Get(napi_env env,napi_callback_info info)454 napi_value I18nCalendarAddon::Get(napi_env env, napi_callback_info info)
455 {
456 size_t argc = 1;
457 napi_value argv[1] = { 0 };
458 argv[0] = nullptr;
459 napi_value thisVar = nullptr;
460 void *data = nullptr;
461 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
462 napi_valuetype valueType = napi_valuetype::napi_undefined;
463 napi_typeof(env, argv[0], &valueType);
464 if (valueType != napi_valuetype::napi_string) {
465 HILOG_ERROR_I18N("Get: Parameter type does not match");
466 return nullptr;
467 }
468 size_t len = 0;
469 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
470 if (status != napi_ok) {
471 HILOG_ERROR_I18N("Get field length failed");
472 return nullptr;
473 }
474 std::vector<char> buf(len + 1);
475 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
476 if (status != napi_ok) {
477 HILOG_ERROR_I18N("Get field failed");
478 return nullptr;
479 }
480 std::string field(buf.data());
481 if (g_fieldsMap.find(field) == g_fieldsMap.end()) {
482 HILOG_ERROR_I18N("Invalid field");
483 return nullptr;
484 }
485 I18nCalendarAddon *obj = nullptr;
486 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
487 if (status != napi_ok || !obj || !obj->calendar_) {
488 HILOG_ERROR_I18N("Get: Get calendar object failed");
489 return nullptr;
490 }
491 int32_t value = obj->calendar_->Get(g_fieldsMap[field]);
492 napi_value result = nullptr;
493 status = napi_create_int32(env, value, &result);
494 if (status != napi_ok) {
495 HILOG_ERROR_I18N("Get: Create int32 failed");
496 return nullptr;
497 }
498 return result;
499 }
500
Add(napi_env env,napi_callback_info info)501 napi_value I18nCalendarAddon::Add(napi_env env, napi_callback_info info)
502 {
503 size_t argc = 2;
504 napi_value argv[2] = { 0 };
505 napi_value thisVar = nullptr;
506 void *data = nullptr;
507 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
508 if (status != napi_ok) {
509 HILOG_ERROR_I18N("Add: can not obtain add function param.");
510 return nullptr;
511 }
512 napi_valuetype valueType = napi_valuetype::napi_undefined;
513 napi_typeof(env, argv[0], &valueType);
514 if (valueType != napi_valuetype::napi_string) {
515 HILOG_ERROR_I18N("Parameter type does not match argv[0]");
516 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "field", "string", true);
517 return nullptr;
518 }
519 int32_t code = 0;
520 std::string field = GetAddField(env, argv[0], code);
521 if (code) {
522 return nullptr;
523 }
524 napi_typeof(env, argv[1], &valueType);
525 if (valueType != napi_valuetype::napi_number) {
526 HILOG_ERROR_I18N("Parameter type does not match argv[1]");
527 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "amount", "number", true);
528 return nullptr;
529 }
530 int32_t amount;
531 status = napi_get_value_int32(env, argv[1], &amount);
532 if (status != napi_ok) {
533 HILOG_ERROR_I18N("Add: Can not obtain add function param.");
534 return nullptr;
535 }
536 I18nCalendarAddon *obj = nullptr;
537 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
538 if (status != napi_ok || !obj || !obj->calendar_) {
539 HILOG_ERROR_I18N("Add: Get calendar object failed");
540 return nullptr;
541 }
542 obj->calendar_->Add(g_fieldsMap[field], amount);
543 return nullptr;
544 }
545
GetDisplayName(napi_env env,napi_callback_info info)546 napi_value I18nCalendarAddon::GetDisplayName(napi_env env, napi_callback_info info)
547 {
548 size_t argc = 1;
549 napi_value argv[1] = { 0 };
550 argv[0] = nullptr;
551 napi_value thisVar = nullptr;
552 void *data = nullptr;
553 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
554 napi_valuetype valueType = napi_valuetype::napi_undefined;
555 napi_typeof(env, argv[0], &valueType);
556 if (valueType != napi_valuetype::napi_string) {
557 HILOG_ERROR_I18N("GetDisplayName: Parameter type does not match");
558 return nullptr;
559 }
560 int32_t code = 0;
561 std::string localeTag = VariableConvertor::GetString(env, argv[0], code);
562 if (code) {
563 return nullptr;
564 }
565 I18nCalendarAddon *obj = nullptr;
566 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
567 if (status != napi_ok || !obj || !obj->calendar_) {
568 HILOG_ERROR_I18N("GetDisplayName: Get calendar object failed");
569 return nullptr;
570 }
571 if (!obj->calendar_) {
572 return nullptr;
573 }
574 std::string name = obj->calendar_->GetDisplayName(localeTag);
575 napi_value result = nullptr;
576 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result);
577 if (status != napi_ok) {
578 HILOG_ERROR_I18N("Create calendar name string failed");
579 return nullptr;
580 }
581 return result;
582 }
583
GetTimeInMillis(napi_env env,napi_callback_info info)584 napi_value I18nCalendarAddon::GetTimeInMillis(napi_env env, napi_callback_info info)
585 {
586 bool flag = true;
587 size_t argc = 0;
588 napi_value *argv = nullptr;
589 napi_value thisVar = nullptr;
590 void *data = nullptr;
591 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
592 I18nCalendarAddon *obj = nullptr;
593 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
594 if (status != napi_ok || !obj || !obj->calendar_) {
595 HILOG_ERROR_I18N("GetTimeInMillis: Get calendar object failed");
596 flag = false;
597 }
598 UDate temp = 0;
599 if (flag) {
600 temp = obj->calendar_->GetTimeInMillis();
601 }
602 napi_value result = nullptr;
603 status = napi_create_double(env, temp, &result);
604 if (status != napi_ok) {
605 HILOG_ERROR_I18N("Create UDate failed");
606 napi_create_double(env, 0, &result);
607 }
608 return result;
609 }
610
IsWeekend(napi_env env,napi_callback_info info)611 napi_value I18nCalendarAddon::IsWeekend(napi_env env, napi_callback_info info)
612 {
613 size_t argc = 1;
614 napi_value argv[1] = { 0 };
615 argv[0] = nullptr;
616 napi_value thisVar = nullptr;
617 void *data = nullptr;
618 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
619 I18nCalendarAddon *obj = nullptr;
620 bool isWeekEnd = false;
621 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
622 do {
623 if (status != napi_ok || !obj || !obj->calendar_) {
624 HILOG_ERROR_I18N("IsWeekend: Get calendar object failed");
625 break;
626 }
627 if (!VariableConvertor::CheckNapiValueType(env, argv[0])) {
628 isWeekEnd = obj->calendar_->IsWeekend();
629 } else {
630 napi_value funcGetDateInfo = nullptr;
631 status = napi_get_named_property(env, argv[0], "valueOf", &funcGetDateInfo);
632 if (status != napi_ok) {
633 HILOG_ERROR_I18N("Get method now failed");
634 break;
635 }
636 napi_value value = nullptr;
637 status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &value);
638 if (status != napi_ok) {
639 HILOG_ERROR_I18N("IsWeekend: Get milliseconds failed");
640 break;
641 }
642 double milliseconds = 0;
643 status = napi_get_value_double(env, value, &milliseconds);
644 if (status != napi_ok) {
645 HILOG_ERROR_I18N("IsWeekend: Retrieve milliseconds failed");
646 break;
647 }
648 UErrorCode error = U_ZERO_ERROR;
649 isWeekEnd = obj->calendar_->IsWeekend(milliseconds, error);
650 }
651 } while (false);
652 napi_value result = nullptr;
653 status = napi_get_boolean(env, isWeekEnd, &result);
654 if (status != napi_ok) {
655 HILOG_ERROR_I18N("Create boolean failed");
656 return nullptr;
657 }
658 return result;
659 }
660
CompareDays(napi_env env,napi_callback_info info)661 napi_value I18nCalendarAddon::CompareDays(napi_env env, napi_callback_info info)
662 {
663 size_t argc = 1;
664 napi_value argv[1] = { 0 };
665 napi_value thisVar = nullptr;
666 void *data = nullptr;
667 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
668 napi_value result = nullptr;
669 UDate milliseconds = 0;
670 napi_status status = napi_get_date_value(env, argv[0], &milliseconds);
671 if (status != napi_ok) {
672 HILOG_ERROR_I18N("compareDays: function param is not Date");
673 return nullptr;
674 }
675
676 I18nCalendarAddon *obj = nullptr;
677 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
678 if (status != napi_ok || !obj || !obj->calendar_) {
679 HILOG_ERROR_I18N("CompareDays: Get calendar object failed");
680 status = napi_create_int32(env, 0, &result); // if error return 0
681 return result;
682 }
683
684 int32_t diff_date = obj->calendar_->CompareDays(milliseconds);
685 status = napi_create_int32(env, diff_date, &result);
686 return result;
687 }
688
InitCalendarContext(napi_env env,napi_callback_info info,const std::string & localeTag,CalendarType type)689 bool I18nCalendarAddon::InitCalendarContext(napi_env env, napi_callback_info info, const std::string &localeTag,
690 CalendarType type)
691 {
692 calendar_ = std::make_unique<I18nCalendar>(localeTag, type);
693 return calendar_ != nullptr;
694 }
695
GetCalendarType(napi_env env,napi_value value)696 CalendarType I18nCalendarAddon::GetCalendarType(napi_env env, napi_value value)
697 {
698 CalendarType type = CalendarType::UNDEFINED;
699 if (value != nullptr) {
700 napi_valuetype valueType = napi_valuetype::napi_undefined;
701 napi_typeof(env, value, &valueType);
702 if (valueType != napi_valuetype::napi_string) {
703 HILOG_ERROR_I18N("GetCalendarType: Parameter type does not match");
704 return type;
705 }
706 int32_t code = 0;
707 std::string calendarType = VariableConvertor::GetString(env, value, code);
708 if (code) {
709 return type;
710 }
711 if (g_typeMap.find(calendarType) != g_typeMap.end()) {
712 type = g_typeMap[calendarType];
713 }
714 }
715 return type;
716 }
717
SetField(napi_env env,napi_value value,UCalendarDateFields field)718 void I18nCalendarAddon::SetField(napi_env env, napi_value value, UCalendarDateFields field)
719 {
720 if (!VariableConvertor::CheckNapiValueType(env, value)) {
721 return;
722 }
723 int32_t val = 0;
724 napi_valuetype valueType = napi_valuetype::napi_undefined;
725 napi_typeof(env, value, &valueType);
726 if (valueType != napi_valuetype::napi_number) {
727 HILOG_ERROR_I18N("SetField: Parameter type does not match");
728 return;
729 }
730 napi_status status = napi_get_value_int32(env, value, &val);
731 if (status != napi_ok) {
732 HILOG_ERROR_I18N("SetField: Retrieve field failed");
733 return;
734 }
735 if (calendar_ != nullptr) {
736 calendar_->Set(field, val);
737 }
738 }
739
GetAddField(napi_env & env,napi_value & value,int32_t & code)740 std::string I18nCalendarAddon::GetAddField(napi_env &env, napi_value &value, int32_t &code)
741 {
742 std::string field = VariableConvertor::GetString(env, value, code);
743 if (code != 0) {
744 HILOG_ERROR_I18N("GetAddField: can't get string from js array param.");
745 return field;
746 }
747 if (g_fieldsInFunctionAdd.find(field) == g_fieldsInFunctionAdd.end()) {
748 code = 1;
749 HILOG_ERROR_I18N("Parameter rangs do not match");
750 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "field", "a valid field", true);
751 return field;
752 }
753 return field;
754 }
755
GetDate(napi_env env,napi_value value)756 napi_value I18nCalendarAddon::GetDate(napi_env env, napi_value value)
757 {
758 if (!value) {
759 return nullptr;
760 }
761 napi_value funcGetDateInfo = nullptr;
762 napi_status status = napi_get_named_property(env, value, "valueOf", &funcGetDateInfo);
763 if (status != napi_ok) {
764 HILOG_ERROR_I18N("Get method valueOf failed");
765 return nullptr;
766 }
767 napi_value ret_value = nullptr;
768 status = napi_call_function(env, value, funcGetDateInfo, 0, nullptr, &ret_value);
769 if (status != napi_ok) {
770 HILOG_ERROR_I18N("GetDate: Get milliseconds failed");
771 return nullptr;
772 }
773 return ret_value;
774 }
775
SetMilliseconds(napi_env env,napi_value value)776 void I18nCalendarAddon::SetMilliseconds(napi_env env, napi_value value)
777 {
778 if (!value) {
779 return;
780 }
781 double milliseconds = 0;
782 napi_valuetype valueType = napi_valuetype::napi_undefined;
783 napi_typeof(env, value, &valueType);
784 if (valueType != napi_valuetype::napi_number) {
785 HILOG_ERROR_I18N("SetMilliseconds: Parameter type does not match");
786 return;
787 }
788 napi_status status = napi_get_value_double(env, value, &milliseconds);
789 if (status != napi_ok) {
790 HILOG_ERROR_I18N("SetMilliseconds: Retrieve milliseconds failed");
791 return;
792 }
793 if (calendar_ != nullptr) {
794 calendar_->SetTime(milliseconds);
795 }
796 }
797
798 } // namespace I18n
799 } // namespace Global
800 } // namespace OHOS