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