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 #include "dirent_n_exporter.h"
17 
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <memory>
22 #include <sstream>
23 
24 #include "securec.h"
25 #include "../../common/log.h"
26 #include "../../common/napi/n_class.h"
27 #include "../../common/napi/n_func_arg.h"
28 #include "../../common/uni_error.h"
29 #include "../common_func.h"
30 #include "dirent_entity.h"
31 
32 namespace OHOS {
33 namespace DistributedFS {
34 namespace ModuleFileIO {
35 using namespace std;
36 
GetDirentEntity(napi_env env,napi_callback_info cbinfo)37 static DirentEntity *GetDirentEntity(napi_env env, napi_callback_info cbinfo)
38 {
39     NFuncArg funcArg(env, cbinfo);
40     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
41         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
42         return nullptr;
43     }
44 
45     auto direntEntity = NClass::GetEntityOf<DirentEntity>(env, funcArg.GetThisVar());
46     if (!direntEntity) {
47         UniError(EIO).ThrowErr(env, "Cannot get entity of Dirent");
48         return nullptr;
49     }
50     return direntEntity;
51 }
52 
CheckDirentDType(napi_env env,napi_callback_info cbinfo,unsigned char dType)53 static napi_value CheckDirentDType(napi_env env, napi_callback_info cbinfo, unsigned char dType)
54 {
55     DirentEntity *direntEntity = GetDirentEntity(env, cbinfo);
56     if (!direntEntity) {
57         return nullptr;
58     }
59 
60     return NVal::CreateBool(env, direntEntity->dirent_.d_type == dType).val_;
61 }
62 
isBlockDevice(napi_env env,napi_callback_info cbinfo)63 napi_value DirentNExporter::isBlockDevice(napi_env env, napi_callback_info cbinfo)
64 {
65     return CheckDirentDType(env, cbinfo, DT_BLK);
66 }
67 
isCharacterDevice(napi_env env,napi_callback_info cbinfo)68 napi_value DirentNExporter::isCharacterDevice(napi_env env, napi_callback_info cbinfo)
69 {
70     return CheckDirentDType(env, cbinfo, DT_CHR);
71 }
72 
isDirectory(napi_env env,napi_callback_info cbinfo)73 napi_value DirentNExporter::isDirectory(napi_env env, napi_callback_info cbinfo)
74 {
75     return CheckDirentDType(env, cbinfo, DT_DIR);
76 }
77 
isFIFO(napi_env env,napi_callback_info cbinfo)78 napi_value DirentNExporter::isFIFO(napi_env env, napi_callback_info cbinfo)
79 {
80     return CheckDirentDType(env, cbinfo, DT_FIFO);
81 }
82 
isFile(napi_env env,napi_callback_info cbinfo)83 napi_value DirentNExporter::isFile(napi_env env, napi_callback_info cbinfo)
84 {
85     return CheckDirentDType(env, cbinfo, DT_REG);
86 }
87 
isSocket(napi_env env,napi_callback_info cbinfo)88 napi_value DirentNExporter::isSocket(napi_env env, napi_callback_info cbinfo)
89 {
90     return CheckDirentDType(env, cbinfo, DT_SOCK);
91 }
92 
isSymbolicLink(napi_env env,napi_callback_info cbinfo)93 napi_value DirentNExporter::isSymbolicLink(napi_env env, napi_callback_info cbinfo)
94 {
95     return CheckDirentDType(env, cbinfo, DT_LNK);
96 }
97 
GetName(napi_env env,napi_callback_info cbinfo)98 napi_value DirentNExporter::GetName(napi_env env, napi_callback_info cbinfo)
99 {
100     DirentEntity *direntEntity = GetDirentEntity(env, cbinfo);
101     if (!direntEntity) {
102         return nullptr;
103     }
104     return NVal::CreateUTF8String(env, direntEntity->dirent_.d_name).val_;
105 }
106 
Constructor(napi_env env,napi_callback_info cbinfo)107 napi_value DirentNExporter::Constructor(napi_env env, napi_callback_info cbinfo)
108 {
109     NFuncArg funcArg(env, cbinfo);
110     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
111         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
112         return nullptr;
113     }
114 
115     auto direntEntity = make_unique<DirentEntity>();
116     if (!NClass::SetEntityFor<DirentEntity>(env, funcArg.GetThisVar(), move(direntEntity))) {
117         UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj dirent");
118         return nullptr;
119     }
120     return funcArg.GetThisVar();
121 }
122 
Export()123 bool DirentNExporter::Export()
124 {
125     vector<napi_property_descriptor> props = {
126         NVal::DeclareNapiFunction("isBlockDevice", isBlockDevice),
127         NVal::DeclareNapiFunction("isCharacterDevice", isCharacterDevice),
128         NVal::DeclareNapiFunction("isDirectory", isDirectory),
129         NVal::DeclareNapiFunction("isFIFO", isFIFO),
130         NVal::DeclareNapiFunction("isFile", isFile),
131         NVal::DeclareNapiFunction("isSocket", isSocket),
132         NVal::DeclareNapiFunction("isSymbolicLink", isSymbolicLink),
133 
134         NVal::DeclareNapiGetter("name", GetName),
135     };
136 
137     string className = GetClassName();
138     bool succ = false;
139     napi_value classValue = nullptr;
140     tie(succ, classValue) = NClass::DefineClass(exports_.env_,
141                                                 className,
142                                                 DirentNExporter::Constructor,
143                                                 std::move(props));
144     if (!succ) {
145         UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class Dirent");
146         return false;
147     }
148 
149     succ = NClass::SaveClass(exports_.env_, className, classValue);
150     if (!succ) {
151         UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class Dirent");
152         return false;
153     }
154 
155     return exports_.AddProp(className, classValue);
156 }
157 
GetClassName()158 string DirentNExporter::GetClassName()
159 {
160     return DirentNExporter::className_;
161 }
162 
DirentNExporter(napi_env env,napi_value exports)163 DirentNExporter::DirentNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}
164 
~DirentNExporter()165 DirentNExporter::~DirentNExporter() {}
166 } // namespace ModuleFileIO
167 } // namespace DistributedFS
168 } // namespace OHOS
169