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 a
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 #include "aip_napi_utils.h"
17
18 #include <dlfcn.h>
19
20 #include "aip_log.h"
21
22 #undef LOG_TAG
23 #define LOG_TAG "AipNapiUtils"
24
25 namespace OHOS {
26 namespace DataIntelligence {
27 namespace {
28 static constexpr uint8_t CONFIG_LENGTH_1 = 2;
29 static constexpr uint8_t CONFIG_LENGTH_2 = 3;
30 static constexpr uint32_t MAX_STR_PARAM_LEN = 512;
31 } // namespace
LoadAlgoLibrary(const std::string & algoPath,AipCoreManagerHandle & aipMgrHandler)32 bool AipNapiUtils::LoadAlgoLibrary(const std::string &algoPath, AipCoreManagerHandle &aipMgrHandler)
33 {
34 AIP_HILOGD("Enter");
35 if (aipMgrHandler.handle != nullptr) {
36 AIP_HILOGE("handle has exists");
37 return false;
38 }
39
40 if (algoPath.empty()) {
41 AIP_HILOGE("algoPath is empty");
42 return false;
43 }
44 char libRealPath[PATH_MAX] = {};
45 if (realpath(algoPath.c_str(), libRealPath) == nullptr) {
46 AIP_HILOGE("get absolute algoPath error, %{public}d", errno);
47 return false;
48 }
49
50 aipMgrHandler.handle = dlopen(libRealPath, RTLD_LAZY);
51 if (aipMgrHandler.handle == nullptr) {
52 AIP_HILOGE("cannot load lib error: %{public}s", dlerror());
53 return false;
54 }
55
56 aipMgrHandler.create = reinterpret_cast<IAipCoreManager *(*)()>(dlsym(aipMgrHandler.handle, "Create"));
57 aipMgrHandler.destroy = reinterpret_cast<void (*)(const IAipCoreManager *)>(dlsym(aipMgrHandler.handle, "Destroy"));
58 if (aipMgrHandler.create == nullptr || aipMgrHandler.destroy == nullptr) {
59 dlclose(aipMgrHandler.handle);
60 aipMgrHandler.Clear();
61 AIP_HILOGE("Failed to create and destroy algo");
62 return false;
63 }
64
65 aipMgrHandler.pAipManager = aipMgrHandler.create();
66 AIP_HILOGD("Exit");
67 return true;
68 }
69
70
UnLoadAlgoLibrary(AipCoreManagerHandle & aipMgrHandler)71 bool AipNapiUtils::UnLoadAlgoLibrary(AipCoreManagerHandle &aipMgrHandler)
72 {
73 AIP_HILOGD("Enter");
74 if (aipMgrHandler.handle == nullptr) {
75 AIP_HILOGE("handle is nullptr");
76 return false;
77 }
78
79 if (aipMgrHandler.pAipManager != nullptr && aipMgrHandler.destroy != nullptr) {
80 aipMgrHandler.destroy(aipMgrHandler.pAipManager);
81 aipMgrHandler.pAipManager = nullptr;
82 }
83
84 dlclose(aipMgrHandler.handle);
85 aipMgrHandler.Clear();
86 AIP_HILOGD("Exit");
87 return true;
88 }
89
GetAlgoObj(AipCoreManagerHandle & aipMgrHandler)90 IAipCoreManager *AipNapiUtils::GetAlgoObj(AipCoreManagerHandle &aipMgrHandler)
91 {
92 AIP_HILOGD("Enter");
93 if (aipMgrHandler.handle == nullptr) {
94 AIP_HILOGE("handle is nullptr");
95 return nullptr;
96 }
97
98 if (aipMgrHandler.pAipManager != nullptr) {
99 AIP_HILOGD("pAipManager already exists");
100 return aipMgrHandler.pAipManager;
101 }
102
103 if (aipMgrHandler.create == nullptr) {
104 AIP_HILOGE("create is nullptr");
105 return nullptr;
106 }
107
108 aipMgrHandler.pAipManager = aipMgrHandler.create();
109 AIP_HILOGD("Exit");
110 return aipMgrHandler.pAipManager;
111 }
112
ValidateArgsType(napi_env env,napi_value * args,size_t argc,const std::vector<std::string> & expectedTypes)113 bool AipNapiUtils::ValidateArgsType(napi_env env, napi_value *args, size_t argc,
114 const std::vector<std::string> &expectedTypes)
115 {
116 AIP_HILOGD("Enter");
117 napi_status status = napi_ok;
118 napi_valuetype valueType = napi_undefined;
119
120 if (argc != expectedTypes.size()) {
121 AIP_HILOGE("Wrong number of arguments");
122 return false;
123 }
124
125 for (size_t i = 0; i < argc; ++i) {
126 status = napi_typeof(env, args[i], &valueType);
127 if (status != napi_ok) {
128 AIP_HILOGE("Error while checking arguments types");
129 return false;
130 }
131 std::string expectedType = expectedTypes[i];
132 if ((expectedType == "string" && valueType != napi_string) ||
133 (expectedType == "object" && valueType != napi_object) ||
134 (expectedType == "number" && valueType != napi_number) ||
135 (expectedType == "function" && valueType != napi_function)) {
136 AIP_HILOGE("Wrong argument type");
137 return false;
138 }
139 }
140 return true;
141 }
142
TransJsToStr(napi_env env,napi_value value,std::string & str)143 bool AipNapiUtils::TransJsToStr(napi_env env, napi_value value, std::string &str)
144 {
145 size_t strlen = 0;
146 napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &strlen);
147 if (status != napi_ok) {
148 AIP_HILOGE("Error string length invalid");
149 return false;
150 }
151 if (strlen < 0 || strlen > MAX_STR_PARAM_LEN) {
152 AIP_HILOGE("The string length invalid");
153 return false;
154 }
155 std::vector<char> buf(strlen + 1);
156 status = napi_get_value_string_utf8(env, value, buf.data(), strlen + 1, &strlen);
157 if (status != napi_ok) {
158 AIP_HILOGE("napi_get_value_string_utf8 failed");
159 return false;
160 }
161 str = buf.data();
162 return true;
163 }
164
TransJsToStrUnlimited(napi_env env,napi_value value,std::string & str)165 bool AipNapiUtils::TransJsToStrUnlimited(napi_env env, napi_value value, std::string &str)
166 {
167 size_t strlen = 0;
168 napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &strlen);
169 if (status != napi_ok) {
170 AIP_HILOGE("Error string length invalid");
171 return false;
172 }
173 if (strlen < 0) {
174 AIP_HILOGE("The string length invalid");
175 return false;
176 }
177 std::vector<char> buf(strlen + 1);
178 status = napi_get_value_string_utf8(env, value, buf.data(), strlen + 1, &strlen);
179 if (status != napi_ok) {
180 AIP_HILOGE("napi_get_value_string_utf8 failed");
181 return false;
182 }
183 str = buf.data();
184 return true;
185 }
186
TransJsToInt32(napi_env env,napi_value value,int32_t & res)187 bool AipNapiUtils::TransJsToInt32(napi_env env, napi_value value, int32_t &res)
188 {
189 napi_status status = napi_get_value_int32(env, value, &res);
190 if (status != napi_ok) {
191 AIP_HILOGE("napi_get_value_int32 failed");
192 return false;
193 }
194 return true;
195 }
196
TransJsToDouble(napi_env env,napi_value value,double & res)197 bool AipNapiUtils::TransJsToDouble(napi_env env, napi_value value, double &res)
198 {
199 napi_status status = napi_get_value_double(env, value, &res);
200 if (status != napi_ok) {
201 AIP_HILOGE("napi_get_value_double failed");
202 return false;
203 }
204 return true;
205 }
206
TransJsToBool(napi_env env,napi_value value,bool & res)207 bool AipNapiUtils::TransJsToBool(napi_env env, napi_value value, bool &res)
208 {
209 napi_status status = napi_get_value_bool(env, value, &res);
210 if (status != napi_ok) {
211 return false;
212 }
213 return true;
214 }
215
CreateStringData(napi_env env,napi_value aipServiceValue,napi_value result,const std::string name,std::string & content)216 void AipNapiUtils::CreateStringData(napi_env env, napi_value aipServiceValue, napi_value result, const std::string name,
217 std::string &content)
218 {
219 napi_status ret = napi_create_string_utf8(env, content.c_str(), NAPI_AUTO_LENGTH, &aipServiceValue);
220 if (ret != napi_ok) {
221 AIP_HILOGE("napi_create_string_utf8 failed");
222 return;
223 }
224
225 ret = napi_set_named_property(env, result, name.c_str(), aipServiceValue);
226 if (ret != napi_ok) {
227 AIP_HILOGE("napi_set_named_property failed");
228 }
229 }
230
CreateInt32Data(napi_env env,napi_value aipServiceValue,napi_value result,const std::string name,int32_t value)231 void AipNapiUtils::CreateInt32Data(napi_env env, napi_value aipServiceValue, napi_value result, const std::string name,
232 int32_t value)
233 {
234 napi_status ret = napi_create_int32(env, value, &aipServiceValue);
235 if (ret != napi_ok) {
236 AIP_HILOGE("napi_create_int32 failed");
237 return;
238 }
239
240 ret = napi_set_named_property(env, result, name.c_str(), aipServiceValue);
241 if (ret != napi_ok) {
242 AIP_HILOGE("napi_set_named_property failed");
243 }
244 }
245
CreateDoubleData(napi_env env,double value,napi_value * result)246 void AipNapiUtils::CreateDoubleData(napi_env env, double value, napi_value *result)
247 {
248 napi_status ret = napi_create_double(env, value, result);
249 if (ret != napi_ok) {
250 AIP_HILOGE("napi_create_int32 failed");
251 return;
252 }
253 }
254
SetInt32Property(napi_env env,napi_value targetObj,int32_t value,const char * propName)255 void AipNapiUtils::SetInt32Property(napi_env env, napi_value targetObj, int32_t value, const char *propName)
256 {
257 napi_value prop = nullptr;
258 napi_status ret = napi_create_int32(env, value, &prop);
259 if (ret != napi_ok) {
260 AIP_HILOGE("napi_create_int32 failed");
261 return;
262 }
263 SetPropertyName(env, targetObj, propName, prop);
264 }
265
SetPropertyName(napi_env env,napi_value targetObj,const char * propName,napi_value propValue)266 void AipNapiUtils::SetPropertyName(napi_env env, napi_value targetObj, const char *propName, napi_value propValue)
267 {
268 napi_status status = napi_set_named_property(env, targetObj, propName, propValue);
269 if (status != napi_ok) {
270 AIP_HILOGE("napi_set_named_property failed");
271 return;
272 }
273 }
274
CheckModelConfig(napi_env env,napi_value value)275 bool AipNapiUtils::CheckModelConfig(napi_env env, napi_value value)
276 {
277 napi_valuetype valuetype;
278 napi_status status = napi_typeof(env, value, &valuetype);
279 if (status != napi_ok || valuetype != napi_object) {
280 AIP_HILOGE("ModelConfig is not object");
281 return false;
282 }
283
284 napi_value KeysArray;
285 status = napi_get_property_names(env, value, &KeysArray);
286 if (status != napi_ok) {
287 AIP_HILOGE("Failed to get property names");
288 return false;
289 }
290
291 uint32_t length;
292 status = napi_get_array_length(env, KeysArray, &length);
293 if (status != napi_ok) {
294 AIP_HILOGE("Failed to get array length");
295 return false;
296 }
297
298 if (length != CONFIG_LENGTH_1 && length != CONFIG_LENGTH_2) {
299 AIP_HILOGE("The modelConfig length is failed");
300 return false;
301 }
302 return true;
303 }
304 } // namespace DataIntelligence
305 } // namespace OHOS
306