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