1 /* 2 * Copyright (c) 2025 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 AIP_NAPI_UTILS_H 17 #define AIP_NAPI_UTILS_H 18 19 #include <type_traits> 20 #include <variant> 21 22 #include "i_aip_core_manager.h" 23 #include "napi/native_api.h" 24 #include "napi/native_node_api.h" 25 26 namespace OHOS { 27 namespace DataIntelligence { 28 class AipNapiUtils { 29 public: 30 AipNapiUtils() = default; 31 ~AipNapiUtils() = default; 32 33 static bool LoadAlgoLibrary(const std::string &libraryName, AipCoreManagerHandle &aipMgrHandler); 34 static bool UnLoadAlgoLibrary(AipCoreManagerHandle &aipMgrHandler); 35 static IAipCoreManager *GetAlgoObj(AipCoreManagerHandle &aipMgrHandler); 36 static bool ValidateArgsType(napi_env env, napi_value *args, size_t argc, 37 const std::vector<std::string> &expectedTypes); 38 static bool TransJsToStr(napi_env env, napi_value value, std::string &str); 39 static bool TransJsToStrUnlimited(napi_env env, napi_value value, std::string &str); 40 static bool TransJsToInt32(napi_env env, napi_value value, int32_t &res); 41 static bool TransJsToDouble(napi_env env, napi_value value, double &res); 42 static bool TransJsToBool(napi_env env, napi_value value, bool &res); 43 static void CreateStringData(napi_env env, napi_value aipServiceValue, napi_value result, const std::string name, 44 std::string &content); 45 static void CreateInt32Data(napi_env env, napi_value aipServiceValue, napi_value result, const std::string name, 46 int32_t value); 47 static void CreateDoubleData(napi_env env, double value, napi_value *result); 48 static void SetInt32Property(napi_env env, napi_value targetObj, int32_t value, const char *propName); 49 static void SetStringProperty(napi_env env, napi_value targetObj, std::string value, const char *propName); 50 static void SetPropertyName(napi_env env, napi_value targetObj, const char *propName, napi_value propValue); 51 static bool CheckModelConfig(napi_env env, napi_value value); 52 53 static napi_status Convert2Value(napi_env env, napi_value in, bool &out); 54 static napi_status Convert2Value(napi_env env, napi_value in, std::vector<uint8_t> &out); 55 static napi_status Convert2Value(napi_env env, napi_value in, int32_t &out); 56 static napi_status Convert2Value(napi_env env, napi_value in, uint32_t &out); 57 static napi_status Convert2Value(napi_env env, napi_value in, int64_t &out); 58 static napi_status Convert2Value(napi_env env, napi_value in, float &out); 59 static napi_status Convert2Value(napi_env env, napi_value in, double &out); 60 static napi_status Convert2Value(napi_env env, napi_value in, std::string &out); 61 static napi_status Convert2Value(napi_env env, napi_value in, std::vector<float> &out); 62 63 template <typename T> 64 struct is_shared_ptr : std::false_type {}; 65 template <typename U> 66 struct is_shared_ptr<std::shared_ptr<U>> : std::true_type {}; 67 68 template<typename T> 69 static typename std::enable_if<!is_shared_ptr<T>::value, napi_status>::type 70 Convert2Value(napi_env env, napi_value in, T &out); 71 72 template<typename T> 73 static typename std::enable_if<is_shared_ptr<T>::value, napi_status>::type 74 Convert2Value(napi_env env, napi_value in, T &out) 75 { 76 return Convert2Value(env, in, *out); 77 } 78 79 static bool IsNull(napi_env env, napi_value value); 80 81 static std::pair<napi_status, napi_value> GetInnerValue(napi_env env, napi_value in, const std::string &prop, 82 bool optional); 83 84 template<typename T> 85 static inline napi_status GetNamedProperty( 86 napi_env env, napi_value in, const std::string &prop, T &value, bool optional = false) 87 { 88 auto [status, jsValue] = GetInnerValue(env, in, prop, optional); 89 if (jsValue == nullptr) { 90 return status; 91 } 92 return Convert2Value(env, jsValue, value); 93 }; 94 95 template<typename T> 96 static napi_status Convert2Value(napi_env env, napi_value in, std::vector<T> &out); 97 98 template<typename T> 99 static napi_status Convert2Value(napi_env env, napi_value in, std::map<std::string, T> &out); 100 101 template<typename T> 102 static napi_status Convert2ValuePtr(napi_env env, napi_value in, std::shared_ptr<T> &out); 103 104 static napi_status Convert2Value(napi_env env, const napi_value &in, napi_value &out); 105 106 static napi_status Convert2JSValue(napi_env env, const std::vector<uint8_t> &in, napi_value &out); 107 static napi_status Convert2JSValue(napi_env env, const std::vector<float> &in, napi_value &out); 108 static napi_status Convert2JSValue(napi_env env, const std::string &in, napi_value &out); 109 static napi_status Convert2JSValue(napi_env env, const int32_t &in, napi_value &out); 110 static napi_status Convert2JSValue(napi_env env, const int64_t &in, napi_value &out); 111 static napi_status Convert2JSValue(napi_env env, const uint64_t &in, napi_value &out); 112 static napi_status Convert2JSValue(napi_env env, const double &in, napi_value &out); 113 static napi_status Convert2JSValue(napi_env env, const bool &in, napi_value &out); 114 static napi_status Convert2JSValue(napi_env env, const std::map<std::string, double> &in, napi_value &out); 115 template <typename T> 116 static napi_status Convert2JSValue(napi_env env, const std::vector<T> &value, napi_value &out); 117 118 template <typename T> 119 static napi_status GetJSValue(napi_env env, const T &value, napi_value &out); 120 121 template <typename T, typename First, typename... Types> 122 static napi_status GetJSValue(napi_env env, const T &value, napi_value &out); 123 124 template <typename... Types> 125 static napi_status Convert2JSValue(napi_env env, const std::variant<Types...> &value, napi_value &out) 126 { 127 return GetJSValue<decltype(value), Types...>(env, value, out); 128 } 129 }; 130 131 template<typename T> 132 napi_status AipNapiUtils::Convert2Value(napi_env env, napi_value jsValue, std::vector<T> &value) 133 { 134 bool isArray = false; 135 napi_is_array(env, jsValue, &isArray); 136 if (!isArray) { 137 return napi_invalid_arg; 138 } 139 140 uint32_t arrLen = 0; 141 napi_get_array_length(env, jsValue, &arrLen); 142 if (arrLen == 0) { 143 return napi_ok; 144 } 145 146 for (size_t i = 0; i < arrLen; ++i) { 147 napi_value element; 148 napi_get_element(env, jsValue, i, &element); 149 T item; 150 auto status = Convert2Value(env, element, item); 151 if (status != napi_ok) { 152 return napi_invalid_arg; 153 } 154 value.push_back(std::move(item)); 155 } 156 return napi_ok; 157 } 158 159 template<typename T> 160 napi_status AipNapiUtils::Convert2Value(napi_env env, napi_value jsValue, std::map<std::string, T> &value) 161 { 162 napi_value jsMapList = nullptr; 163 uint32_t jsCount = 0; 164 napi_status status = napi_get_property_names(env, jsValue, &jsMapList); 165 if (status != napi_ok) { 166 return napi_invalid_arg; 167 } 168 status = napi_get_array_length(env, jsMapList, &jsCount); 169 if (status != napi_ok || jsCount <= 0) { 170 return napi_invalid_arg; 171 } 172 napi_value jsKey = nullptr; 173 napi_value jsVal = nullptr; 174 for (uint32_t index = 0; index < jsCount; index++) { 175 status = napi_get_element(env, jsMapList, index, &jsKey); 176 if (status != napi_ok) { 177 return napi_invalid_arg; 178 } 179 std::string key; 180 int ret = Convert2Value(env, jsKey, key); 181 if (ret != napi_ok) { 182 return napi_invalid_arg; 183 } 184 status = napi_get_property(env, jsValue, jsKey, &jsVal); 185 if (status != napi_ok || jsVal == nullptr) { 186 return napi_invalid_arg; 187 } 188 T val; 189 ret = Convert2Value(env, jsVal, val); 190 if (ret != napi_ok) { 191 return napi_invalid_arg; 192 } 193 value.insert(std::pair<std::string, T>(key, val)); 194 } 195 return napi_ok; 196 } 197 198 199 template <typename T> 200 napi_status AipNapiUtils::Convert2JSValue(napi_env env, const std::vector<T> &value, 201 napi_value &out) 202 { 203 napi_status status = napi_create_array_with_length(env, value.size(), &out); 204 if (status != napi_ok) { 205 return status; 206 } 207 for (size_t i = 0; i < value.size(); ++i) { 208 napi_value jsValue; 209 napi_create_object(env, &jsValue); 210 Convert2JSValue(env, value[i], jsValue); 211 napi_set_element(env, out, i, jsValue); 212 } 213 return napi_ok; 214 } 215 216 template <typename T> 217 napi_status AipNapiUtils::GetJSValue(napi_env env, const T &value, napi_value &out) 218 { 219 return napi_invalid_arg; 220 } 221 222 template <typename T, typename First, typename... Types> 223 napi_status AipNapiUtils::GetJSValue(napi_env env, const T &value, napi_value &out) 224 { 225 auto *val = std::get_if<First>(&value); 226 if (val != nullptr) { 227 Convert2JSValue(env, *val, out); 228 return napi_ok; 229 } 230 return GetJSValue<T, Types...>(env, value, out); 231 } 232 233 #define LOG_ERROR_RETURN(condition, message, retVal) \ 234 do { \ 235 if (!(condition)) { \ 236 AIP_HILOGE(message); \ 237 return retVal; \ 238 } \ 239 } while (0) 240 } // namespace DataIntelligence 241 } // namespace OHOS 242 #endif // AIP_NAPI_UTILS_H 243