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 <iostream>
20 #include <map>
21 #include <string>
22 #include <type_traits>
23 #include <variant>
24 #include <vector>
25 
26 #include "log_print.h"
27 #include "napi/native_api.h"
28 #include "napi/native_common.h"
29 #include "napi/native_node_api.h"
30 #include "napi_preferences_error.h"
31 #include "preferences_value.h"
32 
33 namespace OHOS {
34 namespace PreferencesJsKit {
35 namespace JSUtils {
36 
37 using namespace NativePreferences;
38 
39 constexpr int32_t OK = 0;
40 constexpr int32_t ERR = -1;
41 constexpr int32_t EXCEED_MAX_LENGTH = -2;
42 constexpr int32_t BUF_CACHE_MARGIN = 4;
43 constexpr int32_t ASYNC_RST_SIZE = 2;
44 constexpr int32_t MAX_VALUE_LENGTH = 16 * 1024 * 1024;
45 constexpr int32_t SYNC_RESULT_ELEMNT_NUM = 2;
46 constexpr const char* GLOBAL_JSON = "JSON";
47 constexpr const char* GLOBAL_STRINGIFY = "stringify";
48 constexpr const char* GLOBAL_PARSE = "parse";
49 constexpr const char* GLOBAL_PARSE_SENDABLE = "parseSendable";
50 
51 bool Equals(napi_env env, napi_value value, napi_ref copy);
52 
53 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, bool &output);
54 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, float &output);
55 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, double &output);
56 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, int32_t &output);
57 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, int64_t &output);
58 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, std::vector<uint8_t> &output);
59 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, std::string &output);
60 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, Object &output);
61 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, BigInt &output);
62 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, std::monostate &value);
63 
64 template<typename T> int32_t Convert2NativeValue(napi_env env, napi_value jsValue, std::vector<T> &value);
65 
66 template<typename... Types>
67 int32_t Convert2NativeValue(napi_env env, napi_value jsValue, std::variant<Types...> &value);
68 
69 napi_value Convert2JSValue(napi_env env, int32_t value);
70 napi_value Convert2JSValue(napi_env env, int64_t value);
71 napi_value Convert2JSValue(napi_env env, uint32_t value);
72 napi_value Convert2JSValue(napi_env env, bool value);
73 napi_value Convert2JSValue(napi_env env, float value);
74 napi_value Convert2JSValue(napi_env env, double value);
75 napi_value Convert2JSValue(napi_env env, const std::vector<uint8_t> &value);
76 napi_value Convert2JSValue(napi_env env, const std::string &value);
77 napi_value Convert2JSValue(napi_env env, const OHOS::NativePreferences::Object &value);
78 napi_value Convert2JSValue(napi_env env, const BigInt &value);
79 napi_value Convert2JSValue(napi_env env, const std::monostate &value);
80 
81 napi_valuetype GetValueType(napi_env env, napi_value value);
82 std::tuple<napi_status, napi_value> JsonStringify(napi_env env, napi_value value);
83 napi_value JsonParse(napi_env env, const std::string &inStr, bool sendable = false);
84 
85 template<typename T>
86 std::enable_if_t<std::is_class_v<T>, napi_value> Convert2JSValue(napi_env env, const T &value);
87 template<typename T>
88 std::enable_if_t<!std::is_class_v<T>, napi_value> Convert2JSValue(napi_env env, T value);
89 
90 template<typename T> napi_value Convert2JSValue(napi_env env, const std::vector<T> &value);
91 
92 template<typename... Types> napi_value Convert2JSValue(napi_env env, const std::variant<Types...> &value);
93 
GetCPPValue(napi_env env,napi_value jsValue,T & value)94 template<typename T> int32_t GetCPPValue(napi_env env, napi_value jsValue, T &value)
95 {
96     napi_valuetype type;
97     napi_typeof(env, jsValue, &type);
98     LOG_ERROR("parameter type error, jsValue type is %{public}d", type);
99     return napi_invalid_arg;
100 }
101 
GetCPPValue(napi_env env,napi_value jsValue,T & value)102 template<typename T, typename First, typename... Types> int32_t GetCPPValue(napi_env env, napi_value jsValue, T &value)
103 {
104     First cValue;
105     auto ret = Convert2NativeValue(env, jsValue, cValue);
106     if (ret != NAPI_TYPE_ERROR) {
107         value = cValue;
108         return ret;
109     }
110     return GetCPPValue<T, Types...>(env, jsValue, value);
111 }
112 
GetJSValue(napi_env env,const T & value)113 template<typename T> napi_value GetJSValue(napi_env env, const T &value)
114 {
115     return nullptr;
116 }
117 
GetJSValue(napi_env env,const T & value)118 template<typename T, typename First, typename... Types> napi_value GetJSValue(napi_env env, const T &value)
119 {
120     auto *val = std::get_if<First>(&value);
121     if (val != nullptr) {
122         return Convert2JSValue(env, *val);
123     }
124     return GetJSValue<T, Types...>(env, value);
125 }
126 } // namespace JSUtils
127 
Convert2NativeValue(napi_env env,napi_value jsValue,std::vector<T> & value)128 template<typename T> int32_t JSUtils::Convert2NativeValue(napi_env env, napi_value jsValue, std::vector<T> &value)
129 {
130     bool isArray = false;
131     napi_is_array(env, jsValue, &isArray);
132     if (!isArray) {
133         return NAPI_TYPE_ERROR;
134     }
135 
136     uint32_t arrLen = 0;
137     napi_get_array_length(env, jsValue, &arrLen);
138     if (arrLen == 0) {
139         return napi_ok;
140     }
141 
142     for (size_t i = 0; i < arrLen; ++i) {
143         napi_value element;
144         napi_get_element(env, jsValue, i, &element);
145         T item;
146         auto status = Convert2NativeValue(env, element, item);
147         if (status != napi_ok) {
148             return status;
149         }
150         value.push_back(std::move(item));
151     }
152     return napi_ok;
153 }
154 
155 template<typename... Types>
Convert2NativeValue(napi_env env,napi_value jsValue,std::variant<Types...> & value)156 int32_t JSUtils::Convert2NativeValue(napi_env env, napi_value jsValue, std::variant<Types...> &value)
157 {
158     return GetCPPValue<decltype(value), Types...>(env, jsValue, value);
159 }
160 
Convert2JSValue(napi_env env,const std::vector<T> & value)161 template<typename T> napi_value JSUtils::Convert2JSValue(napi_env env, const std::vector<T> &value)
162 {
163     napi_value jsValue;
164     napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
165     if (status != napi_ok) {
166         return nullptr;
167     }
168 
169     for (size_t i = 0; i < value.size(); ++i) {
170         napi_set_element(env, jsValue, i, Convert2JSValue(env, static_cast<const T &>(value[i])));
171     }
172     return jsValue;
173 }
174 
Convert2JSValue(napi_env env,const std::variant<Types...> & value)175 template<typename... Types> napi_value JSUtils::Convert2JSValue(napi_env env, const std::variant<Types...> &value)
176 {
177     return GetJSValue<decltype(value), Types...>(env, value);
178 }
179 } // namespace PreferencesJsKit
180 } // namespace OHOS
181 
182 #endif // DISTRIBUTEDDATAMGR_APPDATAMGR_JSUTILS_H
183