From 6c3aa790d8587cf885916bd1ea228cad71f394bb Mon Sep 17 00:00:00 2001 From: yudechen Date: Mon, 25 Apr 2022 19:13:56 +0800 Subject: [PATCH] change napi to async. Signed-off-by: yudechen Change-Id: Ia6edcac7022fb02ef02a54aa7e75c29e5e2ed997 --- napi/napi_query_syscap.cpp | 139 ++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 25 deletions(-) diff --git a/napi/napi_query_syscap.cpp b/napi/napi_query_syscap.cpp index eb23c54..71dc4a4 100644 --- a/napi/napi_query_syscap.cpp +++ b/napi/napi_query_syscap.cpp @@ -24,9 +24,10 @@ namespace OHOS { EXTERN_C_START -const int OS_SYSCAP_U32_NUM = 30; -const int U32_TO_STR_MAX_LEN = 11; -const int SYSCAP_STR_MAX_LEN = 128; +constexpr size_t OS_SYSCAP_U32_NUM = 30; +constexpr size_t U32_TO_STR_MAX_LEN = 11; +constexpr size_t SYSCAP_STR_MAX_LEN = 128; +constexpr size_t KEY_BUFFER_SIZE = 32; #define PRINT_ERR(...) \ do { \ @@ -34,33 +35,49 @@ const int SYSCAP_STR_MAX_LEN = 128; printf(__VA_ARGS__); \ } while (0) -napi_value QuerySystemCapability(napi_env env, napi_callback_info info) +#define GET_PARAMS(env, info, num) \ + size_t argc = num; \ + napi_value argv[num] = {0}; \ + napi_value thisVar = nullptr; \ + void *data; \ + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data) + +// Async Function Set +struct systemCapabilityAsyncContext { + napi_env env = nullptr; + napi_async_work work = nullptr; + char key[KEY_BUFFER_SIZE] = { 0 }; + size_t keyLen = 0; + char *value = nullptr; + size_t valueLen = 0; + napi_deferred deferred = nullptr; + napi_ref callbackRef = nullptr; + + int status = 0; +}; + +static char* getSystemCapability() { bool retBool; int retError, priOutputLen, priCapArrayCnt, sumLen; int i = 0; int *osOutput = nullptr; + errno_t err = EOK; uint32_t *osCapU32 = nullptr; char *priOutput = nullptr; char *temp = nullptr; char *allSyscapBUffer = nullptr; char osCapArray[OS_SYSCAP_U32_NUM][U32_TO_STR_MAX_LEN] = {}; char (*priCapArray)[SYSCAP_STR_MAX_LEN] = nullptr; - napi_status ret = napi_ok; - napi_value result = nullptr; - - (void)info; retBool = EncodeOsSyscap(&osOutput); if (!retBool) { PRINT_ERR("get encoded os syscap failed."); - result = nullptr; goto FREE_OSOUTPUT; } retBool = EncodePrivateSyscap(&priOutput, &priOutputLen); if (!retBool) { PRINT_ERR("get encoded private syscap failed."); - result = nullptr; goto FREE_PRIOUTPUT; } @@ -69,7 +86,6 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info) retError = sprintf_s(osCapArray[i], U32_TO_STR_MAX_LEN, "%u", osCapU32[i]); if (retError == -1) { PRINT_ERR("get uint32_t syscap string failed."); - result = nullptr; goto FREE_PRIOUTPUT; } } @@ -77,7 +93,6 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info) retBool = DecodePrivateSyscap(priOutput, &priCapArray, &priCapArrayCnt); if (!retBool) { PRINT_ERR("get encoded private syscap failed."); - result = nullptr; goto FREE_PRICAP_ARRAY; } @@ -93,19 +108,25 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info) // splicing string allSyscapBUffer = (char *)malloc(sumLen); - if (allSyscapBUffer ==nullptr) { + if (allSyscapBUffer == nullptr) { PRINT_ERR("malloc failed!"); - result = nullptr; goto FREE_PRICAP_ARRAY; } - (void)memset_s(allSyscapBUffer, sumLen, 0, sumLen); + err = memset_s(allSyscapBUffer, sumLen, 0, sumLen); + if (err != EOK) { + PRINT_ERR("memset failed!"); + free(allSyscapBUffer); + allSyscapBUffer = nullptr; + goto FREE_PRICAP_ARRAY; + } temp = *osCapArray; for (i = 1; i < OS_SYSCAP_U32_NUM; i++) { retError = sprintf_s(allSyscapBUffer, sumLen, "%s,%s", temp, osCapArray[i]); if (retError == -1) { PRINT_ERR("splicing os syscap string failed."); - result = nullptr; + free(allSyscapBUffer); + allSyscapBUffer = nullptr; goto FREE_PRICAP_ARRAY; } temp = allSyscapBUffer; @@ -114,19 +135,13 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info) retError = sprintf_s(allSyscapBUffer, sumLen, "%s,%s", temp, *(priCapArray + i)); if (retError == -1) { PRINT_ERR("splicing pri syscap string failed."); - result = nullptr; + free(allSyscapBUffer); + allSyscapBUffer = nullptr; goto FREE_PRICAP_ARRAY; } temp = allSyscapBUffer; } - ret = napi_create_string_utf8(env, allSyscapBUffer, sumLen, &result); - if (ret != napi_ok) { - result = nullptr; - goto FREE_ALL_SYSCAP_BUFFER; - } - -FREE_ALL_SYSCAP_BUFFER: - free(allSyscapBUffer); + FREE_PRICAP_ARRAY: free(priCapArray); FREE_PRIOUTPUT: @@ -135,6 +150,79 @@ FREE_OSOUTPUT: free(osOutput); temp = nullptr; + return allSyscapBUffer; +} + +napi_value QuerySystemCapability(napi_env env, napi_callback_info info) +{ + GET_PARAMS(env, info, 1); + NAPI_ASSERT(env, argc <= 1, "too many parameters"); + napi_value result = nullptr; + + systemCapabilityAsyncContext* asyncContext = new systemCapabilityAsyncContext(); + + asyncContext->env = env; + + napi_valuetype valueType = napi_undefined; + if (argc == 1) { + napi_typeof(env, argv[0], &valueType); + } + if (valueType == napi_function) { + napi_create_reference(env, argv[0], 1, &asyncContext->callbackRef); + } + + if (asyncContext->callbackRef == nullptr) { + napi_create_promise(env, &asyncContext->deferred, &result); + } else { + napi_get_undefined(env, &result); + } + + napi_value resource = nullptr; + napi_create_string_utf8(env, "napi_value QuerySystemCapability", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + systemCapabilityAsyncContext *asyncContext = (systemCapabilityAsyncContext *)data; + char *syscapStr = getSystemCapability(); + if (syscapStr != nullptr) { + asyncContext->value = syscapStr; + asyncContext->status = 0; + } else { + asyncContext->status = 1; + } + }, + [](napi_env env, napi_status status, void* data) { + systemCapabilityAsyncContext *asyncContext = (systemCapabilityAsyncContext *)data; + napi_value result[2] = {0}; + if (!asyncContext->status) { + napi_get_undefined(env, &result[0]); + napi_create_string_utf8(env, asyncContext->value, strlen(asyncContext->value), &result[1]); // ? + } else { + napi_value message = nullptr; + napi_create_string_utf8(env, "key does not exist", NAPI_AUTO_LENGTH, &message); + napi_create_error(env, nullptr, message, &result[0]); + napi_get_undefined(env, &result[1]); + } + if (asyncContext->deferred) { + if (!asyncContext->status) { + napi_resolve_deferred(env, asyncContext->deferred, result[1]); + } else { + napi_reject_deferred(env, asyncContext->deferred, result[0]); + } + } else { + napi_value callback = nullptr; + napi_value returnVal; + napi_get_reference_value(env, asyncContext->callbackRef, &callback); + napi_call_function(env, nullptr, callback, 2, result, &returnVal); // 2, count of result + napi_delete_reference(env, asyncContext->callbackRef); + } + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; + }, + (void*)asyncContext, &asyncContext->work); + napi_queue_async_work(env, asyncContext->work); + return result; } @@ -148,6 +236,7 @@ napi_value QuerryExport(napi_env env, napi_value exports) return exports; } EXTERN_C_END + /* * Module define */