1 /*
2  * Copyright (c) 2022 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 #ifndef PRINT_ASYNC_CALL_H
16 #define PRINT_ASYNC_CALL_H
17 
18 #include <functional>
19 #include <memory>
20 
21 #include "napi/native_api.h"
22 #include "napi/native_common.h"
23 #include "napi/native_node_api.h"
24 #include "print_constant.h"
25 
26 namespace OHOS::Print {
27 class PrintAsyncCall final {
28 public:
29     class Context {
30     public:
31         using InputAction = std::function<napi_status(napi_env, size_t, napi_value *, napi_value, napi_callback_info)>;
32         using OutputAction = std::function<napi_status(napi_env, napi_value *)>;
33         using ExecAction = std::function<void(Context *)>;
Context(InputAction input,OutputAction output)34         Context(InputAction input, OutputAction output) : input_(std::move(input)), output_(std::move(output)) {};
35 
~Context()36         virtual ~Context() {};
37         void SetAction(InputAction input, OutputAction output = nullptr)
38         {
39             input_ = input;
40             output_ = output;
41         }
42 
SetAction(OutputAction output)43         void SetAction(OutputAction output)
44         {
45             SetAction(nullptr, std::move(output));
46         }
47 
operator()48         virtual napi_status operator()(
49             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info)
50         {
51             if (input_ == nullptr) {
52                 return napi_ok;
53             }
54             return input_(env, argc, argv, self, info);
55         }
56 
operator()57         virtual napi_status operator()(napi_env env, napi_value *result)
58         {
59             if (output_ == nullptr) {
60                 *result = nullptr;
61                 return napi_ok;
62             }
63             return output_(env, result);
64         }
65 
Exec()66         virtual void Exec()
67         {
68             if (exec_ == nullptr) {
69                 return;
70             }
71             exec_(this);
72         };
73 
SetErrorIndex(uint32_t errorIndex)74         void SetErrorIndex(uint32_t errorIndex)
75         {
76             errorIndex_ = errorIndex;
77         }
78 
GetErrorIndex()79         uint32_t GetErrorIndex()
80         {
81             return errorIndex_;
82         }
83 
84     protected:
85         friend class PrintAsyncCall;
86         InputAction input_ = nullptr;
87         OutputAction output_ = nullptr;
88         ExecAction exec_ = nullptr;
89         uint32_t errorIndex_ = E_PRINT_NONE;
90     };
91 
92     // The default AsyncCallback in the parameters is at the end position.
93     static constexpr size_t ASYNC_DEFAULT_POS = -1;
94     PrintAsyncCall(napi_env env, napi_callback_info info, std::shared_ptr<Context> context,
95             size_t pos = ASYNC_DEFAULT_POS);
96     ~PrintAsyncCall();
97     napi_value Call(napi_env env, Context::ExecAction exec = nullptr);
98     napi_value SyncCall(napi_env env, Context::ExecAction exec = nullptr);
99 
100 private:
101     enum { ARG_ERROR, ARG_DATA, ARG_BUTT };
102     static void OnExecute(napi_env env, void *data);
103     static void OnComplete(napi_env env, napi_status status, void *data);
104     static std::string GetErrorText(uint32_t code);
105     struct AsyncContext {
106         std::shared_ptr<Context> ctx = nullptr;
107         napi_ref callback = nullptr;
108         napi_ref self = nullptr;
109         napi_deferred defer = nullptr;
110         napi_async_work work = nullptr;
111         napi_status paramStatus = napi_ok;
112     };
113     static void DeleteContext(napi_env env, AsyncContext *context);
114     static uint32_t GetErrorIndex(AsyncContext *context);
115 
116     AsyncContext *context_ = nullptr;
117     napi_env env_ = nullptr;
118 };
119 }  // namespace OHOS::Print
120 #endif  // REQUEST_ASYNC_CALL_H
121