• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef DISTRIBUTEDDATAMGR_APPDATAMGR_JSUTILS_H
17 #define DISTRIBUTEDDATAMGR_APPDATAMGR_JSUTILS_H
18 
19 #include <functional>
20 #include <iostream>
21 #include <map>
22 #include <memory>
23 #include <string>
24 #include <variant>
25 #include <vector>
26 #include <optional>
27 #include "napi/native_api.h"
28 #include "napi/native_common.h"
29 #include "napi/native_node_api.h"
30 
31 namespace OHOS {
32 namespace AppDataMgrJsKit {
33 namespace JSUtils {
34 constexpr int OK = 0;
35 constexpr int ERR = -1;
36 constexpr uint32_t ASYNC_RST_SIZE = 2;
37 constexpr uint32_t DEFAULT_VALUE_LENGTH = 1024;
38 constexpr uint32_t MAX_VALUE_LENGTH = 1024 * 1024 * 8; // the max length of all kand of out string value
39 constexpr uint32_t SYNC_RESULT_ELEMENT_NUM = 2;
40 struct JsFeatureSpace {
41     const char* spaceName;
42     const char* nameBase64;
43     bool isComponent;
44 };
45 
46 #ifndef ADD_JS_PROPERTY
47 #define ADD_JS_PROPERTY(env, object, value, member) \
48     napi_set_named_property((env), (object), #member, Convert2JSValue((env), (value).member))
49 #endif
50 
51 #ifndef GET_PROPERTY
52 #define GET_PROPERTY(env, object, value, member) \
53     Convert2Value((env), GetNamedProperty((env), (object), #member), (value).member)
54 #endif
55 
56 napi_value GetNamedProperty(napi_env env, napi_value object, const char *name);
57 
58 int32_t Convert2ValueExt(napi_env env, napi_value jsValue, uint32_t &output);
59 int32_t Convert2ValueExt(napi_env env, napi_value jsValue, int32_t &output);
60 int32_t Convert2ValueExt(napi_env env, napi_value jsValue, int64_t &output);
61 
62 int32_t Convert2Value(napi_env env, napi_value jsValue, bool &output);
63 int32_t Convert2Value(napi_env env, napi_value jsValue, double &output);
64 int32_t Convert2Value(napi_env env, napi_value jsValue, int64_t &output);
65 int32_t Convert2Value(napi_env env, napi_value jsValue, std::string &output);
66 int32_t Convert2Value(napi_env env, napi_value jsValue, std::vector<uint8_t> &output);
67 int32_t Convert2Value(napi_env env, napi_value jsValue, std::monostate &value);
68 int32_t Convert2Value(napi_env env, napi_value jsValue, std::map<std::string, int32_t> &output);
69 int32_t Convert2Value(napi_env env, napi_value jsValue, std::map<std::string, bool> &output);
70 
71 bool IsNull(napi_env env, napi_value value);
72 
73 template<typename T>
74 int32_t Convert2Value(napi_env env, napi_value jsValue, T &output);
75 
76 template<typename T>
77 int32_t Convert2Value(napi_env env, napi_value jsValue, std::vector<T> &value);
78 
79 template<typename... Types>
80 int32_t Convert2Value(napi_env env, napi_value jsValue, std::variant<Types...> &value);
81 
82 using Descriptor = std::function<std::vector<napi_property_descriptor>()>;
83 const std::optional<JsFeatureSpace> GetJsFeatureSpace(const std::string &name);
84 /* napi_define_class  wrapper */
85 napi_value DefineClass(napi_env env, const std::string &spaceName, const std::string &className,
86     const Descriptor &descriptor, napi_callback ctor);
87 napi_value GetClass(napi_env env, const std::string &spaceName, const std::string &className);
88 std::string Convert2String(napi_env env, napi_value jsStr);
89 
90 int32_t Convert2JSValue(napi_env env, std::string value, napi_value &output);
91 int32_t Convert2JSValue(napi_env env, bool value, napi_value &output);
92 int32_t Convert2JSValue(napi_env env, double value, napi_value &output);
93 
94 napi_value Convert2JSValue(napi_env env, const std::vector<std::string> &value);
95 napi_value Convert2JSValue(napi_env env, const std::string &value);
96 napi_value Convert2JSValue(napi_env env, const std::vector<uint8_t> &value);
97 napi_value Convert2JSValue(napi_env env, int32_t value);
98 napi_value Convert2JSValue(napi_env env, uint32_t value);
99 napi_value Convert2JSValue(napi_env env, int64_t value);
100 napi_value Convert2JSValue(napi_env env, double value);
101 napi_value Convert2JSValue(napi_env env, bool value);
102 napi_value Convert2JSValue(napi_env env, const std::map<std::string, int> &value);
103 napi_value Convert2JSValue(napi_env env, const std::monostate &value);
104 
105 template<typename T>
106 napi_value Convert2JSValue(napi_env env, const T &value);
107 
108 template<typename T>
109 napi_value Convert2JSValue(napi_env env, const std::vector<T> &value);
110 
111 template<typename K, typename V>
112 napi_value Convert2JSValue(napi_env env, const std::map<K, V> &value);
113 
114 template<typename... Types>
115 napi_value Convert2JSValue(napi_env env, const std::variant<Types...> &value);
116 
117 template<typename T>
118 std::string ToString(const T &key);
119 
120 template<typename K>
ConvertMapKey(const K & key)121 std::enable_if_t<!std::is_same_v<K, std::string>, std::string> ConvertMapKey(const K &key)
122 {
123     return ToString(key);
124 }
125 
126 template<typename K>
ConvertMapKey(const K & key)127 std::enable_if_t<std::is_same_v<K, std::string>, const std::string &> ConvertMapKey(const K &key)
128 {
129     return key;
130 }
131 
132 template<typename T>
GetCPPValue(napi_env env,napi_value jsValue,T & value)133 int32_t GetCPPValue(napi_env env, napi_value jsValue, T &value)
134 {
135     return napi_invalid_arg;
136 }
137 
138 template<typename T, typename First, typename... Types>
GetCPPValue(napi_env env,napi_value jsValue,T & value)139 int32_t GetCPPValue(napi_env env, napi_value jsValue, T &value)
140 {
141     First cValue;
142     auto ret = Convert2Value(env, jsValue, cValue);
143     if (ret == napi_ok) {
144         value = cValue;
145         return ret;
146     }
147     return GetCPPValue<T, Types...>(env, jsValue, value);
148 }
149 
150 template<typename T>
GetJSValue(napi_env env,const T & value)151 napi_value GetJSValue(napi_env env, const T &value)
152 {
153     return nullptr;
154 }
155 
156 template<typename T, typename First, typename... Types>
GetJSValue(napi_env env,const T & value)157 napi_value GetJSValue(napi_env env, const T &value)
158 {
159     auto *val = std::get_if<First>(&value);
160     if (val != nullptr) {
161         return Convert2JSValue(env, *val);
162     }
163     return GetJSValue<T, Types...>(env, value);
164 }
165 } // namespace JSUtils
166 
167 template<typename T>
Convert2Value(napi_env env,napi_value jsValue,std::vector<T> & value)168 int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, std::vector<T> &value)
169 {
170     bool isArray = false;
171     napi_is_array(env, jsValue, &isArray);
172     if (!isArray) {
173         return napi_invalid_arg;
174     }
175 
176     uint32_t arrLen = 0;
177     napi_get_array_length(env, jsValue, &arrLen);
178     if (arrLen == 0) {
179         return napi_ok;
180     }
181 
182     for (size_t i = 0; i < arrLen; ++i) {
183         napi_value element;
184         napi_get_element(env, jsValue, i, &element);
185         T item;
186         auto status = Convert2Value(env, element, item);
187         if (status != napi_ok) {
188             return napi_invalid_arg;
189         }
190         value.push_back(std::move(item));
191     }
192     return napi_ok;
193 }
194 
195 template<typename K, typename V>
Convert2JSValue(napi_env env,const std::map<K,V> & value)196 napi_value JSUtils::Convert2JSValue(napi_env env, const std::map<K, V> &value)
197 {
198     napi_value jsValue;
199     napi_status status = napi_create_object(env, &jsValue);
200     if (status != napi_ok) {
201         return nullptr;
202     }
203 
204     for (const auto &[key, val] : value) {
205         const std::string &name = ConvertMapKey(key);
206         status = napi_set_named_property(env, jsValue, name.c_str(), Convert2JSValue(env, val));
207         if (status != napi_ok) {
208             return nullptr;
209         }
210     }
211     return jsValue;
212 }
213 
214 template<typename... Types>
Convert2Value(napi_env env,napi_value jsValue,std::variant<Types...> & value)215 int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, std::variant<Types...> &value)
216 {
217     napi_valuetype type;
218     napi_status status = napi_typeof(env, jsValue, &type);
219     if (status != napi_ok || type == napi_undefined) {
220         return napi_invalid_arg;
221     }
222     return GetCPPValue<decltype(value), Types...>(env, jsValue, value);
223 }
224 
225 template<typename T>
Convert2JSValue(napi_env env,const std::vector<T> & value)226 napi_value JSUtils::Convert2JSValue(napi_env env, const std::vector<T> &value)
227 {
228     napi_value jsValue;
229     napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
230     if (status != napi_ok) {
231         return nullptr;
232     }
233 
234     for (size_t i = 0; i < value.size(); ++i) {
235         napi_set_element(env, jsValue, i, Convert2JSValue(env, value[i]));
236     }
237     return jsValue;
238 }
239 
240 template<typename... Types>
Convert2JSValue(napi_env env,const std::variant<Types...> & value)241 napi_value JSUtils::Convert2JSValue(napi_env env, const std::variant<Types...> &value)
242 {
243     return GetJSValue<decltype(value), Types...>(env, value);
244 }
245 } // namespace AppDataMgrJsKit
246 } // namespace OHOS
247 #endif // DISTRIBUTEDDATAMGR_APPDATAMGR_JSUTILS_H
248