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 RESSCHED_INTERFACES_KITS_NAPI_JS_NAPI_UTILS_H
17 #define RESSCHED_INTERFACES_KITS_NAPI_JS_NAPI_UTILS_H
18 
19 #include <memory>
20 
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 
24 namespace OHOS {
25 namespace ResourceSchedule {
26 constexpr size_t ARGC_MAX_COUNT = 10;
27 
28 #define NAPI_CALL_NO_THROW(theCall, retVal)      \
29     do {                                         \
30         if ((theCall) != napi_ok) {              \
31             return retVal;                       \
32         }                                        \
33     } while (0)
34 
35 
CreateJsUndefined(napi_env env)36 inline napi_value CreateJsUndefined(napi_env env)
37 {
38     napi_value result = nullptr;
39     napi_get_undefined(env, &result);
40     return result;
41 }
42 
CreateJsNull(napi_env env)43 inline napi_value CreateJsNull(napi_env env)
44 {
45     napi_value result = nullptr;
46     napi_get_null(env, &result);
47     return result;
48 }
49 
CreateJsNumber(napi_env env,int32_t value)50 inline napi_value CreateJsNumber(napi_env env, int32_t value)
51 {
52     napi_value result = nullptr;
53     napi_create_int32(env, value, &result);
54     return result;
55 }
56 
CreateJsNumber(napi_env env,uint32_t value)57 inline napi_value CreateJsNumber(napi_env env, uint32_t value)
58 {
59     napi_value result = nullptr;
60     napi_create_uint32(env, value, &result);
61     return result;
62 }
63 
CreateJsNumber(napi_env env,int64_t value)64 inline napi_value CreateJsNumber(napi_env env, int64_t value)
65 {
66     napi_value result = nullptr;
67     napi_create_int64(env, value, &result);
68     return result;
69 }
70 
CreateJsNumber(napi_env env,double value)71 inline napi_value CreateJsNumber(napi_env env, double value)
72 {
73     napi_value result = nullptr;
74     napi_create_double(env, value, &result);
75     return result;
76 }
77 
78 template<class T>
CreateJsValue(napi_env env,const T & value)79 napi_value CreateJsValue(napi_env env, const T& value)
80 {
81     using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
82     napi_value result = nullptr;
83     if constexpr (std::is_same_v<ValueType, bool>) {
84         napi_get_boolean(env, value, &result);
85         return result;
86     } else if constexpr (std::is_arithmetic_v<ValueType>) {
87         return CreateJsNumber(env, value);
88     } else if constexpr (std::is_same_v<ValueType, std::string>) {
89         napi_create_string_utf8(env, value.c_str(), value.length(), &result);
90         return result;
91     } else if constexpr (std::is_enum_v<ValueType>) {
92         return CreateJsNumber(env, static_cast<std::make_signed_t<ValueType>>(value));
93     } else if constexpr (std::is_same_v<ValueType, const char*>) {
94         (value != nullptr) ? napi_create_string_utf8(env, value, strlen(value), &result) :
95             napi_get_undefined(env, &result);
96         return result;
97     }
98 }
99 
ConvertFromJsNumber(napi_env env,napi_value jsValue,int32_t & value)100 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, int32_t& value)
101 {
102     NAPI_CALL_NO_THROW(napi_get_value_int32(env, jsValue, &value), false);
103     return true;
104 }
105 
ConvertFromJsNumber(napi_env env,napi_value jsValue,uint32_t & value)106 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, uint32_t& value)
107 {
108     NAPI_CALL_NO_THROW(napi_get_value_uint32(env, jsValue, &value), false);
109     return true;
110 }
111 
ConvertFromJsNumber(napi_env env,napi_value jsValue,int64_t & value)112 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, int64_t& value)
113 {
114     NAPI_CALL_NO_THROW(napi_get_value_int64(env, jsValue, &value), false);
115     return true;
116 }
117 
ConvertFromJsNumber(napi_env env,napi_value jsValue,double & value)118 inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, double& value)
119 {
120     NAPI_CALL_NO_THROW(napi_get_value_double(env, jsValue, &value), false);
121     return true;
122 }
123 
124 template<class T>
ConvertFromJsValue(napi_env env,napi_value jsValue,T & value)125 bool ConvertFromJsValue(napi_env env, napi_value jsValue, T& value)
126 {
127     if (jsValue == nullptr) {
128         return false;
129     }
130 
131     using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
132     if constexpr (std::is_same_v<ValueType, bool>) {
133         NAPI_CALL_NO_THROW(napi_get_value_bool(env, jsValue, &value), false);
134         return true;
135     } else if constexpr (std::is_arithmetic_v<ValueType>) {
136         return ConvertFromJsNumber(env, jsValue, value);
137     } else if constexpr (std::is_same_v<ValueType, std::string>) {
138         size_t len = 0;
139         NAPI_CALL_NO_THROW(napi_get_value_string_utf8(env, jsValue, nullptr, 0, &len), false);
140         auto buffer = std::make_unique<char[]>(len + 1);
141         size_t strLength = 0;
142         NAPI_CALL_NO_THROW(napi_get_value_string_utf8(env, jsValue, buffer.get(), len + 1, &strLength), false);
143         value = buffer.get();
144         return true;
145     } else if constexpr (std::is_enum_v<ValueType>) {
146         std::make_signed_t<ValueType> numberValue = 0;
147         if (!ConvertFromJsNumber(env, jsValue, numberValue)) {
148             return false;
149         }
150         value = static_cast<ValueType>(numberValue);
151         return true;
152     }
153     return false;
154 }
155 } // ResourceSchedule
156 } // OHOS
157 
158 #endif // RESSCHED_INTERFACES_KITS_NAPI_JS_NAPI_UTILS_H