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 <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 napi_valuetype valueType;
40 napi_typeof(env_, val_, &valueType);
41
42 if (expType != valueType) {
43 return false;
44 }
45 return true;
46 }
47
TypeIsError(bool checkErrno) const48 bool NVal::TypeIsError(bool checkErrno) const
49 {
50 if (!*this) {
51 return false;
52 }
53
54 bool res = false;
55 napi_is_error(env_, val_, &res);
56
57 return res;
58 }
59
ToUTF8String() const60 tuple<bool, unique_ptr<char[]>, size_t> NVal::ToUTF8String() const
61 {
62 size_t strLen = 0;
63 napi_status status = napi_get_value_string_utf8(env_, val_, nullptr, -1, &strLen);
64 if (status != napi_ok) {
65 return { false, nullptr, 0 };
66 }
67
68 size_t bufLen = strLen + 1;
69 unique_ptr<char[]> str = make_unique<char[]>(bufLen);
70 status = napi_get_value_string_utf8(env_, val_, str.get(), bufLen, &strLen);
71 return make_tuple(status == napi_ok, move(str), strLen);
72 }
73
ToUTF16String() const74 tuple<bool, unique_ptr<char[]>, size_t> NVal::ToUTF16String() const
75 {
76 #ifdef FILE_SUBSYSTEM_DEV_ON_PC
77 size_t strLen = 0;
78 napi_status status = napi_get_value_string_utf16(env_, val_, nullptr, -1, &strLen);
79 if (status != napi_ok) {
80 return { false, nullptr, 0 };
81 }
82
83 auto str = make_unique<char16_t[]>(++strLen);
84 status = napi_get_value_string_utf16(env_, val_, str.get(), strLen, nullptr);
85 if (status != napi_ok) {
86 return { false, nullptr, 0 };
87 }
88
89 strLen = reinterpret_cast<char *>(str.get() + strLen) - reinterpret_cast<char *>(str.get());
90 auto strRet = unique_ptr<char[]>(reinterpret_cast<char *>(str.release()));
91 return { true, move(strRet), strLen };
92 #else
93 // Note that quickjs doesn't support utf16
94 return ToUTF8String();
95 #endif
96 }
97
ToPointer() const98 tuple<bool, void *> NVal::ToPointer() const
99 {
100 void *res = nullptr;
101 napi_status status = napi_get_value_external(env_, val_, &res);
102 return make_tuple(status == napi_ok, res);
103 }
104
ToBool() const105 tuple<bool, bool> NVal::ToBool() const
106 {
107 bool flag = false;
108 napi_status status = napi_get_value_bool(env_, val_, &flag);
109 return make_tuple(status == napi_ok, flag);
110 }
111
ToInt32() const112 tuple<bool, int32_t> NVal::ToInt32() const
113 {
114 int32_t res = 0;
115 napi_status status = napi_get_value_int32(env_, val_, &res);
116 return make_tuple(status == napi_ok, res);
117 }
118
ToInt64() const119 tuple<bool, int64_t> NVal::ToInt64() const
120 {
121 int64_t res = 0;
122 napi_status status = napi_get_value_int64(env_, val_, &res);
123 return make_tuple(status == napi_ok, res);
124 }
125
ToArraybuffer() const126 tuple<bool, void *, size_t> NVal::ToArraybuffer() const
127 {
128 void *buf = nullptr;
129 size_t bufLen = 0;
130 bool status = napi_get_arraybuffer_info(env_, val_, &buf, &bufLen);
131 return make_tuple(status == napi_ok, buf, bufLen);
132 }
133
ToTypedArray() const134 tuple<bool, void *, size_t> NVal::ToTypedArray() const
135 {
136 napi_typedarray_type type;
137 napi_value in_array_buffer = nullptr;
138 size_t byte_offset;
139 size_t length;
140 void *data = nullptr;
141 napi_status status =
142 napi_get_typedarray_info(env_, val_, &type, &length, (void **)&data, &in_array_buffer, &byte_offset);
143 return make_tuple(status == napi_ok, data, length);
144 }
145
HasProp(string propName) const146 bool NVal::HasProp(string propName) const
147 {
148 bool res = false;
149
150 if (!env_ || !val_ || !TypeIs(napi_object))
151 return false;
152 napi_status status = napi_has_named_property(env_, val_, propName.c_str(), &res);
153 return (status == napi_ok) && res;
154 }
155
GetProp(string propName) const156 NVal NVal::GetProp(string propName) const
157 {
158 if (!HasProp(propName)) {
159 return { env_, nullptr };
160 }
161 napi_value prop = nullptr;
162 napi_status status = napi_get_named_property(env_, val_, propName.c_str(), &prop);
163 if (status != napi_ok) {
164 return { env_, nullptr };
165 }
166 return NVal(env_, prop);
167 }
168
AddProp(vector<napi_property_descriptor> && propVec) const169 bool NVal::AddProp(vector<napi_property_descriptor> &&propVec) const
170 {
171 if (!TypeIs(napi_valuetype::napi_object)) {
172 HILOGE("INNER BUG. Prop should only be added to objects");
173 return false;
174 }
175 napi_status status = napi_define_properties(env_, val_, propVec.size(), propVec.data());
176 if (status != napi_ok) {
177 HILOGE("INNER BUG. Cannot define properties because of %{public}d", status);
178 return false;
179 }
180 return true;
181 }
182
AddProp(string propName,napi_value val) const183 bool NVal::AddProp(string propName, napi_value val) const
184 {
185 if (!TypeIs(napi_valuetype::napi_object) || HasProp(propName)) {
186 HILOGE("INNER BUG. Prop should only be added to objects");
187 return false;
188 }
189
190 napi_status status = napi_set_named_property(env_, val_, propName.c_str(), val);
191 if (status != napi_ok) {
192 HILOGE("INNER BUG. Cannot set named property because of %{public}d", status);
193 return false;
194 }
195 return true;
196 }
197
CreateUndefined(napi_env env)198 NVal NVal::CreateUndefined(napi_env env)
199 {
200 napi_value res = nullptr;
201 napi_get_undefined(env, &res);
202 return { env, res };
203 }
204
CreateInt64(napi_env env,int64_t val)205 NVal NVal::CreateInt64(napi_env env, int64_t val)
206 {
207 napi_value res = nullptr;
208 napi_create_int64(env, val, &res);
209 return { env, res };
210 }
211
CreateInt32(napi_env env,int32_t val)212 NVal NVal::CreateInt32(napi_env env, int32_t val)
213 {
214 napi_value res = nullptr;
215 napi_create_int32(env, val, &res);
216 return { env, res };
217 }
218
CreateObject(napi_env env)219 NVal NVal::CreateObject(napi_env env)
220 {
221 napi_value res = nullptr;
222 napi_create_object(env, &res);
223 return { env, res };
224 }
225
CreateBool(napi_env env,bool val)226 NVal NVal::CreateBool(napi_env env, bool val)
227 {
228 napi_value res = nullptr;
229 napi_get_boolean(env, val, &res);
230 return { env, res };
231 }
232
CreateUTF8String(napi_env env,std::string str)233 NVal NVal::CreateUTF8String(napi_env env, std::string str)
234 {
235 napi_value res = nullptr;
236 napi_create_string_utf8(env, str.c_str(), str.length(), &res);
237 return { env, res };
238 }
239
CreateUint8Array(napi_env env,void * buf,size_t bufLen)240 NVal NVal::CreateUint8Array(napi_env env, void *buf, size_t bufLen)
241 {
242 napi_value output_buffer = nullptr;
243 napi_create_external_arraybuffer(
244 env,
245 buf,
246 bufLen,
247 [](napi_env env, void *finalize_data, void *finalize_hint) { free(finalize_data); },
248 NULL,
249 &output_buffer);
250 napi_value output_array = nullptr;
251 napi_create_typedarray(env, napi_uint8_array, bufLen, output_buffer, 0, &output_array);
252 return { env, output_array };
253 }
254
DeclareNapiProperty(const char * name,napi_value val)255 napi_property_descriptor NVal::DeclareNapiProperty(const char *name, napi_value val)
256 {
257 return { (name), nullptr, nullptr, nullptr, nullptr, val, napi_default, nullptr };
258 }
259
DeclareNapiStaticProperty(const char * name,napi_value val)260 napi_property_descriptor NVal::DeclareNapiStaticProperty(const char *name, napi_value val)
261 {
262 return { (name), nullptr, nullptr, nullptr, nullptr, val, napi_static, nullptr };
263 }
264
DeclareNapiFunction(const char * name,napi_callback func)265 napi_property_descriptor NVal::DeclareNapiFunction(const char *name, napi_callback func)
266 {
267 return { (name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr };
268 }
269
DeclareNapiStaticFunction(const char * name,napi_callback func)270 napi_property_descriptor NVal::DeclareNapiStaticFunction(const char *name, napi_callback func)
271 {
272 return { (name), nullptr, (func), nullptr, nullptr, nullptr, napi_static, nullptr };
273 }
274
DeclareNapiGetter(const char * name,napi_callback getter)275 napi_property_descriptor NVal::DeclareNapiGetter(const char *name, napi_callback getter)
276 {
277 return { (name), nullptr, nullptr, (getter), nullptr, nullptr, napi_default, nullptr };
278 }
279
DeclareNapiSetter(const char * name,napi_callback setter)280 napi_property_descriptor NVal::DeclareNapiSetter(const char *name, napi_callback setter)
281 {
282 return { (name), nullptr, nullptr, nullptr, (setter), nullptr, napi_default, nullptr };
283 }
284
DeclareNapiGetterSetter(const char * name,napi_callback getter,napi_callback setter)285 napi_property_descriptor NVal::DeclareNapiGetterSetter(const char *name, napi_callback getter, napi_callback setter)
286 {
287 return { (name), nullptr, nullptr, (getter), (setter), nullptr, napi_default, nullptr };
288 }
289 } // namespace DistributedFS
290 } // namespace OHOS