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 #ifndef LDBPROJ_NAPI_QUEUE_H 17 #define LDBPROJ_NAPI_QUEUE_H 18 19 #include <functional> 20 #include <memory> 21 #include <string> 22 23 #include "logger.h" 24 #include "napi/native_api.h" 25 #include "napi/native_common.h" 26 #include "napi/native_node_api.h" 27 28 namespace OHOS::CloudData { 29 using namespace OHOS::Rdb; 30 31 constexpr size_t ARGC_MAX = 6; 32 using NapiCbInfoParser = std::function<void(size_t argc, napi_value *argv)>; 33 using NapiAsyncExecute = std::function<void(void)>; 34 using NapiAsyncComplete = std::function<void(napi_value &)>; 35 36 struct ContextBase { 37 virtual ~ContextBase(); 38 void GetCbInfo( 39 napi_env env, napi_callback_info info, NapiCbInfoParser parse = NapiCbInfoParser(), bool sync = false); 40 41 inline void GetCbInfoSync(napi_env env, napi_callback_info info, NapiCbInfoParser parse = NapiCbInfoParser()) 42 { 43 /* sync = true, means no callback, not AsyncWork. */ 44 GetCbInfo(env, info, parse, true); 45 } 46 47 napi_env env = nullptr; 48 napi_value output = nullptr; 49 napi_status status = napi_invalid_arg; 50 std::string error; 51 int32_t jsCode = 0; 52 bool isThrowError = false; 53 54 napi_value self = nullptr; 55 void *native = nullptr; 56 57 private: 58 napi_ref callbackRef = nullptr; 59 napi_ref selfRef = nullptr; 60 friend class NapiQueue; 61 }; 62 63 /* check condition related to argc/argv, return and logging. */ 64 #define ASSERT_VALUE(ctxt, condition, errCode, message) \ 65 do { \ 66 if (!(condition)) { \ 67 (ctxt)->status = errCode; \ 68 (ctxt)->error = std::string(message); \ 69 LOG_ERROR("test (" #condition ") failed: " message); \ 70 return; \ 71 } \ 72 } while (0) 73 74 #define ASSERT_ARGS(ctxt, condition, message) \ 75 ASSERT_VALUE(ctxt, condition, napi_invalid_arg, message) 76 77 #define ASSERT_STATUS(ctxt, message) \ 78 do { \ 79 if ((ctxt)->status != napi_ok) { \ 80 (ctxt)->error = std::string(message); \ 81 LOG_ERROR("test (ctxt->status == napi_ok) failed: " message); \ 82 return; \ 83 } \ 84 } while (0) 85 86 /* check condition, return and logging if condition not true. */ 87 #define ASSERT(condition, message, retVal) \ 88 do { \ 89 if (!(condition)) { \ 90 LOG_ERROR("test (" #condition ") failed: " message); \ 91 return retVal; \ 92 } \ 93 } while (0) 94 95 #define ASSERT_VOID(condition, message) \ 96 do { \ 97 if (!(condition)) { \ 98 LOG_ERROR("test (" #condition ") failed: " message); \ 99 return; \ 100 } \ 101 } while (0) 102 103 #define ASSERT_NULL(condition, message) ASSERT(condition, message, nullptr) 104 105 #define ASSERT_CALL(env, theCall, object) \ 106 do { \ 107 if ((theCall) != napi_ok) { \ 108 delete (object); \ 109 GET_AND_THROW_LAST_ERROR((env)); \ 110 return nullptr; \ 111 } \ 112 } while (0) 113 114 class NapiQueue { 115 public: 116 static napi_value AsyncWork(napi_env env, std::shared_ptr<ContextBase> ctxt, const std::string &name, 117 NapiAsyncExecute execute = NapiAsyncExecute(), NapiAsyncComplete complete = NapiAsyncComplete()); 118 119 private: 120 enum { 121 /* AsyncCallback / Promise output result index */ 122 RESULT_ERROR = 0, 123 RESULT_DATA = 1, 124 RESULT_ALL = 2 125 }; 126 127 struct AsyncContext { 128 napi_env env = nullptr; 129 std::shared_ptr<ContextBase> ctx; 130 NapiAsyncExecute execute = nullptr; 131 NapiAsyncComplete complete = nullptr; 132 napi_deferred deferred = nullptr; 133 napi_async_work work = nullptr; ~AsyncContextAsyncContext134 ~AsyncContext() 135 { 136 execute = nullptr; 137 complete = nullptr; 138 ctx = nullptr; 139 if (env != nullptr) { 140 if (work != nullptr) { 141 napi_delete_async_work(env, work); 142 } 143 } 144 } 145 }; 146 static void GenerateOutput(AsyncContext &ctx, napi_value output); 147 }; 148 } // namespace OHOS::CloudData 149 #endif //LDBPROJ_NAPI_QUEUE_H 150