• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "nfc_napi_common_utils.h"
17 #include <cstring>
18 #include "loghelper.h"
19 #include "nfc_sdk_common.h"
20 #include "securec.h"
21 
22 namespace OHOS {
23 namespace NFC {
24 namespace KITS {
ParseString(napi_env env,std::string & param,napi_value args)25 bool ParseString(napi_env env, std::string &param, napi_value args)
26 {
27     napi_valuetype valuetype;
28     napi_typeof(env, args, &valuetype);
29 
30     DebugLog("param=%{public}d.", valuetype);
31     if (valuetype != napi_string) {
32         DebugLog("Wrong argument type. String expected.");
33         return false;
34     }
35     size_t size = 0;
36 
37     if (napi_get_value_string_utf8(env, args, nullptr, 0, &size) != napi_ok) {
38         ErrorLog("can not get string size");
39         param = "";
40         return false;
41     }
42     param.reserve(size + 1);
43     param.resize(size);
44     if (napi_get_value_string_utf8(env, args, param.data(), (size + 1), &size) != napi_ok) {
45         ErrorLog("can not get string value");
46         param = "";
47         return false;
48     }
49     return true;
50 }
ParseInt32(napi_env env,int32_t & param,napi_value args)51 bool ParseInt32(napi_env env, int32_t &param, napi_value args)
52 {
53     napi_valuetype valuetype;
54     napi_typeof(env, args, &valuetype);
55 
56     DebugLog("ParseInt32, valuetype %{public}d.", valuetype);
57     if (valuetype != napi_number) {
58         ErrorLog("Wrong argument type. Int32 expected.");
59         return false;
60     }
61     napi_get_value_int32(env, args, &param);
62     return true;
63 }
64 
ParseBool(napi_env env,bool & param,napi_value args)65 bool ParseBool(napi_env env, bool &param, napi_value args)
66 {
67     napi_valuetype valuetype;
68     napi_typeof(env, args, &valuetype);
69 
70     DebugLog("param=%{public}d.", valuetype);
71     if (valuetype != napi_boolean) {
72         ErrorLog("Wrong argument type. bool expected.");
73         return false;
74     }
75     napi_get_value_bool(env, args, &param);
76     return true;
77 }
78 
ParseBytesVector(napi_env env,std::vector<unsigned char> & vec,napi_value args)79 bool ParseBytesVector(napi_env env, std::vector<unsigned char> &vec, napi_value args)
80 {
81     bool isArray = false;
82     napi_status status = napi_is_array(env, args, &isArray);
83     if (status != napi_ok || !isArray) {
84         ErrorLog("ParseBytesVector, not array");
85         return false;
86     }
87     uint32_t arrayLength = 0;
88     napi_get_array_length(env, args, &arrayLength);
89     for (uint32_t i = 0; i < arrayLength; i++) {
90         napi_value element = nullptr;
91         napi_get_element(env, args, i, &element);
92 
93         napi_valuetype valueType = napi_undefined;
94         napi_typeof(env, element, &valueType);
95         if (valueType != napi_number) {
96             ErrorLog("ParseBytesVector, not number!");
97             return false;
98         }
99 
100         uint32_t byteValue = 0x0;
101         napi_get_value_uint32(env, element, &byteValue);
102         vec.push_back(static_cast<unsigned char>(byteValue));
103     }
104     return true;
105 }
106 
ParseUInt32Vector(napi_env & env,std::vector<uint32_t> & vec,napi_value & args)107 bool ParseUInt32Vector(napi_env& env, std::vector<uint32_t>& vec, napi_value &args)
108 {
109     bool isArray = false;
110     napi_status status = napi_is_array(env, args, &isArray);
111     if (status != napi_ok || !isArray) {
112         ErrorLog("ParseUInt32Vector: not array");
113         return false;
114     }
115     uint32_t arrayLen = 0;
116     napi_get_array_length(env, args, &arrayLen);
117     for (uint32_t i = 0; i < arrayLen; i++) {
118         napi_value element = nullptr;
119         napi_get_element(env, args, i, &element);
120 
121         napi_valuetype valueType = napi_undefined;
122         napi_typeof(env, element, &valueType);
123         if (valueType != napi_number) {
124             ErrorLog("ParseUInt32Vector, not number!");
125             return false;
126         }
127 
128         uint32_t uint32Value = 0;
129         napi_get_value_uint32(env, element, &uint32Value);
130         vec.push_back(static_cast<uint32_t>(uint32Value));
131     }
132     return true;
133 }
134 
ParseElementName(napi_env & env,ElementName & element,napi_value & args)135 bool ParseElementName(napi_env &env, ElementName &element, napi_value &args)
136 {
137     napi_valuetype valueType = napi_undefined;
138     napi_typeof(env, args, &valueType);
139     if (valueType != napi_object) {
140         ErrorLog("ParseElementName, not object!");
141         return false;
142     }
143     napi_value param = nullptr;
144     napi_get_named_property(env, args, "bundleName", &param);
145     std::string bundleName;
146     ParseString(env, bundleName, param);
147 
148     param = nullptr;
149     napi_get_named_property(env, args, "moduleName", &param);
150     std::string moduleName;
151     ParseString(env, moduleName, param);
152 
153     param = nullptr;
154     napi_get_named_property(env, args, "abilityName", &param);
155     std::string abilityName;
156     ParseString(env, abilityName, param);
157 
158     DebugLog("ParseElementName: bundleName:%{public}s, moduleName:%{public}s, abilityName:%{public}s",
159         bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
160     element.SetBundleName(bundleName);
161     element.SetModuleName(moduleName);
162     element.SetAbilityName(abilityName);
163     return true;
164 }
165 
ParseArrayBuffer(napi_env env,uint8_t ** data,size_t & size,napi_value args)166 bool ParseArrayBuffer(napi_env env, uint8_t **data, size_t &size, napi_value args)
167 {
168     napi_status status;
169     napi_valuetype valuetype;
170     napi_typeof(env, args, &valuetype);
171 
172     DebugLog("param=%{public}d.", valuetype);
173     if (valuetype != napi_object) {
174         ErrorLog("Wrong argument type. object expected.");
175         return false;
176     }
177 
178     status = napi_get_arraybuffer_info(env, args, reinterpret_cast<void **>(data), &size);
179     if (status != napi_ok) {
180         ErrorLog("can not get arraybuffer, error is %{public}d", status);
181         (*data)[0] = 0;
182         return false;
183     }
184     DebugLog("arraybuffer size is %{public}zu,buffer is %{public}d", size, (*data)[0]);
185     return true;
186 }
187 
UndefinedNapiValue(const napi_env & env)188 napi_value UndefinedNapiValue(const napi_env &env)
189 {
190     napi_value result;
191     napi_get_undefined(env, &result);
192     return result;
193 }
194 
ConvertStringVector(napi_env env,napi_value jsValue)195 std::vector<std::string> ConvertStringVector(napi_env env, napi_value jsValue)
196 {
197     bool isTypedArray = false;
198     napi_status status = napi_is_typedarray(env, jsValue, &isTypedArray);
199     if (status != napi_ok || !isTypedArray) {
200         ErrorLog("%{public}s called, napi_is_typedarray error", __func__);
201         return {};
202     }
203 
204     napi_typedarray_type type;
205     size_t length = 0;
206     napi_value buffer = nullptr;
207     size_t offset = 0;
208     NAPI_CALL_BASE(env, napi_get_typedarray_info(env, jsValue, &type, &length, nullptr, &buffer, &offset), {});
209     if (type != napi_uint8_array) {
210         ErrorLog("%{public}s called, napi_uint8_array is null", __func__);
211         return {};
212     }
213     std::string *data = nullptr;
214     size_t total = 0;
215     NAPI_CALL_BASE(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total), {});
216     length = std::min<size_t>(length, total - offset);
217     std::vector<std::string> result(sizeof(std::string) + length);
218     int retCode = memcpy_s(result.data(), result.size(), &data[offset], length);
219     if (retCode != 0) {
220         return {};
221     }
222     return result;
223 }
224 
CreateErrorMessage(napi_env env,const std::string & msg,int32_t errorCode)225 napi_value CreateErrorMessage(napi_env env, const std::string &msg, int32_t errorCode)
226 {
227     napi_value result = nullptr;
228     napi_value message = nullptr;
229     NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), msg.length(), &message));
230     napi_value codeValue = nullptr;
231     std::string errCode = std::to_string(errorCode);
232     NAPI_CALL(env, napi_create_string_utf8(env, errCode.c_str(), errCode.length(), &codeValue));
233     NAPI_CALL(env, napi_create_error(env, codeValue, message, &result));
234     return result;
235 }
236 
CreateUndefined(napi_env env)237 napi_value CreateUndefined(napi_env env)
238 {
239     napi_value result = nullptr;
240     NAPI_CALL(env, napi_get_undefined(env, &result));
241     return result;
242 }
243 
GetNapiStringValue(napi_env env,napi_value napiValue,const std::string & name,const std::string & defValue)244 std::string GetNapiStringValue(
245     napi_env env, napi_value napiValue, const std::string &name, const std::string &defValue)
246 {
247     napi_value value = GetNamedProperty(env, napiValue, name);
248     if (value != nullptr) {
249         return GetStringFromValue(env, value);
250     } else {
251         return defValue;
252     }
253 }
254 
GetStringFromValue(napi_env env,napi_value value)255 std::string GetStringFromValue(napi_env env, napi_value value)
256 {
257     constexpr int32_t maxTextLength = 4096;
258     char msgChars[maxTextLength] = {0};
259     size_t msgLength = 0;
260     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, msgChars, maxTextLength, &msgLength), "");
261     if (msgLength > 0) {
262         return std::string(msgChars, 0, msgLength);
263     } else {
264         return "";
265     }
266 }
267 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)268 napi_value GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
269 {
270     napi_value value = nullptr;
271     bool hasProperty = false;
272     NAPI_CALL(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty));
273     if (hasProperty) {
274         NAPI_CALL(env, napi_get_named_property(env, object, propertyName.data(), &value));
275     }
276     return value;
277 }
278 
GetNapiInt32Value(napi_env env,napi_value napiValue,const std::string & name,const int32_t & defValue)279 int32_t GetNapiInt32Value(napi_env env, napi_value napiValue, const std::string &name, const int32_t &defValue)
280 {
281     napi_value value = GetNamedProperty(env, napiValue, name);
282     if (value != nullptr) {
283         int32_t intValue = 0;
284         napi_status getIntStatus = napi_get_value_int32(env, value, &intValue);
285         if (getIntStatus == napi_ok) {
286             return intValue;
287         }
288     }
289     return defValue;
290 }
291 
UnwrapStringFromJS(napi_env env,napi_value param)292 std::string UnwrapStringFromJS(napi_env env, napi_value param)
293 {
294     constexpr size_t maxTextLength = 1024;
295     char msgChars[maxTextLength] = {0};
296     size_t msgLength = 0;
297     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, param, msgChars, maxTextLength, &msgLength), "");
298     DebugLog("NapiUtil GetStringFromValue msgLength = %{public}zu", msgLength);
299     if (msgLength > 0) {
300         return std::string(msgChars, 0, msgLength);
301     } else {
302         return "";
303     }
304 }
305 
JsStringToBytesVector(napi_env env,napi_value & src,std::vector<unsigned char> & values)306 void JsStringToBytesVector(napi_env env, napi_value &src, std::vector<unsigned char> &values)
307 {
308     napi_valuetype valueType = napi_undefined;
309     napi_typeof(env, src, &valueType);
310     if (valueType != napi_string) {
311         return;
312     }
313 
314     std::string data;
315     ParseString(env, data, src);
316     NfcSdkCommon::HexStringToBytes(data, values);
317 }
318 
ConvertStringVectorToJS(napi_env env,napi_value & result,std::vector<std::string> & stringVector)319 void ConvertStringVectorToJS(napi_env env, napi_value &result, std::vector<std::string>& stringVector)
320 {
321     DebugLog("ConvertStringVectorToJS called");
322     size_t idx = 0;
323 
324     if (stringVector.empty()) {
325         WarnLog("ConvertStringVectorToJS stringVector empty");
326         napi_create_array_with_length(env, 0, &result);
327         return;
328     }
329     DebugLog("ConvertStringVectorToJS size is %{public}zu", stringVector.size());
330     for (auto& str : stringVector) {
331         napi_value obj = nullptr;
332         napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &obj);
333         napi_set_element(env, result, idx, obj);
334         idx++;
335     }
336 }
337 
BytesVectorToJS(napi_env env,napi_value & result,std::vector<unsigned char> & src)338 void BytesVectorToJS(napi_env env, napi_value &result, std::vector<unsigned char>& src)
339 {
340     if (src.empty()) {
341         WarnLog("BytesVectorToJS src empty");
342         napi_create_array_with_length(env, 0, &result);
343         return;
344     }
345     size_t idx = 0;
346     DebugLog("BytesVectorToJS size is %{public}zu", src.size());
347     napi_create_array_with_length(env, src.size(), &result);
348     for (auto& num : src) {
349         napi_value obj = nullptr;
350         napi_create_uint32(env, num, &obj);
351         napi_set_element(env, result, idx, obj);
352         idx++;
353     }
354 }
355 
ConvertStringToNumberArray(napi_env env,napi_value & result,std::string srcValue)356 void ConvertStringToNumberArray(napi_env env, napi_value &result, std::string srcValue)
357 {
358     if (srcValue.empty()) {
359         WarnLog("ConvertStringToNumberArray srcValue empty");
360         napi_create_array_with_length(env, 0, &result);
361         return;
362     }
363     uint32_t strLength = srcValue.length();
364     if (strLength % HEX_BYTE_LEN != 0) {
365         srcValue = '0' + srcValue;
366         strLength++;
367     }
368 
369     napi_create_array_with_length(env, (strLength / HEX_BYTE_LEN), &result);
370     unsigned int srcIntValue;
371     for (uint32_t i = 0; i < strLength; i += HEX_BYTE_LEN) {
372         // parse the hex string bytes into array.
373         std::string oneByte = srcValue.substr(i, HEX_BYTE_LEN);
374         if (sscanf_s(oneByte.c_str(), "%x", &srcIntValue) <= 0) {
375             ErrorLog("ConvertStringToNumberArray, sscanf_s failed.");
376             return;
377         }
378         unsigned char hexByte = static_cast<unsigned char>(srcIntValue & 0xFF);
379         napi_value hexByteValue = nullptr;
380         napi_create_int32(env, hexByte, &hexByteValue);
381         napi_set_element(env, result, (i / HEX_BYTE_LEN), hexByteValue);
382     }
383 }
384 
ConvertNdefRecordVectorToJS(napi_env env,napi_value & result,std::vector<std::shared_ptr<NdefRecord>> & ndefRecords)385 void ConvertNdefRecordVectorToJS(napi_env env, napi_value &result,
386                                  std::vector<std::shared_ptr<NdefRecord>> &ndefRecords)
387 {
388     napi_create_array(env, &result);
389     if (ndefRecords.empty()) {
390         WarnLog("ConvertNdefRecordVectorToJS ndefRecords is empty.");
391         return;
392     }
393     size_t idx = 0;
394     for (auto& ndefRecord : ndefRecords) {
395         napi_value obj = nullptr;
396         ConvertNdefRecordToJS(env, obj, ndefRecord);
397         napi_set_element(env, result, idx, obj);
398         idx++;
399     }
400 }
401 
ConvertNdefRecordToJS(napi_env env,napi_value & result,std::shared_ptr<NdefRecord> & ndefRecord)402 void ConvertNdefRecordToJS(napi_env env, napi_value &result, std::shared_ptr<NdefRecord> &ndefRecord)
403 {
404     napi_create_object(env, &result);
405     if (ndefRecord == nullptr) {
406         WarnLog("ConvertNdefRecordToJS ndefRecord is null.");
407         return;
408     }
409 
410     napi_value tnf;
411     napi_create_int32(env, ndefRecord->tnf_, &tnf);
412     napi_set_named_property(env, result, "tnf", tnf);
413 
414     napi_value rtdType;
415     napi_create_string_utf8(env, ndefRecord->tagRtdType_.c_str(), NAPI_AUTO_LENGTH, &rtdType);
416     napi_set_named_property(env, result, "rtdType", rtdType);
417 
418     napi_value id;
419     napi_create_string_utf8(env, ndefRecord->id_.c_str(), NAPI_AUTO_LENGTH, &id);
420     napi_set_named_property(env, result, "id", id);
421 
422     napi_value payload;
423     napi_create_string_utf8(env, ndefRecord->payload_.c_str(), NAPI_AUTO_LENGTH, &payload);
424     napi_set_named_property(env, result, "payload", payload);
425 }
426 
MatchValueType(napi_env env,napi_value value,napi_valuetype targetType)427 bool MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
428 {
429     napi_valuetype valueType = napi_undefined;
430     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
431     return valueType == targetType;
432 }
433 
MatchParameters(napi_env env,const napi_value parameters[],std::initializer_list<napi_valuetype> valueTypes)434 bool MatchParameters(napi_env env, const napi_value parameters[], std::initializer_list<napi_valuetype> valueTypes)
435 {
436     if (parameters == nullptr) {
437         return false;
438     }
439     int i = 0;
440     for (auto beg = valueTypes.begin(); beg != valueTypes.end(); ++beg) {
441         if (!MatchValueType(env, parameters[i], *beg)) {
442             return false;
443         }
444         ++i;
445     }
446     return true;
447 }
448 
HandleAsyncWork(napi_env env,BaseContext * baseContext,const std::string & workName,napi_async_execute_callback execute,napi_async_complete_callback complete)449 napi_value HandleAsyncWork(napi_env env, BaseContext *baseContext, const std::string &workName,
450     napi_async_execute_callback execute, napi_async_complete_callback complete)
451 {
452     DebugLog("NfcUtil HandleAsyncWork workName = %{public}s", workName.c_str());
453     std::unique_ptr<BaseContext> context(baseContext);
454     if (context == nullptr) {
455         std::string errorCode = std::to_string(napi_invalid_arg);
456         NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), ERR_INIT_CONTEXT.c_str()));
457     }
458     napi_value result = nullptr;
459     if (context != nullptr && context->callbackRef == nullptr) {
460         NAPI_CALL(env, napi_create_promise(env, &context->deferred, &result));
461     } else {
462         NAPI_CALL(env, napi_get_undefined(env, &result));
463     }
464     napi_value resource = CreateUndefined(env);
465     napi_value resourceName = nullptr;
466     NAPI_CALL(env, napi_create_string_utf8(env, workName.data(), NAPI_AUTO_LENGTH, &resourceName));
467     NAPI_CALL(env,
468         napi_create_async_work(env, resource, resourceName, execute, complete, static_cast<void *>(context.get()),
469             &context->work));
470     napi_status queueWorkStatus = napi_queue_async_work(env, context->work);
471     if (queueWorkStatus == napi_ok) {
472         context.release();
473         DebugLog("NapiUtil HandleAsyncWork napi_queue_async_work ok");
474     } else {
475         std::string errorCode = std::to_string(queueWorkStatus);
476         NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), ERR_INIT_CONTEXT.c_str()));
477     }
478     DebugLog("NfcUtil HandleAsyncWork end");
479     return result;
480 }
481 
DoAsyncCallbackOrPromise(const napi_env & env,BaseContext * baseContext,napi_value callbackValue)482 void DoAsyncCallbackOrPromise(const napi_env &env, BaseContext *baseContext, napi_value callbackValue)
483 {
484     if (baseContext == nullptr) {
485         ErrorLog("DoAsyncCallbackOrPromise serious error baseContext nullptr");
486         return;
487     }
488     if (baseContext->callbackRef != nullptr) {
489         DebugLog("DoAsyncCallbackOrPromise for callback");
490         napi_value recv = CreateUndefined(env);
491         napi_value callbackFunc = nullptr;
492         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, baseContext->callbackRef, &callbackFunc));
493         napi_value callbackValues[] = {nullptr, nullptr};
494         callbackValues[0] = baseContext->resolved ? CreateUndefined(env) : callbackValue;
495         callbackValues[1] = baseContext->resolved ? callbackValue : CreateUndefined(env);
496         napi_value result = nullptr;
497         NAPI_CALL_RETURN_VOID(
498             env, napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &result));
499         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, baseContext->callbackRef));
500     } else if (baseContext->deferred != nullptr) {
501         DebugLog("DoAsyncCallbackOrPromise for promise");
502         if (baseContext->resolved) {
503             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, baseContext->deferred, callbackValue));
504         } else {
505             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, baseContext->deferred, callbackValue));
506         }
507     }
508     napi_delete_async_work(env, baseContext->work);
509     delete baseContext;
510     baseContext = nullptr;
511 }
512 
ThrowAsyncError(const napi_env & env,BaseContext * baseContext,int errCode,const std::string & errMsg)513 void ThrowAsyncError(const napi_env &env, BaseContext *baseContext, int errCode, const std::string &errMsg)
514 {
515     if (baseContext == nullptr) {
516         ErrorLog("ThrowAsyncError serious error baseContext nullptr");
517         return;
518     }
519     napi_value businessError = CreateErrorMessage(env, errMsg, errCode);
520     if (baseContext->callbackRef != nullptr) {
521         DebugLog("ThrowAsyncError for callback");
522         napi_value recv = CreateUndefined(env);
523         napi_value callbackFunc = nullptr;
524         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, baseContext->callbackRef, &callbackFunc));
525         napi_value callbackValues[] = {nullptr, nullptr};
526         callbackValues[0] = businessError; // parameter "error"
527         callbackValues[1] = CreateUndefined(env); // parameter "callback"
528         napi_value result = nullptr;
529         NAPI_CALL_RETURN_VOID(
530             env, napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &result));
531         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, baseContext->callbackRef));
532     } else if (baseContext->deferred != nullptr) {
533         DebugLog("ThrowAsyncError for promise");
534         NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, baseContext->deferred, businessError));
535     }
536     if (baseContext->work != nullptr) {
537         napi_delete_async_work(env, baseContext->work);
538     }
539     delete baseContext;
540     baseContext = nullptr;
541 }
542 
IsNumberArray(const napi_env & env,const napi_value & param)543 bool IsNumberArray(const napi_env &env, const napi_value &param)
544 {
545     if (!IsArray(env, param)) {
546         return false;
547     }
548 
549     uint32_t arrayLength = 0;
550     napi_get_array_length(env, param, &arrayLength);
551     napi_value elementValue = nullptr;
552     for (uint32_t i = 0; i < arrayLength; ++i) {
553         napi_get_element(env, param, i, &elementValue);
554         napi_valuetype elementType = napi_undefined;
555         napi_typeof(env, elementValue, &elementType);
556         if (elementType != napi_number) {
557             return false;
558         }
559     }
560     return true;
561 }
562 
IsObjectArray(const napi_env & env,const napi_value & param)563 bool IsObjectArray(const napi_env &env, const napi_value &param)
564 {
565     if (!IsArray(env, param)) {
566         return false;
567     }
568 
569     uint32_t arrayLength = 0;
570     napi_get_array_length(env, param, &arrayLength);
571     napi_value elementValue = nullptr;
572     for (uint32_t i = 0; i < arrayLength; ++i) {
573         napi_get_element(env, param, i, &elementValue);
574         napi_valuetype elementType = napi_undefined;
575         napi_typeof(env, elementValue, &elementType);
576         if (elementType != napi_object) {
577             return false;
578         }
579     }
580     return true;
581 }
582 
IsArray(const napi_env & env,const napi_value & param)583 bool IsArray(const napi_env &env, const napi_value &param)
584 {
585     bool arrayType = false;
586     napi_status status = napi_is_array(env, param, &arrayType);
587     if (status != napi_ok || !arrayType) {
588         return false;
589     }
590 
591     uint32_t arrayLength = 0;
592     napi_get_array_length(env, param, &arrayLength);
593     if (arrayLength == 0) {
594         return false;
595     }
596     return true;
597 }
598 
IsNumber(const napi_env & env,const napi_value & param)599 bool IsNumber(const napi_env &env, const napi_value &param)
600 {
601     napi_valuetype valueType = napi_undefined;
602     napi_typeof(env, param, &valueType);
603     return valueType == napi_number;
604 }
605 
IsString(const napi_env & env,const napi_value & param)606 bool IsString(const napi_env &env, const napi_value &param)
607 {
608     napi_valuetype valueType = napi_undefined;
609     napi_typeof(env, param, &valueType);
610     return valueType == napi_string;
611 }
612 
IsObject(const napi_env & env,const napi_value & param)613 bool IsObject(const napi_env &env, const napi_value &param)
614 {
615     napi_valuetype valueType = napi_undefined;
616     napi_typeof(env, param, &valueType);
617     return valueType == napi_object;
618 }
619 
IsFunction(const napi_env & env,const napi_value & param)620 bool IsFunction(const napi_env &env, const napi_value &param)
621 {
622     napi_valuetype valueType = napi_undefined;
623     napi_typeof(env, param, &valueType);
624     return valueType == napi_function;
625 }
626 
BuildOutputErrorCode(int errCode)627 int BuildOutputErrorCode(int errCode)
628 {
629     if (errCode == BUSI_ERR_PERM) {
630         return BUSI_ERR_PERM;
631     } else if (errCode == BUSI_ERR_PARAM) {
632         return BUSI_ERR_PARAM;
633     } else if (errCode >= ERR_TAG_BASE && errCode < ERR_CE_BASE) {
634         return BUSI_ERR_TAG_STATE_INVALID;
635     }
636     return errCode;
637 }
638 
BuildOutputErrorCodeHce(int errCode)639 int BuildOutputErrorCodeHce(int errCode)
640 {
641     if (errCode == BUSI_ERR_PERM) {
642         return BUSI_ERR_PERM;
643     }
644     if (errCode == BUSI_ERR_PARAM) {
645         return BUSI_ERR_PARAM;
646     }
647     if (errCode == BUSI_ERR_NOT_SYSTEM_APP) {
648         return BUSI_ERR_NOT_SYSTEM_APP;
649     }
650     return BUSI_ERR_HCE_STATE_INVALID;
651 }
652 
BuildErrorMessage(int errCode,std::string funcName,std::string forbiddenPerm,std::string paramName,std::string expertedType)653 std::string BuildErrorMessage(int errCode, std::string funcName, std::string forbiddenPerm,
654     std::string paramName, std::string expertedType)
655 {
656     std::string errMsg;
657     if (errCode == BUSI_ERR_PERM) {
658         return errMsg.append("Permission denied. An attempt was made to ${")
659             .append(funcName)
660             .append("} forbidden by permission: ${")
661             .append(forbiddenPerm)
662             .append("}.");
663     } else if (errCode == BUSI_ERR_PARAM) {
664         if (paramName.length() > 0) {
665             return errMsg.append("Parameter error. The type of \"${")
666                 .append(paramName)
667                 .append("}\" must be ${")
668                 .append(expertedType)
669                 .append("}.");
670         } else {
671             return "Parameter error. The parameter number is invalid.";
672         }
673     } else if (errCode == BUSI_ERR_TAG_STATE_INVALID) {
674         return "Tag running state is abnormal in service.";
675     } else if (errCode == BUSI_ERR_ELEMENT_STATE_INVALID) {
676         return "The element state is invalid.";
677     } else if (errCode == BUSI_ERR_REGISTER_STATE_INVALID) {
678         return "The off() can be called only when the on() has been called.";
679     } else if (errCode == BUSI_ERR_HCE_STATE_INVALID) {
680         return "HCE running state is abnormal in service.";
681     } else if (errCode == BUSI_ERR_NOT_SYSTEM_APP) {
682         return "Not system application.";
683     }
684     return "Unknown error message";
685 }
686 
GenerateBusinessError(const napi_env & env,int errCode,const std::string & errMessage)687 napi_value GenerateBusinessError(const napi_env &env, int errCode, const std::string &errMessage)
688 {
689     napi_value code = nullptr;
690     napi_create_uint32(env, errCode, &code);
691     napi_value message = nullptr;
692     napi_create_string_utf8(env, errMessage.c_str(), NAPI_AUTO_LENGTH, &message);
693     napi_value businessError = nullptr;
694     napi_create_error(env, nullptr, message, &businessError);
695     napi_set_named_property(env, businessError, KEY_CODE.c_str(), code);
696     return businessError;
697 }
698 
CheckUnwrapStatusAndThrow(const napi_env & env,napi_status status,int errCode)699 bool CheckUnwrapStatusAndThrow(const napi_env &env, napi_status status, int errCode)
700 {
701     if (status != napi_ok) {
702         napi_throw(env, GenerateBusinessError(env, errCode, BuildErrorMessage(errCode, "", "", "", "")));
703         return false;
704     }
705     return true;
706 }
CheckContextAndThrow(const napi_env & env,const BaseContext * context,int errCode)707 bool CheckContextAndThrow(const napi_env &env, const BaseContext *context, int errCode)
708 {
709     if (context == nullptr) {
710         napi_throw(env, GenerateBusinessError(env, errCode, BuildErrorMessage(errCode, "", "", "", "")));
711         return false;
712     }
713     return true;
714 }
CheckParametersAndThrow(const napi_env & env,const napi_value parameters[],std::initializer_list<napi_valuetype> types,const std::string & argName,const std::string & argType)715 bool CheckParametersAndThrow(const napi_env &env, const napi_value parameters[],
716     std::initializer_list<napi_valuetype> types, const std::string &argName, const std::string &argType)
717 {
718     if (!MatchParameters(env, parameters, types)) {
719         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PARAM, BuildErrorMessage(BUSI_ERR_PARAM,
720             "", "", argName, argType)));
721         return false;
722     }
723     return true;
724 }
CheckArrayNumberAndThrow(const napi_env & env,const napi_value & param,const std::string & argName,const std::string & argType)725 bool CheckArrayNumberAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
726     const std::string &argType)
727 {
728     if (!IsNumberArray(env, param)) {
729         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PARAM, BuildErrorMessage(BUSI_ERR_PARAM,
730             "", "", argName, argType)));
731         return false;
732     }
733     return true;
734 }
CheckNumberAndThrow(const napi_env & env,const napi_value & param,const std::string & argName,const std::string & argType)735 bool CheckNumberAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
736     const std::string &argType)
737 {
738     if (!IsNumber(env, param)) {
739         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PARAM, BuildErrorMessage(BUSI_ERR_PARAM,
740             "", "", argName, argType)));
741         return false;
742     }
743     return true;
744 }
CheckStringAndThrow(const napi_env & env,const napi_value & param,const std::string & argName,const std::string & argType)745 bool CheckStringAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
746     const std::string &argType)
747 {
748     if (!IsString(env, param)) {
749         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PARAM, BuildErrorMessage(BUSI_ERR_PARAM,
750             "", "", argName, argType)));
751         return false;
752     }
753     return true;
754 }
CheckObjectAndThrow(const napi_env & env,const napi_value & param,const std::string & argName,const std::string & argType)755 bool CheckObjectAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
756     const std::string &argType)
757 {
758     if (!IsObject(env, param)) {
759         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PARAM, BuildErrorMessage(BUSI_ERR_PARAM,
760             "", "", argName, argType)));
761         return false;
762     }
763     return true;
764 }
765 
CheckFunctionAndThrow(const napi_env & env,const napi_value & param,const std::string & argName,const std::string & argType)766 bool CheckFunctionAndThrow(const napi_env &env, const napi_value &param, const std::string &argName,
767     const std::string &argType)
768 {
769     if (!IsFunction(env, param)) {
770         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PARAM, BuildErrorMessage(BUSI_ERR_PARAM,
771             "", "", argName, argType)));
772         return false;
773     }
774     return true;
775 }
776 
CheckArgCountAndThrow(const napi_env & env,int argCount,int expCount)777 bool CheckArgCountAndThrow(const napi_env &env, int argCount, int expCount)
778 {
779     if (argCount != expCount) {
780         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PARAM, BuildErrorMessage(BUSI_ERR_PARAM,
781             "", "", "", "")));
782         return false;
783     }
784     return true;
785 }
CheckTagStatusCodeAndThrow(const napi_env & env,int statusCode,const std::string & funcName)786 bool CheckTagStatusCodeAndThrow(const napi_env &env, int statusCode, const std::string &funcName)
787 {
788     if (statusCode == BUSI_ERR_PERM) {
789         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_PERM,
790             BuildErrorMessage(BUSI_ERR_PERM, funcName, TAG_PERM_DESC, "", "")));
791         return false;
792     } else if (statusCode >= ErrorCode::ERR_TAG_BASE && statusCode < ErrorCode::ERR_CE_BASE) {
793         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_TAG_STATE_INVALID,
794             BuildErrorMessage(BUSI_ERR_TAG_STATE_INVALID, "", "", "", "")));
795         return false;
796     }
797     return true;
798 }
799 
CheckHceStatusCodeAndThrow(const napi_env & env,int statusCode,const std::string & funcName)800 bool CheckHceStatusCodeAndThrow(const napi_env &env, int statusCode, const std::string &funcName)
801 {
802     if (statusCode == KITS::ERR_NONE) {
803         return true;
804     }
805     if (statusCode == BUSI_ERR_NOT_SYSTEM_APP) {
806         napi_throw(env, GenerateBusinessError(env, BUSI_ERR_NOT_SYSTEM_APP,
807                                               BuildErrorMessage(BUSI_ERR_NOT_SYSTEM_APP, funcName, "", "", "")));
808         return false;
809     }
810     if (statusCode == BUSI_ERR_PERM) {
811         napi_value busErr = GenerateBusinessError(
812             env, BUSI_ERR_PERM, BuildErrorMessage(BUSI_ERR_PERM, funcName, CARD_EMULATION_PERM_DESC, "", ""));
813         napi_throw(env, busErr);
814         return false;
815     }
816 
817     napi_throw(env, GenerateBusinessError(env, BUSI_ERR_HCE_STATE_INVALID,
818                                           BuildErrorMessage(BUSI_ERR_HCE_STATE_INVALID, "", "", "", "")));
819     return false;
820 }
821 } // namespace KITS
822 } // namespace NFC
823 } // namespace OHOS
824