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                 asyncCallbackInfo->contents = std::string(buffer.get());
909             }
910         }
911     } else if (statPath == ENOENT) {
912         asyncCallbackInfo->errorType = FILE_PATH_ERROR;
913     }
914 }
915 
ReadArrayBufferComp(napi_env env,napi_status status,void * data)916 void ReadArrayBufferComp(napi_env env, napi_status status, void *data)
917 {
918     auto *asyncCallbackInfo = (AsyncReadBufferCallbackInfo *)data;
919     if (asyncCallbackInfo->result == SUCCESS) {
920         napi_value typeArr = nullptr;
921         napi_create_array(env, &typeArr);
922         for (int32_t i = 0; i < asyncCallbackInfo->len; ++i) {
923             napi_set_property(env, typeArr, NVal::CreateInt32(env, i).val_,
924                               NVal::CreateInt32(env, (int32_t)(asyncCallbackInfo->contents)[i]).val_);
925         }
926         NVal objn = NVal::CreateObject(env);
927         objn.AddProp("buffer", typeArr);
928         CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_);
929     } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) {
930         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "read file failed", FILE_IO_ERROR);
931     } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) {
932         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR);
933     }
934     CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
935     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]);
936     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]);
937     napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
938     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
939     delete asyncCallbackInfo;
940 }
941 
Mkdir(napi_env env,napi_callback_info info)942 napi_value FileNExporter::Mkdir(napi_env env, napi_callback_info info)
943 {
944     NFuncArg funcArg(env, info);
945     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
946         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
947         return nullptr;
948     }
949     bool succ = false;
950     auto *asyncCallbackInfo = new AsyncMkdirCallbackInfo {
951         .env = env,
952         .asyncWork = nullptr,
953     };
954     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
955         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
956 
957     unique_ptr<char[]> uri;
958     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
959 
960     bool recursive = false;
961     tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool();
962 
963     string path = (uri == nullptr) ? "" : uri.get();
964     if (!CheckUri(env, path)) {
965         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
966         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
967         delete asyncCallbackInfo;
968         return nullptr;
969     }
970     asyncCallbackInfo->recursive = recursive;
971     asyncCallbackInfo->url = path;
972 
973     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, MkdirExec, MkdirComp,
974                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
975     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
976     return NVal::CreateUndefined(env).val_;
977 }
978 
Rmdir(napi_env env,napi_callback_info info)979 napi_value FileNExporter::Rmdir(napi_env env, napi_callback_info info)
980 {
981     NFuncArg funcArg(env, info);
982     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
983         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
984         return nullptr;
985     }
986     bool succ = false;
987     auto *asyncCallbackInfo = new AsyncRmdirCallbackInfo {
988         .env = env,
989         .asyncWork = nullptr,
990     };
991     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
992         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
993 
994     unique_ptr<char[]> uri;
995     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
996 
997     bool recursive = false;
998     tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool();
999 
1000     string path = (uri == nullptr) ? "" : uri.get();
1001     if (!CheckUri(env, path)) {
1002         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1003         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1004         delete asyncCallbackInfo;
1005         return nullptr;
1006     }
1007     asyncCallbackInfo->recursive = recursive;
1008     asyncCallbackInfo->url = path;
1009 
1010     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, RmdirExec, RmdirComp,
1011                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1012     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1013 
1014     return NVal::CreateUndefined(env).val_;
1015 }
1016 
Get(napi_env env,napi_callback_info info)1017 napi_value FileNExporter::Get(napi_env env, napi_callback_info info)
1018 {
1019     NFuncArg funcArg(env, info);
1020     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1021         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1022         return nullptr;
1023     }
1024     auto *asyncCallbackInfo = new AsyncGetCallbackInfo {
1025         .env = env,
1026         .asyncWork = nullptr,
1027     };
1028     bool succ = false;
1029     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1030         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1031     unique_ptr<char[]> uri = nullptr;
1032     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
1033 
1034     bool recursive = false;
1035     tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool();
1036     string path = (uri == nullptr) ? "" : uri.get();
1037     asyncCallbackInfo->originUri = path;
1038     if (!CheckUri(env, path)) {
1039         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1040         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1041         delete asyncCallbackInfo;
1042         return nullptr;
1043     }
1044     asyncCallbackInfo->recursive = recursive;
1045     asyncCallbackInfo->url = path;
1046 
1047     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, GetExec, GetComp,
1048                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1049     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1050 
1051     return NVal::CreateUndefined(env).val_;
1052 }
1053 
List(napi_env env,napi_callback_info info)1054 napi_value FileNExporter::List(napi_env env, napi_callback_info info)
1055 {
1056     NFuncArg funcArg(env, info);
1057     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1058         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1059         return nullptr;
1060     }
1061     auto *asyncCallbackInfo = new AsyncListCallbackInfo {
1062         .env = env,
1063         .asyncWork = nullptr,
1064     };
1065     bool succ = false;
1066     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1067         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1068 
1069     unique_ptr<char[]> uri = nullptr;
1070     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
1071 
1072     string path = (uri == nullptr) ? "" : uri.get();
1073     asyncCallbackInfo->originUri = path;
1074     if (!CheckUri(env, path)) {
1075         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1076         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1077         delete asyncCallbackInfo;
1078         return nullptr;
1079     }
1080     asyncCallbackInfo->url = path;
1081 
1082     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ListExec, ListComp,
1083                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1084     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1085 
1086     return NVal::CreateUndefined(env).val_;
1087 }
1088 
Copy(napi_env env,napi_callback_info info)1089 napi_value FileNExporter::Copy(napi_env env, napi_callback_info info)
1090 {
1091     NFuncArg funcArg(env, info);
1092     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1093         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1094         return nullptr;
1095     }
1096     bool succ = false;
1097     auto *asyncCallbackInfo = new AsyncCopyCallbackInfo {
1098         .env = env,
1099         .asyncWork = nullptr,
1100     };
1101     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1102         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1103 
1104     unique_ptr<char[]> srcUri, dstUri;
1105     tie(succ, srcUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("srcUri").ToUTF8StringPath();
1106     tie(succ, dstUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("dstUri").ToUTF8StringPath();
1107     string srcPath = ((srcUri == nullptr) ? "" : (srcUri.get()));
1108     string dstPath = ((dstUri == nullptr) ? "" : (dstUri.get()));
1109     asyncCallbackInfo->originDst = dstPath;
1110     if (!CheckUri(env, srcPath) || !CheckUri(env, dstPath)) {
1111         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1112         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1113         delete asyncCallbackInfo;
1114         return nullptr;
1115     }
1116     asyncCallbackInfo->url = srcPath;
1117     asyncCallbackInfo->urlDst = dstPath;
1118 
1119     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, CopyExec, CopyComp,
1120                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1121     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1122     return NVal::CreateUndefined(env).val_;
1123 }
1124 
Move(napi_env env,napi_callback_info info)1125 napi_value FileNExporter::Move(napi_env env, napi_callback_info info)
1126 {
1127     NFuncArg funcArg(env, info);
1128     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1129         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1130         return nullptr;
1131     }
1132     bool succ = false;
1133     auto *asyncCallbackInfo = new AsyncMoveCallbackInfo {
1134         .env = env,
1135         .asyncWork = nullptr,
1136     };
1137     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1138         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1139 
1140     unique_ptr<char[]> srcUri, dstUri;
1141     tie(succ, srcUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("srcUri").ToUTF8StringPath();
1142     tie(succ, dstUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("dstUri").ToUTF8StringPath();
1143 
1144     string srcPath = ((srcUri == nullptr) ? "" : (srcUri.get()));
1145     string dstPath = ((dstUri == nullptr) ? "" : (dstUri.get()));
1146     asyncCallbackInfo->originDst = dstPath;
1147     if (!CheckUri(env, srcPath) || !CheckUri(env, dstPath)) {
1148         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1149         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1150         delete asyncCallbackInfo;
1151         return nullptr;
1152     }
1153     asyncCallbackInfo->url = srcPath;
1154     asyncCallbackInfo->urlDst = dstPath;
1155 
1156     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, MoveExec, MoveComp,
1157                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1158     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1159     return NVal::CreateUndefined(env).val_;
1160 }
1161 
Delete(napi_env env,napi_callback_info info)1162 napi_value FileNExporter::Delete(napi_env env, napi_callback_info info)
1163 {
1164     NFuncArg funcArg(env, info);
1165     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1166         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1167         return nullptr;
1168     }
1169     bool succ = false;
1170     auto *asyncCallbackInfo = new AsyncDeleteCallbackInfo {
1171         .env = env,
1172         .asyncWork = nullptr,
1173     };
1174     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1175         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1176 
1177     unique_ptr<char[]> uri;
1178     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
1179 
1180     string path = (uri == nullptr) ? "" : uri.get();
1181     if (!CheckUri(env, path)) {
1182         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1183         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1184         delete asyncCallbackInfo;
1185         return nullptr;
1186     }
1187     asyncCallbackInfo->url = path;
1188 
1189     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, DeleteExec, DeleteComp,
1190                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1191     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1192 
1193     return NVal::CreateUndefined(env).val_;
1194 }
1195 
Access(napi_env env,napi_callback_info info)1196 napi_value FileNExporter::Access(napi_env env, napi_callback_info info)
1197 {
1198     NFuncArg funcArg(env, info);
1199     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1200         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1201         return nullptr;
1202     }
1203     bool succ = false;
1204     AsyncAccessCallbackInfo *asyncCallbackInfo = new AsyncAccessCallbackInfo {
1205         .env = env,
1206         .asyncWork = nullptr,
1207     };
1208     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1209         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1210 
1211     unique_ptr<char[]> uri;
1212     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
1213 
1214     string path = (uri == nullptr) ? "" : uri.get();
1215     if (!CheckUri(env, path)) {
1216         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1217         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1218         delete asyncCallbackInfo;
1219         return nullptr;
1220     }
1221     asyncCallbackInfo->url = path;
1222 
1223     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, AccessExec, AccessComp,
1224                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1225     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1226     return NVal::CreateUndefined(env).val_;
1227 }
1228 
WriteText(napi_env env,napi_callback_info info)1229 napi_value FileNExporter::WriteText(napi_env env, napi_callback_info info)
1230 {
1231     NFuncArg funcArg(env, info);
1232     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1233         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1234         return nullptr;
1235     }
1236     auto *asyncCallbackInfo = new AsyncWriteCallbackInfo {
1237         .env = env,
1238         .asyncWork = nullptr,
1239     };
1240     bool succ = false;
1241     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1242         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1243 
1244     unique_ptr<char[]> uri, text, encoding;
1245     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
1246     tie(succ, text, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("text").ToUTF8String();
1247     tie(succ, encoding, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("encoding").ToUTF8String();
1248 
1249     bool append = false;
1250     tie(succ, append) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("append").ToBool();
1251 
1252     string path = (uri == nullptr) ? "" : uri.get();
1253     string encode = (encoding == nullptr) ? ENCODING_UTF8 : encoding.get();
1254     transform(encode.begin(), encode.end(), encode.begin(), ::tolower);
1255     if (!CheckUri(env, path)) {
1256         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1257         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1258         delete asyncCallbackInfo;
1259         return nullptr;
1260     }
1261     if (encode != ENCODING_UTF8) {
1262         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "write file failed", FILE_IO_ERROR);
1263         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1264         delete asyncCallbackInfo;
1265         return nullptr;
1266     }
1267     string content = text.get();
1268     asyncCallbackInfo->url = path;
1269     asyncCallbackInfo->text = content;
1270     asyncCallbackInfo->append = append;
1271 
1272     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, WriteTextExec, WriteTextComp,
1273                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1274     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1275     return NVal::CreateUndefined(env).val_;
1276 }
1277 
WriteArrayBuffer(napi_env env,napi_callback_info info)1278 napi_value FileNExporter::WriteArrayBuffer(napi_env env, napi_callback_info info)
1279 {
1280     NFuncArg funcArg(env, info);
1281     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1282         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1283         return nullptr;
1284     }
1285     bool succ = false;
1286     auto *asyncCallbackInfo = new AsyncWriteBufferCallbackInfo {
1287         .env = env,
1288         .asyncWork = nullptr,
1289     };
1290     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1291         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1292 
1293     unique_ptr<char[]> uri;
1294     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
1295 
1296     int32_t position = 0;
1297     tie(succ, position) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("position").ToInt32();
1298 
1299     bool append = false;
1300     tie(succ, append) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("append").ToBool();
1301 
1302     void *buffer = nullptr;
1303     size_t bufLength = 0;
1304     napi_ref bufferRef = nullptr;
1305     NVal bufNapi = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("buffer");
1306     tie(succ, buffer, bufLength) = bufNapi.ToTypedArray();
1307     napi_status status = napi_create_reference(env, bufNapi.val_, 1, &bufferRef);
1308     if (status != napi_ok) {
1309         UniError(EINVAL).ThrowErr(env, "Failed to create reference to buffer");
1310         delete asyncCallbackInfo;
1311         return nullptr;
1312     }
1313 
1314     string path = (uri == nullptr) ? "" : uri.get();
1315     if (!CheckUri(env, path)) {
1316         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1317         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1318         napi_delete_reference(env, bufferRef);
1319         delete asyncCallbackInfo;
1320         return nullptr;
1321     }
1322     int32_t bufLen { bufLength };
1323     asyncCallbackInfo->url = path;
1324     asyncCallbackInfo->position = position;
1325     asyncCallbackInfo->append = append;
1326     asyncCallbackInfo->buf = buffer;
1327     asyncCallbackInfo->length = bufLen;
1328     asyncCallbackInfo->bufferAddress = bufferRef;
1329 
1330     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, WriteArrayBufferExec,
1331                            WriteArrayBufferComp, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1332     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1333     return NVal::CreateUndefined(env).val_;
1334 }
1335 
ReadText(napi_env env,napi_callback_info info)1336 napi_value FileNExporter::ReadText(napi_env env, napi_callback_info info)
1337 {
1338     NFuncArg funcArg(env, info);
1339     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1340         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1341         return nullptr;
1342     }
1343     bool succ = false;
1344     auto *asyncCallbackInfo = new AsyncReadCallbackInfo {
1345         .env = env,
1346         .asyncWork = nullptr,
1347     };
1348     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1349         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1350 
1351     unique_ptr<char[]> uri, encoding;
1352     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
1353     tie(succ, encoding, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("encoding").ToUTF8String();
1354 
1355     string path = (uri == nullptr) ? "" : uri.get();
1356     string encode = (encoding == nullptr) ? ENCODING_UTF8 : encoding.get();
1357     transform(encode.begin(), encode.end(), encode.begin(), ::tolower);
1358     if (!CheckUri(env, path)) {
1359         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1360         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1361         delete asyncCallbackInfo;
1362         return nullptr;
1363     }
1364     if (encode != ENCODING_UTF8) {
1365         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "read file failed", FILE_IO_ERROR);
1366         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1367         delete asyncCallbackInfo;
1368         return nullptr;
1369     }
1370     asyncCallbackInfo->url = path;
1371 
1372     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ReadTextExec, ReadTextComp,
1373                            (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1374     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1375     return NVal::CreateUndefined(env).val_;
1376 }
1377 
ReadArrayBuffer(napi_env env,napi_callback_info info)1378 napi_value FileNExporter::ReadArrayBuffer(napi_env env, napi_callback_info info)
1379 {
1380     NFuncArg funcArg(env, info);
1381     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
1382         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
1383         return nullptr;
1384     }
1385     auto *asyncCallbackInfo = new AsyncReadBufferCallbackInfo {
1386         .env = env,
1387         .asyncWork = nullptr,
1388     };
1389     bool succ = false;
1390     tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE],
1391         asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]);
1392 
1393     unique_ptr<char[]> uri;
1394     tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8StringPath();
1395 
1396     int position = 0;
1397     tie(succ, position) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("position").ToInt32();
1398 
1399     int length = 0;
1400     tie(succ, length) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("length").ToInt32();
1401 
1402     string path = (uri == nullptr) ? "" : uri.get();
1403     if (!CheckUri(env, path)) {
1404         CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR);
1405         CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]);
1406         delete asyncCallbackInfo;
1407         return nullptr;
1408     }
1409     asyncCallbackInfo->url = path;
1410     asyncCallbackInfo->length = length;
1411     asyncCallbackInfo->position = position;
1412 
1413     napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ReadArrayBufferExec,
1414                            ReadArrayBufferComp, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
1415     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
1416     return NVal::CreateUndefined(env).val_;
1417 }
1418 
Export()1419 bool FileNExporter::Export()
1420 {
1421     return exports_.AddProp({
1422         NVal::DeclareNapiFunction("mkdir", Mkdir),
1423         NVal::DeclareNapiFunction("rmdir", Rmdir),
1424         NVal::DeclareNapiFunction("get", Get),
1425         NVal::DeclareNapiFunction("list", List),
1426         NVal::DeclareNapiFunction("copy", Copy),
1427         NVal::DeclareNapiFunction("move", Move),
1428         NVal::DeclareNapiFunction("delete", Delete),
1429         NVal::DeclareNapiFunction("access", Access),
1430         NVal::DeclareNapiFunction("writeText", WriteText),
1431         NVal::DeclareNapiFunction("writeArrayBuffer", WriteArrayBuffer),
1432         NVal::DeclareNapiFunction("readText", ReadText),
1433         NVal::DeclareNapiFunction("readArrayBuffer", ReadArrayBuffer),
1434     });
1435 }
1436 
GetClassName()1437 string FileNExporter::GetClassName()
1438 {
1439     return FileNExporter::className_;
1440 }
1441 
FileNExporter(napi_env env,napi_value exports)1442 FileNExporter::FileNExporter(napi_env env, napi_value exports)
1443     : NExporter(env, exports)
1444 {}
1445 
~FileNExporter()1446 FileNExporter::~FileNExporter() {}
1447 } // namespace ModuleFile
1448 } // namespace DistributedFS
1449 } // namespace OHOS