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 
16 #include "ext_napi_utils.h"
17 
18 #include <cstddef>
19 
20 #include "napi/native_api.h"
21 #include "napi/native_node_api.h"
22 #include "securec.h"
23 
24 namespace OHOS::Ace {
25 
NapiAsyncEvent(napi_env env,napi_value callback)26 NapiAsyncEvent::NapiAsyncEvent(napi_env env, napi_value callback)
27 {
28     env_ = env;
29     napi_create_reference(env_, callback, 1, &ref_);
30 }
31 
~NapiAsyncEvent()32 NapiAsyncEvent::~NapiAsyncEvent()
33 {
34     napi_delete_reference(env_, ref_);
35 }
36 
Call(int32_t argc,napi_value * argv)37 napi_value NapiAsyncEvent::Call(int32_t argc, napi_value* argv)
38 {
39     napi_value result = nullptr;
40     napi_handle_scope scope;
41     napi_open_handle_scope(env_, &scope);
42     if (scope == nullptr) {
43         napi_close_handle_scope(env_, scope);
44         return result;
45     }
46     napi_value callback = nullptr;
47     napi_get_reference_value(env_, ref_, &callback);
48     napi_value undefined = nullptr;
49     napi_get_undefined(env_, &undefined);
50     napi_call_function(env_, undefined, callback, argc, argv, &result);
51     napi_close_handle_scope(env_, scope);
52     return result;
53 }
54 
GetEnv()55 napi_env NapiAsyncEvent::GetEnv()
56 {
57     return env_;
58 }
59 
CreateInt32(napi_env env,int32_t code)60 napi_value ExtNapiUtils::CreateInt32(napi_env env, int32_t code)
61 {
62     napi_value value = nullptr;
63     if (napi_create_int32(env, code, &value) != napi_ok) {
64         return nullptr;
65     }
66     return value;
67 }
68 
GetCInt32(napi_env env,napi_value value)69 int32_t ExtNapiUtils::GetCInt32(napi_env env, napi_value value)
70 {
71     int32_t num = 0;
72     napi_get_value_int32(env, value, &num);
73     return num;
74 }
75 
GetCInt64(napi_env env,napi_value value)76 int64_t ExtNapiUtils::GetCInt64(napi_env env, napi_value value)
77 {
78     int64_t num = 0;
79     napi_get_value_int64(env, value, &num);
80     return num;
81 }
82 
CreateNull(napi_env env)83 napi_value ExtNapiUtils::CreateNull(napi_env env)
84 {
85     napi_value jsNull = nullptr;
86     NAPI_CALL(env, napi_get_null(env, &jsNull));
87     return jsNull;
88 }
89 
GetBool(napi_env env,napi_value value)90 bool ExtNapiUtils::GetBool(napi_env env, napi_value value)
91 {
92     bool boolValue = false;
93     napi_status ret = napi_get_value_bool(env, value, &boolValue);
94     if (ret == napi_ok) {
95         return boolValue;
96     }
97     return false;
98 }
99 
GetValueType(napi_env env,napi_value value)100 napi_valuetype ExtNapiUtils::GetValueType(napi_env env, napi_value value)
101 {
102     if (value == nullptr) {
103         return napi_undefined;
104     }
105 
106     napi_valuetype valueType = napi_undefined;
107     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
108     return valueType;
109 }
110 
GetStringFromValueUtf8(napi_env env,napi_value value)111 std::string ExtNapiUtils::GetStringFromValueUtf8(napi_env env, napi_value value)
112 {
113     static constexpr size_t max_length = 2048;
114     if (GetValueType(env, value) != napi_string) {
115         return {};
116     }
117 
118     std::string result;
119     size_t stringLength = 0;
120     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, nullptr, 0, &stringLength), result);
121     if (stringLength == 0 || stringLength > max_length) {
122         return result;
123     }
124 
125     auto deleter = [](char* s) { free(reinterpret_cast<void*>(s)); };
126     char* strTmp = static_cast<char*>(malloc(stringLength + 1));
127     if (strTmp == nullptr) {
128         return result;
129     }
130     std::unique_ptr<char, decltype(deleter)> str(strTmp, deleter);
131     if (memset_s(str.get(), stringLength + 1, 0, stringLength + 1) != EOK) {
132         return result;
133     }
134     size_t length = 0;
135     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, str.get(), stringLength + 1, &length), result);
136     if (length > 0) {
137         result.append(str.get(), length);
138     }
139     return result;
140 }
141 
CheckTypeForNapiValue(napi_env env,napi_value param,napi_valuetype expectType)142 bool ExtNapiUtils::CheckTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType)
143 {
144     napi_valuetype valueType = napi_undefined;
145 
146     if (napi_typeof(env, param, &valueType) != napi_ok) {
147         return false;
148     }
149 
150     return valueType == expectType;
151 }
152 }
153