1 /*
2 * Copyright (C) 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 "napi_file_info_exporter.h"
17
18 #include "file_access_framework_errno.h"
19 #include "file_info_entity.h"
20 #include "file_iterator_entity.h"
21 #include "hilog_wrapper.h"
22 #include "napi_file_iterator_exporter.h"
23 #include "napi_utils.h"
24
25 namespace OHOS {
26 namespace FileAccessFwk {
Export()27 bool NapiFileInfoExporter::Export()
28 {
29 std::vector<napi_property_descriptor> props = {
30 NVal::DeclareNapiFunction("listFile", ListFile),
31 NVal::DeclareNapiFunction("scanFile", ScanFile),
32 NVal::DeclareNapiGetter("uri", GetUri),
33 NVal::DeclareNapiGetter("fileName", GetFileName),
34 NVal::DeclareNapiGetter("mode", GetMode),
35 NVal::DeclareNapiGetter("size", GetSize),
36 NVal::DeclareNapiGetter("mtime", GetMtime),
37 NVal::DeclareNapiGetter("mimeType", GetMimeType),
38 };
39
40 std::string className = GetClassName();
41 bool succ = false;
42 napi_value classValue = nullptr;
43 std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className,
44 NapiFileInfoExporter::Constructor, std::move(props));
45 if (!succ) {
46 NError(E_GETRESULT).ThrowErr(exports_.env_);
47 return false;
48 }
49
50 succ = NClass::SaveClass(exports_.env_, className, classValue);
51 if (!succ) {
52 NError(E_GETRESULT).ThrowErr(exports_.env_);
53 return false;
54 }
55
56 return exports_.AddProp(className, classValue);
57 }
58
Constructor(napi_env env,napi_callback_info info)59 napi_value NapiFileInfoExporter::Constructor(napi_env env, napi_callback_info info)
60 {
61 NFuncArg funcArg(env, info);
62 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
63 NError(EINVAL).ThrowErr(env);
64 return nullptr;
65 }
66
67 auto fileInfoEntity = std::make_unique<FileInfoEntity>();
68 if (fileInfoEntity == nullptr) {
69 NError(E_GETRESULT).ThrowErr(env);
70 return nullptr;
71 }
72
73 if (!NClass::SetEntityFor<FileInfoEntity>(env, funcArg.GetThisVar(), std::move(fileInfoEntity))) {
74 NError(E_GETRESULT).ThrowErr(env);
75 return nullptr;
76 }
77
78 return funcArg.GetThisVar();
79 }
80
ListFile(napi_env env,napi_callback_info info)81 napi_value NapiFileInfoExporter::ListFile(napi_env env, napi_callback_info info)
82 {
83 NFuncArg funcArg(env, info);
84 if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) {
85 NError(EINVAL).ThrowErr(env);
86 return nullptr;
87 }
88
89 FileFilter filter({}, {}, {}, 0, 0, false, false);
90 if (funcArg.GetArgc() == NARG_CNT::ONE) {
91 auto ret = GetFileFilterParam(NVal(env, funcArg.GetArg(NARG_POS::FIRST)), filter);
92 if (ret != ERR_OK) {
93 NError(ret).ThrowErr(env);
94 return nullptr;
95 }
96 }
97
98 auto fileInfoEntity = NClass::GetEntityOf<FileInfoEntity>(env, funcArg.GetThisVar());
99 if (fileInfoEntity == nullptr) {
100 NError(E_GETRESULT).ThrowErr(env);
101 return nullptr;
102 }
103
104 if (IsDirectory(fileInfoEntity->fileInfo.mode) != ERR_OK) {
105 HILOG_ERROR("current FileInfo's mode error");
106 return NVal::CreateUndefined(env).val_;
107 }
108
109 if (fileInfoEntity->fileAccessHelper == nullptr) {
110 NError(E_GETRESULT).ThrowErr(env);
111 return nullptr;
112 }
113
114 auto objFileIteratorExporter = NClass::InstantiateClass(env, NapiFileIteratorExporter::className_, {});
115 if (objFileIteratorExporter == nullptr) {
116 NError(E_GETRESULT).ThrowErr(env);
117 return nullptr;
118 }
119
120 auto fileIteratorEntity = NClass::GetEntityOf<FileIteratorEntity>(env, objFileIteratorExporter);
121 if (fileIteratorEntity == nullptr) {
122 NError(E_GETRESULT).ThrowErr(env);
123 return nullptr;
124 }
125
126 {
127 std::lock_guard<std::mutex> lock(fileIteratorEntity->entityOperateMutex);
128 fileIteratorEntity->fileAccessHelper = fileInfoEntity->fileAccessHelper;
129 fileIteratorEntity->fileInfo = fileInfoEntity->fileInfo;
130 fileIteratorEntity->fileInfoVec.clear();
131 fileIteratorEntity->offset = 0;
132 fileIteratorEntity->pos = 0;
133 fileIteratorEntity->filter = std::move(filter);
134 fileIteratorEntity->flag = 0;
135 auto ret = fileInfoEntity->fileAccessHelper->ListFile(fileInfoEntity->fileInfo, fileIteratorEntity->offset,
136 MAX_COUNT, fileIteratorEntity->filter, fileIteratorEntity->fileInfoVec);
137 if (ret != ERR_OK) {
138 NError(ret).ThrowErr(env);
139 return nullptr;
140 }
141 }
142
143 return NVal(env, objFileIteratorExporter).val_;
144 }
145
ScanFile(napi_env env,napi_callback_info info)146 napi_value NapiFileInfoExporter::ScanFile(napi_env env, napi_callback_info info)
147 {
148 NFuncArg funcArg(env, info);
149 if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) {
150 NError(EINVAL).ThrowErr(env);
151 return nullptr;
152 }
153
154 FileFilter filter({}, {}, {}, 0, 0, false, false);
155 if (funcArg.GetArgc() == NARG_CNT::ONE) {
156 auto ret = GetFileFilterParam(NVal(env, funcArg.GetArg(NARG_POS::FIRST)), filter);
157 if (ret != ERR_OK) {
158 NError(ret).ThrowErr(env);
159 return nullptr;
160 }
161 }
162
163 auto fileInfoEntity = NClass::GetEntityOf<FileInfoEntity>(env, funcArg.GetThisVar());
164 if (fileInfoEntity == nullptr) {
165 NError(E_GETRESULT).ThrowErr(env);
166 return nullptr;
167 }
168
169 if (IsDirectory(fileInfoEntity->fileInfo.mode) != ERR_OK) {
170 HILOG_ERROR("current FileInfo's mode error");
171 return NVal::CreateUndefined(env).val_;
172 }
173
174 if (fileInfoEntity->fileAccessHelper == nullptr) {
175 NError(E_GETRESULT).ThrowErr(env);
176 return nullptr;
177 }
178
179 auto objFileIteratorExporter = NClass::InstantiateClass(env, NapiFileIteratorExporter::className_, {});
180 if (objFileIteratorExporter == nullptr) {
181 NError(E_GETRESULT).ThrowErr(env);
182 return nullptr;
183 }
184
185 auto fileIteratorEntity = NClass::GetEntityOf<FileIteratorEntity>(env, objFileIteratorExporter);
186 if (fileIteratorEntity == nullptr) {
187 NError(E_GETRESULT).ThrowErr(env);
188 return nullptr;
189 }
190
191 {
192 std::lock_guard<std::mutex> lock(fileIteratorEntity->entityOperateMutex);
193 fileIteratorEntity->fileAccessHelper = fileInfoEntity->fileAccessHelper;
194 fileIteratorEntity->fileInfo = fileInfoEntity->fileInfo;
195 fileIteratorEntity->fileInfoVec.clear();
196 fileIteratorEntity->offset = 0;
197 fileIteratorEntity->pos = 0;
198 fileIteratorEntity->filter = std::move(filter);
199 fileIteratorEntity->flag = 1;
200 auto ret = fileInfoEntity->fileAccessHelper->ScanFile(fileInfoEntity->fileInfo, fileIteratorEntity->offset,
201 MAX_COUNT, fileIteratorEntity->filter, fileIteratorEntity->fileInfoVec);
202 if (ret != ERR_OK) {
203 NError(ret).ThrowErr(env);
204 return nullptr;
205 }
206 }
207
208 return NVal(env, objFileIteratorExporter).val_;
209 }
210
GetFileInfoEntity(napi_env env,napi_callback_info info)211 static FileInfoEntity *GetFileInfoEntity(napi_env env, napi_callback_info info)
212 {
213 NFuncArg funcArg(env, info);
214 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
215 NError(EINVAL).ThrowErr(env);
216 return nullptr;
217 }
218
219 auto fileInfoEntity = NClass::GetEntityOf<FileInfoEntity>(env, funcArg.GetThisVar());
220 if (fileInfoEntity == nullptr) {
221 NError(E_GETRESULT).ThrowErr(env);
222 return nullptr;
223 }
224
225 return fileInfoEntity;
226 }
227
GetUri(napi_env env,napi_callback_info info)228 napi_value NapiFileInfoExporter::GetUri(napi_env env, napi_callback_info info)
229 {
230 auto fileInfoEntity = GetFileInfoEntity(env, info);
231 if (fileInfoEntity == nullptr) {
232 HILOG_ERROR("Failed to get entity of FileInfoEntity");
233 return NVal::CreateUndefined(env).val_;
234 }
235
236 return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.uri).val_;
237 }
238
GetFileName(napi_env env,napi_callback_info info)239 napi_value NapiFileInfoExporter::GetFileName(napi_env env, napi_callback_info info)
240 {
241 auto fileInfoEntity = GetFileInfoEntity(env, info);
242 if (fileInfoEntity == nullptr) {
243 HILOG_ERROR("Failed to get entity of FileInfoEntity");
244 return NVal::CreateUndefined(env).val_;
245 }
246
247 return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.fileName).val_;
248 }
249
GetMode(napi_env env,napi_callback_info info)250 napi_value NapiFileInfoExporter::GetMode(napi_env env, napi_callback_info info)
251 {
252 auto fileInfoEntity = GetFileInfoEntity(env, info);
253 if (fileInfoEntity == nullptr) {
254 HILOG_ERROR("Failed to get entity of FileInfoEntity");
255 return NVal::CreateUndefined(env).val_;
256 }
257
258 return NVal::CreateInt32(env, fileInfoEntity->fileInfo.mode).val_;
259 }
260
GetSize(napi_env env,napi_callback_info info)261 napi_value NapiFileInfoExporter::GetSize(napi_env env, napi_callback_info info)
262 {
263 auto fileInfoEntity = GetFileInfoEntity(env, info);
264 if (fileInfoEntity == nullptr) {
265 HILOG_ERROR("Failed to get entity of FileInfoEntity");
266 return NVal::CreateUndefined(env).val_;
267 }
268
269 return NVal::CreateInt64(env, fileInfoEntity->fileInfo.size).val_;
270 }
271
GetMtime(napi_env env,napi_callback_info info)272 napi_value NapiFileInfoExporter::GetMtime(napi_env env, napi_callback_info info)
273 {
274 auto fileInfoEntity = GetFileInfoEntity(env, info);
275 if (fileInfoEntity == nullptr) {
276 HILOG_ERROR("Failed to get entity of FileInfoEntity");
277 return NVal::CreateUndefined(env).val_;
278 }
279
280 return NVal::CreateInt64(env, fileInfoEntity->fileInfo.mtime).val_;
281 }
282
GetMimeType(napi_env env,napi_callback_info info)283 napi_value NapiFileInfoExporter::GetMimeType(napi_env env, napi_callback_info info)
284 {
285 auto fileInfoEntity = GetFileInfoEntity(env, info);
286 if (fileInfoEntity == nullptr) {
287 HILOG_ERROR("Failed to get entity of FileInfoEntity");
288 return NVal::CreateUndefined(env).val_;
289 }
290
291 return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.mimeType).val_;
292 }
293
GetClassName()294 std::string NapiFileInfoExporter::GetClassName()
295 {
296 return NapiFileInfoExporter::className_;
297 }
298 } // namespace FileAccessFwk
299 } // namespace OHOS