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 "napi_util.h"
17 #include <endian.h>
18 #include <securec.h>
19 #include <sstream>
20 #include "calendar_log.h"
21 #include "napi_queue.h"
22 #include "native_util.h"
23 #include "event_filter_napi.h"
24 #include <climits>
25
26 namespace OHOS::CalendarApi::NapiUtil {
27 constexpr int32_t STR_MAX_LENGTH = 4096;
28 constexpr size_t STR_TAIL_LENGTH = 1;
29
GetValue(napi_env env, napi_value in, napi_value& out)30 napi_status GetValue(napi_env env, napi_value in, napi_value& out)
31 {
32 out = in;
33 return napi_ok;
34 }
35
SetValue(napi_env env, napi_value in, napi_value& out)36 napi_status SetValue(napi_env env, napi_value in, napi_value& out)
37 {
38 out = in;
39 return napi_ok;
40 }
41
42 /* napi_value <-> bool */
GetValue(napi_env env, napi_value in, bool& out)43 napi_status GetValue(napi_env env, napi_value in, bool& out)
44 {
45 return napi_get_value_bool(env, in, &out);
46 }
47
SetValue(napi_env env, const bool& in, napi_value& out)48 napi_status SetValue(napi_env env, const bool& in, napi_value& out)
49 {
50 return napi_get_boolean(env, in, &out);
51 }
52
53 /* napi_value <-> int32_t */
GetValue(napi_env env, napi_value in, int32_t& out)54 napi_status GetValue(napi_env env, napi_value in, int32_t& out)
55 {
56 return napi_get_value_int32(env, in, &out);
57 }
58
SetValue(napi_env env, const int32_t& in, napi_value& out)59 napi_status SetValue(napi_env env, const int32_t& in, napi_value& out)
60 {
61 return napi_create_int32(env, in, &out);
62 }
63
64 /* napi_value <-> uint32_t */
GetValue(napi_env env, napi_value in, uint32_t& out)65 napi_status GetValue(napi_env env, napi_value in, uint32_t& out)
66 {
67 return napi_get_value_uint32(env, in, &out);
68 }
69
SetValue(napi_env env, const uint32_t& in, napi_value& out)70 napi_status SetValue(napi_env env, const uint32_t& in, napi_value& out)
71 {
72 return napi_create_uint32(env, in, &out);
73 }
74
75 /* napi_value <-> int64_t */
GetValue(napi_env env, napi_value in, int64_t& out)76 napi_status GetValue(napi_env env, napi_value in, int64_t& out)
77 {
78 return napi_get_value_int64(env, in, &out);
79 }
80
SetValue(napi_env env, const int64_t& in, napi_value& out)81 napi_status SetValue(napi_env env, const int64_t& in, napi_value& out)
82 {
83 return napi_create_int64(env, in, &out);
84 }
85
GetValue(napi_env env, napi_value in, uint64_t& out)86 napi_status GetValue(napi_env env, napi_value in, uint64_t& out)
87 {
88 bool lossless = true;
89 return napi_get_value_bigint_uint64(env, in, &out, &lossless);
90 }
91
SetValue(napi_env env, const uint64_t& in, napi_value& out)92 napi_status SetValue(napi_env env, const uint64_t& in, napi_value& out)
93 {
94 return napi_create_bigint_uint64(env, in, &out);
95 }
96
97 /* napi_value <-> double */
GetValue(napi_env env, napi_value in, double& out)98 napi_status GetValue(napi_env env, napi_value in, double& out)
99 {
100 return napi_get_value_double(env, in, &out);
101 }
102
SetValue(napi_env env, const double& in, napi_value& out)103 napi_status SetValue(napi_env env, const double& in, napi_value& out)
104 {
105 return napi_create_double(env, in, &out);
106 }
107
108 /* napi_value <-> std::string */
GetValue(napi_env env, napi_value in, std::string& out)109 napi_status GetValue(napi_env env, napi_value in, std::string& out)
110 {
111 napi_valuetype type = napi_undefined;
112 napi_status status = napi_typeof(env, in, &type);
113 CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_invalid_arg);
114
115 size_t maxLen = STR_MAX_LENGTH;
116 status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen);
117 if (maxLen == 0 || maxLen == UINT_MAX) {
118 return status;
119 }
120 LOG_DEBUG("napi_value -> std::string get length %{public}d", (int)maxLen);
121 char* buf = new (std::nothrow) char[STR_TAIL_LENGTH + maxLen];
122 if (buf != nullptr) {
123 size_t len = 0;
124 status = napi_get_value_string_utf8(env, in, buf, STR_TAIL_LENGTH + maxLen, &len);
125 if (status == napi_ok) {
126 buf[len] = 0;
127 out = std::string(buf);
128 }
129 delete[] buf;
130 } else {
131 status = napi_generic_failure;
132 }
133 return status;
134 }
135
SetValue(napi_env env, const std::string& in, napi_value& out)136 napi_status SetValue(napi_env env, const std::string& in, napi_value& out)
137 {
138 return napi_create_string_utf8(env, in.c_str(), in.size(), &out);
139 }
140
141 /* napi_value <-> std::vector<std::string> */
GetValue(napi_env env, napi_value in, std::vector<std::string>& out)142 napi_status GetValue(napi_env env, napi_value in, std::vector<std::string>& out)
143 {
144 LOG_DEBUG("napi_value -> std::vector<std::string>");
145 return GetValueArray(env, in, out);
146 }
147
SetValue(napi_env env, const std::vector<std::string>& in, napi_value& out)148 napi_status SetValue(napi_env env, const std::vector<std::string>& in, napi_value& out)
149 {
150 LOG_DEBUG("std::vector<std::string> -> napi_value");
151 napi_status status = napi_create_array_with_length(env, in.size(), &out);
152 CHECK_RETURN(status == napi_ok, "create array failed!", status);
153 int index = 0;
154 for (auto& item : in) {
155 napi_value element = nullptr;
156 SetValue(env, item, element);
157 status = napi_set_element(env, out, index++, element);
158 CHECK_RETURN((status == napi_ok), "napi_set_element failed!", status);
159 }
160 return status;
161 }
162
163 /* napi_value <-> std::vector<uint8_t> */
GetValue(napi_env env, napi_value in, std::vector<uint8_t>& out)164 napi_status GetValue(napi_env env, napi_value in, std::vector<uint8_t>& out)
165 {
166 out.clear();
167 LOG_DEBUG("napi_value -> std::vector<uint8_t> ");
168 napi_typedarray_type type = napi_biguint64_array;
169 size_t length = 0;
170 napi_value buffer = nullptr;
171 size_t offset = 0;
172 void* data = nullptr;
173 napi_status status = napi_get_typedarray_info(env, in, &type, &length, &data, &buffer, &offset);
174 LOG_DEBUG("array type=%{public}d length=%{public}d offset=%{public}d", (int)type, (int)length, (int)offset);
175 CHECK_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
176 CHECK_RETURN(type == napi_uint8_array, "is not Uint8Array!", napi_invalid_arg);
177 CHECK_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
178 out.assign((uint8_t*)data, ((uint8_t*)data) + length);
179 return status;
180 }
181
SetValue(napi_env env, const std::vector<uint8_t>& in, napi_value& out)182 napi_status SetValue(napi_env env, const std::vector<uint8_t>& in, napi_value& out)
183 {
184 LOG_DEBUG("napi_value <- std::vector<uint8_t> ");
185 CHECK_RETURN(in.size() > 0, "invalid std::vector<uint8_t>", napi_invalid_arg);
186 void* data = nullptr;
187 napi_value buffer = nullptr;
188 napi_status status = napi_create_arraybuffer(env, in.size(), &data, &buffer);
189 CHECK_RETURN((status == napi_ok), "create array buffer failed!", status);
190
191 if (memcpy_s(data, in.size(), in.data(), in.size()) != EOK) {
192 LOG_ERROR("memcpy_s not EOK");
193 return napi_invalid_arg;
194 }
195 status = napi_create_typedarray(env, napi_uint8_array, in.size(), buffer, 0, &out);
196 CHECK_RETURN((status == napi_ok), "napi_value <- std::vector<uint8_t> invalid value", status);
197 return status;
198 }
199
200 /* napi_value <-> std::vector<int32_t> */
GetValue(napi_env env, napi_value in, std::vector<int32_t>& out)201 napi_status GetValue(napi_env env, napi_value in, std::vector<int32_t>& out)
202 {
203 LOG_DEBUG("napi_value -> std::vector<int32_t> ");
204 return GetValueArray(env, in, out);
205 }
206
SetValue(napi_env env, const std::vector<int32_t>& in, napi_value& out)207 napi_status SetValue(napi_env env, const std::vector<int32_t>& in, napi_value& out)
208 {
209 LOG_DEBUG("napi_value <- std::vector<int32_t> ");
210 return SetValueArray(env, in, out);
211 }
212
213 /* napi_value <-> std::vector<uint32_t> */
GetValue(napi_env env, napi_value in, std::vector<uint32_t>& out)214 napi_status GetValue(napi_env env, napi_value in, std::vector<uint32_t>& out)
215 {
216 LOG_DEBUG("napi_value -> std::vector<uint32_t> ");
217 return GetValueArray(env, in, out);
218 }
219
SetValue(napi_env env, const std::vector<uint32_t>& in, napi_value& out)220 napi_status SetValue(napi_env env, const std::vector<uint32_t>& in, napi_value& out)
221 {
222 LOG_DEBUG("napi_value <- std::vector<uint32_t> ");
223 size_t bytes = in.size() * sizeof(uint32_t);
224 CHECK_RETURN(bytes > 0, "invalid std::vector<uint32_t>", napi_invalid_arg);
225 void* data = nullptr;
226 napi_value buffer = nullptr;
227 napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
228 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
229
230 if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
231 LOG_ERROR("memcpy_s not EOK");
232 return napi_invalid_arg;
233 }
234 status = napi_create_typedarray(env, napi_uint32_array, in.size(), buffer, 0, &out);
235 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
236 return status;
237 }
238
239 /* napi_value <-> std::vector<int64_t> */
GetValue(napi_env env, napi_value in, std::vector<int64_t>& out)240 napi_status GetValue(napi_env env, napi_value in, std::vector<int64_t>& out)
241 {
242 LOG_DEBUG("napi_value -> std::vector<int64_t> ");
243 return GetValueArray(env, in, out);
244 }
245
SetValue(napi_env env, const std::vector<int64_t>& in, napi_value& out)246 napi_status SetValue(napi_env env, const std::vector<int64_t>& in, napi_value& out)
247 {
248 LOG_DEBUG("napi_value <- std::vector<int64_t> ");
249 size_t bytes = in.size() * sizeof(int64_t);
250 CHECK_RETURN(bytes > 0, "invalid std::vector<uint32_t>", napi_invalid_arg);
251 void* data = nullptr;
252 napi_value buffer = nullptr;
253 napi_status status = napi_create_arraybuffer(env, bytes, &data, &buffer);
254 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
255 if (!in.data()) {
256 return napi_invalid_arg;
257 }
258 if (memcpy_s(data, bytes, in.data(), bytes) != EOK) {
259 LOG_ERROR("memcpy_s not EOK");
260 return napi_invalid_arg;
261 }
262 status = napi_create_typedarray(env, napi_bigint64_array, in.size(), buffer, 0, &out);
263 CHECK_RETURN((status == napi_ok), "invalid buffer", status);
264 return status;
265 }
266
GetValue(napi_env env, napi_value in, CalendarAccount& out)267 napi_status GetValue(napi_env env, napi_value in, CalendarAccount& out)
268 {
269 LOG_DEBUG("napi_value -> CalendarAccount ");
270 napi_status status = NapiUtil::GetNamedProperty(env, in, "name", out.name);
271 CHECK_RETURN((status == napi_ok), "invalid name", status);
272 status = NapiUtil::GetNamedProperty(env, in, "type", out.type);
273 CHECK_RETURN((status == napi_ok), "invalid type", status);
274 NapiUtil::GetNamedPropertyOptional(env, in, "displayName", out.displayName);
275 return napi_ok;
276 }
277
SetValue(napi_env env, const CalendarAccount& in, napi_value& out)278 napi_status SetValue(napi_env env, const CalendarAccount& in, napi_value& out)
279 {
280 LOG_DEBUG("CalendarAccount -> napi_value ");
281 napi_status status = napi_create_object(env, &out);
282 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
283
284 napi_value nameValue = nullptr;
285 status = SetValue(env, in.name, nameValue);
286 CHECK_RETURN((status == napi_ok), "invalid entry name", status);
287 napi_set_named_property(env, out, "name", nameValue);
288 napi_value typeValue = nullptr;
289 status = SetValue(env, in.type, typeValue);
290 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
291 napi_set_named_property(env, out, "type", typeValue);
292
293 if (in.displayName) {
294 napi_value displayNameValue = nullptr;
295 status = SetValue(env, in.displayName.value(), displayNameValue);
296 CHECK_RETURN((status == napi_ok), "invalid entry displayName", status);
297 napi_set_named_property(env, out, "displayName", displayNameValue);
298 }
299 return status;
300 }
301
302 /* napi_value <-> CalendarConfig */
GetValue(napi_env env, napi_value in, CalendarConfig& out)303 napi_status GetValue(napi_env env, napi_value in, CalendarConfig& out)
304 {
305 LOG_DEBUG("napi_value -> CalendarConfig ");
306 NapiUtil::GetNamedPropertyOptional(env, in, "enableReminder", out.enableReminder);
307 bool result = true;
308 napi_status status = napi_has_named_property(env, in, "color", &result);
309 if (status == napi_ok && !result) {
310 const int64_t defaultColor = 0xFF0A59F7;
311 LOG_DEBUG("napi_value color is null, use default color: 0xFF0A59F7");
312 out.color.emplace<1>(defaultColor);
313 return napi_ok;
314 }
315 napi_value value = NULL;
316 napi_valuetype valueType = napi_undefined;
317 napi_get_named_property(env, in, "color", &value);
318 napi_typeof(env, value, &valueType);
319 if (valueType == napi_string) {
320 LOG_DEBUG("napi_value color is string");
321 string str = "";
322 NapiUtil::GetValue(env, value, str);
323 LOG_DEBUG("napi_value color: %{public}s", str.c_str());
324 bool ok = Native::ColorParse(str, out.color);
325 if (!ok) {
326 return napi_string_expected;
327 }
328 return napi_ok;
329 }
330 LOG_DEBUG("napi_value color is number");
331 int64_t colorValue;
332 napi_status statusToGetInt64 = napi_get_value_int64(env, value, &colorValue);
333 if (statusToGetInt64 == napi_ok) {
334 out.color.emplace<1>(colorValue);
335 LOG_DEBUG("color: %{public}s", std::to_string(std::get<1>(out.color)).c_str());
336 } else {
337 LOG_DEBUG("color number -> int_64 err");
338 }
339 return statusToGetInt64;
340 }
341
SetValue(napi_env env, const CalendarConfig& in, napi_value& out)342 napi_status SetValue(napi_env env, const CalendarConfig& in, napi_value& out)
343 {
344 LOG_DEBUG("CalendarConfig -> napi_value ");
345 napi_status status = napi_create_object(env, &out);
346 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
347
348 if (in.enableReminder.has_value()) {
349 LOG_DEBUG("config.enableReminder: %{public}d", in.enableReminder.value_or(-1));
350 napi_value enableRemindValue = nullptr;
351 status = SetValue(env, in.enableReminder.value(), enableRemindValue);
352 CHECK_RETURN((status == napi_ok), "invalid entry enableReminder", status);
353 napi_set_named_property(env, out, "enableReminder", enableRemindValue);
354 }
355 if (std::get_if<1>(&in.color)) {
356 napi_value colorValue = nullptr;
357 string color;
358 std::stringstream ss;
359 ss << std::hex << std::uppercase << std::get<1>(in.color);
360 ss >> color;
361 const int rgbLen = 5;
362 const int argbLen = 7;
363 if (color.size() == rgbLen || color.size() == argbLen) {
364 color = '0' + color;
365 }
366 color = '#' + color;
367 LOG_DEBUG("config.color: %{public}s", color.c_str());
368 status = SetValue(env, color, colorValue);
369 CHECK_RETURN((status == napi_ok), "invalid entry color", status);
370 napi_set_named_property(env, out, "color", colorValue);
371 }
372 return status;
373 }
374
GetValue(napi_env env, napi_value in, Location& out)375 napi_status GetValue(napi_env env, napi_value in, Location& out)
376 {
377 LOG_DEBUG("napi_value -> Location ");
378 NapiUtil::GetNamedPropertyOptional(env, in, "location", out.location);
379 NapiUtil::GetNamedPropertyOptional(env, in, "longitude", out.longitude);
380 NapiUtil::GetNamedPropertyOptional(env, in, "latitude", out.latitude);
381 return napi_ok;
382 }
383
SetValue(napi_env env, const Location& in, napi_value& out)384 napi_status SetValue(napi_env env, const Location& in, napi_value& out)
385 {
386 LOG_DEBUG("Location -> napi_value ");
387 napi_status status = napi_create_object(env, &out);
388 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
389
390 if (in.location) {
391 napi_value locationValue = nullptr;
392 status = SetValue(env, in.location.value(), locationValue);
393 CHECK_RETURN((status == napi_ok), "invalid location", status);
394 napi_set_named_property(env, out, "location", locationValue);
395 }
396 if (in.longitude) {
397 napi_value value = nullptr;
398 status = SetValue(env, in.longitude.value(), value);
399 CHECK_RETURN((status == napi_ok), "invalid longitude", status);
400 napi_set_named_property(env, out, "longitude", value);
401 }
402 if (in.latitude) {
403 napi_value value = nullptr;
404 status = SetValue(env, in.latitude.value(), value);
405 CHECK_RETURN((status == napi_ok), "invalid latitude", status);
406 napi_set_named_property(env, out, "latitude", value);
407 }
408 return napi_ok;
409 }
410
411 /* napi_value <-> RecurrenceRule */
GetValue(napi_env env, napi_value in, RecurrenceRule& out)412 napi_status GetValue(napi_env env, napi_value in, RecurrenceRule& out)
413 {
414 LOG_DEBUG("napi_value -> RecurrenceRule ");
415 int recurrence = -1;
416 NapiUtil::GetNamedProperty(env, in, "recurrenceFrequency", recurrence);
417 out.recurrenceFrequency = static_cast<RecurrenceType>(recurrence);
418 NapiUtil::GetNamedPropertyOptional(env, in, "expire", out.expire);
419 NapiUtil::GetNamedPropertyOptional(env, in, "count", out.count);
420 NapiUtil::GetNamedPropertyOptional(env, in, "interval", out.interval);
421 NapiUtil::GetNamedPropertyOptional(env, in, "excludedDates", out.excludedDates);
422 NapiUtil::GetNamedPropertyOptional(env, in, "daysOfWeek", out.daysOfWeek);
423 NapiUtil::GetNamedPropertyOptional(env, in, "daysOfMonth", out.daysOfMonth);
424 NapiUtil::GetNamedPropertyOptional(env, in, "daysOfYear", out.daysOfYear);
425 NapiUtil::GetNamedPropertyOptional(env, in, "weeksOfMonth", out.weeksOfMonth);
426 NapiUtil::GetNamedPropertyOptional(env, in, "weeksOfYear", out.weeksOfYear);
427 NapiUtil::GetNamedPropertyOptional(env, in, "monthsOfYear", out.monthsOfYear);
428 return napi_ok;
429 }
430
SetValue(napi_env env, const RecurrenceRule& in, napi_value& out)431 napi_status SetValue(napi_env env, const RecurrenceRule& in, napi_value& out)
432 {
433 LOG_DEBUG("RecurrenceRule -> napi_value ");
434 napi_status status = napi_create_object(env, &out);
435 CHECK_RETURN((status == napi_ok), "invalid recurrenceRule", status);
436 status = SetNamedProperty(env, "recurrenceFrequency", in.recurrenceFrequency, out);
437 CHECK_RETURN((status == napi_ok), "invalid recurrenceFrequency", status);
438 SetNamedPropertyOptional(env, "expire", in.expire, out);
439 SetNamedPropertyOptional(env, "count", in.count, out);
440 SetNamedPropertyOptional(env, "interval", in.interval, out);
441 SetNamedPropertyOptional(env, "excludedDates", in.excludedDates, out);
442 SetNamedPropertyOptional(env, "daysOfWeek", in.daysOfWeek, out);
443 SetNamedPropertyOptional(env, "daysOfMonth", in.daysOfMonth, out);
444 SetNamedPropertyOptional(env, "daysOfYear", in.daysOfYear, out);
445 SetNamedPropertyOptional(env, "weeksOfMonth", in.weeksOfMonth, out);
446 SetNamedPropertyOptional(env, "weeksOfYear", in.weeksOfYear, out);
447 SetNamedPropertyOptional(env, "monthsOfYear", in.monthsOfYear, out);
448 return napi_ok;
449 }
450
451 /* napi_value <-> Attendee */
GetValue(napi_env env, napi_value in, Attendee& out)452 napi_status GetValue(napi_env env, napi_value in, Attendee& out)
453 {
454 LOG_DEBUG("Attendee -> napi_value ");
455 NapiUtil::GetNamedProperty(env, in, "name", out.name);
456 NapiUtil::GetNamedProperty(env, in, "email", out.email);
457 optional<std::string> value;
458 NapiUtil::GetNamedPropertyOptional(env, in, "role", value);
459 if (!value.has_value()) {
460 return napi_ok;
461 }
462
463 if (value == "organizer") {
464 out.role = ORGANIZER;
465 } else {
466 out.role = PARTICIPANT;
467 }
468 return napi_ok;
469 }
470
SetValue(napi_env env, const Attendee& in, napi_value& out)471 napi_status SetValue(napi_env env, const Attendee& in, napi_value& out)
472 {
473 LOG_DEBUG("napi_value -> Attendee ");
474 napi_status status = napi_create_object(env, &out);
475 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
476
477 napi_value nameValue = nullptr;
478 status = SetValue(env, in.name, nameValue);
479 CHECK_RETURN((status == napi_ok), "invalid entry name", status);
480 napi_set_named_property(env, out, "name", nameValue);
481 napi_value emailValue = nullptr;
482 status = SetValue(env, in.email, emailValue);
483 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
484 napi_set_named_property(env, out, "email", emailValue);
485 if (!in.role.has_value()) {
486 return napi_ok;
487 }
488 std::string value;
489 if (in.role == PARTICIPANT) {
490 value = "organizer";
491 } else {
492 value = "participant";
493 }
494 napi_value roleValue = nullptr;
495 status = SetValue(env, value, roleValue);
496 CHECK_RETURN((status == napi_ok), "invalid role", status);
497 napi_set_named_property(env, out, "role", roleValue);
498 return napi_ok;
499 }
500
501 /* napi_value <-> std::vector<Attendee> */
GetValue(napi_env env, napi_value in, std::vector<Attendee>& out)502 napi_status GetValue(napi_env env, napi_value in, std::vector<Attendee>& out)
503 {
504 LOG_DEBUG("napi_value -> std::vector<Attendee> ");
505 return GetValueArray(env, in, out);
506 }
507
SetValue(napi_env env, const std::vector<Attendee>& in, napi_value& out)508 napi_status SetValue(napi_env env, const std::vector<Attendee>& in, napi_value& out)
509 {
510 LOG_DEBUG("std::vector<Attendee> -> napi_value ");
511 return SetValueArray(env, in, out);
512 }
513
GetValue(napi_env env, napi_value in, EventService& out)514 napi_status GetValue(napi_env env, napi_value in, EventService& out)
515 {
516 LOG_DEBUG("napi_value -> EventService");
517 NapiUtil::GetNamedPropertyOptional(env, in, "description", out.description);
518 NapiUtil::GetNamedProperty(env, in, "type", out.type);
519 return NapiUtil::GetNamedProperty(env, in, "uri", out.uri);
520 }
521
SetValue(napi_env env, const EventService& in, napi_value& out)522 napi_status SetValue(napi_env env, const EventService& in, napi_value& out)
523 {
524 LOG_DEBUG("EventService -> napi_value");
525 napi_status status = napi_create_object(env, &out);
526 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
527
528 napi_value typeValue = nullptr;
529 status = SetValue(env, in.type, typeValue);
530 CHECK_RETURN((status == napi_ok), "invalid typeValue", status);
531 status = napi_set_named_property(env, out, "type", typeValue);
532 CHECK_RETURN((status == napi_ok), "set type failed", status);
533
534 napi_value uriValue = nullptr;
535 status = SetValue(env, in.uri, uriValue);
536 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
537 status = napi_set_named_property(env, out, "uri", uriValue);
538 CHECK_RETURN((status == napi_ok), "set uri failed", status);
539
540 if (in.description) {
541 napi_value descriptionValue = nullptr;
542 status = SetValue(env, in.description.value(), descriptionValue);
543 CHECK_RETURN((status == napi_ok), "invalid description", status);
544 status = napi_set_named_property(env, out, "description", descriptionValue);
545 CHECK_RETURN((status == napi_ok), "set description failed", status);
546 }
547 return status;
548 }
549
550 /* napi_value <-> EventFilter */
GetValue(napi_env env, napi_value in, EventFilterNapi*& out)551 napi_status GetValue(napi_env env, napi_value in, EventFilterNapi*& out)
552 {
553 LOG_DEBUG("napi_value -> EventFilter ");
554 return EventFilterNapi::ToJson(env, in, out);
555 }
556
SetValue(napi_env env, const EventFilterNapi& in, napi_value& out)557 napi_status SetValue(napi_env env, const EventFilterNapi& in, napi_value& out)
558 {
559 LOG_DEBUG("EventFilterNapi -> napi_value ");
560 return napi_ok;
561 }
562
563 /* napi_value <-> EventType */
GetValue(napi_env env, napi_value in, EventType& out)564 napi_status GetValue(napi_env env, napi_value in, EventType& out)
565 {
566 LOG_DEBUG("napi_value -> EventType ");
567 return napi_ok;
568 }
569
SetValue(napi_env env, const EventType& in, napi_value& out)570 napi_status SetValue(napi_env env, const EventType& in, napi_value& out)
571 {
572 LOG_DEBUG("EventType -> napi_value ");
573 return napi_ok;
574 }
575
576 /* napi_value <-> Event */
GetValue(napi_env env, napi_value in, Event& out)577 napi_status GetValue(napi_env env, napi_value in, Event& out)
578 {
579 LOG_DEBUG("napi_value -> Event ");
580 GetNamedPropertyOptional(env, in, "id", out.id);
581 int type = -1;
582 napi_status status = GetNamedProperty(env, in, "type", type);
583 out.type = static_cast<EventType>(type);
584 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
585 GetNamedPropertyOptional(env, in, "title", out.title);
586 GetNamedPropertyOptional(env, in, "location", out.location);
587 status = GetNamedProperty(env, in, "startTime", out.startTime);
588 CHECK_RETURN((status == napi_ok), "invalid entry startTime", status);
589 status = GetNamedProperty(env, in, "endTime", out.endTime);
590 CHECK_RETURN((status == napi_ok), "invalid entry endTime", status);
591 GetNamedPropertyOptional(env, in, "isAllDay", out.isAllDay);
592 GetNamedProperty(env, in, "attendee", out.attendees); // colud be empty not check result
593 GetNamedPropertyOptional(env, in, "timeZone", out.timeZone);
594 GetNamedPropertyOptional(env, in, "reminderTime", out.reminderTime);
595 GetNamedPropertyOptional(env, in, "recurrenceRule", out.recurrenceRule);
596 GetNamedPropertyOptional(env, in, "description", out.description);
597 GetNamedPropertyOptional(env, in, "service", out.service);
598 GetNamedPropertyOptional(env, in, "identifier", out.identifier);
599 GetNamedPropertyOptional(env, in, "isLunar", out.isLunar);
600 return status;
601 }
602
SetValue(napi_env env, const Event& in, napi_value& out)603 napi_status SetValue(napi_env env, const Event& in, napi_value& out)
604 {
605 LOG_DEBUG("Event -> napi_value");
606 napi_status status = napi_create_object(env, &out);
607 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
608
609 status = SetNamedProperty(env, "id", in.id.value(), out);
610 CHECK_RETURN((status == napi_ok), "invalid entry id", status);
611
612 status = SetNamedProperty(env, "type", static_cast<int>(in.type), out);
613 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
614
615 SetNamedPropertyOptional(env, "location", in.location, out);
616 SetNamedPropertyOptional(env, "title", in.title, out);
617
618 status = SetNamedProperty(env, "startTime", in.startTime, out);
619 CHECK_RETURN((status == napi_ok), "invalid entry startTime", status);
620
621 status = SetNamedProperty(env, "endTime", in.endTime, out);
622 CHECK_RETURN((status == napi_ok), "invalid entry endTime", status);
623
624 SetNamedPropertyOptional(env, "isAllDay", in.isAllDay, out);
625 if (!in.attendees.empty()) {
626 status = SetNamedProperty(env, "attendee", in.attendees, out);
627 CHECK_RETURN((status == napi_ok), "invalid entry attendee", status);
628 }
629 SetNamedPropertyOptional(env, "timeZone", in.timeZone, out);
630 SetNamedPropertyOptional(env, "reminderTime", in.reminderTime, out);
631 SetNamedPropertyOptional(env, "description", in.description, out);
632 SetNamedPropertyOptional(env, "service", in.service, out);
633 SetNamedPropertyOptional(env, "recurrenceRule", in.recurrenceRule, out);
634 SetNamedPropertyOptional(env, "identifier", in.identifier, out);
635 SetNamedPropertyOptional(env, "isLunar", in.isLunar, out);
636 return status;
637 }
638
639 /* napi_value <-> std::vector<Event> */
GetValue(napi_env env, napi_value in, std::vector<Event>& out)640 napi_status GetValue(napi_env env, napi_value in, std::vector<Event>& out)
641 {
642 LOG_DEBUG("napi_value -> std::vector<Event>");
643 return GetValueArray(env, in, out);
644 }
645
SetValue(napi_env env, const std::vector<Event>& in, napi_value& out)646 napi_status SetValue(napi_env env, const std::vector<Event>& in, napi_value& out)
647 {
648 LOG_DEBUG("std::vector<Event> -> napi_value");
649 return SetValueArray(env, in, out);
650 }
651
652
DefineClass(napi_env env, const std::string& name, const napi_property_descriptor* properties, size_t count, napi_callback newcb)653 napi_value DefineClass(napi_env env, const std::string& name,
654 const napi_property_descriptor* properties, size_t count, napi_callback newcb)
655 {
656 // base64("calendar.calendarmanager") as rootPropName, i.e. global.<root>
657 const std::string rootPropName = "Y2FsZW5kYXIuY2FsZW5kYXJtYW5hZ2Vy";
658 napi_value root = nullptr;
659 bool hasRoot = false;
660 napi_value global = nullptr;
661 napi_get_global(env, &global);
662 napi_has_named_property(env, global, rootPropName.c_str(), &hasRoot);
663 if (hasRoot) {
664 napi_get_named_property(env, global, rootPropName.c_str(), &root);
665 } else {
666 napi_create_object(env, &root);
667 napi_set_named_property(env, global, rootPropName.c_str(), root);
668 }
669
670 std::string propName = "constructor_of_" + name;
671 napi_value constructor = nullptr;
672 bool hasProp = false;
673 napi_has_named_property(env, root, propName.c_str(), &hasProp);
674 if (hasProp) {
675 napi_get_named_property(env, root, propName.c_str(), &constructor);
676 if (constructor != nullptr) {
677 LOG_DEBUG("got calendar.calendarmanager.%{private}s as constructor", propName.c_str());
678 return constructor;
679 }
680 hasProp = false; // no constructor.
681 }
682
683 NAPI_CALL(env, napi_define_class(env, name.c_str(), name.size(), newcb, nullptr, count, properties, &constructor));
684 NAPI_ASSERT(env, constructor != nullptr, "napi_define_class failed!");
685
686 if (!hasProp) {
687 napi_set_named_property(env, root, propName.c_str(), constructor);
688 LOG_DEBUG("save constructor to calendar.calendarmanager.%{private}s", propName.c_str());
689 }
690 return constructor;
691 }
692
NewWithRef(napi_env env, size_t argc, napi_value* argv, void** out, napi_value constructor)693 napi_ref NewWithRef(napi_env env, size_t argc, napi_value* argv, void** out, napi_value constructor)
694 {
695 napi_value object = nullptr;
696 napi_status status = napi_new_instance(env, constructor, argc, argv, &object);
697 CHECK_RETURN(status == napi_ok, "napi_new_instance failed", nullptr);
698 CHECK_RETURN(object != nullptr, "napi_new_instance failed", nullptr);
699
700 status = napi_unwrap(env, object, out);
701 CHECK_RETURN(status == napi_ok, "napi_unwrap failed", nullptr);
702 CHECK_RETURN(out != nullptr, "napi_unwrap failed", nullptr);
703
704 napi_ref ref = nullptr;
705 status = napi_create_reference(env, object, 1, &ref);
706 CHECK_RETURN(status == napi_ok, "napi_create_reference failed!", nullptr);
707 CHECK_RETURN(ref != nullptr, "napi_create_reference failed!", nullptr);
708 return ref;
709 }
710
Unwrap(napi_env env, napi_value in, void** out, napi_value constructor)711 napi_status Unwrap(napi_env env, napi_value in, void** out, napi_value constructor)
712 {
713 if (constructor != nullptr) {
714 bool isInstance = false;
715 auto status = napi_instanceof(env, in, constructor, &isInstance);
716 if (status != napi_ok) {
717 LOG_ERROR("napi_instanceof failed");
718 return status;
719 }
720 if (!isInstance) {
721 LOG_ERROR("not a instance of *");
722 return napi_invalid_arg;
723 }
724 }
725 return napi_unwrap(env, in, out);
726 }
727
Equals(napi_env env, napi_value value, napi_ref copy)728 bool Equals(napi_env env, napi_value value, napi_ref copy)
729 {
730 if (copy == nullptr) {
731 return value == nullptr? true : false;
732 }
733
734 napi_value copyValue = nullptr;
735 napi_get_reference_value(env, copy, ©Value);
736
737 bool isEquals = false;
738 napi_strict_equals(env, value, copyValue, &isEquals);
739 return isEquals;
740 }
741 } // namespace OHOS::CalendarApi::NapiUtil
742