• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 OHOS_ROSEN_NAPI_ASYNC_WORK_H
17 #define OHOS_ROSEN_NAPI_ASYNC_WORK_H
18 
19 #include <functional>
20 #include <memory>
21 #include <string>
22 #include "refbase.h"
23 
24 #include "napi/native_api.h"
25 #include "napi/native_common.h"
26 #include "napi/native_node_api.h"
27 #include "utils/text_log.h"
28 
29 namespace OHOS::Rosen {
30 #define MAX_LOG_SIZE 1024
31 /* check condition related to argc/argv, return and logging. */
32 #define NAPI_CHECK_ARGS(context, condition, specifyStatus, code, retValue, fmt, ...) \
33     do { \
34         if (!(condition)) { \
35             (context)->status = specifyStatus; \
36             (context)->errCode = static_cast<int32_t>(code); \
37             char buffer[MAX_LOG_SIZE] = {0}; \
38             int res = snprintf_s(buffer, MAX_LOG_SIZE, MAX_LOG_SIZE - 1, fmt, ##__VA_ARGS__); \
39             if (res < 0) { \
40                 TEXT_LOGE("Snprintf err, errcode %{public}d", res); \
41                 retValue; \
42             } \
43             (context)->errMessage = std::string(buffer); \
44             TEXT_LOGE("Test (" #condition ") failed: %{public}s", buffer); \
45             retValue; \
46         } \
47     } while (0)
48 
49 #define NAPI_CHECK_STATUS_RETURN_VOID(context, message, code)                        \
50     do {                                                               \
51         if ((context)->status != napi_ok) {                               \
52             (context)->errMessage = std::string(message);                      \
53             (context)->errCode = code;                      \
54             TEXT_LOGE("test (context->status == napi_ok) failed: " message);  \
55             return;                                                    \
56         }                                                              \
57     } while (0)
58 
59 using NapiCbInfoParser = std::function<void(size_t argc, napi_value* argv)>;
60 using NapiAsyncExecute = std::function<void(void)>;
61 using NapiAsyncComplete = std::function<void(napi_value&)>;
62 
63 struct ContextBase : RefBase {
64     virtual ~ContextBase();
65     void GetCbInfo(napi_env env, napi_callback_info info, NapiCbInfoParser parser = NapiCbInfoParser(),
66                    bool sync = false);
67 
68     napi_env env = nullptr;
69     napi_value output = nullptr;
70     napi_status status = napi_invalid_arg;
71     std::string errMessage;
72     int32_t errCode = -1;
73     napi_value self = nullptr;
74     void* native = nullptr;
75 
76 private:
77     napi_deferred deferred = nullptr;
78     napi_async_work work = nullptr;
79     napi_ref callbackRef = nullptr;
80     napi_ref selfRef = nullptr;
81 
82     NapiAsyncExecute execute = nullptr;
83     NapiAsyncComplete complete = nullptr;
84 
85     static constexpr size_t ARGC_MAX = 6;
86 
87     friend class NapiAsyncWork;
88 };
89 
90 class NapiAsyncWork {
91 public:
92     static napi_value Enqueue(napi_env env, sptr<ContextBase> contextBase, const std::string& name,
93                               NapiAsyncExecute execute = NapiAsyncExecute(),
94                               NapiAsyncComplete complete = NapiAsyncComplete());
95 
96 private:
97     enum {
98         /* AsyncCallback / Promise output result index  */
99         RESULT_ERROR = 0,
100         RESULT_DATA = 1,
101         RESULT_ALL = 2
102     };
103     static void GenerateOutput(sptr<ContextBase> ctxt);
104 };
105 } // namespace OHOS::Rosen
106 #endif // OHOS_ROSEN_NAPI_ASYNC_WORK_H