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