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_iterator_exporter.h"
17
18 #include <cinttypes>
19
20 #include "file_info_entity.h"
21 #include "file_iterator_entity.h"
22 #include "hilog_wrapper.h"
23 #include "napi_file_info_exporter.h"
24 #include "napi_utils.h"
25
26 namespace OHOS {
27 namespace FileAccessFwk {
Export()28 bool NapiFileIteratorExporter::Export()
29 {
30 std::vector<napi_property_descriptor> props = {
31 NVal::DeclareNapiFunction("next", Next),
32 };
33
34 std::string className = GetClassName();
35 bool succ = false;
36 napi_value classValue = nullptr;
37 std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className,
38 NapiFileIteratorExporter::Constructor, std::move(props));
39 if (!succ) {
40 NError(E_GETRESULT).ThrowErr(exports_.env_);
41 return false;
42 }
43
44 succ = NClass::SaveClass(exports_.env_, className, classValue);
45 if (!succ) {
46 NError(E_GETRESULT).ThrowErr(exports_.env_);
47 return false;
48 }
49
50 return exports_.AddProp(className, classValue);
51 }
52
Constructor(napi_env env,napi_callback_info info)53 napi_value NapiFileIteratorExporter::Constructor(napi_env env, napi_callback_info info)
54 {
55 NFuncArg funcArg(env, info);
56 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
57 NError(EINVAL).ThrowErr(env);
58 return nullptr;
59 }
60
61 auto fileIteratorEntity = std::make_unique<FileIteratorEntity>();
62 if (fileIteratorEntity == nullptr) {
63 NError(E_GETRESULT).ThrowErr(env);
64 return nullptr;
65 }
66
67 if (!NClass::SetEntityFor<FileIteratorEntity>(env, funcArg.GetThisVar(), std::move(fileIteratorEntity))) {
68 NError(E_GETRESULT).ThrowErr(env);
69 return nullptr;
70 }
71
72 return funcArg.GetThisVar();
73 }
74
MakeResult(napi_value & objFileInfoExporter,FileIteratorEntity * fileIteratorEntity,FileInfoEntity * fileInfoEntity,napi_env env,NVal & nVal)75 static int MakeResult(napi_value &objFileInfoExporter, FileIteratorEntity *fileIteratorEntity,
76 FileInfoEntity *fileInfoEntity, napi_env env, NVal &nVal)
77 {
78 std::lock_guard<std::mutex> lock(fileIteratorEntity->entityOperateMutex);
79 if (fileIteratorEntity->fileInfoVec.size() == 0) {
80 fileIteratorEntity->fileInfoVec.clear();
81 fileIteratorEntity->offset = 0;
82 fileIteratorEntity->pos = 0;
83 fileInfoEntity = nullptr;
84 objFileInfoExporter = NVal::CreateUndefined(env).val_;
85 nVal.AddProp("value", objFileInfoExporter);
86 nVal.AddProp("done", NVal::CreateBool(env, true).val_);
87 return ERR_OK;
88 }
89
90 if (fileIteratorEntity->pos == MAX_COUNT) {
91 fileIteratorEntity->fileInfoVec.clear();
92 fileIteratorEntity->offset += MAX_COUNT;
93 fileIteratorEntity->pos = 0;
94 if (fileIteratorEntity->flag == 0) {
95 int ret = fileIteratorEntity->fileAccessHelper->ListFile(fileIteratorEntity->fileInfo,
96 fileIteratorEntity->offset, MAX_COUNT, fileIteratorEntity->filter, fileIteratorEntity->fileInfoVec);
97 if (ret != ERR_OK) {
98 HILOG_ERROR("exec ListFile fail, code:%{public}d", ret);
99 return ret;
100 }
101 } else if (fileIteratorEntity->flag == 1) {
102 int ret = fileIteratorEntity->fileAccessHelper->ScanFile(fileIteratorEntity->fileInfo,
103 fileIteratorEntity->offset, MAX_COUNT, fileIteratorEntity->filter, fileIteratorEntity->fileInfoVec);
104 if (ret != ERR_OK) {
105 HILOG_ERROR("exec ScanFile fail, code:%{public}d", ret);
106 return ret;
107 }
108 }
109 }
110
111 if (fileIteratorEntity->pos == fileIteratorEntity->fileInfoVec.size()) {
112 fileIteratorEntity->fileInfoVec.clear();
113 fileIteratorEntity->offset = 0;
114 fileIteratorEntity->pos = 0;
115 fileInfoEntity = nullptr;
116 objFileInfoExporter = NVal::CreateUndefined(env).val_;
117 nVal.AddProp("value", objFileInfoExporter);
118 nVal.AddProp("done", NVal::CreateBool(env, true).val_);
119 return ERR_OK;
120 }
121
122 fileInfoEntity->fileAccessHelper = fileIteratorEntity->fileAccessHelper;
123 fileInfoEntity->fileInfo = fileIteratorEntity->fileInfoVec[fileIteratorEntity->pos];
124 fileIteratorEntity->pos++;
125 nVal.AddProp("value", objFileInfoExporter);
126 nVal.AddProp("done", NVal::CreateBool(env, false).val_);
127 return ERR_OK;
128 }
129
Next(napi_env env,napi_callback_info info)130 napi_value NapiFileIteratorExporter::Next(napi_env env, napi_callback_info info)
131 {
132 NFuncArg funcArg(env, info);
133 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
134 NError(EINVAL).ThrowErr(env);
135 return nullptr;
136 }
137
138 auto fileIteratorEntity = NClass::GetEntityOf<FileIteratorEntity>(env, funcArg.GetThisVar());
139 if (fileIteratorEntity == nullptr) {
140 NError(E_GETRESULT).ThrowErr(env);
141 return nullptr;
142 }
143
144 if (IsDirectory(fileIteratorEntity->fileInfo.mode) != ERR_OK) {
145 HILOG_ERROR("current FileInfo's mode error");
146 return NVal::CreateUndefined(env).val_;
147 }
148
149 auto objFileInfoExporter = NClass::InstantiateClass(env, NapiFileInfoExporter::className_, {});
150 if (objFileInfoExporter == nullptr) {
151 NError(E_GETRESULT).ThrowErr(env);
152 return nullptr;
153 }
154
155 auto fileInfoEntity = NClass::GetEntityOf<FileInfoEntity>(env, objFileInfoExporter);
156 if (fileInfoEntity == nullptr) {
157 NError(E_GETRESULT).ThrowErr(env);
158 return nullptr;
159 }
160
161 if (fileIteratorEntity->fileAccessHelper == nullptr) {
162 NError(E_GETRESULT).ThrowErr(env);
163 return nullptr;
164 }
165
166 auto retNVal = NVal::CreateObject(env);
167 int ret = MakeResult(objFileInfoExporter, fileIteratorEntity, fileInfoEntity, env, retNVal);
168 if (ret != ERR_OK) {
169 NError(ret).ThrowErr(env);
170 return nullptr;
171 }
172
173 return retNVal.val_;
174 }
175
GetClassName()176 std::string NapiFileIteratorExporter::GetClassName()
177 {
178 return NapiFileIteratorExporter::className_;
179 }
180 } // namespace FileAccessFwk
181 } // namespace OHOS