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