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