1 /*
2  * Copyright (c) 2022 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_helper.h"
17 
18 #include "native_engine/native_value.h"
19 #include "object_helper.h"
20 
21 namespace Commonlibrary::Concurrent::Common::Helper {
22 static constexpr uint32_t MAX_CHAR_LENGTH = 1024;
23 
IsTypeForNapiValue(napi_env env,napi_value param,napi_valuetype expectType)24 bool NapiHelper::IsTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType)
25 {
26     napi_valuetype valueType = napi_undefined;
27     if (param == nullptr) {
28         return false;
29     }
30     if (napi_typeof(env, param, &valueType) != napi_ok) {
31         return false;
32     }
33 
34     return valueType == expectType;
35 }
36 
IsString(napi_env env,napi_value value)37 bool NapiHelper::IsString(napi_env env, napi_value value)
38 {
39     return IsTypeForNapiValue(env, value, napi_string);
40 }
41 
IsNotUndefined(napi_env env,napi_value value)42 bool NapiHelper::IsNotUndefined(napi_env env, napi_value value)
43 {
44     if (value == nullptr) {
45         return false;
46     }
47     napi_valuetype valueType = napi_undefined;
48     if (napi_typeof(env, value, &valueType) != napi_ok) {
49         return false;
50     }
51 
52     return valueType != napi_undefined;
53 }
54 
IsArray(napi_env env,napi_value value)55 bool NapiHelper::IsArray(napi_env env, napi_value value)
56 {
57     bool isArray = false;
58     if (value == nullptr) {
59         return false;
60     }
61     if (napi_is_array(env, value, &isArray) != napi_ok) {
62         return false;
63     }
64 
65     return isArray;
66 }
67 
IsFunction(napi_env env,napi_value object)68 bool NapiHelper::IsFunction(napi_env env, napi_value object)
69 {
70     return IsTypeForNapiValue(env, object, napi_function);
71 }
72 
IsArrayBuffer(napi_env env,napi_value value)73 bool NapiHelper::IsArrayBuffer(napi_env env, napi_value value)
74 {
75     bool result = false;
76     if (value == nullptr) {
77         return false;
78     }
79     if (napi_is_arraybuffer(env, value, &result) != napi_ok) {
80         return false;
81     }
82 
83     return result;
84 }
85 
IsBitVector(napi_env env,napi_value value)86 bool NapiHelper::IsBitVector(napi_env env, napi_value value)
87 {
88     bool result = false;
89     if (value == nullptr) {
90         return false;
91     }
92     if (napi_is_bitvector(env, value, &result) != napi_ok) {
93         return false;
94     }
95 
96     return result;
97 }
98 
IsNumber(napi_env env,napi_value value)99 bool NapiHelper::IsNumber(napi_env env, napi_value value)
100 {
101     return IsTypeForNapiValue(env, value, napi_number);
102 }
103 
GetCallbackInfoArgc(napi_env env,napi_callback_info cbInfo)104 size_t NapiHelper::GetCallbackInfoArgc(napi_env env, napi_callback_info cbInfo)
105 {
106     size_t argc = 0;
107     napi_get_cb_info(env, cbInfo, &argc, nullptr, nullptr, nullptr);
108     return argc;
109 }
110 
GetNamePropertyInParentPort(napi_env env,napi_ref parentPort,const char * name)111 napi_value NapiHelper::GetNamePropertyInParentPort(napi_env env, napi_ref parentPort, const char* name)
112 {
113     napi_value obj = nullptr;
114     napi_get_reference_value(env, parentPort, &obj);
115 
116     napi_value value = nullptr;
117     napi_get_named_property(env, obj, name, &value);
118 
119     return value;
120 }
121 
GetUndefinedValue(napi_env env)122 napi_value NapiHelper::GetUndefinedValue(napi_env env)
123 {
124     napi_value result = nullptr;
125     napi_get_undefined(env, &result);
126     return result;
127 }
128 
IsCallable(napi_env env,napi_value value)129 bool NapiHelper::IsCallable(napi_env env, napi_value value)
130 {
131     bool result = false;
132     napi_is_callable(env, value, &result);
133     return result;
134 }
135 
IsCallable(napi_env env,napi_ref value)136 bool NapiHelper::IsCallable(napi_env env, napi_ref value)
137 {
138     napi_value obj = nullptr;
139     napi_get_reference_value(env, value, &obj);
140     if (obj == nullptr) {
141         return false;
142     }
143     return IsCallable(env, obj);
144 }
145 
IsAsyncFunction(napi_env env,napi_value value)146 bool NapiHelper::IsAsyncFunction(napi_env env, napi_value value)
147 {
148     bool res = false;
149     napi_is_async_function(env, value, &res);
150     return res;
151 }
152 
IsConcurrentFunction(napi_env env,napi_value value)153 bool NapiHelper::IsConcurrentFunction(napi_env env, napi_value value)
154 {
155     bool res = false;
156     napi_is_concurrent_function(env, value, &res);
157     return res;
158 }
159 
IsGeneratorFunction(napi_env env,napi_value value)160 bool NapiHelper::IsGeneratorFunction(napi_env env, napi_value value)
161 {
162     bool res = false;
163     napi_is_generator_function(env, value, &res);
164     return res;
165 }
166 
IsStrictEqual(napi_env env,napi_value lhs,napi_value rhs)167 bool NapiHelper::IsStrictEqual(napi_env env, napi_value lhs, napi_value rhs)
168 {
169     bool res = false;
170     napi_strict_equals(env, lhs, rhs, &res);
171     return res;
172 }
173 
IsSendable(napi_env env,napi_value value)174 bool NapiHelper::IsSendable(napi_env env, napi_value value)
175 {
176     bool res = false;
177     napi_is_sendable(env, value, &res);
178     return res;
179 }
180 
SetNamePropertyInGlobal(napi_env env,const char * name,napi_value value)181 void NapiHelper::SetNamePropertyInGlobal(napi_env env, const char* name, napi_value value)
182 {
183     napi_value object = nullptr;
184     napi_get_global(env, &object);
185     napi_set_named_property(env, object, name, value);
186 }
187 
IsObject(napi_env env,napi_value value)188 bool NapiHelper::IsObject(napi_env env, napi_value value)
189 {
190     return IsTypeForNapiValue(env, value, napi_object);
191 }
192 
GetChars(napi_env env,napi_value value)193 char* NapiHelper::GetChars(napi_env env, napi_value value)
194 {
195     size_t bufferSize = 0;
196     size_t strLength = 0;
197     napi_get_value_string_utf8(env, value, nullptr, 0, &bufferSize);
198     if (bufferSize > MAX_CHAR_LENGTH) {
199         bufferSize = MAX_CHAR_LENGTH;
200     }
201     char* buffer = new char[bufferSize + 1] { 0 };
202     napi_get_value_string_utf8(env, value, buffer, bufferSize + 1, &strLength);
203     return buffer;
204 }
205 
GetString(napi_env env,napi_value value)206 std::string NapiHelper::GetString(napi_env env, napi_value value)
207 {
208     std::string str = "";
209     char* buffer = GetChars(env, value);
210     if (buffer == nullptr) {
211         return str;
212     }
213     str = std::string(buffer);
214     CloseHelp::DeletePointer(buffer, true);
215     return str;
216 }
217 
CreateBooleanValue(napi_env env,bool value)218 napi_value NapiHelper::CreateBooleanValue(napi_env env, bool value)
219 {
220     napi_value result = nullptr;
221     napi_get_boolean(env, value, &result);
222     return result;
223 }
224 
GetGlobalObject(napi_env env)225 napi_value NapiHelper::GetGlobalObject(napi_env env)
226 {
227     napi_value object = nullptr;
228     napi_get_global(env, &object);
229     return object;
230 }
231 
CreateReference(napi_env env,napi_value value,uint32_t refcount)232 napi_ref NapiHelper::CreateReference(napi_env env, napi_value value, uint32_t refcount)
233 {
234     napi_ref callback = nullptr;
235     napi_create_reference(env, value, refcount, &callback);
236     return callback;
237 }
238 
CreateUint32(napi_env env,uint32_t value)239 napi_value NapiHelper::CreateUint32(napi_env env, uint32_t value)
240 {
241     napi_value result = nullptr;
242     napi_create_uint32(env, value, &result);
243     return result;
244 }
245 
GetLibUV(napi_env env)246 uv_loop_t* NapiHelper::GetLibUV(napi_env env)
247 {
248     uv_loop_t* loop;
249     napi_get_uv_event_loop(env, &loop);
250     return loop;
251 }
252 
GetReferenceValue(napi_env env,napi_ref ref)253 napi_value NapiHelper::GetReferenceValue(napi_env env, napi_ref ref)
254 {
255     napi_value result = nullptr;
256     napi_get_reference_value(env, ref, &result);
257     return result;
258 }
259 
DeleteReference(napi_env env,napi_ref ref)260 void NapiHelper::DeleteReference(napi_env env, napi_ref ref)
261 {
262     napi_delete_reference(env, ref);
263 }
264 
GetNameProperty(napi_env env,napi_value obj,const char * name)265 napi_value NapiHelper::GetNameProperty(napi_env env, napi_value obj, const char* name)
266 {
267     napi_value result = nullptr;
268     napi_get_named_property(env, obj, name, &result);
269     return result;
270 }
271 
HasNameProperty(napi_env env,napi_value obj,const char * name)272 bool NapiHelper::HasNameProperty(napi_env env, napi_value obj, const char* name)
273 {
274     bool result = false;
275     napi_has_named_property(env, obj, name, &result);
276     return result;
277 }
278 
GetBooleanValue(napi_env env,napi_value value)279 bool NapiHelper::GetBooleanValue(napi_env env, napi_value value)
280 {
281     bool result = false;
282     napi_get_value_bool(env, value, &result);
283     return result;
284 }
285 
StrictEqual(napi_env env,napi_value value,napi_value cmpValue)286 bool NapiHelper::StrictEqual(napi_env env, napi_value value, napi_value cmpValue)
287 {
288     bool isEqual = false;
289     napi_strict_equals(env, value, cmpValue, &isEqual);
290     return isEqual;
291 }
292 
GetConstructorName(napi_env env,napi_value object)293 std::string NapiHelper::GetConstructorName(napi_env env, napi_value object)
294 {
295     while (IsNotUndefined(env, object)) {
296         napi_value func = nullptr;
297         napi_get_own_property_descriptor(env, object, "constructor", &func);
298         bool isInstanceof = false;
299         napi_instanceof(env, object, func, &isInstanceof);
300         if (IsNotUndefined(env, func) && isInstanceof) {
301             napi_value ctorName = nullptr;
302             napi_get_own_property_descriptor(env, func, "name", &ctorName);
303             std::string name = GetPrintString(env, ctorName);
304             if (name.size() > 0) {
305                 return name;
306             }
307         }
308         napi_value result = nullptr;
309         napi_get_prototype(env, object, &result);
310         object = result;
311     }
312     return "";
313 }
314 
CreateObject(napi_env env)315 napi_value NapiHelper::CreateObject(napi_env env)
316 {
317     napi_value obj = nullptr;
318     napi_create_object(env, &obj);
319     return obj;
320 }
321 
CreatePromise(napi_env env,napi_deferred * deferred)322 napi_value NapiHelper::CreatePromise(napi_env env, napi_deferred* deferred)
323 {
324     napi_value promise = nullptr;
325     napi_create_promise(env, deferred, &promise);
326     return promise;
327 }
328 
CreateEmptyString(napi_env env)329 napi_value NapiHelper::CreateEmptyString(napi_env env)
330 {
331     napi_value str = nullptr;
332     const char* name = "";
333     napi_create_string_utf8(env, name, 0, &str);
334     return str;
335 }
336 
GetArrayLength(napi_env env,napi_value array)337 uint32_t NapiHelper::GetArrayLength(napi_env env, napi_value array)
338 {
339     uint32_t arrayLength = 0;
340     napi_get_array_length(env, array, &arrayLength);
341     return arrayLength;
342 }
343 
GetUint32Value(napi_env env,napi_value value)344 uint32_t NapiHelper::GetUint32Value(napi_env env, napi_value value)
345 {
346     uint32_t result = 0;
347     napi_get_value_uint32(env, value, &result);
348     return result;
349 }
350 
GetInt32Value(napi_env env,napi_value value)351 int32_t NapiHelper::GetInt32Value(napi_env env, napi_value value)
352 {
353     int32_t result = 0;
354     napi_get_value_int32(env, value, &result);
355     return result;
356 }
357 
IsExceptionPending(napi_env env)358 bool NapiHelper::IsExceptionPending(napi_env env)
359 {
360     bool isExceptionPending = false;
361     napi_is_exception_pending(env, &isExceptionPending);
362     return isExceptionPending;
363 }
364 
GetPrintString(napi_env env,napi_value value)365 std::string NapiHelper::GetPrintString(napi_env env, napi_value value)
366 {
367     std::string str;
368     if (!IsTypeForNapiValue(env, value, napi_string)) {
369         napi_value strValue = nullptr;
370         if (napi_coerce_to_string(env, value, &strValue) != napi_ok) {
371             return str;
372         }
373         value = strValue;
374     }
375     napi_get_print_string(env, value, str);
376     return str;
377 }
378 
CreateUint64(napi_env env,uint64_t value)379 napi_value NapiHelper::CreateUint64(napi_env env, uint64_t value)
380 {
381     napi_value result;
382     napi_create_bigint_uint64(env, value, &result);
383     return result;
384 }
385 
GetUint64Value(napi_env env,napi_value value,bool lossless)386 uint64_t NapiHelper::GetUint64Value(napi_env env, napi_value value, bool lossless)
387 {
388     uint64_t result = 0;
389     napi_get_value_bigint_uint64(env, value, &result, &lossless);
390     return result;
391 }
392 
GetElement(napi_env env,napi_value value,uint32_t index)393 napi_value NapiHelper::GetElement(napi_env env, napi_value value, uint32_t index)
394 {
395     napi_value result;
396     napi_get_element(env, value, index, &result);
397     return result;
398 }
399 
CreateArrayWithLength(napi_env env,size_t length)400 napi_value NapiHelper::CreateArrayWithLength(napi_env env, size_t length)
401 {
402     napi_value argsArray;
403     napi_create_array_with_length(env, length, &argsArray);
404     return argsArray;
405 }
406 } // namespace Commonlibrary::Concurrent::Common::Helper