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