1 /*
2  * Copyright (c) 2024 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 #include "napi_data_utils.h"
16 
17 #include "napi_queue.h"
18 
19 using namespace OHOS::MiscServices;
20 namespace OHOS {
21 namespace MiscServicesNapi {
22 constexpr int32_t STR_MAX_LENGTH = 4096;
23 constexpr size_t STR_TAIL_LENGTH = 1;
24 
25 /* napi_value <-> bool */
GetValue(napi_env env,napi_value in,bool & out)26 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, bool &out)
27 {
28     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- bool");
29     return napi_get_value_bool(env, in, &out);
30 }
31 
SetValue(napi_env env,const bool & in,napi_value & out)32 napi_status NapiDataUtils::SetValue(napi_env env, const bool &in, napi_value &out)
33 {
34     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> bool");
35     return napi_get_boolean(env, in, &out);
36 }
37 
38 /* napi_value <-> int32_t */
GetValue(napi_env env,napi_value in,int32_t & out)39 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, int32_t &out)
40 {
41     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> int32_t");
42     return napi_get_value_int32(env, in, &out);
43 }
44 
SetValue(napi_env env,const int32_t & in,napi_value & out)45 napi_status NapiDataUtils::SetValue(napi_env env, const int32_t &in, napi_value &out)
46 {
47     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- int32_t");
48     return napi_create_int32(env, in, &out);
49 }
50 
51 /* napi_value <-> int64_t */
GetValue(napi_env env,napi_value in,int64_t & out)52 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, int64_t &out)
53 {
54     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> int64_t");
55     return napi_get_value_int64(env, in, &out);
56 }
57 
SetValue(napi_env env,const int64_t & in,napi_value & out)58 napi_status NapiDataUtils::SetValue(napi_env env, const int64_t &in, napi_value &out)
59 {
60     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- int64_t");
61     return napi_create_int64(env, in, &out);
62 }
63 
64 /* napi_value <-> float */
GetValue(napi_env env,napi_value in,float & out)65 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, float &out)
66 {
67     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> float");
68     double tmp;
69     napi_status status = napi_get_value_double(env, in, &tmp);
70     out = tmp;
71     return status;
72 }
73 
SetValue(napi_env env,const float & in,napi_value & out)74 napi_status NapiDataUtils::SetValue(napi_env env, const float &in, napi_value &out)
75 {
76     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- float");
77     double tmp = in;
78     return napi_create_double(env, tmp, &out);
79 }
80 
81 /* napi_value <-> double */
GetValue(napi_env env,napi_value in,double & out)82 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, double &out)
83 {
84     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> double");
85     return napi_get_value_double(env, in, &out);
86 }
87 
SetValue(napi_env env,const double & in,napi_value & out)88 napi_status NapiDataUtils::SetValue(napi_env env, const double &in, napi_value &out)
89 {
90     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- double");
91     return napi_create_double(env, in, &out);
92 }
93 
94 /* napi_value <-> std::string */
GetValue(napi_env env,napi_value in,std::string & out)95 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::string &out)
96 {
97     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- string");
98     napi_valuetype type = napi_undefined;
99     napi_status status = napi_typeof(env, in, &type);
100     if (!((status == napi_ok) && (type == napi_string))) {
101         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "napi_typeof failed, type=%{public}d status=%{public}d",
102             static_cast<int32_t>(type), status);
103         return napi_invalid_arg;
104     }
105 
106     size_t maxLen = STR_MAX_LENGTH;
107     status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen);
108     if (maxLen == 0) {
109         return status;
110     }
111     char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH];
112     if (buf != nullptr) {
113         size_t len = 0;
114         status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
115         if (status == napi_ok) {
116             buf[len] = 0;
117             out = std::string(buf);
118         }
119         delete[] buf;
120     } else {
121         status = napi_generic_failure;
122     }
123     return status;
124 }
125 
SetValue(napi_env env,const std::string & in,napi_value & out)126 napi_status NapiDataUtils::SetValue(napi_env env, const std::string &in, napi_value &out)
127 {
128     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- std::string %{public}d", (int)in.length());
129     return napi_create_string_utf8(env, in.c_str(), in.size(), &out);
130 }
131 
132 /* napi_value <-> std::vector<std::string> */
GetValue(napi_env env,napi_value in,std::vector<std::string> & out)133 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::vector<std::string> &out)
134 {
135     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::vector<std::string>");
136     bool isArray = false;
137     napi_is_array(env, in, &isArray);
138     if (!isArray) {
139         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "napi_value is not an array");
140         return napi_invalid_arg;
141     }
142 
143     uint32_t length = 0;
144     napi_status status = napi_get_array_length(env, in, &length);
145     if (!((status == napi_ok) && (length > 0))) {
146         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "get_array failed, status=%{public}d length=%{public}u",
147             status, length);
148         return napi_invalid_arg;
149     }
150     for (uint32_t i = 0; i < length; ++i) {
151         napi_value item = nullptr;
152         status = napi_get_element(env, in, i, &item);
153         if (!((item != nullptr) && (status == napi_ok))) {
154             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "napi_get_element failed, status=%{public}d", status);
155             return napi_invalid_arg;
156         }
157         std::string value;
158         status = GetValue(env, item, value);
159         if (status != napi_ok) {
160             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "napi_value is nota string, status=%{public}d", status);
161             return napi_invalid_arg;
162         }
163         out.push_back(value);
164     }
165     return status;
166 }
167 
SetValue(napi_env env,const std::vector<std::string> & in,napi_value & out)168 napi_status NapiDataUtils::SetValue(napi_env env, const std::vector<std::string> &in, napi_value &out)
169 {
170     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- std::vector<std::string>");
171     napi_status status = napi_create_array_with_length(env, in.size(), &out);
172     if (status != napi_ok) {
173         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "create array failed, status=%{public}d", status);
174         return status;
175     }
176     int index = 0;
177     for (auto &item : in) {
178         napi_value element = nullptr;
179         SetValue(env, item, element);
180         status = napi_set_element(env, out, index++, element);
181         if (status != napi_ok) {
182             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "napi_set_element failed, status=%{public}d", status);
183             return status;
184         }
185     }
186     return status;
187 }
188 
189 /* napi_value <-> std::vector<uint8_t> */
GetValue(napi_env env,napi_value in,std::vector<uint8_t> & out)190 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::vector<uint8_t> &out)
191 {
192     out.clear();
193     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::vector<uint8_t> ");
194     napi_typedarray_type type = napi_biguint64_array;
195     size_t length = 0;
196     napi_value buffer = nullptr;
197     size_t offset = 0;
198     void *data = nullptr;
199     napi_status status = napi_get_typedarray_info(env, in, &type, &length, &data, &buffer, &offset);
200     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI,
201         "array type=%{public}d length=%{public}d offset=%{public}d  status=%{public}d",
202         (int)type, (int)length, (int)offset, status);
203     if (!((status == napi_ok) && (length > 0) && (type == napi_uint8_array) && (data != nullptr))) {
204         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI,
205             "array type=%{public}d length=%{public}d status=%{public}d",
206             static_cast<int32_t>(type), static_cast<int32_t>(length), status);
207         return napi_invalid_arg;
208     }
209     out.assign(reinterpret_cast<uint8_t *>(data), reinterpret_cast<uint8_t *>(data) + length);
210     return status;
211 }
212 
SetValue(napi_env env,const std::vector<uint8_t> & in,napi_value & out)213 napi_status NapiDataUtils::SetValue(napi_env env, const std::vector<uint8_t> &in, napi_value &out)
214 {
215     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- std::vector<uint8_t> ");
216     if (in.size() <= 0) {
217         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "invalid std::vector<uint8_t>");
218         return napi_invalid_arg;
219     }
220     void *data = nullptr;
221     napi_value buffer = nullptr;
222     napi_status status = napi_create_arraybuffer(env, in.size(), &data, &buffer);
223     if (status != napi_ok) {
224         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "create array buffer failed, status=%{public}d", status);
225         return status;
226     }
227 
228     if (memcpy_s(data, in.size(), in.data(), in.size()) != EOK) {
229         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "memcpy_s not EOK");
230         return napi_invalid_arg;
231     }
232     status = napi_create_typedarray(env, napi_uint8_array, in.size(), buffer, 0, &out);
233     if (status != napi_ok) {
234         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI,
235             "napi_value <- std::vector<uint8_t> invalid value, status=%{public}d", status);
236         return status;
237     }
238     return status;
239 }
240 
241 /* napi_value <-> std::map<std::string, int32_t> */
GetValue(napi_env env,napi_value in,std::map<std::string,int32_t> & out)242 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::map<std::string, int32_t> &out)
243 {
244     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::map<std::string, int32_t> ");
245     (void)(env);
246     (void)(in);
247     (void)(out);
248     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "std::map<std::string, uint32_t> from napi_value, unsupported!");
249     return napi_invalid_arg;
250 }
251 
SetValue(napi_env env,const std::map<std::string,int32_t> & in,napi_value & out)252 napi_status NapiDataUtils::SetValue(napi_env env, const std::map<std::string, int32_t> &in, napi_value &out)
253 {
254     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- std::map<std::string, int32_t> ");
255     napi_status status = napi_create_array_with_length(env, in.size(), &out);
256     if (status != napi_ok) {
257         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "invalid object, status=%{public}d", status);
258         return status;
259     }
260     int index = 0;
261     for (const auto &[key, value] : in) {
262         napi_value element = nullptr;
263         napi_create_array_with_length(env, TUPLE_SIZE, &element);
264         napi_value jsKey = nullptr;
265         napi_create_string_utf8(env, key.c_str(), key.size(), &jsKey);
266         napi_set_element(env, element, TUPLE_KEY, jsKey);
267         napi_value jsValue = nullptr;
268         napi_create_int32(env, static_cast<int32_t>(value), &jsValue);
269         napi_set_element(env, element, TUPLE_VALUE, jsValue);
270         napi_set_element(env, out, index++, element);
271     }
272     return status;
273 }
274 
275 /* napi_value <-> std::map<std::string, int64_t> */
GetValue(napi_env env,napi_value in,std::map<std::string,int64_t> & out)276 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::map<std::string, int64_t> &out)
277 {
278     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::map<std::string, int64_t> ");
279     (void)(env);
280     (void)(in);
281     (void)(out);
282     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "std::map<std::string, int64_t> from napi_value, unsupported!");
283     return napi_invalid_arg;
284 }
285 
SetValue(napi_env env,const std::map<std::string,int64_t> & in,napi_value & out)286 napi_status NapiDataUtils::SetValue(napi_env env, const std::map<std::string, int64_t> &in, napi_value &out)
287 {
288     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- std::map<std::string, int64_t> ");
289     napi_status status = napi_create_array_with_length(env, in.size(), &out);
290     if (status != napi_ok) {
291         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "invalid object, status=%{public}d", status);
292         return status;
293     }
294     int index = 0;
295     for (const auto &[key, value] : in) {
296         napi_value element = nullptr;
297         napi_create_array_with_length(env, TUPLE_SIZE, &element);
298         napi_value jsKey = nullptr;
299         napi_create_string_utf8(env, key.c_str(), key.size(), &jsKey);
300         napi_set_element(env, element, TUPLE_KEY, jsKey);
301         napi_value jsValue = nullptr;
302         napi_create_int64(env, static_cast<int64_t>(value), &jsValue);
303         napi_set_element(env, element, TUPLE_VALUE, jsValue);
304         napi_set_element(env, out, index++, element);
305     }
306     return status;
307 }
308 
GetValue(napi_env env,napi_value in,std::shared_ptr<OHOS::Media::PixelMap> & pixelMap)309 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
310 {
311     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::shared_ptr<OHOS::Media::PixelMap>");
312     pixelMap = OHOS::Media::PixelMapNapi::GetPixelMap(env, in);
313     return napi_ok;
314 }
315 
SetValue(napi_env env,const std::shared_ptr<OHOS::Media::PixelMap> & in,napi_value & out)316 napi_status NapiDataUtils::SetValue(napi_env env, const std::shared_ptr<OHOS::Media::PixelMap> &in, napi_value &out)
317 {
318     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- std::shared_ptr<OHOS::Media::PixelMap>");
319     out = OHOS::Media::PixelMapNapi::CreatePixelMap(env, in);
320     return napi_ok;
321 }
322 
GetValue(napi_env env,napi_value in,std::shared_ptr<OHOS::AAFwk::Want> & wantPtr)323 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::shared_ptr<OHOS::AAFwk::Want> &wantPtr)
324 {
325     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::shared_ptr<OHOS::AAFwk::Want>");
326     OHOS::AAFwk::Want want;
327     AppExecFwk::UnwrapWant(env, in, want);
328     wantPtr = std::make_shared<OHOS::AAFwk::Want>(want);
329     return napi_ok;
330 }
331 
SetValue(napi_env env,const std::shared_ptr<OHOS::AAFwk::Want> & in,napi_value & out)332 napi_status NapiDataUtils::SetValue(napi_env env, const std::shared_ptr<OHOS::AAFwk::Want> &in, napi_value &out)
333 {
334     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- std::shared_ptr<OHOS::AAFwk::Want>");
335     out = OHOS::AppExecFwk::WrapWant(env, *in);
336     return napi_ok;
337 }
338 
GetValue(napi_env env,napi_value in,std::shared_ptr<UDMF::Object> & object)339 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::shared_ptr<UDMF::Object> &object)
340 {
341     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::GetValue Object");
342     napi_value attributeNames = nullptr;
343     NAPI_CALL_BASE(env, napi_get_property_names(env, in, &attributeNames), napi_invalid_arg);
344     uint32_t attributesNum = 0;
345     NAPI_CALL_BASE(env, napi_get_array_length(env, attributeNames, &attributesNum), napi_invalid_arg);
346     for (uint32_t i = 0; i < attributesNum; i++) {
347         napi_value attributeNameNapi = nullptr;
348         NAPI_CALL_BASE(env, napi_get_element(env, attributeNames, i, &attributeNameNapi), napi_invalid_arg);
349         size_t len = 0;
350         char str[STR_MAX_SIZE] = { 0 };
351         NAPI_CALL_BASE(env, napi_get_value_string_utf8(
352             env, attributeNameNapi, str, STR_MAX_SIZE, &len), napi_invalid_arg);
353         std::string attributeName = str;
354         napi_value attributeValueNapi = nullptr;
355         NAPI_CALL_BASE(env, napi_get_named_property(env, in, str, &attributeValueNapi), napi_invalid_arg);
356 
357         bool isArrayBuffer = false;
358         NAPI_CALL_BASE(env, napi_is_arraybuffer(env, attributeValueNapi, &isArrayBuffer), napi_invalid_arg);
359         if (isArrayBuffer) {
360             void *data = nullptr;
361             size_t dataLen = 0;
362             NAPI_CALL_BASE(env, napi_get_arraybuffer_info(env, attributeValueNapi, &data, &dataLen), napi_invalid_arg);
363             object->value_[attributeName] = std::vector<uint8_t>(
364                 reinterpret_cast<uint8_t *>(data), reinterpret_cast<uint8_t *>(data) + dataLen);
365             continue;
366         }
367         napi_valuetype valueType = napi_undefined;
368         NAPI_CALL_BASE(env, napi_typeof(env, attributeValueNapi, &valueType), napi_invalid_arg);
369         switch (valueType) {
370             case napi_valuetype::napi_object:
371                 object->value_[attributeName] = std::make_shared<UDMF::Object>();
372                 break;
373             case napi_valuetype::napi_number:
374                 object->value_[attributeName] = double();
375                 break;
376             case napi_valuetype::napi_string:
377                 object->value_[attributeName] = std::string();
378                 break;
379             case napi_valuetype::napi_boolean:
380                 object->value_[attributeName] = bool();
381                 break;
382             case napi_valuetype::napi_undefined:
383                 object->value_[attributeName] = std::monostate();
384                 break;
385             case napi_valuetype::napi_null:
386                 object->value_[attributeName] = nullptr;
387                 break;
388             default:
389                 return napi_invalid_arg;
390         }
391         napi_status status = napi_ok;
392         std::visit([&](auto &value) {status = NapiDataUtils::GetValue(env, attributeValueNapi, value);},
393             object->value_[attributeName]);
394         if (status != napi_ok) {
395             return status;
396         }
397     }
398     return napi_ok;
399 }
400 
SetValue(napi_env env,const std::shared_ptr<UDMF::Object> & object,napi_value & out)401 napi_status NapiDataUtils::SetValue(napi_env env, const std::shared_ptr<UDMF::Object> &object, napi_value &out)
402 {
403     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::GetValue Object");
404     napi_create_object(env, &out);
405     for (auto &[key, value] : object->value_) {
406         napi_value valueNapi = nullptr;
407         if (std::holds_alternative<std::vector<uint8_t>>(value)) {
408             auto array = std::get<std::vector<uint8_t>>(value);
409             void *data = nullptr;
410             size_t len = array.size();
411             NAPI_CALL_BASE(env, napi_create_arraybuffer(env, len, &data, &valueNapi), napi_generic_failure);
412             if (memcpy_s(data, len, reinterpret_cast<const void *>(array.data()), len) != 0) {
413                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "memcpy_s failed");
414                 return napi_generic_failure;
415             }
416         } else {
417             std::visit([&](const auto &value) {NapiDataUtils::SetValue(env, value, valueNapi);}, value);
418         }
419         napi_set_named_property(env, out, key.c_str(), valueNapi);
420     }
421     return napi_ok;
422 }
423 
GetValue(napi_env env,napi_value in,std::monostate & out)424 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::monostate &out)
425 {
426     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> std::monostate");
427     out = std::monostate{};
428     return napi_ok;
429 }
430 
SetValue(napi_env env,const std::monostate & in,napi_value & out)431 napi_status NapiDataUtils::SetValue(napi_env env, const std::monostate &in, napi_value &out)
432 {
433     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- std::monostate");
434     return napi_get_undefined(env, &out);
435 }
436 
GetValue(napi_env env,napi_value in,nullptr_t & out)437 napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, nullptr_t &out)
438 {
439     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value -> null");
440     out = nullptr;
441     return napi_ok;
442 }
443 
SetValue(napi_env env,const nullptr_t & in,napi_value & out)444 napi_status NapiDataUtils::SetValue(napi_env env, const nullptr_t &in, napi_value &out)
445 {
446     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_value <- null");
447     return napi_get_null(env, &out);
448 }
449 
IsTypeForNapiValue(napi_env env,napi_value param,napi_valuetype expectType)450 bool NapiDataUtils::IsTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType)
451 {
452     napi_valuetype valueType = napi_undefined;
453 
454     if (param == nullptr) {
455         return false;
456     }
457 
458     if (napi_typeof(env, param, &valueType) != napi_ok) {
459         return false;
460     }
461 
462     return valueType == expectType;
463 }
464 
IsNull(napi_env env,napi_value value)465 bool NapiDataUtils::IsNull(napi_env env, napi_value value)
466 {
467     napi_valuetype type = napi_undefined;
468     napi_status status = napi_typeof(env, value, &type);
469     if (status == napi_ok && (type == napi_undefined || type == napi_null)) {
470         return true;
471     }
472     if (type == napi_string) {
473         size_t len;
474         napi_get_value_string_utf8(env, value, NULL, 0, &len);
475         return len == 0;
476     }
477     return false;
478 }
479 
DefineClass(napi_env env,const std::string & name,const napi_property_descriptor * properties,size_t count,napi_callback newcb)480 napi_value NapiDataUtils::DefineClass(napi_env env, const std::string &name,
481     const napi_property_descriptor *properties, size_t count, napi_callback newcb)
482 {
483     // base64("data.udmf") as rootPropName, i.e. global.<root>
484     const std::string rootPropName = "ZGF0YS51ZG1m";
485     napi_value root = nullptr;
486     bool hasRoot = false;
487     napi_value global = nullptr;
488     napi_get_global(env, &global);
489     napi_has_named_property(env, global, rootPropName.c_str(), &hasRoot);
490     if (hasRoot) {
491         napi_get_named_property(env, global, rootPropName.c_str(), &root);
492     } else {
493         napi_create_object(env, &root);
494         napi_set_named_property(env, global, rootPropName.c_str(), root);
495     }
496 
497     std::string propName = "constructor_of_" + name;
498     napi_value constructor = nullptr;
499     bool hasProp = false;
500     napi_has_named_property(env, root, propName.c_str(), &hasProp);
501     if (hasProp) {
502         napi_get_named_property(env, root, propName.c_str(), &constructor);
503         if (constructor != nullptr) {
504             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI,
505                 "got data.distributeddata.%{public}s as constructor", propName.c_str());
506             return constructor;
507         }
508         hasProp = false; // no constructor.
509     }
510 
511     NAPI_CALL_BASE(env,
512         napi_define_class(env, name.c_str(), name.size(), newcb, nullptr, count, properties, &constructor),
513         nullptr);
514     NAPI_ASSERT(env, constructor != nullptr, "napi_define_class failed!");
515 
516     if (!hasProp) {
517         napi_set_named_property(env, root, propName.c_str(), constructor);
518         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI,
519             "save constructor to data.distributeddata.%{public}s", propName.c_str());
520     }
521     return constructor;
522 }
523 } // namespace MiscServicesNapi
524 } // namespace OHOS
525