• 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 #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, &copyValue);
754 
755     bool isEquals = false;
756     napi_strict_equals(env, value, copyValue, &isEquals);
757     return isEquals;
758 }
759 } // namespace OHOS::CalendarApi::NapiUtil
760