• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #ifndef DATASHARE_JSUTILS_H
17 #define DATASHARE_JSUTILS_H
18 
19 #include <iostream>
20 #include <map>
21 #include <string>
22 #include <variant>
23 #include <vector>
24 
25 #include "datashare_observer.h"
26 #include "datashare_operation_statement.h"
27 #include "datashare_template.h"
28 #include "datashare_value_object.h"
29 #include "napi/native_api.h"
30 #include "dataproxy_handle_common.h"
31 
32 #define NAPI_ASSERT_ERRCODE(env, assertion, error)                                                          \
33 do {                                                                                                        \
34     if (!(assertion)) {                                                                                     \
35         napi_throw_error((env), std::to_string((error)->GetCode()).c_str(), (error)->GetMessage().c_str()); \
36         return;                                                                                             \
37     }                                                                                                       \
38 } while (0)
39 
40 #define NAPI_ASSERT_CALL_ERRCODE(env, assertion, call, retVal) \
41     do {                                                       \
42         if (!(assertion)) {                                    \
43             call;                                              \
44             return retVal;                                     \
45         }                                                      \
46     } while (0)
47 
48 #define NAPI_ASSERT_CALL_ERRCODE_SYNC(env, assertion, call, error, retVal)                                      \
49     do {                                                                                                        \
50         if (!(assertion)) {                                                                                     \
51             call;                                                                                               \
52             napi_throw_error((env), std::to_string((error)->GetCode()).c_str(), (error)->GetMessage().c_str()); \
53             return retVal;                                                                                      \
54         }                                                                                                       \
55     } while (0)
56 
57 namespace OHOS {
58 namespace DataShare {
59 class DataShareJSUtils final {
60 public:
61     static constexpr int32_t DEFAULT_BUF_SIZE = 1024;
62     static constexpr int32_t ASYNC_RST_SIZE = 2;
63     static constexpr int32_t SYNC_RESULT_ELEMNT_NUM = 2;
64 
65     template<typename T>
66     static int32_t Convert2Value(napi_env env, napi_value input, T &output);
67 
68     template<typename T>
69     static int32_t Convert2JSValue(napi_env env, napi_value input, T &output);
70 
71     template<typename T>
72     static napi_value Convert2JSValue(napi_env env, const std::vector<T> &value);
73 
74     template<typename T>
75     static int32_t Convert2Value(napi_env env, napi_value input, std::vector<T> &output);
76 
77     template<typename T>
78     static int32_t Convert2Value(napi_env env, napi_value input, std::map<std::string, T> &output);
79 
80     template<typename T>
81     static int32_t Convert2Value(napi_env env, napi_value input, const char* propertyName, T &output);
82 
83     static int32_t Convert2Value(napi_env env, napi_value input, std::string &str);
84     static int32_t Convert2Value(napi_env env, napi_value input, DataShareObserver::ChangeType &changeType);
85     static int32_t Convert2Value(napi_env env, napi_value input, DataSharePredicates &predicates);
86     static int32_t Convert2Value(napi_env env, napi_value input, DataShareValuesBucket &valueBucket);
87     static int32_t Convert2Value(napi_env env, napi_value input, UpdateOperation &operation);
88     static int32_t Convert2Value(napi_env env, napi_value input, DataShareObserver::ChangeInfo &changeInfo);
89     static int32_t Convert2Value(napi_env env, napi_value input, DataProxyType &proxyType);
90     static std::string Convert2String(napi_env env, napi_value jsStr, size_t max = DEFAULT_BUF_SIZE);
91     static std::vector<std::string> Convert2StrVector(napi_env env, napi_value value, size_t strMax);
92     static std::vector<uint8_t> Convert2U8Vector(napi_env env, napi_value jsValue);
93     static std::string ConvertAny2String(napi_env env, const napi_value jsValue);
94     static std::string UnwrapStringFromJS(napi_env env, napi_value param, const std::string &defaultValue = "");
95     static DataShareValueObject Convert2ValueObject(napi_env env, napi_value value, bool &status);
96     static Template Convert2Template(napi_env env, napi_value value);
97     static TemplateId Convert2TemplateId(napi_env env, napi_value value);
98     static Data Convert2PublishedData(napi_env env, napi_value value);
99     static std::vector<DataShareProxyData> Convert2ProxyData(napi_env env, napi_value value);
100 
101     static napi_value Convert2JSValue(napi_env env, const std::monostate &value = {});
102     static napi_value Convert2JSValue(napi_env env, const std::vector<std::string> &value);
103     static napi_value Convert2JSValue(napi_env env, const std::string &value);
104     static napi_value Convert2JSValue(napi_env env, const std::vector<uint8_t> &value, bool isTypedArray = true);
105     static napi_value Convert2JSValue(napi_env env, int32_t value);
106     static napi_value Convert2JSValue(napi_env env, int64_t value);
107     static napi_value Convert2JSValue(napi_env env, uint32_t value);
108     static napi_value Convert2JSValue(napi_env env, double value);
109     static napi_value Convert2JSValue(napi_env env, bool value);
110     static napi_value Convert2JSValue(napi_env env, const std::map<std::string, int> &value);
111     template<class... Types>
112     static napi_value Convert2JSValue(napi_env env, const std::variant<Types...> &value);
113     static napi_value Convert2JSValue(napi_env env, const TemplateId &templateId);
114     static napi_value Convert2JSValue(napi_env env, const RdbChangeNode &changeNode);
115     static napi_value Convert2JSValue(napi_env env, PublishedDataItem &publishedDataItem);
116     static napi_value Convert2JSValue(napi_env env, std::vector<PublishedDataItem> &publishedDataItems);
117     static napi_value Convert2JSValue(napi_env env, PublishedDataChangeNode &changeNode);
118     static napi_value Convert2JSValue(napi_env env, const OperationResult &results);
119     static napi_value Convert2JSValue(napi_env env, const std::vector<OperationResult> &results);
120     static napi_value Convert2JSValue(napi_env env, const DataProxyResult &result);
121     static napi_value Convert2JSValue(napi_env env, const std::vector<DataProxyResult> &results);
122     static napi_value Convert2JSValue(napi_env env, const DataProxyGetResult &result);
123     static napi_value Convert2JSValue(napi_env env, const std::vector<DataProxyGetResult> &results);
124     static napi_value Convert2JSValue(napi_env env, const DataShareValueObject &valueObject);
125     static napi_value Convert2JSValue(napi_env env, const DataProxyChangeInfo &changeInfo);
126     static napi_value Convert2JSValue(napi_env env, const DataShareValuesBucket &valueBucket);
127     static std::vector<uint8_t> ConvertU8Vector(napi_env env, napi_value jsValue);
128     static napi_value Convert2JSValue(napi_env env, const DataShareObserver::ChangeInfo &changeInfo);
129     static napi_value Convert2JSValue(napi_env env, const std::vector<BatchUpdateResult> &result);
130 
131     static bool UnwrapDataSharePredicates(napi_env env, napi_value value, DataSharePredicates &dataSharePredicates);
132     static bool Equals(napi_env env, napi_value value, napi_ref copy);
133     static bool UnwrapPublishedDataItem(napi_env env, napi_value value, PublishedDataItem &publishedDataItem);
134     static bool UnwrapPublishedDataItemVector(napi_env env, napi_value value,
135         std::vector<PublishedDataItem> &publishedDataItems);
136     static bool UnwrapTemplatePredicates(napi_env env, napi_value jsPredicates,
137         std::vector<PredicateTemplateNode> &predicates);
138     static bool UnwrapStringByPropertyName(napi_env env, napi_value jsObject, const char *propertyName,
139         std::string &value);
140     static bool UnwrapDataProxyValue(napi_env env, napi_value jsObject, DataProxyValue &value, bool &isValueUndefined);
141     static bool UnwrapProxyDataItem(napi_env env, napi_value jsObject, DataShareProxyData &proxyData);
142     static bool UnwrapProxyDataItemVector(napi_env env, napi_value value, std::vector<DataShareProxyData> &proxyDatas);
143     static bool UnwrapDataProxyConfig(napi_env env, napi_value value, DataProxyConfig &config);
144     static bool IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize);
145 private:
146     template<typename _VTp>
ReadVariant(napi_env env,uint32_t step,uint32_t index,const _VTp & output)147     static napi_value ReadVariant(napi_env env, uint32_t step, uint32_t index, const _VTp &output)
148     {
149         (void)step;
150         (void)index;
151         (void)output;
152         return Convert2JSValue(env);
153     }
154 
155     template<typename _VTp, typename _First, typename ..._Rest>
ReadVariant(napi_env env,uint32_t step,uint32_t index,const _VTp & value)156     static napi_value ReadVariant(napi_env env, uint32_t step, uint32_t index, const _VTp &value)
157     {
158         if (step == index) {
159             auto *realValue = std::get_if<_First>(&value);
160             if (realValue == nullptr) {
161                 return nullptr;
162             }
163             return Convert2JSValue(env, *realValue);
164         }
165         return ReadVariant<_VTp, _Rest...>(env, step + 1, index, value);
166     }
167 };
168 
169 template<class... Types>
Convert2JSValue(napi_env env,const std::variant<Types...> & value)170 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::variant<Types...> &value)
171 {
172     return ReadVariant<decltype(value), Types...>(env, 0, static_cast<uint32_t>(value.index()), value);
173 }
174 
175 template<typename T>
Convert2Value(napi_env env,napi_value input,const char * propertyName,T & output)176 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, const char* propertyName, T& output)
177 {
178     napi_value jsObject = nullptr;
179     if (napi_get_named_property(env, input, propertyName, &jsObject) != napi_ok) {
180         return napi_invalid_arg;
181     }
182     if (Convert2Value(env, jsObject, output) != napi_ok) {
183         return napi_invalid_arg;
184     }
185     return napi_ok;
186 }
187 
188 template<typename T>
Convert2JSValue(napi_env env,const std::vector<T> & value)189 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<T> &value)
190 {
191     napi_value jsValue;
192     napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
193     if (status != napi_ok) {
194         return nullptr;
195     }
196 
197     for (size_t i = 0; i < value.size(); ++i) {
198         napi_set_element(env, jsValue, i, Convert2JSValue(env, value[i]));
199     }
200     return jsValue;
201 }
202 
203 template<typename T>
Convert2Value(napi_env env,napi_value input,std::vector<T> & output)204 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, std::vector<T> &output)
205 {
206     bool isArray = false;
207     napi_is_array(env, input, &isArray);
208     if (!isArray) {
209         return napi_invalid_arg;
210     }
211 
212     uint32_t arrLen = 0;
213     napi_get_array_length(env, input, &arrLen);
214     if (arrLen == 0) {
215         return napi_invalid_arg;
216     }
217 
218     for (size_t i = 0; i < arrLen; ++i) {
219         napi_value element;
220         napi_get_element(env, input, i, &element);
221         T item;
222         auto status = Convert2Value(env, element, item);
223         if (status != napi_ok) {
224             return napi_invalid_arg;
225         }
226         output.push_back(std::move(item));
227     }
228     return napi_ok;
229 }
230 
231 template<typename T>
Convert2Value(napi_env env,napi_value input,std::map<std::string,T> & output)232 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, std::map<std::string, T> &output)
233 {
234     napi_value map = nullptr;
235     uint32_t count = 0;
236     napi_status status = napi_get_property_names(env, input, &map);
237     if (status != napi_ok) {
238         return napi_invalid_arg;
239     }
240     status = napi_get_array_length(env, map, &count);
241     if (status != napi_ok || count == 0) {
242         return napi_invalid_arg;
243     }
244     napi_value jsKey = nullptr;
245     napi_value jsVal = nullptr;
246     for (uint32_t index = 0; index < count; index++) {
247         status = napi_get_element(env, map, index, &jsKey);
248         if (status != napi_ok) {
249             return napi_invalid_arg;
250         }
251         std::string key = Convert2String(env, jsKey);
252         status = napi_get_property(env, input, jsKey, &jsVal);
253         if (status != napi_ok || jsVal == nullptr) {
254             return napi_invalid_arg;
255         }
256         T val;
257         int32_t ret = Convert2Value(env, jsVal, val);
258         if (ret != napi_ok) {
259             return napi_invalid_arg;
260         }
261         output.insert(std::pair<std::string, T>(key, val));
262     }
263     return napi_ok;
264 }
265 } // namespace DataShare
266 } // namespace OHOS
267 
268 #endif // DATASHARE_JSUTILS_H