1 /*
2 * Copyright (c) 2021 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 "n_val.h"
17
18 #include <sstream>
19 #include <string>
20
21 namespace OHOS {
22 namespace HiviewDFX {
23 using namespace std;
24
NVal(napi_env nEnv,napi_value nVal=nullptr)25 NVal::NVal(napi_env nEnv, napi_value nVal = nullptr) : env_(nEnv), val_(nVal) {}
26
operator bool() const27 NVal::operator bool() const
28 {
29 return env_ && val_;
30 }
31
TypeIs(napi_valuetype expType) const32 bool NVal::TypeIs(napi_valuetype expType) const
33 {
34 if (!*this) {
35 return false;
36 }
37
38 napi_valuetype valueType;
39 napi_typeof(env_, val_, &valueType);
40
41 if (expType != valueType) {
42 return false;
43 }
44 return true;
45 }
46
IsArray() const47 tuple<bool, bool> NVal::IsArray() const
48 {
49 bool res = false;
50 napi_status status = napi_is_array(env_, val_, &res);
51 return make_tuple(status == napi_ok, res);
52 }
53
ToUTF8String() const54 tuple<bool, unique_ptr<char[]>, size_t> NVal::ToUTF8String() const
55 {
56 size_t strLen = 0;
57 napi_status status = napi_get_value_string_utf8(env_, val_, nullptr, -1, &strLen);
58 if (status != napi_ok) {
59 return {false, nullptr, 0};
60 }
61
62 size_t bufLen = strLen + 1;
63 unique_ptr<char[]> str = make_unique<char[]>(bufLen);
64 status = napi_get_value_string_utf8(env_, val_, str.get(), bufLen, &strLen);
65 return make_tuple(status == napi_ok, move(str), strLen);
66 }
67
ToUTF16String() const68 tuple<bool, unique_ptr<char[]>, size_t> NVal::ToUTF16String() const
69 {
70 #ifdef FILE_SUBSYSTEM_DEV_ON_PC
71 size_t strLen = 0;
72 napi_status status = napi_get_value_string_utf16(env_, val_, nullptr, -1, &strLen);
73 if (status != napi_ok) {
74 return { false, nullptr, 0 };
75 }
76
77 auto str = make_unique<char16_t[]>(++strLen);
78 status = napi_get_value_string_utf16(env_, val_, str.get(), strLen, nullptr);
79 if (status != napi_ok) {
80 return { false, nullptr, 0 };
81 }
82
83 strLen = reinterpret_cast<char *>(str.get() + strLen) - reinterpret_cast<char *>(str.get());
84 auto strRet = unique_ptr<char[]>(reinterpret_cast<char *>(str.release()));
85 return { true, move(strRet), strLen };
86 #else
87 // Note that quickjs doesn't support utf16
88 return ToUTF8String();
89 #endif
90 }
91
ToPointer() const92 tuple<bool, void *> NVal::ToPointer() const
93 {
94 void *res = nullptr;
95 napi_status status = napi_get_value_external(env_, val_, &res);
96 return make_tuple(status == napi_ok, res);
97 }
98
IsTypeArray() const99 tuple<bool, bool> NVal::IsTypeArray() const
100 {
101 bool res = false;
102 napi_status status = napi_is_typedarray(env_, val_, &res);
103 return make_tuple(status == napi_ok, res);
104 }
105
ToBool() const106 tuple<bool, bool> NVal::ToBool() const
107 {
108 bool flag = false;
109 napi_status status = napi_get_value_bool(env_, val_, &flag);
110 return make_tuple(status == napi_ok, flag);
111 }
112
ToDouble() const113 tuple<bool, double> NVal::ToDouble() const
114 {
115 double res = 0.0;
116 napi_status status = napi_get_value_double(env_, val_, &res);
117 return make_tuple(status == napi_ok, res);
118 }
119
ToInt32() const120 tuple<bool, int32_t> NVal::ToInt32() const
121 {
122 int32_t res = 0;
123 napi_status status = napi_get_value_int32(env_, val_, &res);
124 return make_tuple(status == napi_ok, res);
125 }
126
ToInt64() const127 tuple<bool, int64_t> NVal::ToInt64() const
128 {
129 int64_t res = 0;
130 napi_status status = napi_get_value_int64(env_, val_, &res);
131 return make_tuple(status == napi_ok, res);
132 }
133
ToArraybuffer() const134 tuple<bool, void *, size_t> NVal::ToArraybuffer() const
135 {
136 void *buf = nullptr;
137 size_t bufLen = 0;
138 bool status = napi_get_arraybuffer_info(env_, val_, &buf, &bufLen);
139 return make_tuple(status == napi_ok, buf, bufLen);
140 }
141
ToTypedArray() const142 tuple<bool, napi_typedarray_type, void *, size_t> NVal::ToTypedArray() const
143 {
144 napi_typedarray_type type;
145 napi_value in_array_buffer = nullptr;
146 size_t byte_offset;
147 size_t length;
148 void *data = nullptr;
149 napi_status status = napi_get_typedarray_info(env_, val_, &type, &length, (void **) &data, &in_array_buffer,
150 &byte_offset);
151 return make_tuple(status == napi_ok, type, data, length);
152 }
153
ToDataview() const154 tuple<bool, void *, size_t> NVal::ToDataview() const
155 {
156 size_t bufLen = 0;
157 void *buf = nullptr;
158 napi_value arraybuffer = nullptr;
159 size_t byteoff = 0;
160 bool status = napi_get_dataview_info(env_, val_, &bufLen, &buf, &arraybuffer, &byteoff);
161 return make_tuple(status == napi_ok, buf, bufLen);
162 }
163
ToTypedArrayInfo() const164 tuple<bool, void *, size_t, size_t, napi_typedarray_type> NVal::ToTypedArrayInfo() const
165 {
166 napi_typedarray_type type;
167 napi_value in_array_buffer = nullptr;
168 size_t byte_offset;
169 size_t length;
170 void *data = nullptr;
171 napi_status status =
172 napi_get_typedarray_info(env_, val_, &type, &length, (void **)&data, &in_array_buffer, &byte_offset);
173 return make_tuple(status == napi_ok, data, length, byte_offset, type);
174 }
175
HasProp(string propName) const176 bool NVal::HasProp(string propName) const
177 {
178 bool res = false;
179
180 if (!env_ || !val_ || !TypeIs(napi_object))
181 return false;
182 napi_status status = napi_has_named_property(env_, val_, propName.c_str(), &res);
183 return (status == napi_ok) && res;
184 }
185
GetProp(string propName) const186 NVal NVal::GetProp(string propName) const
187 {
188 if (!HasProp(propName)) {
189 return {env_, nullptr};
190 }
191 napi_value prop = nullptr;
192 napi_status status = napi_get_named_property(env_, val_, propName.c_str(), &prop);
193 if (status != napi_ok) {
194 return {env_, nullptr};
195 }
196 return NVal(env_, prop);
197 }
198
AddProp(vector<napi_property_descriptor> && propVec) const199 bool NVal::AddProp(vector<napi_property_descriptor> &&propVec) const
200 {
201 if (!TypeIs(napi_valuetype::napi_object)) {
202 return false;
203 }
204 napi_status status = napi_define_properties(env_, val_, propVec.size(), propVec.data());
205 if (status != napi_ok) {
206 return false;
207 }
208 return true;
209 }
210
AddProp(string propName,napi_value val) const211 bool NVal::AddProp(string propName, napi_value val) const
212 {
213 if (!TypeIs(napi_valuetype::napi_object) || HasProp(propName)) {
214 return false;
215 }
216
217 napi_status status = napi_set_named_property(env_, val_, propName.c_str(), val);
218 if (status != napi_ok) {
219 return false;
220 }
221 return true;
222 }
223
CreateUndefined(napi_env env)224 NVal NVal::CreateUndefined(napi_env env)
225 {
226 napi_value res = nullptr;
227 napi_get_undefined(env, &res);
228 return {env, res};
229 }
230
CreateNull(napi_env env)231 NVal NVal::CreateNull(napi_env env)
232 {
233 napi_value res = nullptr;
234 napi_get_null(env, &res);
235 return {env, res};
236 }
237
CreateInt64(napi_env env,int64_t val)238 NVal NVal::CreateInt64(napi_env env, int64_t val)
239 {
240 napi_value res = nullptr;
241 napi_create_int64(env, val, &res);
242 return {env, res};
243 }
244
CreateObject(napi_env env)245 NVal NVal::CreateObject(napi_env env)
246 {
247 napi_value res = nullptr;
248 napi_create_object(env, &res);
249 return {env, res};
250 }
251
CreateBool(napi_env env,bool val)252 NVal NVal::CreateBool(napi_env env, bool val)
253 {
254 napi_value res = nullptr;
255 napi_get_boolean(env, val, &res);
256 return {env, res};
257 }
258
CreateUTF8String(napi_env env,std::string str)259 NVal NVal::CreateUTF8String(napi_env env, std::string str)
260 {
261 napi_value res = nullptr;
262 napi_create_string_utf8(env, str.c_str(), str.length(), &res);
263 return {env, res};
264 }
265
CreateUint8Array(napi_env env,void * buf,size_t bufLen)266 NVal NVal::CreateUint8Array(napi_env env, void *buf, size_t bufLen)
267 {
268 napi_value output_buffer = nullptr;
269 napi_create_external_arraybuffer(env, buf, bufLen,
270 [](napi_env env, void *finalize_data, void *finalize_hint) { free(finalize_data); },
271 NULL, &output_buffer);
272 napi_value output_array = nullptr;
273 napi_create_typedarray(env, napi_uint8_array, bufLen, output_buffer, 0, &output_array);
274 return {env, output_array};
275 }
276
CreateDouble(napi_env env,double val)277 NVal NVal::CreateDouble(napi_env env, double val)
278 {
279 napi_value res = nullptr;
280 napi_create_double(env, val, &res);
281 return {env, res};
282 }
283
DeclareNapiProperty(const char * name,napi_value val)284 napi_property_descriptor NVal::DeclareNapiProperty(const char *name, napi_value val)
285 {
286 return {(name), nullptr, nullptr, nullptr, nullptr, val, napi_default, nullptr};
287 }
288
DeclareNapiStaticProperty(const char * name,napi_value val)289 napi_property_descriptor NVal::DeclareNapiStaticProperty(const char *name, napi_value val)
290 {
291 return {(name), nullptr, nullptr, nullptr, nullptr, val, napi_static, nullptr};
292 }
293
DeclareNapiFunction(const char * name,napi_callback func)294 napi_property_descriptor NVal::DeclareNapiFunction(const char *name, napi_callback func)
295 {
296 return {(name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr};
297 }
298
DeclareNapiStaticFunction(const char * name,napi_callback func)299 napi_property_descriptor NVal::DeclareNapiStaticFunction(const char *name, napi_callback func)
300 {
301 return {(name), nullptr, (func), nullptr, nullptr, nullptr, napi_static, nullptr};
302 }
303
DeclareNapiGetter(const char * name,napi_callback getter)304 napi_property_descriptor NVal::DeclareNapiGetter(const char *name, napi_callback getter)
305 {
306 return {(name), nullptr, nullptr, (getter), nullptr, nullptr, napi_default, nullptr};
307 }
308
DeclareNapiSetter(const char * name,napi_callback setter)309 napi_property_descriptor NVal::DeclareNapiSetter(const char *name, napi_callback setter)
310 {
311 return {(name), nullptr, nullptr, nullptr, (setter), nullptr, napi_default, nullptr};
312 }
313
DeclareNapiGetterSetter(const char * name,napi_callback getter,napi_callback setter)314 napi_property_descriptor NVal::DeclareNapiGetterSetter(const char *name, napi_callback getter, napi_callback setter)
315 {
316 return {(name), nullptr, nullptr, (getter), (setter), nullptr, napi_default, nullptr};
317 }
318 } // namespace HiviewDFX
319 } // namespace OHOS