• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "napi_util.h"
16 
17 #include "hiappevent_base.h"
18 #include "hilog/log.h"
19 
20 namespace OHOS {
21 namespace HiviewDFX {
22 namespace NapiUtil {
23 namespace {
24 constexpr HiLogLabel LABEL = { LOG_CORE, HIAPPEVENT_DOMAIN, "HiAppEvent_NapiUtil" };
25 }
26 
IsNull(const napi_env env,const napi_value value)27 bool IsNull(const napi_env env, const napi_value value)
28 {
29     return GetType(env, value) == napi_null;
30 }
31 
IsBoolean(const napi_env env,const napi_value value)32 bool IsBoolean(const napi_env env, const napi_value value)
33 {
34     return GetType(env, value) == napi_boolean;
35 }
36 
IsNumber(const napi_env env,const napi_value value)37 bool IsNumber(const napi_env env, const napi_value value)
38 {
39     return GetType(env, value) == napi_number;
40 }
41 
IsString(const napi_env env,const napi_value value)42 bool IsString(const napi_env env, const napi_value value)
43 {
44     return GetType(env, value) == napi_string;
45 }
46 
IsObject(const napi_env env,const napi_value value)47 bool IsObject(const napi_env env, const napi_value value)
48 {
49     return GetType(env, value) == napi_object;
50 }
51 
IsFunction(const napi_env env,const napi_value value)52 bool IsFunction(const napi_env env, const napi_value value)
53 {
54     return GetType(env, value) == napi_function;
55 }
56 
IsArray(const napi_env env,const napi_value value)57 bool IsArray(const napi_env env, const napi_value value)
58 {
59     bool result = false;
60     if (napi_is_array(env, value, &result) != napi_ok) {
61         HiLog::Error(LABEL, "failed to check array type");
62         return false;
63     }
64     return result;
65 }
66 
IsArrayType(const napi_env env,const napi_value value,napi_valuetype type)67 bool IsArrayType(const napi_env env, const napi_value value, napi_valuetype type)
68 {
69     if (!IsArray(env, value)) {
70         return false;
71     }
72     if (GetArrayLength(env, value) == 0) {
73         return true;
74     }
75     return GetArrayType(env, value) == type;
76 }
77 
GetType(const napi_env env,const napi_value value)78 napi_valuetype GetType(const napi_env env, const napi_value value)
79 {
80     napi_valuetype type;
81     if (napi_typeof(env, value, &type) != napi_ok) {
82         HiLog::Error(LABEL, "failed to get value type");
83         return napi_undefined;
84     }
85     return type;
86 }
87 
GetArrayType(const napi_env env,const napi_value arr)88 napi_valuetype GetArrayType(const napi_env env, const napi_value arr)
89 {
90     uint32_t result = 0;
91     if (napi_get_array_length(env, arr, &result) != napi_ok) {
92         HiLog::Error(LABEL, "failed to get the length of array");
93         return napi_undefined;
94     }
95 
96     napi_valuetype type = napi_null; // note: empty array returns null type
97     for (size_t i = 0; i < result; ++i) {
98         napi_value element = nullptr;
99         if (napi_get_element(env, arr, i, &element) != napi_ok) {
100             HiLog::Error(LABEL, "failed to get the element of array");
101             return napi_undefined;
102         }
103         if (i == 0) {
104             type = GetType(env, element);
105             continue;
106         }
107         if (type != GetType(env, element)) {
108             HiLog::Error(LABEL, "array has different element types");
109             return napi_undefined;
110         }
111     }
112     return type;
113 }
114 
GetArrayLength(const napi_env env,const napi_value arr)115 uint32_t GetArrayLength(const napi_env env, const napi_value arr)
116 {
117     uint32_t result = 0;
118     if (napi_get_array_length(env, arr, &result) != napi_ok) {
119         HiLog::Error(LABEL, "failed to get the length of array");
120         return 0;
121     }
122     return result;
123 }
124 
GetElement(const napi_env env,const napi_value arr,uint32_t index)125 napi_value GetElement(const napi_env env, const napi_value arr, uint32_t index)
126 {
127     napi_value element = nullptr;
128     if (napi_get_element(env, arr, index, &element) != napi_ok) {
129         HiLog::Error(LABEL, "failed to get the element of array.");
130         return nullptr;
131     }
132     return element;
133 }
134 
GetBoolean(const napi_env env,const napi_value value)135 bool GetBoolean(const napi_env env, const napi_value value)
136 {
137     bool bValue = false;
138     if (napi_get_value_bool(env, value, &bValue) != napi_ok) {
139         HiLog::Error(LABEL, "failed to get bool value");
140         return false;
141     }
142     return bValue;
143 }
144 
GetBooleans(const napi_env env,const napi_value arr,std::vector<bool> & bools)145 void GetBooleans(const napi_env env, const napi_value arr, std::vector<bool>& bools)
146 {
147     uint32_t len = GetArrayLength(env, arr);
148     for (size_t i = 0; i < len; ++i) {
149         napi_value element = GetElement(env, arr, i);
150         if (element == nullptr) {
151             continue;
152         }
153         bools.push_back(GetBoolean(env, element));
154     }
155 }
156 
GetInt32(const napi_env env,const napi_value value)157 int32_t GetInt32(const napi_env env, const napi_value value)
158 {
159     int32_t iValue = 0;
160     if (napi_get_value_int32(env, value, &iValue) != napi_ok) {
161         HiLog::Error(LABEL, "failed to get int32 value");
162         return 0;
163     }
164     return iValue;
165 }
166 
GetInt32s(const napi_env env,const napi_value arr,std::vector<int32_t> & ints)167 void GetInt32s(const napi_env env, const napi_value arr, std::vector<int32_t>& ints)
168 {
169     uint32_t len = GetArrayLength(env, arr);
170     for (size_t i = 0; i < len; ++i) {
171         napi_value element = GetElement(env, arr, i);
172         if (element == nullptr) {
173             continue;
174         }
175         ints.push_back(GetInt32(env, element));
176     }
177 }
178 
GetDouble(const napi_env env,const napi_value value)179 double GetDouble(const napi_env env, const napi_value value)
180 {
181     double dValue = 0;
182     if (napi_get_value_double(env, value, &dValue) != napi_ok) {
183         HiLog::Error(LABEL, "failed to get double value");
184         return 0;
185     }
186     return dValue;
187 }
188 
GetDoubles(const napi_env env,const napi_value arr,std::vector<double> & doubles)189 void GetDoubles(const napi_env env, const napi_value arr, std::vector<double>& doubles)
190 {
191     uint32_t len = GetArrayLength(env, arr);
192     for (size_t i = 0; i < len; ++i) {
193         napi_value element = GetElement(env, arr, i);
194         if (element == nullptr) {
195             continue;
196         }
197         doubles.push_back(GetDouble(env, element));
198     }
199 }
200 
GetString(const napi_env env,const napi_value value,size_t bufsize)201 std::string GetString(const napi_env env, const napi_value value, size_t bufsize)
202 {
203     char strValue[bufsize + 1]; // 1 for '\0'
204     size_t result = 0;
205     if (napi_get_value_string_utf8(env, value, strValue, bufsize, &result) != napi_ok) {
206         HiLog::Error(LABEL, "failed to get string value");
207         return "";
208     }
209     return strValue;
210 }
211 
GetStrings(const napi_env env,const napi_value arr,std::vector<std::string> & strs,size_t bufsize)212 void GetStrings(const napi_env env, const napi_value arr, std::vector<std::string>& strs, size_t bufsize)
213 {
214     uint32_t len = GetArrayLength(env, arr);
215     for (size_t i = 0; i < len; ++i) {
216         napi_value element = GetElement(env, arr, i);
217         if (element == nullptr) {
218             continue;
219         }
220         strs.push_back(GetString(env, element, bufsize));
221     }
222 }
223 
HasProperty(const napi_env env,const napi_value object,const std::string & name)224 bool HasProperty(const napi_env env, const napi_value object, const std::string& name)
225 {
226     bool result = false;
227     if (napi_has_named_property(env, object, name.c_str(), &result) != napi_ok) {
228         HiLog::Error(LABEL, "failed to check whether the object has the named property");
229         return false;
230     }
231     return result;
232 }
233 
GetProperty(const napi_env env,const napi_value object,const std::string & name)234 napi_value GetProperty(const napi_env env, const napi_value object, const std::string& name)
235 {
236     if (!HasProperty(env, object, name)) {
237         return nullptr;
238     }
239     napi_value value = nullptr;
240     if (napi_get_named_property(env, object, name.c_str(), &value) != napi_ok) {
241         HiLog::Error(LABEL, "failed to get property=%{public}s from object", name.c_str());
242         return nullptr;
243     }
244     return value;
245 }
246 
GetPropertyNames(const napi_env env,const napi_value object,std::vector<std::string> & names)247 void GetPropertyNames(const napi_env env, const napi_value object, std::vector<std::string>& names)
248 {
249     napi_value propertyNames = nullptr;
250     if (napi_get_property_names(env, object, &propertyNames) != napi_ok) {
251         HiLog::Error(LABEL, "failed to get property names.");
252         return;
253     }
254     uint32_t len = 0;
255     if (napi_get_array_length(env, propertyNames, &len) != napi_ok) {
256         HiLog::Error(LABEL, "failed to get array length");
257         return;
258     }
259     for (uint32_t i = 0; i < len; ++i) {
260         napi_value element = nullptr;
261         if (napi_get_element(env, propertyNames, i, &element) != napi_ok) {
262             HiLog::Error(LABEL, "failed to get the element of array");
263             continue;
264         }
265         names.push_back(GetString(env, element));
266     }
267 }
268 
GetReferenceValue(const napi_env env,const napi_ref funcRef)269 napi_value GetReferenceValue(const napi_env env, const napi_ref funcRef)
270 {
271     napi_value refValue = nullptr;
272     if (napi_get_reference_value(env, funcRef, &refValue) != napi_ok) {
273         HiLog::Error(LABEL, "failed to get reference value");
274         return nullptr;
275     }
276     return refValue;
277 }
278 
GetCbInfo(const napi_env env,napi_callback_info info,napi_value argv[],size_t argc)279 size_t GetCbInfo(const napi_env env, napi_callback_info info, napi_value argv[], size_t argc)
280 {
281     size_t paramNum = argc;
282     if (napi_get_cb_info(env, info, &paramNum, argv, nullptr, nullptr) != napi_ok) {
283         HiLog::Error(LABEL, "failed to get callback info");
284         return 0;
285     }
286     return paramNum;
287 }
288 
CreateReference(const napi_env env,const napi_value func)289 napi_ref CreateReference(const napi_env env, const napi_value func)
290 {
291     napi_ref ref = nullptr;
292     if (napi_create_reference(env, func, 1, &ref) != napi_ok) { // 1 means initial reference count
293         HiLog::Error(LABEL, "failed to create reference");
294         return nullptr;
295     }
296     return ref;
297 }
298 
CreateNull(const napi_env env)299 napi_value CreateNull(const napi_env env)
300 {
301     napi_value nullValue = nullptr;
302     if (napi_get_null(env, &nullValue) != napi_ok) {
303         HiLog::Error(LABEL, "failed to create null");
304         return nullptr;
305     }
306     return nullValue;
307 }
308 
CreateUndefined(const napi_env env)309 napi_value CreateUndefined(const napi_env env)
310 {
311     napi_value undefinedValue = nullptr;
312     if (napi_get_undefined(env, &undefinedValue) != napi_ok) {
313         HiLog::Error(LABEL, "failed to create undefined");
314         return nullptr;
315     }
316     return undefinedValue;
317 }
318 
CreateBoolean(const napi_env env,bool bValue)319 napi_value CreateBoolean(const napi_env env, bool bValue)
320 {
321     napi_value boolValue = nullptr;
322     if (napi_get_boolean(env, bValue, &boolValue) != napi_ok) {
323         HiLog::Error(LABEL, "failed to create boolean");
324         return nullptr;
325     }
326     return boolValue;
327 }
328 
CreateInt32(const napi_env env,int32_t num)329 napi_value CreateInt32(const napi_env env, int32_t num)
330 {
331     napi_value intValue = nullptr;
332     if (napi_create_int32(env, num, &intValue) != napi_ok) {
333         HiLog::Error(LABEL, "failed to create int32");
334         return nullptr;
335     }
336     return intValue;
337 }
338 
CreateString(const napi_env env,const std::string & str)339 napi_value CreateString(const napi_env env, const std::string& str)
340 {
341     napi_value strValue = nullptr;
342     if (napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &strValue) != napi_ok) {
343         HiLog::Error(LABEL, "failed to create string");
344         return nullptr;
345     }
346     return strValue;
347 }
348 
CreateStrings(const napi_env env,const std::vector<std::string> & strs)349 napi_value CreateStrings(const napi_env env, const std::vector<std::string>& strs)
350 {
351     napi_value arr = CreateArray(env);
352     for (size_t i = 0; i < strs.size(); ++i) {
353         SetElement(env, arr, i, CreateString(env, strs[i]));
354     }
355     return arr;
356 }
357 
CreateObject(const napi_env env)358 napi_value CreateObject(const napi_env env)
359 {
360     napi_value obj = nullptr;
361     if (napi_create_object(env, &obj) != napi_ok) {
362         HiLog::Error(LABEL, "failed to create object");
363         return nullptr;
364     }
365     return obj;
366 }
367 
CreateObject(const napi_env env,const std::string & key,const napi_value value)368 napi_value CreateObject(const napi_env env, const std::string& key, const napi_value value)
369 {
370     napi_value obj = nullptr;
371     if (napi_create_object(env, &obj) != napi_ok) {
372         HiLog::Error(LABEL, "failed to create object");
373         return nullptr;
374     }
375     if (napi_set_named_property(env, obj, key.c_str(), value) != napi_ok) {
376         HiLog::Error(LABEL, "failed to set property");
377         return nullptr;
378     }
379     return obj;
380 }
381 
CreateArray(const napi_env env)382 napi_value CreateArray(const napi_env env)
383 {
384     napi_value arr = nullptr;
385     if (napi_create_array(env, &arr) != napi_ok) {
386         HiLog::Error(LABEL, "failed to create array");
387         return nullptr;
388     }
389     return arr;
390 }
391 
SetElement(const napi_env env,const napi_value obj,uint32_t index,const napi_value value)392 void SetElement(const napi_env env, const napi_value obj, uint32_t index, const napi_value value)
393 {
394     if (napi_set_element(env, obj, index, value) != napi_ok) {
395         HiLog::Error(LABEL, "failed to set element");
396     }
397 }
398 
SetNamedProperty(const napi_env env,const napi_value obj,const std::string & key,const napi_value value)399 void SetNamedProperty(const napi_env env, const napi_value obj, const std::string& key, const napi_value value)
400 {
401     if (napi_set_named_property(env, obj, key.c_str(), value) != napi_ok) {
402         HiLog::Error(LABEL, "failed to set property");
403     }
404 }
405 
ConvertToString(const napi_env env,const napi_value value)406 std::string ConvertToString(const napi_env env, const napi_value value)
407 {
408     napi_valuetype type = GetType(env, value);
409     if (type == napi_undefined) {
410         return "";
411     }
412 
413     std::string result = "";
414     switch (type) {
415         case napi_boolean:
416             result = GetBoolean(env, value) ? "true" : "false";
417             break;
418         case napi_number:
419             result = std::to_string(GetDouble(env, value));
420             break;
421         case napi_string:
422             result = GetString(env, value);
423             break;
424         default:
425             break;
426     }
427     return result;
428 }
429 
ThrowError(napi_env env,int code,const std::string & msg,bool isThrow)430 void ThrowError(napi_env env, int code, const std::string& msg, bool isThrow)
431 {
432     // no error needs to be thrown before api 9
433     if (!isThrow) {
434         return;
435     }
436 
437     if (napi_throw_error(env, std::to_string(code).c_str(), msg.c_str()) != napi_ok) {
438         HiLog::Error(LABEL, "failed to throw error, code=%{public}d, msg=%{public}s", code, msg.c_str());
439     }
440 }
441 
CreateError(napi_env env,int code,const std::string & msg)442 napi_value CreateError(napi_env env, int code, const std::string& msg)
443 {
444     napi_value err = nullptr;
445     if (napi_create_error(env, CreateString(env, std::to_string(code)), CreateString(env, msg), &err) != napi_ok) {
446         HiLog::Error(LABEL, "failed to create error");
447         return nullptr;
448     }
449     return err;
450 }
451 
CreateErrMsg(const std::string & name)452 std::string CreateErrMsg(const std::string& name)
453 {
454     return "Parameter error. The " + name + " parameter is mandatory.";
455 }
456 
CreateErrMsg(const std::string & name,const std::string & type)457 std::string CreateErrMsg(const std::string& name, const std::string& type)
458 {
459     return "Parameter error. The type of " + name + " must be " + type + ".";
460 }
CreateErrMsg(const std::string & name,const napi_valuetype type)461 std::string CreateErrMsg(const std::string& name, const napi_valuetype type)
462 {
463     std::string typeStr = "";
464     switch (type) {
465         case napi_boolean:
466             typeStr = "boolean";
467             break;
468         case napi_number:
469             typeStr = "number";
470             break;
471         case napi_string:
472             typeStr = "string";
473             break;
474         case napi_object:
475             typeStr = "object";
476             break;
477         default:
478             break;
479     }
480     return CreateErrMsg(name, typeStr);
481 }
482 } // namespace NapiUtil
483 } // namespace HiviewDFX
484 } // namespace OHOS
485