• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 
16 #ifndef COMMUNICATIONNETSTACK_NETSTACK_BASE_ASYNC_WORK_H
17 #define COMMUNICATIONNETSTACK_NETSTACK_BASE_ASYNC_WORK_H
18 
19 #include <limits>
20 #include <memory>
21 
22 #include <napi/native_api.h>
23 #include <napi/native_common.h>
24 
25 #include "base_context.h"
26 #include "napi_utils.h"
27 #include "netstack_log.h"
28 
29 namespace OHOS::NetStack {
30 class BaseAsyncWork final {
31 public:
32     BaseAsyncWork() = delete;
33 
ExecAsyncWork(napi_env env,void * data)34     template <class Context, bool (*Executor)(Context *)> static void ExecAsyncWork(napi_env env, void *data)
35     {
36         static_assert(std::is_base_of<BaseContext, Context>::value);
37 
38         (void)env;
39 
40         auto context = reinterpret_cast<Context *>(data);
41         if (context == nullptr || Executor == nullptr) {
42             NETSTACK_LOGE("context or Executor is nullptr");
43             return;
44         }
45         if (!context->IsParseOK()) {
46             context->SetError(PARSE_ERROR_CODE, PARSE_ERROR_MSG); // if developer not set error, there will set.
47             NETSTACK_LOGE("parameter error");
48             return;
49         }
50         context->SetExecOK(Executor(context));
51         /* do not have async executor, execOK should be set in sync work */
52     }
53 
54     template <class Context, napi_value (*Callback)(Context *)>
AsyncWorkCallback(napi_env env,napi_status status,void * data)55     static void AsyncWorkCallback(napi_env env, napi_status status, void *data)
56     {
57         static_assert(std::is_base_of<BaseContext, Context>::value);
58 
59         if (status != napi_ok) {
60             return;
61         }
62         auto deleter = [](Context *context) {
63             context->DeleteReference();
64             delete context;
65         };
66         std::unique_ptr<Context, decltype(deleter)> context(static_cast<Context *>(data), deleter);
67         size_t argc = 2;
68         napi_value argv[2] = {nullptr};
69         if (context->IsParseOK() && context->IsExecOK()) {
70             argv[0] = NapiUtils::GetUndefined(env);
71 
72             if (Callback != nullptr) {
73                 argv[1] = Callback(context.get());
74             } else {
75                 argv[1] = NapiUtils::GetUndefined(env);
76             }
77             if (argv[1] == nullptr) {
78                 return;
79             }
80         } else {
81             argv[0] = NapiUtils::CreateErrorMessage(env, context->GetErrorCode(), context->GetErrorMessage());
82             if (argv[0] == nullptr) {
83                 NETSTACK_LOGE("AsyncWorkName %{public}s createErrorMessage fail", context->GetAsyncWorkName().c_str());
84                 return;
85             }
86 
87             argv[1] = NapiUtils::GetUndefined(env);
88         }
89 
90         if (context->GetDeferred() != nullptr) {
91             if (context->IsExecOK()) {
92                 napi_resolve_deferred(env, context->GetDeferred(), argv[1]);
93             } else {
94                 napi_reject_deferred(env, context->GetDeferred(), argv[0]);
95             }
96             return;
97         }
98 
99         napi_value func = context->GetCallback();
100         if (NapiUtils::GetValueType(env, func) == napi_function) {
101             napi_value undefined = NapiUtils::GetUndefined(env);
102             (void)NapiUtils::CallFunction(env, undefined, func, argc, argv);
103         }
104     }
105 
106     template <class Context, napi_value (*Callback)(Context *)>
AsyncWorkCallbackForSystem(napi_env env,napi_status status,void * data)107     static void AsyncWorkCallbackForSystem(napi_env env, napi_status status, void *data)
108     {
109         static_assert(std::is_base_of<BaseContext, Context>::value);
110 
111         if (status != napi_ok) {
112             return;
113         }
114         auto deleter = [](Context *context) { delete context; };
115         std::unique_ptr<Context, decltype(deleter)> context(static_cast<Context *>(data), deleter);
116         if (Callback != nullptr) {
117             (void)Callback(context.get());
118         }
119     }
120 };
121 } // namespace OHOS::NetStack
122 
123 #endif /* COMMUNICATIONNETSTACK_NETSTACK_BASE_ASYNC_WORK_H */
124