1 /*
2  * Copyright (c) 2021 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 #include "watcher_n_exporter.h"
17 
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <memory>
22 
23 #include "../../common/log.h"
24 #include "../../common/napi/n_async/n_async_work_callback.h"
25 #include "../../common/napi/n_async/n_async_work_promise.h"
26 #include "../../common/napi/n_class.h"
27 #include "../../common/napi/n_func_arg.h"
28 #include "../../common/uni_error.h"
29 #include "securec.h"
30 #include "watcher_entity.h"
31 
32 namespace OHOS {
33 namespace DistributedFS {
34 namespace ModuleFileIO {
35 using namespace std;
36 
Constructor(napi_env env,napi_callback_info info)37 napi_value WatcherNExporter::Constructor(napi_env env, napi_callback_info info)
38 {
39     NFuncArg funcArg(env, info);
40     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
41         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
42         return nullptr;
43     }
44 
45     unique_ptr<WatcherEntity> watcherEntity = make_unique<WatcherEntity>();
46     if (!NClass::SetEntityFor<WatcherEntity>(env, funcArg.GetThisVar(), move(watcherEntity))) {
47         UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj stat");
48         return nullptr;
49     }
50 
51     return funcArg.GetThisVar();
52 }
53 
StopSync(napi_env env,napi_callback_info info)54 napi_value WatcherNExporter::StopSync(napi_env env, napi_callback_info info)
55 {
56     NFuncArg funcArg(env, info);
57     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
58         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
59         return nullptr;
60     }
61 
62     auto watchEntity = NClass::GetEntityOf<WatcherEntity>(env, funcArg.GetThisVar());
63     if (!watchEntity) {
64         UniError(EINVAL).ThrowErr(env, "get watcherEntity fail");
65         return nullptr;
66     }
67 
68     watchEntity->fsEventReq_.reset();
69     return NVal::CreateUndefined(env).val_;
70 }
71 
Stop(napi_env env,napi_callback_info info)72 napi_value WatcherNExporter::Stop(napi_env env, napi_callback_info info)
73 {
74     NFuncArg funcArg(env, info);
75     if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) {
76         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
77         return nullptr;
78     }
79 
80     auto watchEntity = NClass::GetEntityOf<WatcherEntity>(env, funcArg.GetThisVar());
81     if (!watchEntity) {
82         UniError(EINVAL).ThrowErr(env, "get watcherEntity fail");
83         return nullptr;
84     }
85 
86     auto cbExec = [watchEntity](napi_env env) -> UniError {
87         watchEntity->fsEventReq_.reset();
88         return UniError(ERRNO_NOERR);
89     };
90 
91     auto cbCompl = [](napi_env env, UniError err) -> NVal {
92         if (err) {
93             return { env, err.GetNapiErr(env) };
94         }
95         return { NVal::CreateUndefined(env) };
96     };
97 
98     const string procedureName = "FileIOCreaterWatcher";
99     NVal thisVar(env, funcArg.GetThisVar());
100     if (funcArg.GetArgc() == NARG_CNT::ZERO) {
101         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_;
102     } else {
103         NVal cb(env, funcArg[NARG_POS::FIRST]);
104         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_;
105     }
106 }
107 
Export()108 bool WatcherNExporter::Export()
109 {
110     vector<napi_property_descriptor> props = {
111         NVal::DeclareNapiFunction("stop", Stop),
112         NVal::DeclareNapiFunction("stopSync", StopSync),
113     };
114 
115     string className = GetClassName();
116     auto [resDefineClass, classValue] = NClass::DefineClass(exports_.env_,
117                                                             className,
118                                                             WatcherNExporter::Constructor,
119                                                             std::move(props));
120     if (!resDefineClass) {
121         UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class");
122         return false;
123     }
124 
125     bool succ = NClass::SaveClass(exports_.env_, className, classValue);
126     if (!succ) {
127         UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class");
128         return false;
129     }
130 
131     return exports_.AddProp(className, classValue);
132 }
133 
GetClassName()134 string WatcherNExporter::GetClassName()
135 {
136     return WatcherNExporter::className_;
137 }
138 
WatcherNExporter(napi_env env,napi_value exports)139 WatcherNExporter::WatcherNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}
140 
~WatcherNExporter()141 WatcherNExporter::~WatcherNExporter() {}
142 } // namespace ModuleFileIO
143 } // namespace DistributedFS
144 } // namespace OHOS