• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &copyValue);
634 
635     bool isEquals = false;
636     napi_strict_equals(env, value, copyValue, &isEquals);
637     return isEquals;
638 }
639 
640 } // namespace OHOS::DistributedData
641