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