• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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*/
15const { writeFile } = require("../tools/FileRW");
16const re = require("../tools/re");
17
18let xNapiToolH = `\
19#ifndef CC_TOOL_H
20#define CC_TOOL_H
21
22#include <node_api.h>
23#include <string>
24#include <memory>
25#include <map>
26#include <any>
27#include <optional>
28#include <vector>
29#include <cmath>
30
31using DataPtr = struct DumyData*;
32
33struct CallFunc {
34    napi_env env_;
35    napi_ref funcRef_;
36    napi_ref thisVarRef_;
37};
38struct ThreadsafeFunc {
39    napi_env env_;
40    napi_ref thisVarRef_;
41    napi_threadsafe_function threadsafefunc_;
42};
43class XNapiTool {
44public:
45    static const int ZERO = 0;
46    static const int ONE = 1;
47    static const int TWO = 2;
48    static const int THREE = 3;
49    static const int FOUE = 4;
50    static const int FIVE = 5;
51    static const int SIX = 6;
52    static const int SEVEN = 7;
53    static const int EIGHT = 8;
54    static const int NINE = 9;
55    void RegistOnOffFunc(std::string name, napi_value func);
56    void UnregistOnOffFunc(std::string name);
57    void RegistThreadsafeFunc(std::string name, napi_threadsafe_function thraedsafeFunc);
58    static void CallSyncFunc(CallFunc *pSyncFuncs, napi_value ret);
59    static void CallAsyncFunc(CallFunc *pAsyncFuncs, napi_value ret);
60    static void CallThreadSafeFunc(std::string eventName);
61
62    using CallbackFunction = void (*)(XNapiTool *pxt, DataPtr data);
63    using RELEASE_INSTANCE = void (*)(DataPtr p);
64    static napi_value UndefinedValue(napi_env env);
65    const uint32_t DEFAULT_ARG_COUNT = 8;
66    napi_value UndefinedValue();
67
68    napi_value CreateSubObject(napi_value parent, const char *name);
69    void DefineFunction(const char *funcName, napi_callback callback, napi_value dest = nullptr);
70    void DefineClass(const char *className, napi_callback constructorFunc,
71        std::map<const char *, std::map<const char *, napi_callback>> &valueList, std::map<const char *,
72        napi_callback> &funcList, napi_value dest = nullptr);
73
74    void SetEnumProperty(napi_value dstObj, const char *propName, const std::any objValue);
75    void CreateEnumObject(const char *enumName, std::map<const char *, std::any> enumMap);
76
77    XNapiTool(napi_env env, napi_callback_info info);
78    XNapiTool(napi_env env, napi_value exports);
79    ~XNapiTool();
80
81    bool SwapJs2CBool(napi_value value);
82    int32_t SwapJs2CInt32(napi_value value);
83    uint32_t SwapJs2CUint32(napi_value value);
84    int64_t SwapJs2CInt64(napi_value value);
85    double_t SwapJs2CDouble(napi_value value);
86    size_t SwapJs2CUtf8(napi_value value, std::string &str);
87
88    napi_value SwapC2JsBool(bool value);
89    napi_value SwapC2JsInt32(int32_t value);
90    napi_value SwapC2JsUint32(uint32_t value);
91    napi_value SwapC2JsInt64(int64_t value);
92    napi_value SwapC2JsDouble(double_t value);
93    napi_value SwapC2JsUtf8(const char *value);
94
95    napi_value GetArgv(uint32_t p);
96    uint32_t GetArgc();
97
98    bool GetProperty(napi_value value, const char *propertyName);
99    napi_value GetValueProperty(napi_value value, const char *propertyName);
100    napi_value SetValueProperty(napi_value &value, const char *propertyName, napi_value property);
101
102    napi_value CreateArray(napi_value &value);
103    uint32_t GetArrayLength(napi_value value);
104    napi_value GetArrayElement(napi_value value, uint32_t p);
105    napi_value SetArrayElement(napi_value &value, uint32_t p, napi_value ele);
106
107    uint32_t GetMapLength(napi_value value);
108    napi_value GetMapElementName(napi_value value, uint32_t p);
109    napi_value GetMapElementValue(napi_value value, const char *p);
110    napi_value SetMapElement(napi_value &value, const char *ele_key, napi_value ele_value);
111
112    std::string GetUnionType(napi_value object);
113
114    std::string GetAnyType(napi_value object);
115    std::string GetAnyArrayType(napi_value object);
116    /**
117     * @brief Get any type when function param is any and any type is Array<map<string, string/number/boolean>>.
118     *
119     * @param object Indicates data to be parsed.
120     * @return Returns specific return value type if this function is successfully called such as arr_map_string.
121     */
122    std::string GetAnyTypeArrMap(napi_value object);
123    /**
124     * @brief Get any type when function param is any and any type is map<string, Array<string/number/boolean>>.
125     *
126     * @param object Indicates data to be parsed.
127     * @return Returns specific return value type if this function is successfully called such as map_arr_string.
128     */
129    std::string GetAnyTypeMapArr(napi_value object);
130    /**
131     * @brief Set any value when function param is any and any type is Array<map<string, string/number/boolean>>.
132     *
133     * @param any_type Indicates the type of the param any.
134     * @param argv Indicates data to be parsed.
135     * @param any Indicates parsed data of the param any.
136     * @param len Indicates the length of Array.
137     */
138    void SetAnyValueArrMap(std::string &any_type, napi_value argv, std::any &any, uint32_t len);
139    /**
140     * @brief Set any value when function param is any and any type is map<string, Array<string/number/boolean>>.
141     *
142     * @param any_type Indicates the type of the param any.
143     * @param argv Indicates data to be parsed.
144     * @param any Indicates parsed data of the param any.
145     * @param len Indicates the length of map.
146     */
147    void SetAnyValueMapArr(std::string &any_type, napi_value argv, std::any &any, uint32_t len);
148    void SetAnyValue(std::string &any_type, napi_value argv, std::any &any);
149    /**
150     * @brief Get any value when function param is any and any type is Array<map<string, string/number/boolean>>.
151     *
152     * @param any_type Indicates the type of the param any.
153    * @param result Indicates parsed data of the param any.
154    * @param any Indicates data to be parsed.
155     */
156    void GetAnyValueArrMap(std::string any_type, napi_value &result, std::any any);
157    /**
158     * @brief Get any value when function param is any and any type is map<string, Array<string/number/boolean>>.
159     *
160     * @param any_type Indicates the type of the param any.
161     * @param result Indicates parsed data of the param any.
162     * @param any Indicates data to be parsed.
163     */
164    void GetAnyValueMapArr(std::string any_type, napi_value &result, std::any any);
165    void GetAnyValue(std::string any_type, napi_value &result, std::any any);
166    void GetObjectValVecUint32(std::any &anyVal, napi_value &tnv2);
167    void GetObjectValVecInt32(std::any &anyVal, napi_value &tnv2);
168    void GetObjectValVecInt64(std::any &anyVal, napi_value &tnv2);
169    void GetObjectValVecDouble(std::any &anyVal, napi_value &tnv2);
170    void GetObjectValVecBool(std::any &anyVal, napi_value &tnv2);
171    void GetObjectValVecConstchar(std::any &anyVal, napi_value &tnv2);
172    void GetObjectValMapString(std::any &anyVal, napi_value &tnv2);
173    void GetObjectValMapUint32(std::any &anyVal, napi_value &tnv2);
174    void GetObjectValMapInt32(std::any &anyVal, napi_value &tnv2);
175    void GetObjectValMapInt64(std::any &anyVal, napi_value &tnv2);
176    void GetObjectValMapDouble(std::any &anyVal, napi_value &tnv2);
177    void GetObjectValMapBool(std::any &anyVal, napi_value &tnv2);
178    void GetObjectValMapAny(std::any &anyVal, napi_value &tnv2);
179    void GetObjectValue(napi_value &result, std::map<std::string, std::any> valueIn);
180
181    napi_value SyncCallBack(napi_value func, size_t argc, napi_value *args);
182
183    napi_value StartAsync(CallbackFunction pe, DataPtr data, CallbackFunction pc, napi_value func = nullptr);
184    void FinishAsync(size_t argc, napi_value *args);
185
186    bool IsFailed()
187    {
188        return bFailed_;
189    }
190    napi_value GetError()
191    {
192        return error_;
193    }
194    napi_env GetEnv()
195    {
196        return env_;
197    }
198
199    napi_value tmp_value;
200
201    // create code related class
202public:
203    static void WrapFinalize(napi_env env, XNapiTool *data, DataPtr hint);
204    static std::map<std::string, CallFunc> callFuncs_;
205    static std::map<std::string, ThreadsafeFunc> threadsafeCallFuncs_;
206    void ReleaseInstance();
207    napi_value WrapInstance(DataPtr instance, RELEASE_INSTANCE ri);
208    DataPtr UnWarpInstance();
209
210    void SetAsyncInstance(DataPtr p);
211    void* GetAsyncInstance();
212
213private:
214    napi_env env_;
215    napi_value exports_;
216
217    // analyze params
218    napi_value argv_[8];
219    size_t argc_size;
220    napi_value thisVar_;
221    void *data_;
222
223    // error message
224    napi_value error_;
225    bool bFailed_;
226    bool CheckFailed(bool b, const char *errStr);
227    bool CheckValueType(napi_value value, napi_valuetype type);
228
229    // asynchronous call related code
230    static void AsyncExecute(napi_env env, XNapiTool *p);
231    void AsyncExecuteFunction();
232    static void AsyncComplete(napi_env env, napi_status status, XNapiTool *p);
233    void AsyncCompleteFunction();
234    napi_ref callbackFunc_;
235    napi_ref asyncThisVar_;
236    napi_async_work work_;
237    bool asyncNeedRelease_;
238    CallbackFunction executeFunction_;
239    CallbackFunction completeFunction_;
240    DataPtr valueData_;
241    napi_deferred deferred_;
242    enum class AsyncMode {
243        NONE,
244        CALLBACK,
245        PROMISE,
246    };
247    AsyncMode asyncMode_;
248
249private:
250    napi_ref wrapper_;
251    DataPtr pInstance_;
252    RELEASE_INSTANCE releaseInstance_;
253    DataPtr asyncInstance_;
254};
255
256#endif
257`
258
259let xNapiToolCpp = `
260
261#include "tool_utility.h"
262#include <cassert>
263#include <cstring>
264#include <uv.h>
265
266#define CC_ASSERT(btrue) \\
267    if (!(btrue)) {      \\
268                         \\
269    }                    \\
270    assert(btrue)
271
272XNapiTool::XNapiTool(napi_env env, napi_callback_info info)
273{
274    env_ = env;
275    bFailed_ = false;
276    executeFunction_ = nullptr;
277    completeFunction_ = nullptr;
278    valueData_ = nullptr;
279    asyncNeedRelease_ = false;
280    asyncMode_ = AsyncMode::NONE;
281    pInstance_ = nullptr;
282    releaseInstance_ = nullptr;
283    wrapper_ = nullptr;
284
285    argc_size = DEFAULT_ARG_COUNT;
286
287    napi_status result_status = napi_get_cb_info(env, info, &argc_size, argv_, &thisVar_, &data_);
288    CheckFailed(result_status == napi_ok, "get args fail");
289}
290
291XNapiTool::XNapiTool(napi_env env, napi_value exports)
292{
293    env_ = env;
294    exports_ = exports;
295
296    asyncMode_ = AsyncMode::NONE;
297    wrapper_ = nullptr;
298}
299
300XNapiTool::~XNapiTool()
301{
302    if (asyncMode_ == AsyncMode::PROMISE) {
303        napi_status result_status = napi_delete_async_work(env_, work_);
304        CC_ASSERT(result_status == napi_ok);
305    }
306    if (asyncMode_ == AsyncMode::CALLBACK) {
307        napi_status result_status = napi_delete_reference(env_, callbackFunc_);
308        CC_ASSERT(result_status == napi_ok);
309        napi_delete_reference(env_, asyncThisVar_);
310        result_status = napi_delete_async_work(env_, work_);
311        CC_ASSERT(result_status == napi_ok);
312    }
313    if (wrapper_ != nullptr) {
314        napi_status result_status = napi_delete_reference(env_, wrapper_);
315        CC_ASSERT(result_status == napi_ok);
316    }
317}
318
319bool XNapiTool::SwapJs2CBool(napi_value value)
320{
321    bool result;
322    napi_status result_status = napi_get_value_bool(env_, value, &result);
323    if (CheckFailed(result_status == napi_ok, "swap_js_2_c_bool fail"))
324        return -1;
325    return result;
326}
327
328napi_value XNapiTool::GetArgv(uint32_t p)
329{
330    if (CheckFailed(p < argc_size, "GetArgv失败"))
331        return error_;
332
333    return argv_[p];
334}
335
336uint32_t XNapiTool::GetArgc()
337{
338    return argc_size;
339}
340
341bool XNapiTool::GetProperty(napi_value value, const char *propertyName)
342{
343    napi_value result;
344    bool hasProperty = false;
345    bool isNull = false;
346    bool isUndefined = false;
347    napi_has_named_property(env_, value, propertyName, &hasProperty);
348    if (hasProperty) {
349        napi_get_named_property(env_, value, propertyName, &result);
350        napi_strict_equals(env_, result, nullptr, &isNull);
351        napi_strict_equals(env_, result, nullptr, &isUndefined);
352        if (isNull || isUndefined) {
353            return false;
354        } else {
355            return true;
356        }
357    } else {
358        return false;
359    }
360}
361
362napi_value XNapiTool::GetValueProperty(napi_value value, const char *propertyName)
363{
364    napi_value result;
365    napi_status result_status = napi_get_named_property(env_, value, propertyName, &result);
366    CC_ASSERT(result_status == napi_ok);
367    return result;
368}
369
370napi_value XNapiTool::SetValueProperty(napi_value &value, const char *propertyName, napi_value property)
371{
372    napi_status result_status;
373    if (value == nullptr) {
374        result_status = napi_create_object(env_, &value);
375        CC_ASSERT(result_status == napi_ok);
376    }
377    result_status = napi_set_named_property(env_, value, propertyName, property);
378    CC_ASSERT(result_status == napi_ok);
379    return value;
380}
381
382napi_value XNapiTool::CreateArray(napi_value &value)
383{
384    if (value == nullptr) {
385        napi_status result_status = napi_create_array(env_, &value);
386        CC_ASSERT(result_status == napi_ok);
387    }
388    return value;
389}
390
391uint32_t XNapiTool::GetArrayLength(napi_value value)
392{
393    uint32_t ret;
394    napi_status result_status = napi_get_array_length(env_, value, &ret);
395    CC_ASSERT(result_status == napi_ok);
396    return ret;
397}
398
399napi_value XNapiTool::GetArrayElement(napi_value value, uint32_t p)
400{
401    napi_value result;
402    napi_status result_status = napi_get_element(env_, value, p, &result);
403    CC_ASSERT(result_status == napi_ok);
404    return result;
405}
406
407napi_value XNapiTool::SetArrayElement(napi_value &value, uint32_t p, napi_value ele)
408{
409    napi_status result_status;
410    if (value == nullptr) {
411        result_status = napi_create_array(env_, &value);
412        CC_ASSERT(result_status == napi_ok);
413    }
414    result_status = napi_set_element(env_, value, p, ele);
415    CC_ASSERT(result_status == napi_ok);
416    return value;
417}
418
419uint32_t XNapiTool::GetMapLength(napi_value value)
420{
421    napi_value name_result;
422    napi_get_property_names(env_, value, &name_result);
423    uint32_t ret;
424    napi_status result_status = napi_get_array_length(env_, name_result, &ret);
425    CC_ASSERT(result_status == napi_ok);
426    return ret;
427}
428
429napi_value XNapiTool::GetMapElementName(napi_value value, uint32_t p)
430{
431    napi_value name_result;
432    napi_get_property_names(env_, value, &name_result);
433    napi_value result;
434    napi_status result_status = napi_get_element(env_, name_result, p, &result);
435    CC_ASSERT(result_status == napi_ok);
436    return result;
437}
438
439napi_value XNapiTool::GetMapElementValue(napi_value value, const char *utf8Name)
440{
441    napi_value result;
442    napi_status result_status = napi_get_named_property(env_, value, utf8Name, &result);
443    CC_ASSERT(result_status == napi_ok);
444    return result;
445}
446
447napi_value XNapiTool::SetMapElement(napi_value &value, const char *ele_key, napi_value ele_value)
448{
449    napi_status result_status;
450    if (value == nullptr) {
451        result_status = napi_create_object(env_, &value);
452        CC_ASSERT(result_status == napi_ok);
453    }
454    result_status = napi_set_named_property(env_, value, ele_key, ele_value);
455    CC_ASSERT(result_status == napi_ok);
456    return value;
457}
458
459std::string XNapiTool::GetAnyType(napi_value object)
460{
461    napi_valuetype result;
462    napi_typeof(env_, object, &result);
463    if (result == napi_string) {
464        return "string";
465    } else if (result == napi_number) {
466        return "number";
467    } else if (result == napi_boolean) {
468        return "boolean";
469    } else if (result == napi_object) {
470        bool is_array;
471        napi_is_array(env_, object, &is_array);
472        if (is_array) {
473            napi_value arr_value_result;
474            napi_valuetype arr_type_result;
475            napi_get_element (env_, object, 0, &arr_value_result);
476            napi_typeof(env_, arr_value_result, &arr_type_result);
477            if (arr_type_result == napi_string) {
478                return "arr_string";
479            } else if (arr_type_result == napi_number) {
480                return "arr_number";
481            } else if (arr_type_result == napi_boolean) {
482                return "arr_boolean";
483            } else if (arr_type_result == napi_object) {
484                return GetAnyTypeArrMap(arr_value_result);
485            } else {
486                return nullptr;
487            }
488        }
489        napi_value obj_name_value;
490        napi_value obj_name_result;
491        napi_valuetype obj_name_type;
492        std::string obj_name_string;
493        napi_get_property_names (env_, object, &obj_name_value);
494        napi_get_element (env_, obj_name_value, 0, &obj_name_result);
495        napi_typeof(env_, obj_name_result, &obj_name_type);
496        if (obj_name_type == napi_string) {
497            napi_value obj_value;
498            napi_valuetype obj_value_type;
499            SwapJs2CUtf8(obj_name_result, obj_name_string);
500            napi_get_named_property (env_, object, obj_name_string.c_str(), &obj_value);
501            napi_typeof(env_, obj_value, &obj_value_type);
502            if (obj_value_type == napi_string) {
503                return "map_string";
504            } else if (obj_value_type == napi_number) {
505                return "map_number";
506            } else if (obj_value_type == napi_boolean) {
507                return "map_boolean";
508            } else if (obj_value_type == napi_object) {
509                return GetAnyTypeMapArr(obj_value);
510            } else {
511                return nullptr;
512            }
513        }
514        return nullptr;
515    } else {
516        return nullptr;
517    }
518}
519
520std::string XNapiTool::GetAnyArrayType(napi_value object)
521{
522    napi_valuetype result;
523    napi_typeof(env_, object, &result);
524    if (result == napi_object) {
525        bool is_array;
526        napi_is_array(env_, object, &is_array);
527        if (is_array) {
528            napi_value arr_value_result;
529            napi_valuetype arr_type_result;
530            napi_get_element (env_, object, 0, &arr_value_result);
531            napi_typeof(env_, arr_value_result, &arr_type_result);
532            if (arr_type_result == napi_string) {
533                return "arr_string";
534            } else if (arr_type_result == napi_number) {
535                return "arr_number";
536            } else if (arr_type_result == napi_boolean) {
537                return "arr_boolean";
538            } else {
539                return nullptr;
540            }
541        }
542        return nullptr;
543    }
544    return nullptr;
545}
546
547std::string XNapiTool::GetAnyTypeArrMap(napi_value object) {
548    napi_value obj_name_value;
549    napi_value obj_name_result;
550    napi_valuetype obj_name_type;
551    std::string obj_name_string;
552    napi_get_property_names (env_, object, &obj_name_value);
553    napi_get_element (env_, obj_name_value, 0, &obj_name_result);
554    napi_typeof(env_, obj_name_result, &obj_name_type);
555    if (obj_name_type == napi_string) {
556        napi_value obj_value;
557        napi_valuetype obj_value_type;
558        SwapJs2CUtf8(obj_name_result, obj_name_string);
559        napi_get_named_property (env_, object, obj_name_string.c_str(), &obj_value);
560        napi_typeof(env_, obj_value, &obj_value_type);
561        if (obj_value_type == napi_string) {
562            return "arr_map_string";
563        } else if (obj_value_type == napi_number) {
564            return "arr_map_number";
565        } else if (obj_value_type == napi_boolean) {
566            return "arr_map_boolean";
567        } else {
568            return nullptr;
569        }
570    }
571    return nullptr;
572}
573
574std::string XNapiTool::GetAnyTypeMapArr(napi_value object) {
575    bool is_map_array;
576    napi_is_array(env_, object, &is_map_array);
577    if (is_map_array) {
578        napi_value map_arr_value_result;
579        napi_valuetype map_arr_type_result;
580        napi_get_element (env_, object, 0, &map_arr_value_result);
581        napi_typeof(env_, map_arr_value_result, &map_arr_type_result);
582        if (map_arr_type_result == napi_string) {
583            return "map_arr_string";
584        } else if (map_arr_type_result == napi_number) {
585            return "map_arr_number";
586        } else if (map_arr_type_result == napi_boolean) {
587            return "map_arr_boolean";
588        } else {
589            return nullptr;
590        }
591    }
592    return nullptr;
593}
594
595void XNapiTool::SetAnyValueArrMap(std::string &any_type, napi_value argv, std::any &any, uint32_t len)
596{
597    if (any_type == "arr_map_string") {
598        std::vector<std::map<std::string, std::string>> any_arr_map_string;
599        for (uint32_t i = 0; i < len; i++) {
600            std::map<std::string, std::string> arr_map_string;
601            uint32_t len2 = GetMapLength(GetArrayElement(argv, i));
602            for (uint32_t j = 0; j < len2; j++) {
603                std::string tt1;
604                std::string tt2;
605                SwapJs2CUtf8(GetMapElementName(GetArrayElement(argv, i), j), tt1);
606                SwapJs2CUtf8(GetMapElementValue(GetArrayElement(argv, i), tt1.c_str()), tt2);
607                arr_map_string.insert(std::make_pair(tt1, tt2));
608            }
609            any_arr_map_string.push_back(arr_map_string);
610        }
611        any = any_arr_map_string;
612    } else if (any_type == "arr_map_number") {
613        std::vector<std::map<std::string, std::uint32_t>> any_arr_map_number;
614        for (uint32_t i = 0; i < len; i++) {
615            std::map<std::string, std::uint32_t> arr_map_number;
616            uint32_t len2 = GetMapLength(GetArrayElement(argv, i));
617            for (uint32_t j = 0; j < len2; j++) {
618                std::string tt1;
619                uint32_t tt2;
620                SwapJs2CUtf8(GetMapElementName(GetArrayElement(argv, i), i), tt1);
621                tt2 = SwapJs2CInt32(GetMapElementValue(GetArrayElement(argv, i), tt1.c_str()));
622                arr_map_number.insert(std::make_pair(tt1, tt2));
623            }
624            any_arr_map_number.push_back(arr_map_number);
625        }
626        any = any_arr_map_number;
627    } else if (any_type == "arr_map_boolean") {
628        std::vector<std::map<std::string, bool>> any_arr_map_bool;
629        for (uint32_t i = 0; i < len; i++) {
630            std::map<std::string, bool> arr_map_bool;
631            uint32_t len2 = GetMapLength(GetArrayElement(argv, i));
632            for (uint32_t j = 0; j < len2; j++) {
633                std::string tt1;
634                bool tt2;
635                SwapJs2CUtf8(GetMapElementName(GetArrayElement(argv, i), i), tt1);
636                tt2 = SwapJs2CBool(GetMapElementValue(GetArrayElement(argv, i), tt1.c_str()));
637                arr_map_bool.insert(std::make_pair(tt1, tt2));
638            }
639            any_arr_map_bool.push_back(arr_map_bool);
640        }
641        any = any_arr_map_bool;
642    }
643    return;
644}
645
646void XNapiTool::SetAnyValueMapArr(std::string &any_type, napi_value argv, std::any &any, uint32_t len)
647{
648    if (any_type == "map_arr_string") {
649        std::map<std::string, std::vector<std::string>> any_map_arr_string;
650        for (uint32_t i = 0; i < len; i++) {
651            std::string tt1;
652            std::vector<std::string> map_arr_string;
653            SwapJs2CUtf8(GetMapElementName(argv, i), tt1);
654            uint32_t len2 = GetArrayLength(GetMapElementValue(argv, tt1.c_str()));
655            for (uint32_t j = 0; j < len2; j++) {
656                std::string tt;
657                SwapJs2CUtf8(GetArrayElement(GetMapElementValue(argv, tt1.c_str()), j), tt);
658                map_arr_string.push_back(tt);
659            }
660            any_map_arr_string.insert(std::make_pair(tt1, map_arr_string));
661        }
662        any = any_map_arr_string;
663        return;
664    } else if (any_type == "map_arr_number") {
665        std::map<std::string, std::vector<std::uint32_t>> any_map_arr_number;
666        for (uint32_t i = 0; i < len; i++) {
667            std::string tt1;
668            std::vector<std::uint32_t> map_arr_number;
669            SwapJs2CUtf8(GetMapElementName(argv, i), tt1);
670            uint32_t len2 = GetArrayLength(GetMapElementValue(argv, tt1.c_str()));
671            for (uint32_t j = 0; j < len2; j++) {
672                uint32_t tt;
673                tt = SwapJs2CInt32(GetArrayElement(GetMapElementValue(argv, tt1.c_str()), j));
674                map_arr_number.push_back(tt);
675            }
676            any_map_arr_number.insert(std::make_pair(tt1, map_arr_number));
677        }
678        any = any_map_arr_number;
679        return;
680    } else if (any_type == "map_arr_boolean") {
681        std::map<std::string, std::vector<bool>> any_map_arr_bool;
682        for (uint32_t i = 0; i < len; i++) {
683            std::string tt1;
684            std::vector<bool> map_arr_bool;
685            SwapJs2CUtf8(GetMapElementName(argv, i), tt1);
686            uint32_t len2 = GetArrayLength(GetMapElementValue(argv, tt1.c_str()));
687            for (uint32_t j = 0; j < len2; j++) {
688                bool tt;
689                tt = SwapJs2CBool(GetArrayElement(GetMapElementValue(argv, tt1.c_str()), j));
690                map_arr_bool.push_back(tt);
691            }
692            any_map_arr_bool.insert(std::make_pair(tt1, map_arr_bool));
693        }
694        any = any_map_arr_bool;
695        return;
696    }
697    return;
698}
699
700void XNapiTool::SetAnyValue(std::string &any_type, napi_value argv, std::any &any)
701{
702    std::string get_any_type = any_type.substr(0, 3);
703    if (any_type == "string") {
704        std::string any_string;
705        SwapJs2CUtf8(argv, any_string);
706        any = any_string;
707        return;
708    } else if (any_type == "boolean") {
709        bool any_bool;
710        any_bool = SwapJs2CBool(argv);
711        any = any_bool;
712        return;
713    } else if (any_type == "number") {
714        std::uint32_t any_number;
715        any_number = SwapJs2CInt32(argv);
716        any = any_number;
717        return;
718    } else if (get_any_type == "arr") {
719        uint32_t len = GetArrayLength(argv);
720        if (any_type == "arr_string") {
721            std::vector<std::string> any_arr_string;
722            for (uint32_t i = 0; i < len; i++) {
723                std::string tt;
724                SwapJs2CUtf8(GetArrayElement(argv, i), tt);
725                any_arr_string.push_back(tt);
726            }
727            any = any_arr_string;
728            return;
729        } else if (any_type == "arr_number") {
730            std::vector<std::uint32_t> any_arr_number;
731            for (uint32_t i = 0; i < len; i++) {
732                uint32_t tt;
733                tt = SwapJs2CInt32(GetArrayElement(argv, i));
734                any_arr_number.push_back(tt);
735            }
736            any = any_arr_number;
737            return;
738        } else if (any_type == "arr_boolean") {
739            std::vector<bool> any_arr_boolean;
740            for (uint32_t i = 0; i < len; i++) {
741                bool tt;
742                tt = SwapJs2CBool(GetArrayElement(argv, i));
743                any_arr_boolean.push_back(tt);
744            }
745            any = any_arr_boolean;
746            return;
747        } else if (any_type.substr(0, 7) == "arr_map") {
748            SetAnyValueArrMap(any_type, argv, any, len);
749            return;
750        }
751        return;
752    }  else if (get_any_type == "map") {
753        uint32_t len = GetMapLength(argv);
754        if (any_type == "map_string") {
755            std::map<std::string, std::string> any_map_string;
756            for (uint32_t i = 0; i < len; i++) {
757                std::string tt1;
758                std::string tt2;
759                SwapJs2CUtf8(GetMapElementName(argv, i), tt1);
760                SwapJs2CUtf8(GetMapElementValue(argv, tt1.c_str()), tt2);
761                any_map_string.insert(std::make_pair(tt1, tt2));
762            }
763            any = any_map_string;
764            return;
765        } else if (any_type == "map_number") {
766            std::map<std::string, std::uint32_t> any_map_number;
767            for (uint32_t i = 0; i < len; i++) {
768                std::string tt1;
769                uint32_t tt2;
770                SwapJs2CUtf8(GetMapElementName(argv, i), tt1);
771                tt2 = SwapJs2CInt32(GetMapElementValue(argv, tt1.c_str()));
772                any_map_number.insert(std::make_pair(tt1, tt2));
773            }
774            any = any_map_number;
775            return;
776        } else if (any_type == "map_boolean") {
777            std::map<std::string, bool> any_map_boolean;
778            for (uint32_t i = 0; i < len; i++) {
779                std::string tt1;
780                bool tt2;
781                SwapJs2CUtf8(GetMapElementName(argv, i), tt1);
782                tt2 = SwapJs2CBool(GetMapElementValue(argv, tt1.c_str()));
783                any_map_boolean.insert(std::make_pair(tt1, tt2));
784            }
785            any = any_map_boolean;
786            return;
787        } else if (any_type.substr(0, 7) == "map_arr") {
788            SetAnyValueMapArr(any_type, argv, any, len);
789            return;
790        }
791        return;
792    }
793    return;
794}
795
796void XNapiTool::GetAnyValueArrMap (std::string any_type, napi_value &result, std::any any)
797{
798    if (any_type == "arr_map_number") {
799        std::vector<std::map<std::string, std::uint32_t>> any_arr_map_number =
800        std::any_cast<std::vector<std::map<std::string, std::uint32_t>>>(any);
801        uint32_t len = any_arr_map_number.size();
802        for (uint32_t i = 0; i < len; i++) {
803            napi_value tnv = nullptr;
804            std::map<std::string, std::uint32_t> any_map_number = any_arr_map_number[i];
805            for (auto j = any_map_number.begin(); j != any_map_number.end(); j++) {
806                const char *tnv1;
807                napi_value tnv2 = nullptr;
808                tnv1 = (j->first).c_str();
809                if (typeid(j->second) == typeid(int32_t)) {
810                    tnv2 = SwapC2JsInt32(j->second);
811                } else if (typeid(j->second) == typeid(uint32_t)) {
812                    tnv2 = SwapC2JsUint32(j->second);
813                } else if (typeid(j->second) == typeid(int64_t)) {
814                    tnv2 = SwapC2JsInt64(j->second);
815                } else if (typeid(j->second) == typeid(double_t)) {
816                    tnv2 = SwapC2JsDouble(j->second);
817                }
818                SetMapElement(tnv, tnv1, tnv2);
819            }
820            SetArrayElement(result, i, tnv);
821        }
822        return;
823    } else if (any_type == "arr_map_string") {
824        std::vector<std::map<std::string, std::string>> any_arr_map_string =
825        std::any_cast<std::vector<std::map<std::string, std::string>>>(any);
826        uint32_t len = any_arr_map_string.size();
827        for (uint32_t i = 0; i < len; i++) {
828            napi_value tnv = nullptr;
829            std::map<std::string, std::string> any_map_string = any_arr_map_string[i];
830            for (auto j = any_map_string.begin(); j != any_map_string.end(); j++) {
831                const char *tnv1;
832                napi_value tnv2 = nullptr;
833                tnv1 = (j->first).c_str();
834                tnv2 = SwapC2JsUtf8(j->second.c_str());
835                SetMapElement(tnv, tnv1, tnv2);
836            }
837            SetArrayElement(result, i, tnv);
838        }
839        return;
840    } else if (any_type == "arr_map_boolean") {
841        std::vector<std::map<std::string, bool>> any_arr_map_bool =
842        std::any_cast<std::vector<std::map<std::string, bool>>>(any);
843        uint32_t len = any_arr_map_bool.size();
844        for (uint32_t i = 0; i < len; i++) {
845            napi_value tnv = nullptr;
846            std::map<std::string, bool> any_map_bool= any_arr_map_bool[i];
847            for (auto j = any_map_bool.begin(); j != any_map_bool.end(); j++) {
848                const char *tnv1;
849                napi_value tnv2 = nullptr;
850                tnv1 = (j->first).c_str();
851                tnv2 = SwapC2JsBool(j->second);
852                SetMapElement(tnv, tnv1, tnv2);
853            }
854            SetArrayElement(result, i, tnv);
855        }
856        return;
857    }
858    return;
859}
860
861void XNapiTool::GetAnyValueMapArr (std::string any_type, napi_value &result, std::any any)
862{
863    if (any_type == "map_arr_string") {
864        std::map<std::string, std::vector<std::string>> any_map_arr_string =
865        std::any_cast<std::map<std::string, std::vector<std::string>>>(any);
866        for (auto i = any_map_arr_string.begin(); i != any_map_arr_string.end(); i++) {
867            const char *tnv1;
868            napi_value tnv2 = nullptr;
869            tnv1 = (i->first).c_str();
870            std::vector<std::string> map_arr_string = i->second;
871            uint32_t len2 = map_arr_string.size();
872            for (uint32_t j = 0; j < len2; j++) {
873                napi_value tnv = nullptr;
874                tnv = SwapC2JsUtf8(map_arr_string[j].c_str());
875                SetArrayElement(tnv2, j, tnv);
876            }
877            SetMapElement(result, tnv1, tnv2);
878        }
879        return;
880    } else if (any_type == "map_arr_number") {
881        std::map<std::string, std::vector<std::uint32_t>> any_map_arr_number =
882        std::any_cast<std::map<std::string, std::vector<std::uint32_t>>>(any);
883        for (auto i = any_map_arr_number.begin(); i != any_map_arr_number.end(); i++) {
884            const char *tnv1;
885            napi_value tnv2 = nullptr;
886            tnv1 = (i->first).c_str();
887            std::vector<std::uint32_t> map_arr_number = i->second;
888            uint32_t len2 = map_arr_number.size();
889            for (uint32_t j = 0; j < len2; j++) {
890                napi_value tnv = nullptr;
891                if (typeid(map_arr_number[j]) == typeid(int32_t)) {
892                    tnv = SwapC2JsInt32(map_arr_number[j]);
893                } else if (typeid(map_arr_number[j]) == typeid(uint32_t)) {
894                    tnv = SwapC2JsUint32(map_arr_number[j]);
895                } else if (typeid(map_arr_number[j]) == typeid(int64_t)) {
896                    tnv = SwapC2JsInt64(map_arr_number[j]);
897                } else if (typeid(map_arr_number[j]) == typeid(double_t)) {
898                    tnv = SwapC2JsDouble(map_arr_number[j]);
899                }
900                SetArrayElement(tnv2, j, tnv);
901            }
902            SetMapElement(result, tnv1, tnv2);
903        }
904        return;
905    } else if (any_type == "map_arr_boolean") {
906        std::map<std::string, std::vector<bool>> any_map_arr_bool =
907        std::any_cast<std::map<std::string, std::vector<bool>>>(any);
908        for (auto i = any_map_arr_bool.begin(); i != any_map_arr_bool.end(); i++) {
909            const char *tnv1;
910            napi_value tnv2 = nullptr;
911            tnv1 = (i->first).c_str();
912            std::vector<bool> map_arr_bool = i->second;
913            uint32_t len2 = map_arr_bool.size();
914            for (uint32_t j = 0; j < len2; j++) {
915                napi_value tnv = nullptr;
916                tnv = SwapC2JsBool(map_arr_bool[j]);
917                SetArrayElement(result, j, tnv);
918            }
919            SetMapElement(result, tnv1, tnv2);
920        }
921        return;
922    }
923    return;
924}
925
926void XNapiTool::GetAnyValue (std::string any_type, napi_value &result, std::any any)
927{
928    result = nullptr;
929    std::string get_any_type = any_type.substr(0, 3);
930    if (any_type == "string") {
931        std::string any_string = std::any_cast<std::string>(any);
932        result = SwapC2JsUtf8(any_string.c_str());
933        return;
934    } else if (any_type == "boolean") {
935        bool any_bool = std::any_cast<bool>(any);
936        result = SwapC2JsBool(any_bool);
937        return;
938    } else if (any_type == "number") {
939        std::uint32_t any_number = std::any_cast<std::uint32_t>(any);
940        if (typeid(any_number) == typeid(int32_t))
941            result = SwapC2JsInt32(any_number);
942        else if (typeid(any_number) == typeid(uint32_t))
943            result = SwapC2JsUint32(any_number);
944        else if (typeid(any_number) == typeid(int64_t))
945            result = SwapC2JsInt64(any_number);
946        else if (typeid(any_number) == typeid(double_t))
947            result = SwapC2JsDouble(any_number);
948        return;
949    } else if (get_any_type == "arr") {
950        result = nullptr;
951        if (any_type == "arr_string") {
952            std::vector<std::string> any_arr_string = std::any_cast<std::vector<std::string>>(any);
953            uint32_t len = any_arr_string.size();
954            for (uint32_t i = 0; i < len; i++) {
955                napi_value tnv = nullptr;
956                tnv = SwapC2JsUtf8(any_arr_string[i].c_str());
957                SetArrayElement(result, i, tnv);
958            }
959            return;
960        } else if (any_type == "arr_number") {
961            std::vector<std::uint32_t> any_arr_number = std::any_cast<std::vector<std::uint32_t>>(any);
962            uint32_t len = any_arr_number.size();
963            for (uint32_t i = 0; i < len; i++) {
964                napi_value tnv = nullptr;
965                if (typeid(any_arr_number[i]) == typeid(int32_t)) {
966                    tnv = SwapC2JsInt32(any_arr_number[i]);
967                } else if (typeid(any_arr_number[i]) == typeid(uint32_t)) {
968                    tnv = SwapC2JsUint32(any_arr_number[i]);
969                } else if (typeid(any_arr_number[i]) == typeid(int64_t)) {
970                    tnv = SwapC2JsInt64(any_arr_number[i]);
971                } else if (typeid(any_arr_number[i]) == typeid(double_t)) {
972                    tnv = SwapC2JsDouble(any_arr_number[i]);
973                }
974                SetArrayElement(result, i, tnv);
975            }
976            return;
977        } else if (any_type == "arr_boolean") {
978            std::vector<bool> any_arr_boolean = std::any_cast<std::vector<bool>>(any);
979            uint32_t len = any_arr_boolean.size();
980            for (uint32_t i = 0; i < len; i++) {
981                napi_value tnv = nullptr;
982                tnv = SwapC2JsBool(any_arr_boolean[i]);
983                SetArrayElement(result, i, tnv);
984            }
985            return;
986        } else if (any_type.substr(0, 7) == "arr_map") {
987            GetAnyValueArrMap(any_type, result, any);
988            return;
989        }
990        return;
991    } else if (get_any_type == "map") {
992        if (any_type == "map_string") {
993            std::map<std::string, std::string> any_map_string =
994            std::any_cast<std::map<std::string, std::string>>(any);
995            for (auto i = any_map_string.begin(); i != any_map_string.end(); i++) {
996                const char *tnv1;
997                napi_value tnv2 = nullptr;
998                tnv1 = (i->first).c_str();
999                tnv2 = SwapC2JsUtf8(i->second.c_str());
1000                SetMapElement(result, tnv1, tnv2);
1001            }
1002            return;
1003        } else if (any_type == "map_number") {
1004            std::map<std::string, std::uint32_t> any_map_number =
1005            std::any_cast<std::map<std::string, std::uint32_t>>(any);
1006            for (auto i = any_map_number.begin(); i != any_map_number.end(); i++) {
1007                const char *tnv1;
1008                napi_value tnv2 = nullptr;
1009                tnv1 = (i->first).c_str();
1010                if (typeid(i->second) == typeid(int32_t)) {
1011                    tnv2 = SwapC2JsInt32(i->second);
1012                } else if (typeid(i->second) == typeid(uint32_t)) {
1013                    tnv2 = SwapC2JsUint32(i->second);
1014                } else if (typeid(i->second) == typeid(int64_t)) {
1015                    tnv2 = SwapC2JsInt64(i->second);
1016                } else if (typeid(i->second) == typeid(double_t)) {
1017                    tnv2 = SwapC2JsDouble(i->second);
1018                }
1019                SetMapElement(result, tnv1, tnv2);
1020            }
1021            return;
1022        } else if (any_type == "map_boolean") {
1023            std::map<std::string, bool> any_map_boolean = std::any_cast<std::map<std::string, bool>>(any);
1024            for (auto i = any_map_boolean.begin(); i != any_map_boolean.end(); i++) {
1025                const char *tnv1;
1026                napi_value tnv2 = nullptr;
1027                tnv1 = (i->first).c_str();
1028                tnv2 = SwapC2JsBool(i->second);
1029                SetMapElement(result, tnv1, tnv2);
1030            }
1031            return;
1032        } else if (any_type.substr(0, 7) == "map_arr") {
1033            GetAnyValueMapArr(any_type, result, any);
1034            return;
1035        }
1036        return;
1037    }
1038    return;
1039}
1040
1041std::string XNapiTool::GetUnionType(napi_value object)
1042{
1043    napi_valuetype result;
1044    napi_typeof(env_, object, &result);
1045    if (result == napi_string) {
1046        return "string";
1047    } else if (result == napi_number) {
1048        return "number";
1049    } else if (result == napi_boolean) {
1050        return "boolean";
1051    } else {
1052        return nullptr;
1053    }
1054}
1055
1056void XNapiTool::GetObjectValVecUint32 (std::any &anyVal, napi_value &tnv2)
1057{
1058    std::vector<uint32_t> arr = std::any_cast<std::vector<uint32_t>>(anyVal);
1059    for (size_t j = 0; j < arr.size(); j++) {
1060        uint32_t tt = arr[j] ;
1061        napi_value tnv3 = SwapC2JsUint32(tt);
1062        SetArrayElement(tnv2, j, tnv3);
1063    }
1064}
1065
1066void XNapiTool::GetObjectValVecInt32 (std::any &anyVal, napi_value &tnv2)
1067{
1068    std::vector<int32_t> arr = std::any_cast<std::vector<int32_t>>(anyVal);
1069    for (size_t j = 0; j < arr.size(); j++) {
1070        int32_t tt = arr[j] ;
1071        napi_value tnv3 = SwapC2JsInt32(tt);
1072        SetArrayElement(tnv2, j, tnv3);
1073    }
1074}
1075
1076void XNapiTool::GetObjectValVecInt64 (std::any &anyVal, napi_value &tnv2)
1077{
1078    std::vector<int64_t> arr = std::any_cast<std::vector<int64_t>>(anyVal);
1079    for (size_t j = 0; j < arr.size(); j++) {
1080        int64_t tt = arr[j] ;
1081        napi_value tnv3 = SwapC2JsInt64(tt);
1082        SetArrayElement(tnv2, j, tnv3);
1083    }
1084}
1085
1086void XNapiTool::GetObjectValVecDouble (std::any &anyVal, napi_value &tnv2)
1087{
1088    std::vector<double_t> arr = std::any_cast<std::vector<double_t>>(anyVal);
1089    for (size_t j = 0; j < arr.size(); j++) {
1090        double_t tt = arr[j] ;
1091        napi_value tnv3 = SwapC2JsDouble(tt);
1092        SetArrayElement(tnv2, j, tnv3);
1093    }
1094}
1095
1096void XNapiTool::GetObjectValVecBool (std::any &anyVal, napi_value &tnv2)
1097{
1098    std::vector<bool> arr = std::any_cast<std::vector<bool>>(anyVal);
1099    for (size_t j = 0; j < arr.size(); j++) {
1100        bool tt = arr[j] ;
1101        napi_value tnv3 = SwapC2JsBool(tt);
1102        SetArrayElement(tnv2, j, tnv3);
1103    }
1104}
1105
1106void XNapiTool::GetObjectValVecConstchar (std::any &anyVal, napi_value &tnv2)
1107{
1108    std::vector<const char *> arr = std::any_cast<std::vector<const char *>>(anyVal);
1109    for (size_t j = 0; j < arr.size(); j++) {
1110        const char *tt = arr[j] ;
1111        napi_value tnv3 = SwapC2JsUtf8(tt);
1112        SetArrayElement(tnv2, j, tnv3);
1113    }
1114}
1115
1116void XNapiTool::GetObjectValMapString (std::any &anyVal, napi_value &tnv2)
1117{
1118    std::map<std::string, std::string> a = std::any_cast<std::map<std::string, std::string>>(anyVal);
1119    std::map<std::string, std::string>::iterator iter;
1120    for (iter = a.begin(); iter != a.end(); iter++) {
1121        const char *key = iter->first.c_str();
1122        napi_value value = SwapC2JsUtf8(iter->second.c_str());
1123        SetMapElement(tnv2, key, value);
1124    }
1125}
1126
1127void XNapiTool::GetObjectValMapUint32 (std::any &anyVal, napi_value &tnv2)
1128{
1129    std::map<std::string, uint32_t> a = std::any_cast<std::map<std::string, uint32_t>>(anyVal);
1130    std::map<std::string, uint32_t>::iterator iter;
1131    for (iter = a.begin(); iter != a.end(); iter++) {
1132        const char *key = iter->first.c_str();
1133        napi_value value =  SwapC2JsUint32(iter->second);
1134        SetMapElement(tnv2, key, value);
1135    }
1136}
1137
1138void XNapiTool::GetObjectValMapInt32 (std::any &anyVal, napi_value &tnv2)
1139{
1140    std::map<std::string, int32_t> a = std::any_cast<std::map<std::string, int32_t>>(anyVal);
1141    std::map<std::string, int32_t>::iterator iter;
1142    for (iter = a.begin(); iter != a.end(); iter++) {
1143        const char *key = iter->first.c_str();
1144        napi_value value =  SwapC2JsInt32(iter->second);
1145        SetMapElement(tnv2, key, value);
1146    }
1147}
1148
1149void XNapiTool::GetObjectValMapInt64 (std::any &anyVal, napi_value &tnv2)
1150{
1151    std::map<std::string, int64_t> a = std::any_cast<std::map<std::string, int64_t>>(anyVal);
1152    std::map<std::string, int64_t>::iterator iter;
1153    for (iter = a.begin(); iter != a.end(); iter++) {
1154        const char *key = iter->first.c_str();
1155        napi_value value =  SwapC2JsInt64(iter->second);
1156        SetMapElement(tnv2, key, value);
1157    }
1158}
1159
1160void XNapiTool::GetObjectValMapDouble (std::any &anyVal, napi_value &tnv2)
1161{
1162    std::map<std::string, double_t> a = std::any_cast<std::map<std::string, double_t>>(anyVal);
1163    std::map<std::string, double_t>::iterator iter;
1164    for (iter = a.begin(); iter != a.end(); iter++) {
1165        const char *key = iter->first.c_str();
1166        napi_value value =  SwapC2JsDouble(iter->second);
1167        SetMapElement(tnv2, key, value);
1168    }
1169}
1170
1171void XNapiTool::GetObjectValMapBool (std::any &anyVal, napi_value &tnv2)
1172{
1173    std::map<std::string, bool> a = std::any_cast<std::map<std::string, bool>>(anyVal);
1174    std::map<std::string, bool>::iterator iter;
1175    for (iter = a.begin(); iter != a.end(); iter++) {
1176        const char *key = iter->first.c_str();
1177        napi_value value = SwapC2JsBool(iter->second);
1178        SetMapElement(tnv2, key, value);
1179    }
1180}
1181
1182void XNapiTool::GetObjectValMapAny (std::any &anyVal, napi_value &tnv2)
1183{
1184    std::map<std::string, std::any> a = std::any_cast<std::map<std::string, std::any>>(anyVal);
1185    std::map<std::string, std::any>::iterator iter;
1186    for (iter = a.begin(); iter != a.end(); iter++) {
1187        auto c = iter->second;
1188        if (c.type() == typeid(uint32_t)) {
1189            const char *key = iter->first.c_str();
1190            uint32_t val = std::any_cast<uint32_t>(iter->second);
1191            napi_value value = SwapC2JsUint32(val);
1192            SetMapElement(tnv2, key, value);
1193        } else if (c.type() == typeid(int32_t)) {
1194            const char *key = iter->first.c_str();
1195            int32_t val = std::any_cast<int32_t>(iter->second);
1196            napi_value value = SwapC2JsInt32(val);
1197            SetMapElement(tnv2, key, value);
1198        } else if (c.type() == typeid(int64_t)) {
1199            const char *key = iter->first.c_str();
1200            int64_t val = std::any_cast<int64_t>(iter->second);
1201            napi_value value = SwapC2JsInt64(val);
1202            SetMapElement(tnv2, key, value);
1203        } else if (c.type() == typeid(double_t)) {
1204            const char *key = iter->first.c_str();
1205            double_t val = std::any_cast<double_t>(iter->second);
1206            napi_value value = SwapC2JsDouble(val);
1207            SetMapElement(tnv2, key, value);
1208        } else if (c.type() == typeid(const char *)) {
1209            const char *key = iter->first.c_str();
1210            const char *val = std::any_cast<const char *>(iter->second);
1211            napi_value value = SwapC2JsUtf8(val);
1212            SetMapElement(tnv2, key, value);
1213        } else if (c.type() == typeid(bool)) {
1214            const char *key = iter->first.c_str();
1215            bool val = std::any_cast<bool>(iter->second);
1216            napi_value value = SwapC2JsBool(val);
1217            SetMapElement(tnv2, key, value);
1218        }
1219    }
1220}
1221
1222void XNapiTool::GetObjectValue(napi_value &result, std::map<std::string, std::any> valueIn)
1223{
1224    napi_create_object(env_, &result);
1225
1226    for (auto i = valueIn.begin(); i != valueIn.end(); i++) {
1227        const char *tnv1;
1228        std::any anyValue;
1229        napi_value tnv2 = nullptr;
1230        tnv1 = (i->first).c_str();
1231        auto temp = i->second;
1232        if (temp.type() == typeid(int32_t)) {
1233            tnv2 = SwapC2JsInt32(std::any_cast<int32_t>(temp));
1234        } else if (temp.type() == typeid(uint32_t)) {
1235            tnv2 = SwapC2JsUint32(std::any_cast<uint32_t>(temp));
1236        } else if (temp.type() == typeid(int64_t)) {
1237            tnv2 = SwapC2JsInt64(std::any_cast<int64_t>(temp));
1238        } else if (temp.type() == typeid(double_t)) {
1239            tnv2 = SwapC2JsDouble(std::any_cast<double_t>(temp));
1240        } else if (temp.type() == typeid(const char *)) {
1241            tnv2 = SwapC2JsUtf8(std::any_cast<const char *>(temp));
1242        } else if (temp.type() == typeid(bool)) {
1243            tnv2 = SwapC2JsBool(std::any_cast<bool>(temp));
1244        } else if (temp.type() == typeid(std::vector<uint32_t>)) {
1245            GetObjectValVecUint32(i->second, tnv2);
1246        } else if (temp.type() == typeid(std::vector<int32_t>)) {
1247            GetObjectValVecInt32(i->second, tnv2);
1248        } else if (temp.type() == typeid(std::vector<int64_t>)) {
1249            GetObjectValVecInt64(i->second, tnv2);
1250        } else if (temp.type() == typeid(std::vector<double_t>)) {
1251            GetObjectValVecDouble(i->second, tnv2);
1252        } else if (temp.type() == typeid(std::vector<bool>)) {
1253            GetObjectValVecBool(i->second, tnv2);
1254        } else if (temp.type() == typeid(std::vector<const char *>)) {
1255            GetObjectValVecConstchar(i->second, tnv2);
1256        } else if (temp.type() == typeid(std::map<std::string, std::string>)) {
1257            GetObjectValMapString(i->second, tnv2);
1258        } else if (temp.type() == typeid(std::map<std::string, uint32_t>)) {
1259            GetObjectValMapUint32(i->second, tnv2);
1260        } else if (temp.type() == typeid(std::map<std::string, int32_t>)) {
1261            GetObjectValMapInt32(i->second, tnv2);
1262        } else if (temp.type() == typeid(std::map<std::string, int64_t>)) {
1263            GetObjectValMapInt64(i->second, tnv2);
1264        } else if (temp.type() == typeid(std::map<std::string, double_t>)) {
1265            GetObjectValMapDouble(i->second, tnv2);
1266        } else if (temp.type() == typeid(std::map<std::string, bool>)) {
1267            GetObjectValMapBool(i->second, tnv2);
1268        } else if (temp.type() == typeid(std::map<std::string, std::any>)) {
1269            GetObjectValMapAny(i->second, tnv2);
1270        }
1271
1272        SetMapElement(result, tnv1, tnv2);
1273    }
1274    return;
1275}
1276
1277bool XNapiTool::CheckFailed(bool b, const char *errStr)
1278{
1279    if (bFailed_) {
1280        return true;
1281    }
1282    if (b) {
1283        return false;
1284    }
1285
1286    napi_value errCode = nullptr;
1287    napi_value errMessage = nullptr;
1288
1289    napi_create_string_utf8(env_, "x_tool", strlen("x_tool"), &errCode);
1290    napi_create_string_utf8(env_, errStr, strlen(errStr), &errMessage);
1291    napi_create_error(env_, errCode, errMessage, &error_);
1292    printf("tool_utility err : %s\\n", errStr);
1293
1294    bFailed_ = true;
1295    return true;
1296}
1297
1298int32_t XNapiTool::SwapJs2CInt32(napi_value value)
1299{
1300    int32_t result;
1301    napi_status result_status = napi_get_value_int32(env_, value, &result);
1302    if (CheckFailed(result_status == napi_ok, "swap_js_2_c_int32 fail"))
1303        return -1;
1304    return result;
1305}
1306
1307uint32_t XNapiTool::SwapJs2CUint32(napi_value value)
1308{
1309    uint32_t result;
1310    napi_status result_status = napi_get_value_uint32(env_, value, &result);
1311    if (CheckFailed(result_status == napi_ok, "swap_js_2_c_uint32 fail"))
1312        return -1;
1313    return result;
1314}
1315
1316int64_t XNapiTool::SwapJs2CInt64(napi_value value)
1317{
1318    int64_t result;
1319    napi_status result_status = napi_get_value_int64(env_, value, &result);
1320    if (CheckFailed(result_status == napi_ok, "swap_js_2_c_int32 fail"))
1321        return -1;
1322    return result;
1323}
1324
1325double_t XNapiTool::SwapJs2CDouble(napi_value value)
1326{
1327    double_t result;
1328    napi_status result_status = napi_get_value_double(env_, value, &result);
1329    if (CheckFailed(result_status == napi_ok, "swap_js_2_c_int32 fail"))
1330        return -1;
1331    return result;
1332}
1333
1334size_t XNapiTool::SwapJs2CUtf8(napi_value value, std::string &str)
1335{
1336    char buf[1024];
1337    size_t result;
1338    napi_status result_status = napi_get_value_string_utf8(env_, value, buf, 1024, &result);
1339    if (CheckFailed(result_status == napi_ok, "napi_get_value_string_utf8 fail"))
1340        return -1;
1341    str = buf;
1342    return result;
1343}
1344
1345napi_value XNapiTool::SwapC2JsBool(bool value)
1346{
1347    napi_value result;
1348    napi_status result_status = napi_get_boolean(env_, value, &result);
1349    CC_ASSERT(result_status == napi_ok);
1350    return result;
1351}
1352
1353napi_value XNapiTool::SwapC2JsInt32(int32_t value)
1354{
1355    napi_value result;
1356    napi_status result_status = napi_create_int32(env_, value, &result);
1357    CC_ASSERT(result_status == napi_ok);
1358    return result;
1359}
1360
1361napi_value XNapiTool::SwapC2JsUint32(uint32_t value)
1362{
1363    napi_value result;
1364    napi_status result_status = napi_create_uint32(env_, value, &result);
1365    CC_ASSERT(result_status == napi_ok);
1366    return result;
1367}
1368
1369napi_value XNapiTool::SwapC2JsInt64(int64_t value)
1370{
1371    napi_value result;
1372    napi_status result_status = napi_create_int64(env_, value, &result);
1373    CC_ASSERT(result_status == napi_ok);
1374    return result;
1375}
1376
1377napi_value XNapiTool::SwapC2JsDouble(double_t value)
1378{
1379    napi_value result;
1380    napi_status result_status = napi_create_double(env_, value, &result);
1381    CC_ASSERT(result_status == napi_ok);
1382    return result;
1383}
1384
1385napi_value XNapiTool::SwapC2JsUtf8(const char *value)
1386{
1387    napi_value result;
1388    napi_status result_status = napi_create_string_utf8(env_, value, NAPI_AUTO_LENGTH, &result);
1389    CC_ASSERT(result_status == napi_ok);
1390    return result;
1391}
1392
1393bool XNapiTool::CheckValueType(napi_value value, napi_valuetype type)
1394{
1395    napi_valuetype valueType;
1396    napi_status result_status = napi_typeof(env_, value, &valueType);
1397    CC_ASSERT(result_status == napi_ok);
1398    if (CheckFailed(valueType == type, "传入参数类型不是回调函数"))
1399        return false;
1400    return true;
1401}
1402
1403napi_value XNapiTool::SyncCallBack(napi_value func, size_t argc, napi_value *args)
1404{
1405    napi_value cb_result;
1406    napi_status result_status = napi_call_function(env_, thisVar_, func, argc, args, &cb_result);
1407    CC_ASSERT(result_status == napi_ok);
1408    return cb_result;
1409}
1410
1411void XNapiTool::AsyncExecuteFunction()
1412{
1413    if (executeFunction_ != nullptr) {
1414        executeFunction_(this, valueData_);
1415    }
1416}
1417void XNapiTool::AsyncExecute(napi_env env, XNapiTool *p)
1418{
1419    XNapiTool *pxt = p;
1420    pxt->AsyncExecuteFunction();
1421}
1422void XNapiTool::AsyncCompleteFunction()
1423{
1424    if (completeFunction_ != nullptr) {
1425        completeFunction_(this, valueData_);
1426    }
1427}
1428void XNapiTool::AsyncComplete(napi_env env, napi_status status, XNapiTool *p)
1429{
1430    XNapiTool *pxt = p;
1431    pxt->AsyncCompleteFunction();
1432    delete pxt;
1433}
1434
1435napi_value XNapiTool::StartAsync(CallbackFunction pe, DataPtr data, CallbackFunction pc, napi_value func)
1436{
1437    napi_value result;
1438    napi_status result_status;
1439
1440    if (func == nullptr) {
1441        // promise
1442        result_status = napi_create_promise(env_, &deferred_, &result);
1443        CC_ASSERT(result_status == napi_ok);
1444        asyncMode_ = AsyncMode::PROMISE;
1445    } else {
1446        // callback
1447        result_status = napi_create_reference(env_, func, 1, &callbackFunc_);
1448        CC_ASSERT(result_status == napi_ok);
1449        napi_create_reference(env_, thisVar_, 1, &asyncThisVar_);
1450        asyncMode_ = AsyncMode::CALLBACK;
1451        result = UndefinedValue(env_);
1452    }
1453
1454    asyncNeedRelease_ = true;
1455    executeFunction_ = pe;
1456    completeFunction_ = pc;
1457    valueData_ = data;
1458
1459    napi_value resourceName = nullptr;
1460    result_status = napi_create_string_utf8(env_, "tool_utility", NAPI_AUTO_LENGTH, &resourceName);
1461    CC_ASSERT(result_status == napi_ok);
1462    result_status = napi_create_async_work(env_, nullptr, resourceName,
1463        (napi_async_execute_callback)XNapiTool::AsyncExecute,
1464        (napi_async_complete_callback)XNapiTool::AsyncComplete, this, &work_);
1465    CC_ASSERT(result_status == napi_ok);
1466    result_status = napi_queue_async_work(env_, work_);
1467    CC_ASSERT(result_status == napi_ok);
1468
1469    return result;
1470}
1471
1472void XNapiTool::FinishAsync(size_t argc, napi_value *args)
1473{
1474    if (asyncMode_ == AsyncMode::PROMISE) {
1475        if (argc > 1) {
1476            napi_resolve_deferred(env_, deferred_, args[1]);
1477        } else {
1478            napi_reject_deferred(env_, deferred_, SwapC2JsUtf8("promise fail"));
1479        }
1480        return;
1481    }
1482    napi_value result = 0;
1483    napi_value cb = 0;
1484
1485    napi_status result_status = napi_get_reference_value(env_, callbackFunc_, &cb);
1486    CC_ASSERT(result_status == napi_ok);
1487    napi_value asyncThis = 0;
1488    napi_get_reference_value(env_, asyncThisVar_, &asyncThis);
1489    result_status = napi_call_function(env_, asyncThis, cb, argc, args, &result);
1490    CC_ASSERT(result_status == napi_ok);
1491}
1492
1493napi_value XNapiTool::UndefinedValue(napi_env env)
1494{
1495    napi_value result;
1496    napi_get_undefined(env, &result);
1497    return result;
1498}
1499
1500napi_value XNapiTool::UndefinedValue()
1501{
1502    napi_value result;
1503    napi_get_undefined(env_, &result);
1504    return result;
1505}
1506
1507napi_value XNapiTool::CreateSubObject(napi_value parent, const char *name)
1508{
1509    napi_value result;
1510    napi_status result_status = napi_create_object(env_, &result);
1511    CC_ASSERT(result_status == napi_ok);
1512
1513    result_status = napi_set_named_property(env_, parent, name, result);
1514    CC_ASSERT(result_status == napi_ok);
1515
1516    return result;
1517}
1518
1519void XNapiTool::DefineFunction(const char *funcName, napi_callback callback, napi_value dest)
1520{
1521    if (dest == nullptr)
1522        dest = exports_;
1523    napi_property_descriptor descriptor[] = {
1524        {funcName, 0, callback, 0, 0, 0, napi_default, 0}};
1525
1526    napi_status result_status = napi_define_properties(env_, dest, 1, descriptor);
1527    CC_ASSERT(result_status == napi_ok);
1528}
1529
1530void XNapiTool::SetEnumProperty(napi_value dstObj, const char *propName, std::any objValue)
1531{
1532    napi_value prop = nullptr;
1533    napi_status result_status = napi_invalid_arg;
1534
1535    if (objValue.type() == typeid(int32_t)) {
1536        result_status = napi_create_int32(env_, std::any_cast<int32_t>(objValue), &prop);
1537    } else if (objValue.type() == typeid(uint32_t)) {
1538        result_status = napi_create_uint32(env_, std::any_cast<uint32_t>(objValue), &prop);
1539    } else if (objValue.type() == typeid(int64_t)) {
1540        result_status = napi_create_int64(env_, std::any_cast<int64_t>(objValue), &prop);
1541    } else if (objValue.type() == typeid(double_t)) {
1542        result_status = napi_create_double(env_, std::any_cast<double_t>(objValue), &prop);
1543    } else if (objValue.type() == typeid(const char *)) {
1544        result_status = napi_create_string_utf8(env_, std::any_cast<const char *>(objValue), NAPI_AUTO_LENGTH, &prop);
1545    }
1546
1547    CC_ASSERT(result_status == napi_ok);
1548    result_status = napi_set_named_property(env_, dstObj, propName, prop);
1549    CC_ASSERT(result_status == napi_ok);
1550}
1551
1552void XNapiTool::CreateEnumObject(const char *enumName, std::map<const char *, std::any> enumMap)
1553{
1554    napi_value enumObj = nullptr;
1555    napi_create_object(env_, &enumObj);
1556
1557    for (auto it = enumMap.begin(); it != enumMap.end(); it++) {
1558        SetEnumProperty(enumObj, it->first, it->second);
1559    }
1560
1561    napi_property_descriptor exportEnum[] = {
1562        {enumName, 0, 0, 0, 0, enumObj, napi_enumerable, 0}
1563    };
1564    napi_status result_status = napi_define_properties(env_, exports_, 1, exportEnum);
1565    CC_ASSERT(result_status == napi_ok);
1566}
1567
1568void XNapiTool::DefineClass(const char *className, napi_callback constructorFunc,
1569    std::map<const char *, std::map<const char *, napi_callback>> &valueList,
1570    std::map<const char *, napi_callback> &funcList, napi_value dest)
1571{
1572    if (dest == nullptr)
1573        dest = exports_;
1574    napi_value tmpClass = nullptr;
1575    napi_property_descriptor funcs[funcList.size() + valueList.size()];
1576
1577    uint32_t p = 0;
1578    for (auto it = valueList.begin(); it != valueList.end(); it++) {
1579        funcs[p++] = {it->first, 0, 0, it->second["getvalue"], it->second["setvalue"], 0, napi_default, 0}; // get,set
1580    }
1581    for (auto it = funcList.begin(); it != funcList.end(); it++) {
1582        funcs[p++] = {it->first, 0, it->second, 0, 0, 0, napi_default, 0};
1583    }
1584
1585    napi_status result_status = napi_define_class(env_, className, NAPI_AUTO_LENGTH, constructorFunc,
1586    nullptr, p, funcs, &tmpClass);
1587    CC_ASSERT(result_status == napi_ok);
1588
1589    result_status = napi_set_named_property(env_, dest, className, tmpClass);
1590    CC_ASSERT(result_status == napi_ok);
1591}
1592
1593void XNapiTool::WrapFinalize(napi_env env, XNapiTool *data, DataPtr hint)
1594{
1595    XNapiTool *pxt = data;
1596    pxt->ReleaseInstance();
1597    delete pxt;
1598}
1599
1600void XNapiTool::ReleaseInstance()
1601{
1602    if (releaseInstance_ != nullptr) {
1603        releaseInstance_(pInstance_);
1604    }
1605}
1606
1607napi_value XNapiTool::WrapInstance(DataPtr instance, RELEASE_INSTANCE ri)
1608{
1609    pInstance_ = instance;
1610    releaseInstance_ = ri;
1611    napi_status result_status = napi_wrap(env_, thisVar_, this, (napi_finalize)WrapFinalize, nullptr, &wrapper_);
1612    CC_ASSERT(result_status == napi_ok);
1613    return thisVar_;
1614}
1615
1616DataPtr XNapiTool::UnWarpInstance()
1617{
1618    XNapiTool *p;
1619    napi_status result_status = napi_unwrap(env_, thisVar_, (void **)&p);
1620    CC_ASSERT(result_status == napi_ok);
1621    return p->pInstance_;
1622}
1623
1624void XNapiTool::SetAsyncInstance(DataPtr p)
1625{
1626    asyncInstance_ = p;
1627}
1628
1629void* XNapiTool::GetAsyncInstance()
1630{
1631    return asyncInstance_;
1632}
1633
1634std::map<std::string, CallFunc> XNapiTool::callFuncs_;
1635void XNapiTool::RegistOnOffFunc(std::string name, napi_value func)
1636{
1637    if (XNapiTool::callFuncs_.count(name) > 0) {
1638        UnregistOnOffFunc(name);
1639    }
1640    XNapiTool::callFuncs_[name].env_ = env_;
1641    napi_status result_status = napi_create_reference(env_, func, 1, &XNapiTool::callFuncs_[name].funcRef_);
1642    CC_ASSERT(result_status == napi_ok);
1643    result_status = napi_create_reference(env_, thisVar_, 1, &XNapiTool::callFuncs_[name].thisVarRef_);
1644    CC_ASSERT(result_status == napi_ok);
1645}
1646
1647void XNapiTool::UnregistOnOffFunc(std::string name)
1648{
1649    if (XNapiTool::callFuncs_.count(name) <= 0) {
1650        return;
1651    }
1652    napi_status result_status = napi_delete_reference(env_, XNapiTool::callFuncs_[name].funcRef_);
1653    CC_ASSERT(result_status == napi_ok);
1654    result_status = napi_delete_reference(env_, XNapiTool::callFuncs_[name].thisVarRef_);
1655    CC_ASSERT(result_status == napi_ok);
1656    XNapiTool::callFuncs_.erase(name);
1657}
1658
1659std::map<std::string, ThreadsafeFunc> XNapiTool::threadsafeCallFuncs_;
1660void XNapiTool::RegistThreadsafeFunc(std::string name, napi_threadsafe_function thraedsafeFunc)
1661{
1662    XNapiTool::threadsafeCallFuncs_[name].env_ = env_;
1663    XNapiTool::threadsafeCallFuncs_[name].threadsafefunc_ = thraedsafeFunc;
1664}
1665
1666void XNapiTool::CallSyncFunc(CallFunc *pSyncFuncs, napi_value ret)
1667{
1668    napi_handle_scope scope = nullptr;
1669    napi_open_handle_scope(pSyncFuncs->env_, &scope);
1670
1671    napi_value cb;
1672    napi_status result_status = napi_get_reference_value(pSyncFuncs->env_, pSyncFuncs->funcRef_, &cb);
1673    CC_ASSERT(result_status == napi_ok);
1674
1675    napi_value thisvar;
1676    result_status = napi_get_reference_value(pSyncFuncs->env_, pSyncFuncs->thisVarRef_, &thisvar);
1677    CC_ASSERT(result_status == napi_ok);
1678
1679    uint32_t length = 0;
1680    napi_value element;
1681    napi_get_array_length(pSyncFuncs->env_, ret, &length);
1682
1683    const uint32_t LENGTH = length;
1684    std::vector<napi_value> args(LENGTH);
1685    for (uint32_t i = 0; i < length; i++) {
1686        napi_get_element(pSyncFuncs->env_, ret, i, &element);
1687        args[i] = element;
1688    }
1689
1690    napi_value cb_result;
1691
1692    result_status = napi_call_function(pSyncFuncs->env_, thisvar, cb, length, args.data(), &cb_result);
1693    CC_ASSERT(result_status == napi_ok);
1694
1695    result_status = napi_close_handle_scope(pSyncFuncs->env_, scope);
1696    CC_ASSERT(result_status == napi_ok);
1697}
1698
1699void XNapiTool::CallAsyncFunc(CallFunc *pAsyncFuncs, napi_value ret)
1700{
1701    uv_loop_s *loop = nullptr;
1702    napi_get_uv_event_loop(pAsyncFuncs->env_, &loop);
1703    uv_work_t *work = new uv_work_t;
1704
1705    struct AsyncCallData {
1706        napi_ref resultRef;
1707        CallFunc *p;
1708    };
1709    AsyncCallData *data = (AsyncCallData *)malloc(sizeof(AsyncCallData));
1710    napi_create_reference(pAsyncFuncs->env_, ret, 1, &data->resultRef);
1711    data->p = pAsyncFuncs;
1712    work->data = data;
1713
1714    uv_queue_work(
1715        loop,
1716        work,
1717        [](uv_work_t *) {},
1718        [](uv_work_t *work, int status) {
1719            AsyncCallData *data = (AsyncCallData *)work->data;
1720            CallFunc *paf = data->p;
1721            napi_handle_scope scope = nullptr;
1722            napi_open_handle_scope(paf->env_, &scope);
1723
1724            napi_value cb;
1725            napi_status result_status = napi_get_reference_value(paf->env_, paf->funcRef_, &cb);
1726            CC_ASSERT(result_status == napi_ok);
1727
1728            napi_value thisvar;
1729            result_status = napi_get_reference_value(paf->env_, paf->thisVarRef_, &thisvar);
1730            CC_ASSERT(result_status == napi_ok);
1731
1732            napi_value retValue;
1733            result_status = napi_get_reference_value(paf->env_, data->resultRef, &retValue);
1734            CC_ASSERT(result_status == napi_ok);
1735            uint32_t length = 0;
1736            napi_value element;
1737            napi_get_array_length(paf->env_, retValue, &length);
1738            const static uint32_t LENGTH = length;
1739            std::vector<napi_value> args(LENGTH);
1740            for (uint32_t i = 0; i < length; i++) {
1741                napi_get_element(paf->env_, retValue, i, &element);
1742                args[i] = element;
1743            }
1744            napi_value cb_result;
1745            result_status = napi_call_function(paf->env_, thisvar, cb, length, args.data(), &cb_result);
1746            CC_ASSERT(result_status == napi_ok);
1747
1748            result_status = napi_delete_reference(paf->env_, data->resultRef);
1749            CC_ASSERT(result_status == napi_ok);
1750
1751            napi_close_handle_scope(paf->env_, scope);
1752            free(data);
1753            delete work;
1754        });
1755}
1756
1757//供业务线程调用安全函数的接口
1758void XNapiTool::CallThreadSafeFunc(std::string eventName) {
1759	if(XNapiTool::threadsafeCallFuncs_.count(eventName) <= 0) {
1760        return;
1761    }
1762    ThreadsafeFunc *pThreadSafeFunc = &XNapiTool::threadsafeCallFuncs_[eventName];
1763
1764    auto status = napi_acquire_threadsafe_function(pThreadSafeFunc->threadsafefunc_);
1765    if (status != napi_ok) {
1766        return;
1767    }
1768
1769    status = napi_call_threadsafe_function(
1770        pThreadSafeFunc->threadsafefunc_, nullptr, napi_tsfn_nonblocking);
1771    if (status != napi_ok) {
1772        return;
1773    }
1774
1775    status = napi_release_threadsafe_function(pThreadSafeFunc->threadsafefunc_, napi_tsfn_abort);
1776    if (status != napi_ok) {
1777        return;
1778    }
1779}
1780`
1781
1782function generateBase(destDir, license) {
1783    writeFile(re.pathJoin(destDir, "tool_utility.h"), null != license ? (license + "\n" + xNapiToolH) : xNapiToolH)
1784    writeFile(re.pathJoin(destDir, "tool_utility.cpp"), null != license ? (license + "\n" + xNapiToolCpp):xNapiToolCpp)
1785}
1786
1787module.exports = {
1788    generateBase
1789}