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