• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "file_n_exporter.h"
17 
18 #include <cerrno>
19 #include <climits>
20 #include <cstdio>
21 #include <cstring>
22 #include <dirent.h>
23 #include <fcntl.h>
24 #include <fstream>
25 #include <iostream>
26 #include <memory>
27 #include <sstream>
28 #include <stack>
29 #include <sys/sendfile.h>
30 #include <sys/stat.h>
31 #include <vector>
32 
33 #include "../../common/ability_helper.h"
34 #include "../../common/file_helper/fd_guard.h"
35 #include "../../common/napi/n_class.h"
36 #include "../../common/napi/n_func_arg.h"
37 #include "../../common/napi/n_val.h"
38 #include "../../common/uni_error.h"
39 #include "../common_func.h"
40 
41 namespace OHOS {
42 namespace DistributedFS {
43 namespace ModuleFile {
44 using namespace std;
45 
46 constexpr int SUCCESS = 0;
47 constexpr int FAILED = -1;
48 constexpr int URI_PARAMER_ERROR = 202;
49 constexpr int FILE_IO_ERROR = 300;
50 constexpr int FILE_PATH_ERROR = 301;
51 constexpr int DIR_FAULT_PERM = 0775;
52 constexpr int SPLITE_ZERO = 0;
53 const string TYPE_FILE = "file";
54 const string TYPE_DIR = "dir";
55 const string ENCODING_UTF8 = "utf-8";
56 
CallBackSuccess(napi_env env,napi_ref successFuncRef,int32_t count,napi_value obj)57 void CallBackSuccess(napi_env env, napi_ref successFuncRef, int32_t count, napi_value obj)
58 {
59     napi_value results = nullptr;
60     napi_value successFunc = nullptr;
61     napi_value global = nullptr;
62     napi_get_global(env, &global);
63     napi_get_reference_value(env, successFuncRef, &successFunc);
64     if (successFunc == nullptr) {
65         return;
66     }
67     napi_call_function(env, global, successFunc, count, &obj, &results);
68 }
69 
CallBackError(napi_env env,napi_ref failFuncRef,string errorProp,int errorCode)70 void CallBackError(napi_env env, napi_ref failFuncRef, string errorProp, int errorCode)
71 {
72     napi_value argvFail[2] = { 0 };
73     napi_value results = nullptr;
74     napi_value failFunc = nullptr;
75     napi_value global = nullptr;
76     napi_get_global(env, &global);
77     argvFail[0] = NVal::CreateUTF8String(env, errorProp).val_;
78     argvFail[1] = NVal::CreateInt32(env, errorCode).val_;
79     napi_get_reference_value(env, failFuncRef, &failFunc);
80     if (failFunc == nullptr) {
81         return;
82     }
83     napi_call_function(env, global, failFunc, COMMON_NUM::TWO, argvFail, &results);
84 }
85 
CallComplete(napi_env env,napi_ref completeFuncRef)86 void CallComplete(napi_env env, napi_ref completeFuncRef)
87 {
88     napi_value completeFunc = nullptr;
89     napi_value results = nullptr;
90     napi_value global = nullptr;
91     napi_get_global(env, &global);
92     napi_get_reference_value(env, completeFuncRef, &completeFunc);
93     if (completeFunc == nullptr) {
94         return;
95     }
96     napi_call_function(env, global, completeFunc, COMMON_NUM::ZERO, nullptr, &results);
97 }
98 
CheckUri(napi_env env,string & path)99 bool CheckUri(napi_env env, string &path)
100 {
101     constexpr int spilteOne = 1;
102     constexpr int spilteTwo = 2;
103     constexpr int spilteThree = 3;
104     string pathOrigin = path;
105     vector<string> uriSplit;
106     string pattern = "/";
107     if (path == "") {
108         return false;
109     }
110     string pathTmp = pathOrigin + pattern;
111     size_t pos = pathTmp.find(pattern);
112     while (pos != pathTmp.npos) {
113         string temp = pathTmp.substr(SPLITE_ZERO, pos);
114         uriSplit.push_back(temp);
115         pathTmp = pathTmp.substr(pos + 1, pathTmp.size());
116         pos = pathTmp.find(pattern);
117     }
118     if (uriSplit[SPLITE_ZERO] != "internal:" || uriSplit[spilteOne] != "" || uriSplit.size() <= spilteThree) {
119         return false;
120     }
121     AppExecFwk::Ability *ability = AbilityHelper::GetJsAbility(env);
122     if (!ability) {
123         return false;
124     }
125     if (uriSplit[spilteTwo] == "app") {
126         path = "/data/storage/el2/base/haps/entry/files";
127     } else if (uriSplit[spilteTwo] == "cache") {
128         path = "/data/storage/el2/base/haps/entry/cache";
129     } else {
130         return false;
131     }
132     for (size_t i = spilteThree; i < uriSplit.size(); ++i) {
133         path = path + "/" + uriSplit[i];
134     }
135     return true;
136 }
137 
GetRealPath(string & path)138 int GetRealPath(string &path)
139 {
140     unique_ptr<char[]> absPath = make_unique<char[]>(PATH_MAX + 1);
141     if (realpath(path.c_str(), absPath.get()) == nullptr) {
142         return errno;
143     }
144     path = absPath.get();
145     return 0;
146 }
147 
UriToAbsolute(string path)148 string UriToAbsolute(string path)
149 {
150     stack<string> uriResult;
151     vector<string> uriSplit;
152     string pattern = "/";
153 
154     string pathTmp = path + pattern;
155     size_t pos = pathTmp.find(pattern);
156     while (pos != pathTmp.npos) {
157         string temp = pathTmp.substr(SPLITE_ZERO, pos);
158         uriSplit.push_back(temp);
159         pathTmp = pathTmp.substr(pos + 1, pathTmp.size());
160         pos = pathTmp.find(pattern);
161     }
162     for (auto urisp : uriSplit) {
163         if (urisp == "." || urisp == "") {
164             continue;
165         } else if (urisp == ".." && !uriResult.empty()) {
166             uriResult.pop();
167         } else {
168             uriResult.push(urisp);
169         }
170     }
171     path = "";
172     while (!uriResult.empty()) {
173         path = "/" + uriResult.top() + path;
174         uriResult.pop();
175     }
176     return path;
177 }
178 
GetFileNames(string path,vector<string> & filenames,bool rec,bool isList)179 bool GetFileNames(string path, vector<string> &filenames, bool rec, bool isList)
180 {
181     DIR *pDir;
182     struct dirent *ptr = nullptr;
183     if (!(pDir = opendir(path.c_str()))) {
184         return false;
185     }
186     while ((ptr = readdir(pDir)) != nullptr) {
187         if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
188             if (isList) {
189                 filenames.push_back(path + "/" + ptr->d_name);
190             } else if (ptr->d_type == DT_DIR && rec) {
191                 GetFileNames(path + "/" + ptr->d_name, filenames, rec, isList);
192             } else if (ptr->d_type == DT_REG) {
193                 filenames.push_back(path + "/" + ptr->d_name);
194             }
195         }
196     }
197     closedir(pDir);
198     return true;
199 }
200 
Mkdirs(string path)201 bool Mkdirs(string path)
202 {
203     for (size_t i = 1; i < path.length(); ++i) {
204         if (path[i] == '/') {
205             path[i] = '\0';
206             if (access(path.c_str(), 0) != 0 && mkdir(path.c_str(), DIR_FAULT_PERM) == FAILED) {
207                 return false;
208             }
209             path[i] = '/';
210         }
211     }
212     if (path.length() <= 0 || access(path.c_str(), 0) == 0 || mkdir(path.c_str(), DIR_FAULT_PERM) == FAILED) {
213         return false;
214     }
215     return true;
216 }
217 
Rmdirs(string path)218 bool Rmdirs(string path)
219 {
220     DIR *pDir;
221     struct dirent *ptr = nullptr;
222     if (!(pDir = opendir(path.c_str()))) {
223         return false;
224     }
225     while ((ptr = readdir(pDir)) != nullptr) {
226         if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
227             if ((ptr->d_type == DT_DIR && Rmdirs(path + "/" + ptr->d_name)) ||
228                 remove((path + "/" + ptr->d_name).c_str()) == 0) {
229             } else {
230                 closedir(pDir);
231                 return false;
232             }
233         }
234     }
235     closedir(pDir);
236     if (rmdir(path.c_str()) != 0) {
237         return false;
238     }
239     return true;
240 }
241 
ConvertUri(string path,string originPath,string originUri)242 string ConvertUri(string path, string originPath, string originUri)
243 {
244     if (path.find(originPath) != path.npos) {
245         if (originUri[originUri.length() - 1] == '/') {
246             originUri = originUri.substr(0, originUri.length() - 1);
247         }
248         path.replace(0, originPath.length(), originUri);
249     } else {
250         return "error";
251     }
252     return path;
253 }
254 
MkdirExec(napi_env env,void * data)255 void MkdirExec(napi_env env, void *data)
256 {
257     auto *asyncCallbackInfo = (AsyncMkdirCallbackInfo *)data;
258     string path = asyncCallbackInfo->url;
259     asyncCallbackInfo->result = FAILED;
260     asyncCallbackInfo->errorType = FILE_IO_ERROR;
261     if (GetRealPath(path) == ENOENT) {
262         path = UriToAbsolute(path);
263         if (asyncCallbackInfo->recursive && Mkdirs(path)) {
264             asyncCallbackInfo->result = SUCCESS;
265         } else if (mkdir((char *)path.c_str(), DIR_FAULT_PERM) != FAILED) {
266             asyncCallbackInfo->result = SUCCESS;
267         }
268     }
269 }
270 
MkdirComp(napi_env env,napi_status status,void * data)271 void MkdirComp(napi_env env, napi_status status, void *data)
272 {
273     auto *asyncCallbackInfo = (AsyncMkdirCallbackInfo *)data;
274 
275     if (asyncCallbackInfo->result == SUCCESS) {
276         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr);
277     } else if (asyncCallbackInfo->result == FAILED) {
278         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "make directory failed", FILE_IO_ERROR);
279     }
280     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
281     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
282     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
283     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
284     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
285     delete asyncCallbackInfo;
286 }
287 
RmdirExec(napi_env env,void * data)288 void RmdirExec(napi_env env, void *data)
289 {
290     auto *asyncCallbackInfo = (AsyncRmdirCallbackInfo *)data;
291     string path = asyncCallbackInfo->url;
292     asyncCallbackInfo->result = FAILED;
293     asyncCallbackInfo->errorType = FILE_IO_ERROR;
294     int statPath = GetRealPath(path);
295     if (statPath == COMMON_NUM::ZERO) {
296         if (asyncCallbackInfo->recursive && Rmdirs(path)) {
297             asyncCallbackInfo->result = SUCCESS;
298         } else if (remove((char *)path.c_str()) != FAILED) {
299             asyncCallbackInfo->result = SUCCESS;
300         }
301     } else if (statPath == ENOENT) {
302         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
303     }
304 }
305 
RmdirComp(napi_env env,napi_status status,void * data)306 void RmdirComp(napi_env env, napi_status status, void *data)
307 {
308     auto *asyncCallbackInfo = (AsyncRmdirCallbackInfo *)data;
309     if (asyncCallbackInfo->result == SUCCESS) {
310         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr);
311     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
312         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "remove directory failed", FILE_IO_ERROR);
313     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
314         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
315     }
316     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
317     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
318     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
319     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
320     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
321     delete asyncCallbackInfo;
322 }
323 
GetExec(napi_env env,void * data)324 void GetExec(napi_env env, void *data)
325 {
326     auto *asyncCallbackInfo = (AsyncGetCallbackInfo *)data;
327     string path = asyncCallbackInfo->url;
328     asyncCallbackInfo->result = FAILED;
329     asyncCallbackInfo->errorType = FILE_IO_ERROR;
330     struct stat buf;
331     int statPath = GetRealPath(path);
332     if (statPath == COMMON_NUM::ZERO && stat((char *)path.c_str(), &buf) == COMMON_NUM::ZERO) {
333         asyncCallbackInfo->length = buf.st_size;
334         asyncCallbackInfo->lastMT = buf.st_mtime * COMMON_NUM::THOUSAND +
335             (int64_t)((buf.st_mtim).tv_nsec / COMMON_NUM::MILLION);
336         asyncCallbackInfo->url = path;
337         std::vector<string> subFiles;
338         bool rec = asyncCallbackInfo->recursive;
339         if ((buf.st_mode & S_IFMT) == S_IFDIR && GetFileNames(path, subFiles, rec, false)) {
340             (asyncCallbackInfo->subFiles).assign(subFiles.begin(), subFiles.end());
341             asyncCallbackInfo->type = TYPE_DIR;
342             asyncCallbackInfo->result = SUCCESS;
343         } else if ((buf.st_mode & S_IFMT) == S_IFREG) {
344             asyncCallbackInfo->type = TYPE_FILE;
345             asyncCallbackInfo->result = SUCCESS;
346         }
347     } else if (statPath == ENOENT) {
348         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
349     }
350 }
351 
GetComp(napi_env env,napi_status status,void * data)352 void GetComp(napi_env env, napi_status status, void *data)
353 {
354     auto *asyncCallbackInfo = (AsyncGetCallbackInfo *)data;
355     if (asyncCallbackInfo->result == SUCCESS) {
356         napi_value subFilesNapi = nullptr;
357         napi_create_array(env, &subFilesNapi);
358         int32_t i = 0;
359         for (auto filename : asyncCallbackInfo->subFiles) {
360             napi_set_property(
361                 env, subFilesNapi, NVal::CreateInt32(env, i).val_,
362                 NVal::CreateUTF8String(
363                     env, ConvertUri(filename, asyncCallbackInfo->url, asyncCallbackInfo->originUri).c_str())
364                     .val_);
365             i = i + 1;
366         }
367         NVal objn = NVal::CreateObject(env);
368         objn.AddProp("lastModifiedTime", NVal::CreateInt64(env, asyncCallbackInfo->lastMT).val_);
369         objn.AddProp("length", NVal::CreateInt32(env, asyncCallbackInfo->length).val_);
370         objn.AddProp("uri", NVal::CreateUTF8String(env, asyncCallbackInfo->originUri).val_);
371         objn.AddProp("type", NVal::CreateUTF8String(env, asyncCallbackInfo->type).val_);
372         objn.AddProp("subFiles", subFilesNapi);
373 
374         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_);
375     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
376         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
377     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
378         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "get file failed", FILE_IO_ERROR);
379     }
380     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
381     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
382     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
383     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
384     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
385     delete asyncCallbackInfo;
386 }
387 
ListExec(napi_env env,void * data)388 void ListExec(napi_env env, void *data)
389 {
390     auto *asyncCallbackInfo = (AsyncListCallbackInfo *)data;
391     string path = asyncCallbackInfo->url;
392     asyncCallbackInfo->result = FAILED;
393     std::vector<string> fileNames;
394     struct stat buf;
395     int statPath = GetRealPath(path);
396     if (statPath == ENOENT) {
397         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
398     } else if (statPath != COMMON_NUM::ZERO || stat((char *)path.c_str(), &buf) != COMMON_NUM::ZERO) {
399         asyncCallbackInfo->errorType = FILE_IO_ERROR;
400     } else if ((buf.st_mode & S_IFMT) == S_IFREG) {
401         asyncCallbackInfo->result = SUCCESS;
402     } else {
403         asyncCallbackInfo->url = path;
404         bool getStat = GetFileNames(path, fileNames, false, true);
405         if (!getStat) {
406             asyncCallbackInfo->errorType = FILE_IO_ERROR;
407         } else {
408             vector<FileInfo> fileList;
409             for (auto ph : fileNames) {
410                 struct stat tmp;
411                 int r = stat(ph.c_str(), &tmp);
412                 FileInfo fi;
413                 if (r == 0 && S_ISDIR(tmp.st_mode)) {
414                     fi.type = TYPE_DIR;
415                 } else if (r == 0 && (tmp.st_mode & S_IFMT) == S_IFREG) {
416                     fi.type = TYPE_FILE;
417                 }
418                 fi.length = tmp.st_size;
419                 fi.lastModifiedTime = tmp.st_mtime * COMMON_NUM::THOUSAND +
420                     (int64_t)((tmp.st_mtim).tv_nsec / COMMON_NUM::MILLION);
421                 fi.uri = ph;
422                 fileList.push_back(fi);
423             }
424             (asyncCallbackInfo->fileList).assign(fileList.begin(), fileList.end());
425             asyncCallbackInfo->result = SUCCESS;
426         }
427     }
428 }
429 
ListComp(napi_env env,napi_status status,void * data)430 void ListComp(napi_env env, napi_status status, void *data)
431 {
432     auto *asyncCallbackInfo = (AsyncListCallbackInfo *)data;
433     if (asyncCallbackInfo->result == SUCCESS) {
434         napi_value fileListNapi;
435         napi_create_array(env, &fileListNapi);
436         int32_t i = 0;
437         for (auto fileInfo : asyncCallbackInfo->fileList) {
438             NVal objt = NVal::CreateObject(env);
439             objt.AddProp("lastModifiedTime", NVal::CreateInt64(env, fileInfo.lastModifiedTime).val_);
440             objt.AddProp("length", NVal::CreateInt32(env, fileInfo.length).val_);
441             string uriTojs = ConvertUri(fileInfo.uri, asyncCallbackInfo->url, asyncCallbackInfo->originUri);
442             objt.AddProp("uri", NVal::CreateUTF8String(env, uriTojs).val_);
443             objt.AddProp("type", NVal::CreateUTF8String(env, fileInfo.type).val_);
444 
445             napi_set_property(env, fileListNapi, NVal::CreateInt32(env, i).val_, objt.val_);
446             i = i + 1;
447         }
448         NVal objn = NVal::CreateObject(env);
449         objn.AddProp("fileList", fileListNapi);
450         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_);
451     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
452         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
453     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
454         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "list file failed", FILE_IO_ERROR);
455     }
456     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
457     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
458     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
459     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
460     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
461     delete asyncCallbackInfo;
462 }
463 
FileCopy(const string & srcPath,const string & dstPath)464 int FileCopy(const string& srcPath, const string& dstPath)
465 {
466     bool ret = FILE_IO_ERROR;
467     string src = srcPath;
468     string dest = dstPath;
469     if (GetRealPath(src) == 0) {
470         if (GetRealPath(dest) == ENOENT) {
471             FDGuard sfd;
472             sfd.SetFD(open((char *)src.c_str(), O_RDONLY));
473             struct stat attrSrc;
474             if (stat((char *)src.c_str(), &attrSrc) == FAILED) {
475                 return FILE_IO_ERROR;
476             }
477             dest = UriToAbsolute(dest);
478             FDGuard ofd;
479             ofd.SetFD(open((char *)dest.c_str(), O_WRONLY | O_CREAT, attrSrc.st_mode));
480             if (sfd.GetFD() == FAILED || ofd.GetFD() == FAILED) {
481                 return FILE_IO_ERROR;
482             }
483 
484             if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, attrSrc.st_size) != FAILED) {
485                 ret = SUCCESS;
486             } else {
487                 remove((char *)dest.c_str());
488             }
489         } else if (GetRealPath(dest) == 0) {
490             return (dest == src) ? SUCCESS : FILE_IO_ERROR;
491         }
492     }
493     return ret;
494 }
495 
DirCopy(const string & srcPath,const string & dstPath)496 int DirCopy(const string& srcPath, const string& dstPath)
497 {
498     string src = srcPath;
499     string dest = dstPath;
500     if (GetRealPath(src) == ENOENT) {
501         return FILE_PATH_ERROR;
502     }
503     if (GetRealPath(dest) == ENOENT) {
504         struct stat attrSrc;
505         if (stat((char *)src.c_str(), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) {
506             return FILE_IO_ERROR;
507         }
508         dest = UriToAbsolute(dest);
509         if (mkdir(dest.c_str(), attrSrc.st_mode) == FAILED) {
510             return FILE_IO_ERROR;
511         }
512     } else {
513         return (dest == src) ? SUCCESS : FILE_IO_ERROR;
514     }
515     return SUCCESS;
516 }
517 
CopyExec(napi_env env,void * data)518 void CopyExec(napi_env env, void *data)
519 {
520     auto *asyncCallbackInfo = (AsyncCopyCallbackInfo *)data;
521     string path = asyncCallbackInfo->url;
522     string pathDst = asyncCallbackInfo->urlDst;
523     asyncCallbackInfo->result = FAILED;
524     asyncCallbackInfo->errorType = FILE_IO_ERROR;
525     if (GetRealPath(path) == ENOENT) {
526         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
527         return;
528     }
529 
530     struct stat statbf;
531     if (stat((char *)path.c_str(), &statbf) == FAILED) {
532         asyncCallbackInfo->errorType = FILE_IO_ERROR;
533         return;
534     }
535 
536     int retval;
537     if (S_ISREG(statbf.st_mode)) {
538         retval = FileCopy(path, pathDst);
539         if (retval == SUCCESS) {
540             asyncCallbackInfo->result = SUCCESS;
541         } else {
542             asyncCallbackInfo->errorType = retval;
543         }
544     } else if (S_ISDIR(statbf.st_mode)) {
545         retval = DirCopy(path, pathDst);
546         if (retval == SUCCESS) {
547             asyncCallbackInfo->result = SUCCESS;
548         } else {
549             asyncCallbackInfo->errorType = retval;
550         }
551     }
552 }
553 
CopyComp(napi_env env,napi_status status,void * data)554 void CopyComp(napi_env env, napi_status status, void *data)
555 {
556     auto *asyncCallbackInfo = (AsyncCopyCallbackInfo *)data;
557     if (asyncCallbackInfo->result == SUCCESS) {
558         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE,
559                         NVal::CreateUTF8String(env, asyncCallbackInfo->originDst).val_);
560     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
561         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "copy file failed", FILE_IO_ERROR);
562     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
563         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
564     }
565     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
566     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
567     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
568     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
569     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
570     delete asyncCallbackInfo;
571 }
572 
DirMove(const string & srcPath,const string & dstPath)573 int DirMove(const string& srcPath, const string& dstPath)
574 {
575     string src = srcPath;
576     string dest = dstPath;
577     if (GetRealPath(src) == ENOENT) {
578         return FILE_PATH_ERROR;
579     }
580 
581     auto res = GetRealPath(dest);
582     if (res == 0 && dest == src) {
583         return SUCCESS;
584     } else if (res != ENOENT) {
585         return FILE_PATH_ERROR;
586     }
587 
588     struct stat attrSrc;
589     if (stat((char *)src.c_str(), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) {
590         return FILE_IO_ERROR;
591     }
592     dest = UriToAbsolute(dest);
593     if (FAILED == mkdir(dest.c_str(), attrSrc.st_mode)) {
594         return FILE_IO_ERROR;
595     }
596     DIR *dirp = opendir(src.c_str());
597     if (dirp == nullptr) {
598         return FILE_IO_ERROR;
599     }
600     struct dirent *entp;
601     while ((entp = readdir(dirp)) != nullptr) {
602         if (string(entp->d_name) == "." || string(entp->d_name) == "..") {
603             continue;
604         }
605         string srcBuf = src + "/" + string(entp->d_name);
606         string dstBuf = dest + "/" + string(entp->d_name);
607         if (entp->d_type == DT_DIR && DirMove(srcBuf.c_str(), dstBuf.c_str()) != SUCCESS) {
608             closedir(dirp);
609             return FILE_IO_ERROR;
610         }
611 
612         if (entp->d_type == DT_REG) {
613             if (FileCopy(srcBuf.c_str(), dstBuf.c_str()) != SUCCESS) {
614                 closedir(dirp);
615                 return FILE_IO_ERROR;
616             } else {
617                 remove(srcBuf.c_str());
618             }
619         }
620     }
621     closedir(dirp);
622     rmdir(src.c_str());
623 
624     return SUCCESS;
625 }
626 
MoveExec(napi_env env,void * data)627 void MoveExec(napi_env env, void *data)
628 {
629     auto *asyncCallbackInfo = (AsyncMoveCallbackInfo *)data;
630     string path = asyncCallbackInfo->url;
631     string pathDst = asyncCallbackInfo->urlDst;
632     asyncCallbackInfo->result = FAILED;
633     asyncCallbackInfo->errorType = FILE_IO_ERROR;
634     if (GetRealPath(path) == ENOENT) {
635         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
636         return;
637     }
638 
639     struct stat statbf;
640     if (stat((char *)path.c_str(), &statbf) == FAILED) {
641         asyncCallbackInfo->errorType = FILE_IO_ERROR;
642         return;
643     }
644 
645     if (S_ISREG(statbf.st_mode)) {
646         int retval = FileCopy(path, pathDst);
647         if (retval == SUCCESS) {
648             asyncCallbackInfo->result = SUCCESS;
649             remove((char *)path.c_str());
650         } else {
651             asyncCallbackInfo->errorType = retval;
652         }
653     } else if (S_ISDIR(statbf.st_mode)) {
654         int retval = DirMove(path, pathDst);
655         if (retval == SUCCESS) {
656             asyncCallbackInfo->result = SUCCESS;
657         } else {
658             asyncCallbackInfo->errorType = retval;
659         }
660     }
661 }
662 
MoveComp(napi_env env,napi_status status,void * data)663 void MoveComp(napi_env env, napi_status status, void *data)
664 {
665     auto *asyncCallbackInfo = (AsyncMoveCallbackInfo *)data;
666     if (asyncCallbackInfo->result == SUCCESS) {
667         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE,
668                         NVal::CreateUTF8String(env, asyncCallbackInfo->originDst).val_);
669     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
670         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "move file failed", FILE_IO_ERROR);
671     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
672         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
673     }
674     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
675     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
676     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
677     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
678     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
679     delete asyncCallbackInfo;
680 }
681 
DeleteExec(napi_env env,void * data)682 void DeleteExec(napi_env env, void *data)
683 {
684     auto *asyncCallbackInfo = (AsyncDeleteCallbackInfo *)data;
685     string path = asyncCallbackInfo->url;
686     asyncCallbackInfo->result = FAILED;
687     int statPath = GetRealPath(path);
688     if (statPath == ENOENT) {
689         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
690     } else if (statPath == COMMON_NUM::ZERO && remove((char *)path.c_str()) != FAILED) {
691         asyncCallbackInfo->result = SUCCESS;
692     } else {
693         asyncCallbackInfo->errorType = FILE_IO_ERROR;
694     }
695 }
696 
DeleteComp(napi_env env,napi_status status,void * data)697 void DeleteComp(napi_env env, napi_status status, void *data)
698 {
699     auto *asyncCallbackInfo = (AsyncDeleteCallbackInfo *)data;
700     if (asyncCallbackInfo->result == SUCCESS) {
701         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr);
702     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
703         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "delete file failed", FILE_IO_ERROR);
704     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
705         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
706     }
707     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
708     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
709     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
710     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
711     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
712     delete asyncCallbackInfo;
713 }
714 
AccessExec(napi_env env,void * data)715 void AccessExec(napi_env env, void *data)
716 {
717     auto *asyncCallbackInfo = (AsyncAccessCallbackInfo *)data;
718     string path = asyncCallbackInfo->url;
719     asyncCallbackInfo->result = FAILED;
720     int statPath = GetRealPath(path);
721     if (statPath == ENOENT) {
722         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
723     } else if (statPath == COMMON_NUM::ZERO) {
724         asyncCallbackInfo->result = SUCCESS;
725     } else {
726         asyncCallbackInfo->errorType = FILE_IO_ERROR;
727     }
728 }
729 
AccessComp(napi_env env,napi_status status,void * data)730 void AccessComp(napi_env env, napi_status status, void *data)
731 {
732     auto *asyncCallbackInfo = (AsyncAccessCallbackInfo *)data;
733     if (asyncCallbackInfo->result == SUCCESS) {
734         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr);
735     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
736         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "access file failed", FILE_IO_ERROR);
737     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
738         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
739     }
740     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
741     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
742     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
743     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
744     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
745     delete asyncCallbackInfo;
746 }
747 
WriteTextExec(napi_env env,void * data)748 void WriteTextExec(napi_env env, void *data)
749 {
750     auto *asyncCallbackInfo = (AsyncWriteCallbackInfo *)data;
751     string path = asyncCallbackInfo->url;
752     string text = asyncCallbackInfo->text;
753     asyncCallbackInfo->result = FAILED;
754     asyncCallbackInfo->errorType = FILE_IO_ERROR;
755     int fd = -1;
756     int statPath = GetRealPath(path);
757     if (statPath == COMMON_NUM::ZERO || statPath == ENOENT) {
758         if (asyncCallbackInfo->append) {
759             fd = open(path.c_str(), O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
760         } else {
761             fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
762         }
763         if (fd != FAILED) {
764             if (write(fd, text.c_str(), text.length()) != FAILED) {
765                 asyncCallbackInfo->result = SUCCESS;
766             }
767             close(fd);
768         }
769     }
770 }
771 
WriteTextComp(napi_env env,napi_status status,void * data)772 void WriteTextComp(napi_env env, napi_status status, void *data)
773 {
774     auto *asyncCallbackInfo = (AsyncWriteCallbackInfo *)data;
775     if (asyncCallbackInfo->result == SUCCESS) {
776         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr);
777     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
778         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "write file failed", FILE_IO_ERROR);
779     }
780     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
781     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
782     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
783     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
784     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
785     delete asyncCallbackInfo;
786 }
787 
WriteArrayBufferExec(napi_env env,void * data)788 void WriteArrayBufferExec(napi_env env, void *data)
789 {
790     auto *asyncCallbackInfo = (AsyncWriteBufferCallbackInfo *)data;
791     string path = asyncCallbackInfo->url;
792     asyncCallbackInfo->result = FAILED;
793     asyncCallbackInfo->errorType = FILE_IO_ERROR;
794     int fd = -1;
795     int statPath = GetRealPath(path);
796     if (statPath == COMMON_NUM::ZERO || statPath == ENOENT) {
797         if (asyncCallbackInfo->append) {
798             fd = open(path.c_str(), O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
799             if (fd == FAILED) {
800                 return;
801             }
802         } else {
803             fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
804             if (fd == FAILED) {
805                 return;
806             }
807             lseek(fd, asyncCallbackInfo->position, SEEK_CUR);
808         }
809         if (write(fd, asyncCallbackInfo->buf, asyncCallbackInfo->length) != FAILED) {
810             asyncCallbackInfo->result = SUCCESS;
811         }
812         close(fd);
813     }
814 }
815 
WriteArrayBufferComp(napi_env env,napi_status status,void * data)816 void WriteArrayBufferComp(napi_env env, napi_status status, void *data)
817 {
818     auto *asyncCallbackInfo = (AsyncWriteBufferCallbackInfo *)data;
819     if (asyncCallbackInfo->result == SUCCESS) {
820         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr);
821     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
822         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "write file failed", FILE_IO_ERROR);
823     }
824     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
825     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
826     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
827     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
828     napi_delete_reference(env, asyncCallbackInfo->bufferAddress);
829     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
830     delete asyncCallbackInfo;
831 }
832 
ReadTextExec(napi_env env,void * data)833 void ReadTextExec(napi_env env, void *data)
834 {
835     auto *asyncCallbackInfo = (AsyncReadCallbackInfo *)data;
836     string path = asyncCallbackInfo->url;
837     asyncCallbackInfo->result = FAILED;
838     asyncCallbackInfo->errorType = FILE_IO_ERROR;
839     int statPath = GetRealPath(path);
840     if (statPath == COMMON_NUM::ZERO) {
841         FDGuard fdg;
842         fdg.SetFD(open(path.c_str(), O_RDONLY));
843         struct stat buf;
844         int result = stat((char *)path.c_str(), &buf);
845         if (fdg.GetFD() != FAILED && result != FAILED) {
846             auto buffer = std::make_unique<char[]>(buf.st_size + 1);
847             if (buffer == nullptr) {
848                 UniError(ENOMEM).ThrowErr(env);
849                 return;
850             }
851             if (read(fdg.GetFD(), buffer.get(), buf.st_size) != FAILED) {
852                 asyncCallbackInfo->result = SUCCESS;
853                 asyncCallbackInfo->contents = std::string(buffer.get());
854             }
855         }
856     } else if (statPath == ENOENT) {
857         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
858     }
859 }
860 
ReadTextComp(napi_env env,napi_status status,void * data)861 void ReadTextComp(napi_env env, napi_status status, void *data)
862 {
863     auto *asyncCallbackInfo = (AsyncReadCallbackInfo *)data;
864     if (asyncCallbackInfo->result == SUCCESS) {
865         NVal objn = NVal::CreateObject(env);
866         objn.AddProp("text", NVal::CreateUTF8String(env, asyncCallbackInfo->contents).val_);
867         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_);
868     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
869         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "read file failed", FILE_IO_ERROR);
870     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
871         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
872     }
873     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
874     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
875     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
876     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
877     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
878     delete asyncCallbackInfo;
879 }
880 
ReadArrayBufferExec(napi_env env,void * data)881 void ReadArrayBufferExec(napi_env env, void *data)
882 {
883     auto *asyncCallbackInfo = (AsyncReadBufferCallbackInfo *)data;
884     string path = asyncCallbackInfo->url;
885     asyncCallbackInfo->result = FAILED;
886     asyncCallbackInfo->errorType = FILE_IO_ERROR;
887     int statPath = GetRealPath(path);
888     if (statPath == COMMON_NUM::ZERO) {
889         FDGuard fdg;
890         fdg.SetFD(open(path.c_str(), O_RDONLY));
891         struct stat buf;
892         int result = stat((char *)path.c_str(), &buf);
893         if (fdg.GetFD() != FAILED && result != FAILED) {
894             int32_t begin = (buf.st_size < asyncCallbackInfo->position) ? buf.st_size : asyncCallbackInfo->position;
895             int32_t len =
896                 (asyncCallbackInfo->length == COMMON_NUM::ZERO) ? (buf.st_size - begin) : asyncCallbackInfo->length;
897             auto buffer = std::make_unique<char[]>(len + 1);
898             if (buffer == nullptr) {
899                 UniError(ENOMEM).ThrowErr(env);
900                 return;
901             }
902             lseek(fdg.GetFD(), begin, SEEK_CUR);
903             if (read(fdg.GetFD(), buffer.get(), len) != FAILED) {
904                 asyncCallbackInfo->result = SUCCESS;
905                 asyncCallbackInfo->len = len;
906                 asyncCallbackInfo->contents = std::string(buffer.get());
907             }
908         }
909     } else if (statPath == ENOENT) {
910         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
911     }
912 }
913 
ReadArrayBufferComp(napi_env env,napi_status status,void * data)914 void ReadArrayBufferComp(napi_env env, napi_status status, void *data)
915 {
916     auto *asyncCallbackInfo = (AsyncReadBufferCallbackInfo *)data;
917     if (asyncCallbackInfo->result == SUCCESS) {
918         napi_value typeArr = nullptr;
919         napi_create_array(env, &typeArr);
920         for (int32_t i = 0; i < asyncCallbackInfo->len; ++i) {
921             napi_set_property(env, typeArr, NVal::CreateInt32(env, i).val_,
922                               NVal::CreateInt32(env, (int32_t)(asyncCallbackInfo->contents)[i]).val_);
923         }
924         NVal objn = NVal::CreateObject(env);
925         objn.AddProp("buffer", typeArr);
926         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_);
927     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
928         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "read file failed", FILE_IO_ERROR);
929     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
930         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
931     }
932     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
933     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
934     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
935     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
936     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
937     delete asyncCallbackInfo;
938 }
939 
Mkdir(napi_env env,napi_callback_info info)940 napi_value FileNExporter::Mkdir(napi_env env, napi_callback_info info)
941 {
942     NFuncArg funcArg(env, info);
943     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
944         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
945         return nullptr;
946     }
947     bool succ = false;
948     auto *asyncCallbackInfo = new AsyncMkdirCallbackInfo {
949         .env = env,
950         .asyncWork = nullptr,
951     };
952     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
953         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
954 
955     unique_ptr<char[]> uri;
956     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
957 
958     bool recursive = false;
959     tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool();
960 
961     string path = (uri == nullptr) ? "" : uri.get();
962     if (!CheckUri(env, path)) {
963         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
964         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
965         delete asyncCallbackInfo;
966         return nullptr;
967     }
968     asyncCallbackInfo->recursive = recursive;
969     asyncCallbackInfo->url = path;
970 
971     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, MkdirExec, MkdirComp,
972                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
973     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
974     return NVal::CreateUndefined(env).val_;
975 }
976 
Rmdir(napi_env env,napi_callback_info info)977 napi_value FileNExporter::Rmdir(napi_env env, napi_callback_info info)
978 {
979     NFuncArg funcArg(env, info);
980     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
981         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
982         return nullptr;
983     }
984     bool succ = false;
985     auto *asyncCallbackInfo = new AsyncRmdirCallbackInfo {
986         .env = env,
987         .asyncWork = nullptr,
988     };
989     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
990         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
991 
992     unique_ptr<char[]> uri;
993     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
994 
995     bool recursive = false;
996     tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool();
997 
998     string path = (uri == nullptr) ? "" : uri.get();
999     if (!CheckUri(env, path)) {
1000         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1001         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1002         delete asyncCallbackInfo;
1003         return nullptr;
1004     }
1005     asyncCallbackInfo->recursive = recursive;
1006     asyncCallbackInfo->url = path;
1007 
1008     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, RmdirExec, RmdirComp,
1009                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1010     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1011 
1012     return NVal::CreateUndefined(env).val_;
1013 }
1014 
Get(napi_env env,napi_callback_info info)1015 napi_value FileNExporter::Get(napi_env env, napi_callback_info info)
1016 {
1017     NFuncArg funcArg(env, info);
1018     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1019         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1020         return nullptr;
1021     }
1022     auto *asyncCallbackInfo = new AsyncGetCallbackInfo {
1023         .env = env,
1024         .asyncWork = nullptr,
1025     };
1026     bool succ = false;
1027     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1028         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1029     unique_ptr<char[]> uri = nullptr;
1030     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
1031 
1032     bool recursive = false;
1033     tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool();
1034     string path = (uri == nullptr) ? "" : uri.get();
1035     asyncCallbackInfo->originUri = path;
1036     if (!CheckUri(env, path)) {
1037         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1038         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1039         delete asyncCallbackInfo;
1040         return nullptr;
1041     }
1042     asyncCallbackInfo->recursive = recursive;
1043     asyncCallbackInfo->url = path;
1044 
1045     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, GetExec, GetComp,
1046                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1047     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1048 
1049     return NVal::CreateUndefined(env).val_;
1050 }
1051 
List(napi_env env,napi_callback_info info)1052 napi_value FileNExporter::List(napi_env env, napi_callback_info info)
1053 {
1054     NFuncArg funcArg(env, info);
1055     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1056         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1057         return nullptr;
1058     }
1059     auto *asyncCallbackInfo = new AsyncListCallbackInfo {
1060         .env = env,
1061         .asyncWork = nullptr,
1062     };
1063     bool succ = false;
1064     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1065         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1066 
1067     unique_ptr<char[]> uri = nullptr;
1068     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
1069 
1070     string path = (uri == nullptr) ? "" : uri.get();
1071     asyncCallbackInfo->originUri = path;
1072     if (!CheckUri(env, path)) {
1073         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1074         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1075         delete asyncCallbackInfo;
1076         return nullptr;
1077     }
1078     asyncCallbackInfo->url = path;
1079 
1080     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ListExec, ListComp,
1081                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1082     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1083 
1084     return NVal::CreateUndefined(env).val_;
1085 }
1086 
Copy(napi_env env,napi_callback_info info)1087 napi_value FileNExporter::Copy(napi_env env, napi_callback_info info)
1088 {
1089     NFuncArg funcArg(env, info);
1090     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1091         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1092         return nullptr;
1093     }
1094     bool succ = false;
1095     auto *asyncCallbackInfo = new AsyncCopyCallbackInfo {
1096         .env = env,
1097         .asyncWork = nullptr,
1098     };
1099     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1100         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1101 
1102     unique_ptr<char[]> srcUri, dstUri;
1103     tie(succ, srcUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("srcUri").ToUTF8String();
1104     tie(succ, dstUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("dstUri").ToUTF8String();
1105     string srcPath = ((srcUri == nullptr) ? "" : (srcUri.get()));
1106     string dstPath = ((dstUri == nullptr) ? "" : (dstUri.get()));
1107     asyncCallbackInfo->originDst = dstPath;
1108     if (!CheckUri(env, srcPath) || !CheckUri(env, dstPath)) {
1109         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1110         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1111         delete asyncCallbackInfo;
1112         return nullptr;
1113     }
1114     asyncCallbackInfo->url = srcPath;
1115     asyncCallbackInfo->urlDst = dstPath;
1116 
1117     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, CopyExec, CopyComp,
1118                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1119     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1120     return NVal::CreateUndefined(env).val_;
1121 }
1122 
Move(napi_env env,napi_callback_info info)1123 napi_value FileNExporter::Move(napi_env env, napi_callback_info info)
1124 {
1125     NFuncArg funcArg(env, info);
1126     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1127         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1128         return nullptr;
1129     }
1130     bool succ = false;
1131     auto *asyncCallbackInfo = new AsyncMoveCallbackInfo {
1132         .env = env,
1133         .asyncWork = nullptr,
1134     };
1135     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1136         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1137 
1138     unique_ptr<char[]> srcUri, dstUri;
1139     tie(succ, srcUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("srcUri").ToUTF8String();
1140     tie(succ, dstUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("dstUri").ToUTF8String();
1141 
1142     string srcPath = ((srcUri == nullptr) ? "" : (srcUri.get()));
1143     string dstPath = ((dstUri == nullptr) ? "" : (dstUri.get()));
1144     asyncCallbackInfo->originDst = dstPath;
1145     if (!CheckUri(env, srcPath) || !CheckUri(env, dstPath)) {
1146         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1147         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1148         delete asyncCallbackInfo;
1149         return nullptr;
1150     }
1151     asyncCallbackInfo->url = srcPath;
1152     asyncCallbackInfo->urlDst = dstPath;
1153 
1154     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, MoveExec, MoveComp,
1155                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1156     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1157     return NVal::CreateUndefined(env).val_;
1158 }
1159 
Delete(napi_env env,napi_callback_info info)1160 napi_value FileNExporter::Delete(napi_env env, napi_callback_info info)
1161 {
1162     NFuncArg funcArg(env, info);
1163     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1164         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1165         return nullptr;
1166     }
1167     bool succ = false;
1168     auto *asyncCallbackInfo = new AsyncDeleteCallbackInfo {
1169         .env = env,
1170         .asyncWork = nullptr,
1171     };
1172     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1173         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1174 
1175     unique_ptr<char[]> uri;
1176     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
1177 
1178     string path = (uri == nullptr) ? "" : uri.get();
1179     if (!CheckUri(env, path)) {
1180         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1181         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1182         delete asyncCallbackInfo;
1183         return nullptr;
1184     }
1185     asyncCallbackInfo->url = path;
1186 
1187     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, DeleteExec, DeleteComp,
1188                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1189     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1190 
1191     return NVal::CreateUndefined(env).val_;
1192 }
1193 
Access(napi_env env,napi_callback_info info)1194 napi_value FileNExporter::Access(napi_env env, napi_callback_info info)
1195 {
1196     NFuncArg funcArg(env, info);
1197     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1198         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1199         return nullptr;
1200     }
1201     bool succ = false;
1202     AsyncAccessCallbackInfo *asyncCallbackInfo = new AsyncAccessCallbackInfo {
1203         .env = env,
1204         .asyncWork = nullptr,
1205     };
1206     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1207         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1208 
1209     unique_ptr<char[]> uri;
1210     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
1211 
1212     string path = (uri == nullptr) ? "" : uri.get();
1213     if (!CheckUri(env, path)) {
1214         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1215         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1216         delete asyncCallbackInfo;
1217         return nullptr;
1218     }
1219     asyncCallbackInfo->url = path;
1220 
1221     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, AccessExec, AccessComp,
1222                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1223     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1224     return NVal::CreateUndefined(env).val_;
1225 }
1226 
WriteText(napi_env env,napi_callback_info info)1227 napi_value FileNExporter::WriteText(napi_env env, napi_callback_info info)
1228 {
1229     NFuncArg funcArg(env, info);
1230     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1231         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1232         return nullptr;
1233     }
1234     auto *asyncCallbackInfo = new AsyncWriteCallbackInfo {
1235         .env = env,
1236         .asyncWork = nullptr,
1237     };
1238     bool succ = false;
1239     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1240         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1241 
1242     unique_ptr<char[]> uri, text, encoding;
1243     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
1244     tie(succ, text, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("text").ToUTF8String();
1245     tie(succ, encoding, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("encoding").ToUTF8String();
1246 
1247     bool append = false;
1248     tie(succ, append) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("append").ToBool();
1249 
1250     string path = (uri == nullptr) ? "" : uri.get();
1251     string encode = (encoding == nullptr) ? ENCODING_UTF8 : encoding.get();
1252     transform(encode.begin(), encode.end(), encode.begin(), ::tolower);
1253     if (!CheckUri(env, path)) {
1254         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1255         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1256         delete asyncCallbackInfo;
1257         return nullptr;
1258     }
1259     if (encode != ENCODING_UTF8) {
1260         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "write file failed", FILE_IO_ERROR);
1261         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1262         delete asyncCallbackInfo;
1263         return nullptr;
1264     }
1265     string content = text.get();
1266     asyncCallbackInfo->url = path;
1267     asyncCallbackInfo->text = content;
1268     asyncCallbackInfo->append = append;
1269 
1270     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, WriteTextExec, WriteTextComp,
1271                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1272     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1273     return NVal::CreateUndefined(env).val_;
1274 }
1275 
WriteArrayBuffer(napi_env env,napi_callback_info info)1276 napi_value FileNExporter::WriteArrayBuffer(napi_env env, napi_callback_info info)
1277 {
1278     NFuncArg funcArg(env, info);
1279     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1280         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1281         return nullptr;
1282     }
1283     bool succ = false;
1284     auto *asyncCallbackInfo = new AsyncWriteBufferCallbackInfo {
1285         .env = env,
1286         .asyncWork = nullptr,
1287     };
1288     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1289         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1290 
1291     unique_ptr<char[]> uri;
1292     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
1293 
1294     int32_t position = 0;
1295     tie(succ, position) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("position").ToInt32();
1296 
1297     bool append = false;
1298     tie(succ, append) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("append").ToBool();
1299 
1300     void *buffer = nullptr;
1301     size_t bufLength = 0;
1302     napi_ref bufferRef = nullptr;
1303     NVal bufNapi = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("buffer");
1304     tie(succ, buffer, bufLength) = bufNapi.ToTypedArray();
1305     napi_create_reference(env, bufNapi.val_, 1, &bufferRef);
1306 
1307     string path = (uri == nullptr) ? "" : uri.get();
1308     if (!CheckUri(env, path)) {
1309         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1310         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1311         delete asyncCallbackInfo;
1312         return nullptr;
1313     }
1314     asyncCallbackInfo->url = path;
1315     asyncCallbackInfo->position = position;
1316     asyncCallbackInfo->append = append;
1317     asyncCallbackInfo->buf = buffer;
1318     asyncCallbackInfo->length = bufLength;
1319     asyncCallbackInfo->bufferAddress = bufferRef;
1320 
1321     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, WriteArrayBufferExec,
1322                            WriteArrayBufferComp, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1323     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1324     return NVal::CreateUndefined(env).val_;
1325 }
1326 
ReadText(napi_env env,napi_callback_info info)1327 napi_value FileNExporter::ReadText(napi_env env, napi_callback_info info)
1328 {
1329     NFuncArg funcArg(env, info);
1330     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1331         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1332         return nullptr;
1333     }
1334     bool succ = false;
1335     auto *asyncCallbackInfo = new AsyncReadCallbackInfo {
1336         .env = env,
1337         .asyncWork = nullptr,
1338     };
1339     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1340         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1341 
1342     unique_ptr<char[]> uri, encoding;
1343     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
1344     tie(succ, encoding, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("encoding").ToUTF8String();
1345 
1346     string path = (uri == nullptr) ? "" : uri.get();
1347     string encode = (encoding == nullptr) ? ENCODING_UTF8 : encoding.get();
1348     transform(encode.begin(), encode.end(), encode.begin(), ::tolower);
1349     if (!CheckUri(env, path)) {
1350         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1351         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1352         delete asyncCallbackInfo;
1353         return nullptr;
1354     }
1355     if (encode != ENCODING_UTF8) {
1356         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "read file failed", FILE_IO_ERROR);
1357         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1358         delete asyncCallbackInfo;
1359         return nullptr;
1360     }
1361     asyncCallbackInfo->url = path;
1362 
1363     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ReadTextExec, ReadTextComp,
1364                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1365     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1366     return NVal::CreateUndefined(env).val_;
1367 }
1368 
ReadArrayBuffer(napi_env env,napi_callback_info info)1369 napi_value FileNExporter::ReadArrayBuffer(napi_env env, napi_callback_info info)
1370 {
1371     NFuncArg funcArg(env, info);
1372     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1373         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1374         return nullptr;
1375     }
1376     auto *asyncCallbackInfo = new AsyncReadBufferCallbackInfo {
1377         .env = env,
1378         .asyncWork = nullptr,
1379     };
1380     bool succ = false;
1381     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1382         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1383 
1384     unique_ptr<char[]> uri;
1385     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String();
1386 
1387     int position = 0;
1388     tie(succ, position) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("position").ToInt32();
1389 
1390     int length = 0;
1391     tie(succ, length) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("length").ToInt32();
1392 
1393     string path = (uri == nullptr) ? "" : uri.get();
1394     if (!CheckUri(env, path)) {
1395         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1396         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1397         delete asyncCallbackInfo;
1398         return nullptr;
1399     }
1400     asyncCallbackInfo->url = path;
1401     asyncCallbackInfo->length = length;
1402     asyncCallbackInfo->position = position;
1403 
1404     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ReadArrayBufferExec,
1405                            ReadArrayBufferComp, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1406     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1407     return NVal::CreateUndefined(env).val_;
1408 }
1409 
Export()1410 bool FileNExporter::Export()
1411 {
1412     return exports_.AddProp({
1413         NVal::DeclareNapiFunction("mkdir", Mkdir),
1414         NVal::DeclareNapiFunction("rmdir", Rmdir),
1415         NVal::DeclareNapiFunction("get", Get),
1416         NVal::DeclareNapiFunction("list", List),
1417         NVal::DeclareNapiFunction("copy", Copy),
1418         NVal::DeclareNapiFunction("move", Move),
1419         NVal::DeclareNapiFunction("delete", Delete),
1420         NVal::DeclareNapiFunction("access", Access),
1421         NVal::DeclareNapiFunction("writeText", WriteText),
1422         NVal::DeclareNapiFunction("writeArrayBuffer", WriteArrayBuffer),
1423         NVal::DeclareNapiFunction("readText", ReadText),
1424         NVal::DeclareNapiFunction("readArrayBuffer", ReadArrayBuffer),
1425     });
1426 }
1427 
GetClassName()1428 string FileNExporter::GetClassName()
1429 {
1430     return FileNExporter::className_;
1431 }
1432 
FileNExporter(napi_env env,napi_value exports)1433 FileNExporter::FileNExporter(napi_env env, napi_value exports)
1434     : NExporter(env, exports)
1435 {}
1436 
~FileNExporter()1437 FileNExporter::~FileNExporter() {}
1438 } // namespace ModuleFile
1439 } // namespace DistributedFS
1440 } // namespace OHOS