1 /*
2  * Copyright (C) 2022 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 #include "image_napi_utils.h"
17 #include <securec.h>
18 #include <unistd.h>
19 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) && defined(HICHECKER_ENABLE)
20 #include "hichecker.h"
21 #endif
22 
23 namespace OHOS {
24 namespace Media {
25 const size_t NUM0 = 0;
26 const size_t NUM1 = 1;
27 const int ARGS3 = 3;
28 const int ARGS4 = 4;
29 const int PARAM0 = 0;
30 const int PARAM1 = 1;
31 const int PARAM2 = 2;
32 const int PARAM3 = 3;
33 
GetBufferByName(napi_env env,napi_value root,const char * name,void ** res,size_t * len)34 bool ImageNapiUtils::GetBufferByName(napi_env env, napi_value root, const char* name, void **res, size_t* len)
35 {
36     napi_value tempValue = nullptr;
37 
38     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_named_property(env, root, name, &tempValue)), false);
39 
40     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_arraybuffer_info(env, tempValue, res, len)), false);
41 
42     return true;
43 }
44 
GetUint32ByName(napi_env env,napi_value root,const char * name,uint32_t * res)45 bool ImageNapiUtils::GetUint32ByName(napi_env env, napi_value root, const char* name, uint32_t *res)
46 {
47     napi_value tempValue = nullptr;
48 
49     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_named_property(env, root, name, &tempValue)), false);
50 
51     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_value_uint32(env, tempValue, res)), false);
52 
53     return true;
54 }
55 
GetInt32ByName(napi_env env,napi_value root,const char * name,int32_t * res)56 bool ImageNapiUtils::GetInt32ByName(napi_env env, napi_value root, const char* name, int32_t *res)
57 {
58     napi_value tempValue = nullptr;
59 
60     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_named_property(env, root, name, &tempValue)), false);
61 
62     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_value_int32(env, tempValue, res)), false);
63 
64     return true;
65 }
66 
GetDoubleByName(napi_env env,napi_value root,const char * name,double * res)67 bool ImageNapiUtils::GetDoubleByName(napi_env env, napi_value root, const char* name, double *res)
68 {
69     napi_value tempValue = nullptr;
70 
71     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_named_property(env, root, name, &tempValue)), false);
72 
73     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_value_double(env, tempValue, res)), false);
74 
75     return true;
76 }
77 
GetBoolByName(napi_env env,napi_value root,const char * name,bool * res)78 bool ImageNapiUtils::GetBoolByName(napi_env env, napi_value root, const char* name, bool *res)
79 {
80     napi_value tempValue = nullptr;
81 
82     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_named_property(env, root, name, &tempValue)), false);
83 
84     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_value_bool(env, tempValue, res)), false);
85 
86     return true;
87 }
88 
GetNodeByName(napi_env env,napi_value root,const char * name,napi_value * res)89 bool ImageNapiUtils::GetNodeByName(napi_env env, napi_value root, const char* name, napi_value *res)
90 {
91     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_named_property(env, root, name, res)), false);
92 
93     return true;
94 }
95 
GetUtf8String(napi_env env,napi_value root,std::string & res,bool eof)96 bool ImageNapiUtils::GetUtf8String(napi_env env, napi_value root, std::string &res, bool eof)
97 {
98     size_t bufferSize = NUM0;
99     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_value_string_utf8(env, root, nullptr,
100         NUM0, &bufferSize)) && bufferSize > NUM0, false);
101 
102     size_t resultSize = NUM0;
103     if (eof) {
104         bufferSize = bufferSize + NUM1;
105     }
106     std::vector<char> buffer(bufferSize);
107     IMG_NAPI_CHECK_RET(IMG_IS_OK(napi_get_value_string_utf8(env, root, &(buffer[NUM0]),
108         bufferSize, &resultSize)) && resultSize > NUM0, false);
109     res.assign(buffer.begin(), buffer.end());
110     return true;
111 }
112 
CreateArrayBuffer(napi_env env,void * src,size_t srcLen,napi_value * res)113 bool ImageNapiUtils::CreateArrayBuffer(napi_env env, void* src, size_t srcLen, napi_value *res)
114 {
115     if (src == nullptr || srcLen == 0) {
116         return false;
117     }
118 
119     void *nativePtr = nullptr;
120     if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) {
121         return false;
122     }
123 
124     if (memcpy_s(nativePtr, srcLen, src, srcLen) != EOK) {
125         return false;
126     }
127     return true;
128 }
129 
CreateNapiInt32(napi_env env,int32_t value,napi_value & root)130 bool ImageNapiUtils::CreateNapiInt32(napi_env env, int32_t value, napi_value &root)
131 {
132     if (napi_create_int32(env, value, &root) != napi_ok) {
133         return false;
134     }
135     return true;
136 }
137 
CreateNapiDouble(napi_env env,double value,napi_value & root)138 bool ImageNapiUtils::CreateNapiDouble(napi_env env, double value, napi_value &root)
139 {
140     if (napi_create_double(env, value, &root) != napi_ok) {
141         return false;
142     }
143     return true;
144 }
145 
getType(napi_env env,napi_value root)146 napi_valuetype ImageNapiUtils::getType(napi_env env, napi_value root)
147 {
148     napi_valuetype res = napi_undefined;
149     napi_typeof(env, root, &res);
150     return res;
151 }
152 
ParseSize(napi_env env,napi_value root,int32_t & width,int32_t & height)153 static bool ParseSize(napi_env env, napi_value root, int32_t& width, int32_t& height)
154 {
155     if (!GET_INT32_BY_NAME(root, "width", width) || !GET_INT32_BY_NAME(root, "height", height)) {
156         return false;
157     }
158     return true;
159 }
160 
ParseImageCreatorReceiverArgs(napi_env env,size_t argc,napi_value argv[],int32_t args[],std::string & errMsg)161 bool ImageNapiUtils::ParseImageCreatorReceiverArgs(napi_env env, size_t argc,
162     napi_value argv[], int32_t args[], std::string &errMsg)
163 {
164     if ((argc != ARGS3) && (argc != ARGS4)) {
165         errMsg = "Invalid arg counts ";
166         errMsg.append(std::to_string(argc));
167         return false;
168     }
169     if (argc == ARGS3) {
170         napi_valuetype argvType0 = ImageNapiUtils::getType(env, argv[PARAM0]);
171         if (argvType0 != napi_object || !ParseSize(env, argv[PARAM0], args[PARAM0], args[PARAM1])) {
172             errMsg = "Invalid arg ";
173             errMsg.append(std::to_string(PARAM0)).append(",type:").append(std::to_string(argvType0));
174             return false;
175         }
176         napi_valuetype argvType1 = ImageNapiUtils::getType(env, argv[PARAM1]);
177         if (argvType1 != napi_number || napi_get_value_int32(env, argv[PARAM1], &(args[PARAM2])) != napi_ok) {
178             errMsg = "Invalid arg ";
179             errMsg.append(std::to_string(PARAM1)).append(",type:").append(std::to_string(argvType1));
180             return false;
181         }
182         napi_valuetype argvType2 = ImageNapiUtils::getType(env, argv[PARAM2]);
183         if (argvType2 != napi_number || napi_get_value_int32(env, argv[PARAM2], &(args[PARAM3])) != napi_ok) {
184             errMsg = "Invalid arg ";
185             errMsg.append(std::to_string(PARAM2)).append(",type:").append(std::to_string(argvType2));
186             return false;
187         }
188         return true;
189     }
190     for (size_t i = PARAM0; i < argc; i++) {
191         napi_valuetype argvType = ImageNapiUtils::getType(env, argv[i]);
192         if (argvType != napi_number) {
193             errMsg = "Invalid arg ";
194             errMsg.append(std::to_string(i)).append(" type ").append(std::to_string(argvType));
195             return false;
196         }
197 
198         napi_status status = napi_get_value_int32(env, argv[i], &(args[i]));
199         if (status != napi_ok) {
200             errMsg = "fail to get arg ";
201             errMsg.append(std::to_string(i)).append(" : ").append(std::to_string(status));
202             return false;
203         }
204     }
205     return true;
206 }
207 
HicheckerReport()208 void ImageNapiUtils::HicheckerReport()
209 {
210 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) && defined(HICHECKER_ENABLE)
211     uint32_t pid = getpid();
212     uint32_t tid = gettid();
213     std::string cautionMsg = "Trigger: pid = " + std::to_string(pid) + ", tid = " + std::to_string(tid);
214     HiviewDFX::HiChecker::NotifySlowProcess(cautionMsg);
215 #endif
216 }
217 
CreateErrorObj(napi_env env,napi_value & errorObj,const int32_t errCode,const std::string errMsg)218 void ImageNapiUtils::CreateErrorObj(napi_env env, napi_value &errorObj,
219     const int32_t errCode, const std::string errMsg)
220 {
221     napi_value outErrorCode = nullptr;
222     napi_value outErrorMsg = nullptr;
223     napi_status status = napi_create_string_utf8(env, std::to_string(errCode).c_str(),
224         NAPI_AUTO_LENGTH, &outErrorCode);
225     if (status != napi_ok) {
226         return;
227     }
228 
229     status = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &outErrorMsg);
230     if (status != napi_ok) {
231         return;
232     }
233 
234     status = napi_create_error(env, outErrorCode, outErrorMsg, &errorObj);
235     if (status != napi_ok) {
236         napi_get_undefined(env, &errorObj);
237     }
238 }
239 
ThrowExceptionError(napi_env env,const int32_t errCode,const std::string errMsg)240 napi_value ImageNapiUtils::ThrowExceptionError(napi_env env, const int32_t errCode,
241     const std::string errMsg)
242 {
243     napi_value result = nullptr;
244     napi_status status = napi_throw_error(env, std::to_string(errCode).c_str(), errMsg.c_str());
245     if (status == napi_ok) {
246         napi_get_undefined(env, &result);
247     }
248     return result;
249 }
250 }  // namespace Media
251 }  // namespace OHOS
252