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", static_cast<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 = 0;
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 while (color.size() < rgbLen) {
364 color = '0' + color;
365 }
366 if (color.size() == rgbLen || color.size() == argbLen) {
367 color = '0' + color;
368 }
369 color = '#' + color;
370 LOG_DEBUG("config.color: %{public}s", color.c_str());
371 status = SetValue(env, color, colorValue);
372 CHECK_RETURN((status == napi_ok), "invalid entry color", status);
373 napi_set_named_property(env, out, "color", colorValue);
374 }
375 return status;
376 }
377
GetValue(napi_env env,napi_value in,Location & out)378 napi_status GetValue(napi_env env, napi_value in, Location& out)
379 {
380 LOG_DEBUG("napi_value -> Location ");
381 NapiUtil::GetNamedPropertyOptional(env, in, "location", out.location);
382 NapiUtil::GetNamedPropertyOptional(env, in, "longitude", out.longitude);
383 NapiUtil::GetNamedPropertyOptional(env, in, "latitude", out.latitude);
384 return napi_ok;
385 }
386
SetValue(napi_env env,const Location & in,napi_value & out)387 napi_status SetValue(napi_env env, const Location& in, napi_value& out)
388 {
389 LOG_DEBUG("Location -> napi_value ");
390 napi_status status = napi_create_object(env, &out);
391 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
392
393 if (in.location) {
394 napi_value locationValue = nullptr;
395 status = SetValue(env, in.location.value(), locationValue);
396 CHECK_RETURN((status == napi_ok), "invalid location", status);
397 napi_set_named_property(env, out, "location", locationValue);
398 }
399 if (in.longitude) {
400 napi_value value = nullptr;
401 status = SetValue(env, in.longitude.value(), value);
402 CHECK_RETURN((status == napi_ok), "invalid longitude", status);
403 napi_set_named_property(env, out, "longitude", value);
404 }
405 if (in.latitude) {
406 napi_value value = nullptr;
407 status = SetValue(env, in.latitude.value(), value);
408 CHECK_RETURN((status == napi_ok), "invalid latitude", status);
409 napi_set_named_property(env, out, "latitude", value);
410 }
411 return napi_ok;
412 }
413
414 /* napi_value <-> RecurrenceRule */
GetValue(napi_env env,napi_value in,RecurrenceRule & out)415 napi_status GetValue(napi_env env, napi_value in, RecurrenceRule& out)
416 {
417 LOG_DEBUG("napi_value -> RecurrenceRule ");
418 int recurrence = -1;
419 NapiUtil::GetNamedProperty(env, in, "recurrenceFrequency", recurrence);
420 out.recurrenceFrequency = static_cast<RecurrenceType>(recurrence);
421 NapiUtil::GetNamedPropertyOptional(env, in, "expire", out.expire);
422 NapiUtil::GetNamedPropertyOptional(env, in, "count", out.count);
423 NapiUtil::GetNamedPropertyOptional(env, in, "interval", out.interval);
424 NapiUtil::GetNamedPropertyOptional(env, in, "excludedDates", out.excludedDates);
425 NapiUtil::GetNamedPropertyOptional(env, in, "daysOfWeek", out.daysOfWeek);
426 NapiUtil::GetNamedPropertyOptional(env, in, "daysOfMonth", out.daysOfMonth);
427 NapiUtil::GetNamedPropertyOptional(env, in, "daysOfYear", out.daysOfYear);
428 NapiUtil::GetNamedPropertyOptional(env, in, "weeksOfMonth", out.weeksOfMonth);
429 NapiUtil::GetNamedPropertyOptional(env, in, "weeksOfYear", out.weeksOfYear);
430 NapiUtil::GetNamedPropertyOptional(env, in, "monthsOfYear", out.monthsOfYear);
431 return napi_ok;
432 }
433
SetValue(napi_env env,const RecurrenceRule & in,napi_value & out)434 napi_status SetValue(napi_env env, const RecurrenceRule& in, napi_value& out)
435 {
436 LOG_DEBUG("RecurrenceRule -> napi_value ");
437 napi_status status = napi_create_object(env, &out);
438 CHECK_RETURN((status == napi_ok), "invalid recurrenceRule", status);
439 status = SetNamedProperty(env, "recurrenceFrequency", in.recurrenceFrequency, out);
440 CHECK_RETURN((status == napi_ok), "invalid recurrenceFrequency", status);
441 SetNamedPropertyOptional(env, "expire", in.expire, out);
442 SetNamedPropertyOptional(env, "count", in.count, out);
443 SetNamedPropertyOptional(env, "interval", in.interval, out);
444 SetNamedPropertyOptional(env, "excludedDates", in.excludedDates, out);
445 SetNamedPropertyOptional(env, "daysOfWeek", in.daysOfWeek, out);
446 SetNamedPropertyOptional(env, "daysOfMonth", in.daysOfMonth, out);
447 SetNamedPropertyOptional(env, "daysOfYear", in.daysOfYear, out);
448 SetNamedPropertyOptional(env, "weeksOfMonth", in.weeksOfMonth, out);
449 SetNamedPropertyOptional(env, "weeksOfYear", in.weeksOfYear, out);
450 SetNamedPropertyOptional(env, "monthsOfYear", in.monthsOfYear, out);
451 return napi_ok;
452 }
453
454 /* napi_value <-> Attendee */
GetValue(napi_env env,napi_value in,Attendee & out)455 napi_status GetValue(napi_env env, napi_value in, Attendee &out)
456 {
457 LOG_DEBUG("Attendee -> napi_value ");
458 NapiUtil::GetNamedProperty(env, in, "name", out.name);
459 NapiUtil::GetNamedProperty(env, in, "email", out.email);
460 optional<std::string> role = std::nullopt;
461 optional<int> status = std::nullopt;
462 optional<int> type = std::nullopt;
463 NapiUtil::GetNamedPropertyOptional(env, in, "role", role);
464 if (role.has_value()) {
465 if (role == "organizer") {
466 out.role = ORGANIZER;
467 } else {
468 out.role = PARTICIPANT;
469 }
470 }
471 NapiUtil::GetNamedPropertyOptional(env, in, "status", status);
472 if (status.has_value()) {
473 out.status = static_cast<AttendeeStatus>(status.value());
474 LOG_INFO("status.value() %{public}d", status.value());
475 }
476 NapiUtil::GetNamedPropertyOptional(env, in, "type", type);
477 if (type.has_value()) {
478 out.type = static_cast<AttendeeType>(type.value());
479 }
480 return napi_ok;
481 }
482
SetValue(napi_env env,const Attendee & in,napi_value & out)483 napi_status SetValue(napi_env env, const Attendee& in, napi_value& out)
484 {
485 LOG_DEBUG("napi_value -> Attendee ");
486 napi_status status = napi_create_object(env, &out);
487 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
488
489 napi_value nameValue = nullptr;
490 status = SetValue(env, in.name, nameValue);
491 CHECK_RETURN((status == napi_ok), "invalid entry name", status);
492 napi_set_named_property(env, out, "name", nameValue);
493 napi_value emailValue = nullptr;
494 status = SetValue(env, in.email, emailValue);
495 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
496 napi_set_named_property(env, out, "email", emailValue);
497 optional<std::string> value = std::nullopt;
498 if (in.role.has_value()) {
499 if (in.role == ORGANIZER) {
500 value = "organizer";
501 } else {
502 value = "participant";
503 }
504 }
505 if (value.has_value()) {
506 SetNamedPropertyOptional(env, "role", value, out);
507 }
508 SetNamedPropertyOptional(env, "status", in.status, out);
509 CHECK_RETURN((status == napi_ok), "invalid status", status);
510 SetNamedPropertyOptional(env, "type", in.type, out);
511 CHECK_RETURN((status == napi_ok), "invalid type", status);
512 return napi_ok;
513 }
514
515 /* napi_value <-> std::vector<Attendee> */
GetValue(napi_env env,napi_value in,std::vector<Attendee> & out)516 napi_status GetValue(napi_env env, napi_value in, std::vector<Attendee>& out)
517 {
518 LOG_DEBUG("napi_value -> std::vector<Attendee> ");
519 return GetValueArray(env, in, out);
520 }
521
SetValue(napi_env env,const std::vector<Attendee> & in,napi_value & out)522 napi_status SetValue(napi_env env, const std::vector<Attendee>& in, napi_value& out)
523 {
524 LOG_DEBUG("std::vector<Attendee> -> napi_value ");
525 return SetValueArray(env, in, out);
526 }
527
GetValue(napi_env env,napi_value in,EventService & out)528 napi_status GetValue(napi_env env, napi_value in, EventService& out)
529 {
530 LOG_DEBUG("napi_value -> EventService");
531 NapiUtil::GetNamedPropertyOptional(env, in, "description", out.description);
532 NapiUtil::GetNamedProperty(env, in, "type", out.type);
533 return NapiUtil::GetNamedProperty(env, in, "uri", out.uri);
534 }
535
SetValue(napi_env env,const EventService & in,napi_value & out)536 napi_status SetValue(napi_env env, const EventService& in, napi_value& out)
537 {
538 LOG_DEBUG("EventService -> napi_value");
539 napi_status status = napi_create_object(env, &out);
540 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
541
542 napi_value typeValue = nullptr;
543 status = SetValue(env, in.type, typeValue);
544 CHECK_RETURN((status == napi_ok), "invalid typeValue", status);
545 status = napi_set_named_property(env, out, "type", typeValue);
546 CHECK_RETURN((status == napi_ok), "set type failed", status);
547
548 napi_value uriValue = nullptr;
549 status = SetValue(env, in.uri, uriValue);
550 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
551 status = napi_set_named_property(env, out, "uri", uriValue);
552 CHECK_RETURN((status == napi_ok), "set uri failed", status);
553
554 if (in.description) {
555 napi_value descriptionValue = nullptr;
556 status = SetValue(env, in.description.value(), descriptionValue);
557 CHECK_RETURN((status == napi_ok), "invalid description", status);
558 status = napi_set_named_property(env, out, "description", descriptionValue);
559 CHECK_RETURN((status == napi_ok), "set description failed", status);
560 }
561 return status;
562 }
563
564 /* napi_value <-> EventFilter */
GetValue(napi_env env,napi_value in,EventFilterNapi * & out)565 napi_status GetValue(napi_env env, napi_value in, EventFilterNapi*& out)
566 {
567 LOG_DEBUG("napi_value -> EventFilter ");
568 return EventFilterNapi::ToJson(env, in, out);
569 }
570
SetValue(napi_env env,const EventFilterNapi & in,napi_value & out)571 napi_status SetValue(napi_env env, const EventFilterNapi& in, napi_value& out)
572 {
573 LOG_DEBUG("EventFilterNapi -> napi_value ");
574 return napi_ok;
575 }
576
577 /* napi_value <-> EventType */
GetValue(napi_env env,napi_value in,EventType & out)578 napi_status GetValue(napi_env env, napi_value in, EventType& out)
579 {
580 LOG_DEBUG("napi_value -> EventType ");
581 return napi_ok;
582 }
583
SetValue(napi_env env,const EventType & in,napi_value & out)584 napi_status SetValue(napi_env env, const EventType& in, napi_value& out)
585 {
586 LOG_DEBUG("EventType -> napi_value ");
587 return napi_ok;
588 }
589
590 /* napi_value <-> Event */
GetValue(napi_env env,napi_value in,Event & out)591 napi_status GetValue(napi_env env, napi_value in, Event& out)
592 {
593 LOG_DEBUG("napi_value -> Event ");
594 GetNamedPropertyOptional(env, in, "id", out.id);
595 int type = -1;
596 napi_status status = GetNamedProperty(env, in, "type", type);
597 out.type = static_cast<EventType>(type);
598 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
599 GetNamedPropertyOptional(env, in, "title", out.title);
600 GetNamedPropertyOptional(env, in, "location", out.location);
601 status = GetNamedProperty(env, in, "startTime", out.startTime);
602 CHECK_RETURN((status == napi_ok), "invalid entry startTime", status);
603 status = GetNamedProperty(env, in, "endTime", out.endTime);
604 CHECK_RETURN((status == napi_ok), "invalid entry endTime", status);
605 GetNamedPropertyOptional(env, in, "isAllDay", out.isAllDay);
606 GetNamedProperty(env, in, "attendee", out.attendees); // colud be empty not check result
607 GetNamedPropertyOptional(env, in, "timeZone", out.timeZone);
608 GetNamedPropertyOptional(env, in, "reminderTime", out.reminderTime);
609 GetNamedPropertyOptional(env, in, "recurrenceRule", out.recurrenceRule);
610 GetNamedPropertyOptional(env, in, "description", out.description);
611 GetNamedPropertyOptional(env, in, "service", out.service);
612 GetNamedPropertyOptional(env, in, "identifier", out.identifier);
613 GetNamedPropertyOptional(env, in, "isLunar", out.isLunar);
614 GetNamedPropertyOptional(env, in, "instanceStartTime", out.instanceStartTime);
615 GetNamedPropertyOptional(env, in, "instanceEndTime", out.instanceEndTime);
616 return status;
617 }
618
SetValue(napi_env env,const Event & in,napi_value & out)619 napi_status SetValue(napi_env env, const Event& in, napi_value& out)
620 {
621 LOG_DEBUG("Event -> napi_value");
622 napi_status status = napi_create_object(env, &out);
623 CHECK_RETURN((status == napi_ok), "invalid entry object", status);
624
625 status = SetNamedProperty(env, "id", in.id.value(), out);
626 CHECK_RETURN((status == napi_ok), "invalid entry id", status);
627
628 status = SetNamedProperty(env, "type", static_cast<int>(in.type), out);
629 CHECK_RETURN((status == napi_ok), "invalid entry type", status);
630
631 SetNamedPropertyOptional(env, "location", in.location, out);
632 SetNamedPropertyOptional(env, "title", in.title, out);
633
634 status = SetNamedProperty(env, "startTime", in.startTime, out);
635 CHECK_RETURN((status == napi_ok), "invalid entry startTime", status);
636
637 status = SetNamedProperty(env, "endTime", in.endTime, out);
638 CHECK_RETURN((status == napi_ok), "invalid entry endTime", status);
639
640 SetNamedPropertyOptional(env, "isAllDay", in.isAllDay, out);
641 if (!in.attendees.empty()) {
642 status = SetNamedProperty(env, "attendee", in.attendees, out);
643 CHECK_RETURN((status == napi_ok), "invalid entry attendee", status);
644 }
645 SetNamedPropertyOptional(env, "timeZone", in.timeZone, out);
646 SetNamedPropertyOptional(env, "reminderTime", in.reminderTime, out);
647 SetNamedPropertyOptional(env, "description", in.description, out);
648 SetNamedPropertyOptional(env, "service", in.service, out);
649 SetNamedPropertyOptional(env, "recurrenceRule", in.recurrenceRule, out);
650 SetNamedPropertyOptional(env, "identifier", in.identifier, out);
651 SetNamedPropertyOptional(env, "isLunar", in.isLunar, out);
652 SetNamedPropertyOptional(env, "instanceStartTime", in.instanceStartTime, out);
653 SetNamedPropertyOptional(env, "instanceEndTime", in.instanceEndTime, out);
654 return status;
655 }
656
657 /* napi_value <-> std::vector<Event> */
GetValue(napi_env env,napi_value in,std::vector<Event> & out)658 napi_status GetValue(napi_env env, napi_value in, std::vector<Event>& out)
659 {
660 LOG_DEBUG("napi_value -> std::vector<Event>");
661 return GetValueArray(env, in, out);
662 }
663
SetValue(napi_env env,const std::vector<Event> & in,napi_value & out)664 napi_status SetValue(napi_env env, const std::vector<Event>& in, napi_value& out)
665 {
666 LOG_DEBUG("std::vector<Event> -> napi_value");
667 return SetValueArray(env, in, out);
668 }
669
670
DefineClass(napi_env env,const std::string & name,const napi_property_descriptor * properties,size_t count,napi_callback newcb)671 napi_value DefineClass(napi_env env, const std::string& name,
672 const napi_property_descriptor* properties, size_t count, napi_callback newcb)
673 {
674 // base64("calendar.calendarmanager") as rootPropName, i.e. global.<root>
675 const std::string rootPropName = "Y2FsZW5kYXIuY2FsZW5kYXJtYW5hZ2Vy";
676 napi_value root = nullptr;
677 bool hasRoot = false;
678 napi_value global = nullptr;
679 napi_get_global(env, &global);
680 napi_has_named_property(env, global, rootPropName.c_str(), &hasRoot);
681 if (hasRoot) {
682 napi_get_named_property(env, global, rootPropName.c_str(), &root);
683 } else {
684 napi_create_object(env, &root);
685 napi_set_named_property(env, global, rootPropName.c_str(), root);
686 }
687
688 std::string propName = "constructor_of_" + name;
689 napi_value constructor = nullptr;
690 bool hasProp = false;
691 napi_has_named_property(env, root, propName.c_str(), &hasProp);
692 if (hasProp) {
693 napi_get_named_property(env, root, propName.c_str(), &constructor);
694 if (constructor != nullptr) {
695 LOG_DEBUG("got calendar.calendarmanager.%{private}s as constructor", propName.c_str());
696 return constructor;
697 }
698 hasProp = false; // no constructor.
699 }
700
701 NAPI_CALL(env, napi_define_class(env, name.c_str(), name.size(), newcb, nullptr, count, properties, &constructor));
702 NAPI_ASSERT(env, constructor != nullptr, "napi_define_class failed!");
703
704 if (!hasProp) {
705 napi_set_named_property(env, root, propName.c_str(), constructor);
706 LOG_DEBUG("save constructor to calendar.calendarmanager.%{private}s", propName.c_str());
707 }
708 return constructor;
709 }
710
NewWithRef(napi_env env,size_t argc,napi_value * argv,void ** out,napi_value constructor)711 napi_ref NewWithRef(napi_env env, size_t argc, napi_value* argv, void** out, napi_value constructor)
712 {
713 napi_value object = nullptr;
714 napi_status status = napi_new_instance(env, constructor, argc, argv, &object);
715 CHECK_RETURN(status == napi_ok, "napi_new_instance failed", nullptr);
716 CHECK_RETURN(object != nullptr, "napi_new_instance failed", nullptr);
717
718 status = napi_unwrap(env, object, out);
719 CHECK_RETURN(status == napi_ok, "napi_unwrap failed", nullptr);
720 CHECK_RETURN(out != nullptr, "napi_unwrap failed", nullptr);
721
722 napi_ref ref = nullptr;
723 status = napi_create_reference(env, object, 1, &ref);
724 CHECK_RETURN(status == napi_ok, "napi_create_reference failed!", nullptr);
725 CHECK_RETURN(ref != nullptr, "napi_create_reference failed!", nullptr);
726 return ref;
727 }
728
Unwrap(napi_env env,napi_value in,void ** out,napi_value constructor)729 napi_status Unwrap(napi_env env, napi_value in, void** out, napi_value constructor)
730 {
731 if (constructor != nullptr) {
732 bool isInstance = false;
733 auto status = napi_instanceof(env, in, constructor, &isInstance);
734 if (status != napi_ok) {
735 LOG_ERROR("napi_instanceof failed");
736 return status;
737 }
738 if (!isInstance) {
739 LOG_ERROR("not a instance of *");
740 return napi_invalid_arg;
741 }
742 }
743 return napi_unwrap(env, in, out);
744 }
745
Equals(napi_env env,napi_value value,napi_ref copy)746 bool Equals(napi_env env, napi_value value, napi_ref copy)
747 {
748 if (copy == nullptr) {
749 return value == nullptr? true : false;
750 }
751
752 napi_value copyValue = nullptr;
753 napi_get_reference_value(env, copy, ©Value);
754
755 bool isEquals = false;
756 napi_strict_equals(env, value, copyValue, &isEquals);
757 return isEquals;
758 }
759 } // namespace OHOS::CalendarApi::NapiUtil
760