• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "n_val.h"
17 
18 #include <string>
19 
20 #include "../log.h"
21 #include "../uni_error.h"
22 
23 namespace OHOS {
24 namespace DistributedFS {
25 using namespace std;
26 
NVal(napi_env nEnv,napi_value nVal=nullptr)27 NVal::NVal(napi_env nEnv, napi_value nVal = nullptr) : env_(nEnv), val_(nVal) {}
28 
operator bool() const29 NVal::operator bool() const
30 {
31     return env_ && val_;
32 }
33 
TypeIs(napi_valuetype expType) const34 bool NVal::TypeIs(napi_valuetype expType) const
35 {
36     if (!*this) {
37         return false;
38     }
39 
40     napi_valuetype valueType;
41     napi_typeof(env_, val_, &valueType);
42     if (expType != valueType) {
43         return false;
44     }
45 
46     return true;
47 }
48 
TypeIsError(bool checkErrno) const49 bool NVal::TypeIsError(bool checkErrno) const
50 {
51     if (!*this) {
52         return false;
53     }
54 
55     bool res = false;
56     napi_is_error(env_, val_, &res);
57 
58     return res;
59 }
60 
ToUTF8String() const61 tuple<bool, unique_ptr<char[]>, size_t> NVal::ToUTF8String() const
62 {
63     size_t strLen = 0;
64     napi_status status = napi_get_value_string_utf8(env_, val_, nullptr, -1, &strLen);
65     if (status != napi_ok) {
66         return { false, nullptr, 0 };
67     }
68 
69     size_t bufLen = strLen + 1;
70     unique_ptr<char[]> str = make_unique<char[]>(bufLen);
71     status = napi_get_value_string_utf8(env_, val_, str.get(), bufLen, &strLen);
72     return make_tuple(status == napi_ok, move(str), strLen);
73 }
74 
ToUTF8String(string_view defaultValue) const75 tuple<bool, unique_ptr<char[]>, size_t> NVal::ToUTF8String(string_view defaultValue) const
76 {
77     if (TypeIs(napi_undefined) || TypeIs(napi_function)) {
78         auto str = make_unique<char[]>(defaultValue.size() + 1);
79         copy(defaultValue.begin(), defaultValue.end(), str.get());
80         return make_tuple(true, move(str), defaultValue.size());
81     }
82     return ToUTF8String();
83 }
84 
ToUTF16String() const85 tuple<bool, unique_ptr<char[]>, size_t> NVal::ToUTF16String() const
86 {
87 #ifdef FILE_SUBSYSTEM_DEBUG_LOCAL
88     size_t strLen = 0;
89     napi_status status = napi_get_value_string_utf16(env_, val_, nullptr, -1, &strLen);
90     if (status != napi_ok) {
91         return { false, nullptr, 0 };
92     }
93 
94     auto str = make_unique<char16_t[]>(++strLen);
95     status = napi_get_value_string_utf16(env_, val_, str.get(), strLen, nullptr);
96     if (status != napi_ok) {
97         return { false, nullptr, 0 };
98     }
99 
100     strLen = reinterpret_cast<char *>(str.get() + strLen) - reinterpret_cast<char *>(str.get());
101     auto strRet = unique_ptr<char[]>(reinterpret_cast<char *>(str.release()));
102     return { true, move(strRet), strLen };
103 #else
104     // Note that quickjs doesn't support utf16
105     return ToUTF8String();
106 #endif
107 }
108 
ToPointer() const109 tuple<bool, void *> NVal::ToPointer() const
110 {
111     void *res = nullptr;
112     napi_status status = napi_get_value_external(env_, val_, &res);
113     return make_tuple(status == napi_ok, res);
114 }
115 
ToBool() const116 tuple<bool, bool> NVal::ToBool() const
117 {
118     bool flag = false;
119     napi_status status = napi_get_value_bool(env_, val_, &flag);
120     return make_tuple(status == napi_ok, flag);
121 }
122 
ToBool(bool defaultValue) const123 tuple<bool, bool> NVal::ToBool(bool defaultValue) const
124 {
125     if (TypeIs(napi_undefined) || TypeIs(napi_function)) {
126         return make_tuple(true, defaultValue);
127     }
128     return ToBool();
129 }
130 
ToInt32() const131 tuple<bool, int32_t> NVal::ToInt32() const
132 {
133     int32_t res = 0;
134     napi_status status = napi_get_value_int32(env_, val_, &res);
135     return make_tuple(status == napi_ok, res);
136 }
137 
ToInt32(int32_t defaultValue) const138 tuple<bool, int32_t> NVal::ToInt32(int32_t defaultValue) const
139 {
140     if (TypeIs(napi_undefined) || TypeIs(napi_function)) {
141         return make_tuple(true, defaultValue);
142     }
143     return ToInt32();
144 }
145 
ToInt64() const146 tuple<bool, int64_t> NVal::ToInt64() const
147 {
148     int64_t res = 0;
149     napi_status status = napi_get_value_int64(env_, val_, &res);
150     return make_tuple(status == napi_ok, res);
151 }
152 
ToInt64(int64_t defaultValue) const153 tuple<bool, int64_t> NVal::ToInt64(int64_t defaultValue) const
154 {
155     if (TypeIs(napi_undefined) || TypeIs(napi_function)) {
156         return make_tuple(true, defaultValue);
157     }
158     return ToInt64();
159 }
160 
ToDouble() const161 tuple<bool, double> NVal::ToDouble() const
162 {
163     double res = 0;
164     napi_status status = napi_get_value_double(env_, val_, &res);
165     return make_tuple(status == napi_ok, res);
166 }
167 
ToUint64() const168 tuple<bool, uint64_t, bool> NVal::ToUint64() const
169 {
170     uint64_t res = 0;
171     bool lossless = false;
172     napi_status status = napi_get_value_bigint_uint64(env_, val_, &res, &lossless);
173     return make_tuple(status == napi_ok, res, lossless);
174 }
175 
ToStringArray()176 tuple<bool, vector<string>, uint32_t> NVal::ToStringArray()
177 {
178     napi_status status;
179     uint32_t size;
180     status = napi_get_array_length(env_, val_, &size);
181     vector<string> stringArray;
182     napi_value result;
183     for (uint32_t i = 0; i < size; i++) {
184         status = napi_get_element(env_, val_, i, &result);
185         auto [succ, str, ignore] = NVal(env_, result).ToUTF8String();
186         stringArray.push_back(string(str.get()));
187     }
188     return make_tuple(status == napi_ok, stringArray, size);
189 }
190 
ToArraybuffer() const191 tuple<bool, void *, size_t> NVal::ToArraybuffer() const
192 {
193     void *buf = nullptr;
194     size_t bufLen = 0;
195     bool status = napi_get_arraybuffer_info(env_, val_, &buf, &bufLen);
196     return make_tuple(status == napi_ok, buf, bufLen);
197 }
198 
ToTypedArray() const199 tuple<bool, void *, size_t> NVal::ToTypedArray() const
200 {
201     napi_typedarray_type type;
202     napi_value in_array_buffer = nullptr;
203     size_t byte_offset;
204     size_t length;
205     void *data = nullptr;
206     napi_status status =
207         napi_get_typedarray_info(env_, val_, &type, &length, (void **)&data, &in_array_buffer, &byte_offset);
208     return make_tuple(status == napi_ok, data, length);
209 }
210 
HasProp(string propName) const211 bool NVal::HasProp(string propName) const
212 {
213     bool res = false;
214 
215     if (!env_ || !val_ || !TypeIs(napi_object))
216         return false;
217     napi_status status = napi_has_named_property(env_, val_, propName.c_str(), &res);
218     return (status == napi_ok) && res;
219 }
220 
GetProp(string propName) const221 NVal NVal::GetProp(string propName) const
222 {
223     if (!HasProp(propName)) {
224         return { env_, nullptr };
225     }
226 
227     napi_value prop = nullptr;
228     napi_status status = napi_get_named_property(env_, val_, propName.c_str(), &prop);
229     if (status != napi_ok) {
230         return { env_, nullptr };
231     }
232 
233     return NVal(env_, prop);
234 }
235 
AddProp(vector<napi_property_descriptor> && propVec) const236 bool NVal::AddProp(vector<napi_property_descriptor> &&propVec) const
237 {
238     if (!TypeIs(napi_valuetype::napi_object)) {
239         HILOGE("INNER BUG. Prop should only be added to objects");
240         return false;
241     }
242 
243     napi_status status = napi_define_properties(env_, val_, propVec.size(), propVec.data());
244     if (status != napi_ok) {
245         HILOGE("INNER BUG. Cannot define properties because of %{public}d", status);
246         return false;
247     }
248 
249     return true;
250 }
251 
AddProp(string propName,napi_value val) const252 bool NVal::AddProp(string propName, napi_value val) const
253 {
254     if (!TypeIs(napi_valuetype::napi_object) || HasProp(propName)) {
255         HILOGE("INNER BUG. Prop should only be added to objects");
256         return false;
257     }
258 
259     napi_status status = napi_set_named_property(env_, val_, propName.c_str(), val);
260     if (status != napi_ok) {
261         HILOGE("INNER BUG. Cannot set named property because of %{public}d", status);
262         return false;
263     }
264 
265     return true;
266 }
267 
CreateUndefined(napi_env env)268 NVal NVal::CreateUndefined(napi_env env)
269 {
270     napi_value res = nullptr;
271     napi_get_undefined(env, &res);
272     return { env, res };
273 }
274 
CreateBigInt64(napi_env env,int64_t val)275 NVal NVal::CreateBigInt64(napi_env env, int64_t val)
276 {
277     napi_value res = nullptr;
278     napi_create_bigint_int64(env, val, &res);
279     return { env, res };
280 }
281 
CreateInt64(napi_env env,int64_t val)282 NVal NVal::CreateInt64(napi_env env, int64_t val)
283 {
284     napi_value res = nullptr;
285     napi_create_int64(env, val, &res);
286     return { env, res };
287 }
288 
CreateInt32(napi_env env,int32_t val)289 NVal NVal::CreateInt32(napi_env env, int32_t val)
290 {
291     napi_value res = nullptr;
292     napi_create_int32(env, val, &res);
293     return { env, res };
294 }
295 
CreateObject(napi_env env)296 NVal NVal::CreateObject(napi_env env)
297 {
298     napi_value res = nullptr;
299     napi_create_object(env, &res);
300     return { env, res };
301 }
302 
CreateBool(napi_env env,bool val)303 NVal NVal::CreateBool(napi_env env, bool val)
304 {
305     napi_value res = nullptr;
306     napi_get_boolean(env, val, &res);
307     return { env, res };
308 }
309 
CreateUTF8String(napi_env env,std::string str)310 NVal NVal::CreateUTF8String(napi_env env, std::string str)
311 {
312     napi_value res = nullptr;
313     napi_create_string_utf8(env, str.c_str(), str.length(), &res);
314     return { env, res };
315 }
316 
CreateUTF8String(napi_env env,const char * str,ssize_t len)317 NVal NVal::CreateUTF8String(napi_env env, const char* str, ssize_t len)
318 {
319     napi_value res = nullptr;
320     napi_create_string_utf8(env, str, len, &res);
321     return { env, res };
322 }
323 
CreateUint8Array(napi_env env,void * buf,size_t bufLen)324 NVal NVal::CreateUint8Array(napi_env env, void *buf, size_t bufLen)
325 {
326     napi_value output_buffer = nullptr;
327     napi_create_external_arraybuffer(
328         env,
329         buf,
330         bufLen,
331         [](napi_env env, void *finalize_data, void *finalize_hint) { free(finalize_data); },
332         NULL,
333         &output_buffer);
334     napi_value output_array = nullptr;
335     napi_create_typedarray(env, napi_uint8_array, bufLen, output_buffer, 0, &output_array);
336     return { env, output_array };
337 }
338 
CreateArrayString(napi_env env,vector<string> strs)339 NVal NVal::CreateArrayString(napi_env env, vector<string> strs)
340 {
341     napi_value res = nullptr;
342     napi_create_array(env, &res);
343     for (size_t i = 0; i < strs.size(); i++) {
344         napi_value filename;
345         napi_create_string_utf8(env, strs[i].c_str(), strs[i].length(), &filename);
346         napi_set_element(env, res, i, filename);
347     }
348     return {env, res};
349 }
350 
CreateArrayBuffer(napi_env env,size_t len)351 tuple<NVal, void *> NVal::CreateArrayBuffer(napi_env env, size_t len)
352 {
353     napi_value val;
354     void *buf = nullptr;
355     napi_create_arraybuffer(env, len, &buf, &val);
356     return { { env, val }, { buf } };
357 }
358 
DeclareNapiProperty(const char * name,napi_value val)359 napi_property_descriptor NVal::DeclareNapiProperty(const char *name, napi_value val)
360 {
361     return { (name), nullptr, nullptr, nullptr, nullptr, val, napi_default, nullptr };
362 }
363 
DeclareNapiStaticProperty(const char * name,napi_value val)364 napi_property_descriptor NVal::DeclareNapiStaticProperty(const char *name, napi_value val)
365 {
366     return { (name), nullptr, nullptr, nullptr, nullptr, val, napi_static, nullptr };
367 }
368 
DeclareNapiFunction(const char * name,napi_callback func)369 napi_property_descriptor NVal::DeclareNapiFunction(const char *name, napi_callback func)
370 {
371     return { (name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr };
372 }
373 
DeclareNapiStaticFunction(const char * name,napi_callback func)374 napi_property_descriptor NVal::DeclareNapiStaticFunction(const char *name, napi_callback func)
375 {
376     return { (name), nullptr, (func), nullptr, nullptr, nullptr, napi_static, nullptr };
377 }
378 
DeclareNapiGetter(const char * name,napi_callback getter)379 napi_property_descriptor NVal::DeclareNapiGetter(const char *name, napi_callback getter)
380 {
381     return { (name), nullptr, nullptr, (getter), nullptr, nullptr, napi_default, nullptr };
382 }
383 
DeclareNapiSetter(const char * name,napi_callback setter)384 napi_property_descriptor NVal::DeclareNapiSetter(const char *name, napi_callback setter)
385 {
386     return { (name), nullptr, nullptr, nullptr, (setter), nullptr, napi_default, nullptr };
387 }
388 
DeclareNapiGetterSetter(const char * name,napi_callback getter,napi_callback setter)389 napi_property_descriptor NVal::DeclareNapiGetterSetter(const char *name, napi_callback getter, napi_callback setter)
390 {
391     return { (name), nullptr, nullptr, (getter), (setter), nullptr, napi_default, nullptr };
392 }
393 } // namespace DistributedFS
394 } // namespace OHOS