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