diff --git a/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9633bbbbe2cce80cf33f7414b5e63881e83db69d --- /dev/null +++ b/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.cpp @@ -0,0 +1,1578 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "file_n_exporter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../common/ability_helper.h" +#include "../../common/file_helper/fd_guard.h" +#include "../../common/log.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/napi/n_val.h" +#include "../../common/uni_error.h" +#include "../common_func.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFile { +using namespace std; +namespace { + constexpr int SUCCESS = 0; + constexpr int FAILED = -1; + constexpr int PARAMS_NUMBER_TWO = 2; + constexpr int URI_PARAMER_ERROR = 202; + constexpr int FILE_IO_ERROR = 300; + constexpr int FILE_PATH_ERROR = 301; + constexpr int DIR_FAULT_PERM = 0775; + constexpr int SPLIT_ZERO = 0; + static const string TYPE_FILE = "file"; + static const string TYPE_DIR = "dir"; + static const string ENCODING_UTF8 = "utf-8"; +} + +void CallBackSuccess(napi_env env, napi_ref successFuncRef, int32_t count, napi_value obj) +{ + napi_value results = nullptr; + napi_value successFunc = nullptr; + napi_value global = nullptr; + napi_get_global(env, &global); + napi_get_reference_value(env, successFuncRef, &successFunc); + if (successFunc == nullptr) { + return; + } + napi_call_function(env, global, successFunc, count, &obj, &results); +} + +void CallBackError(napi_env env, napi_ref failFuncRef, string errorProp, int errorCode) +{ + napi_value argvFail[PARAMS_NUMBER_TWO] = { 0 }; + napi_value results = nullptr; + napi_value failFunc = nullptr; + napi_value global = nullptr; + napi_get_global(env, &global); + argvFail[0] = NVal::CreateUTF8String(env, errorProp).val_; + argvFail[1] = NVal::CreateInt32(env, errorCode).val_; + napi_get_reference_value(env, failFuncRef, &failFunc); + if (failFunc == nullptr) { + return; + } + napi_call_function(env, global, failFunc, COMMON_NUM::TWO, argvFail, &results); +} + +void CallComplete(napi_env env, napi_ref completeFuncRef) +{ + napi_value completeFunc = nullptr; + napi_value results = nullptr; + napi_value global = nullptr; + napi_get_global(env, &global); + napi_get_reference_value(env, completeFuncRef, &completeFunc); + if (completeFunc == nullptr) { + return; + } + napi_call_function(env, global, completeFunc, COMMON_NUM::ZERO, nullptr, &results); +} + +vector SplitString(const string &path) +{ + vector uriSplit; + if (path == "") { + HILOGE("Parameter path is empty"); + return uriSplit; + } + + string pattern = "/"; + string pathTmp = path + pattern; + size_t pos = pathTmp.find(pattern); + while (pos != pathTmp.npos) { + string temp = pathTmp.substr(SPLIT_ZERO, pos); + uriSplit.push_back(temp); + pathTmp = pathTmp.substr(pos + 1, pathTmp.size()); + pos = pathTmp.find(pattern); + } + + return uriSplit; +} + +bool CheckUri(napi_env env, string &path) +{ + constexpr int splitOne = 1; + constexpr int splitTwo = 2; + constexpr int splitThree = 3; + vector uriSplit = SplitString(path); + if (uriSplit[SPLIT_ZERO] != "internal:" || uriSplit[splitOne] != "" || uriSplit.size() <= splitThree) { + HILOGE("Illegal URI address"); + return false; + } + + AppExecFwk::Ability *ability = AbilityHelper::GetJsAbility(env); + if (!ability) { + HILOGE("JS ability object address is empty"); + return false; + } + + auto abilityContext = ability->GetAbilityContext(); + if (abilityContext && uriSplit[splitTwo] == "app") { + path = abilityContext->GetFilesDir(); + } else if (abilityContext && uriSplit[splitTwo] == "cache") { + path = abilityContext->GetCacheDir(); + } else { + HILOGE("Failed to get URI path"); + return false; + } + for (size_t i = splitThree; i < uriSplit.size(); ++i) { + path = path + "/" + uriSplit[i]; + } + return true; +} + +int GetRealPath(string &path) +{ + unique_ptr absPath = make_unique(PATH_MAX + 1); + if (realpath(path.c_str(), absPath.get()) == nullptr) { + return errno; + } + path = absPath.get(); + return 0; +} + +string UriToAbsolute(string path) +{ + stack uriResult; + vector uriSplit = SplitString(path); + for (auto urisp : uriSplit) { + if (urisp == "." || urisp == "") { + continue; + } else if (urisp == ".." && !uriResult.empty()) { + uriResult.pop(); + } else { + uriResult.push(urisp); + } + } + path = ""; + while (!uriResult.empty()) { + path = "/" + uriResult.top() + path; + uriResult.pop(); + } + return path; +} + +bool GetFileNames(const string &path, vector &filenames, bool rec, bool isList) +{ + DIR *pDir; + struct dirent *ptr = nullptr; + if (!(pDir = opendir(path.c_str()))) { + HILOGE("open a directory %{public}s failed", path.c_str()); + return false; + } + while ((ptr = readdir(pDir)) != nullptr) { + if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { + if (isList) { + filenames.push_back(path + "/" + ptr->d_name); + } else if (ptr->d_type == DT_DIR && rec && + GetFileNames(path + "/" + ptr->d_name, filenames, rec, isList) == false) { + break; + } else if (ptr->d_type == DT_REG) { + filenames.push_back(path + "/" + ptr->d_name); + } + } + } + closedir(pDir); + return true; +} + +bool Mkdirs(string path) +{ + for (size_t i = 1; i < path.length(); ++i) { + if (path[i] == '/') { + path[i] = '\0'; + if (access(path.c_str(), 0) != 0 && mkdir(path.c_str(), DIR_FAULT_PERM) == FAILED) { + HILOGE("create a directory %{public}s failed", path.c_str()); + return false; + } + path[i] = '/'; + } + } + if (path.length() <= 0 || access(path.c_str(), 0) == 0 || mkdir(path.c_str(), DIR_FAULT_PERM) == FAILED) { + HILOGE("path is empty, or access failed, or create a directory failed"); + return false; + } + return true; +} + +bool Rmdirs(string path) +{ + DIR *pDir; + struct dirent *ptr = nullptr; + if (!(pDir = opendir(path.c_str()))) { + HILOGE("open a directory %{public}s failed", path.c_str()); + return false; + } + while ((ptr = readdir(pDir)) != nullptr) { + if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { + if ((ptr->d_type == DT_DIR && Rmdirs(path + "/" + ptr->d_name)) || + remove((path + "/" + ptr->d_name).c_str()) == 0) { + } else { + closedir(pDir); + return false; + } + } + } + closedir(pDir); + if (rmdir(path.c_str()) != 0) { + HILOGE("delete a directory %{public}s failed", path.c_str()); + return false; + } + return true; +} + +string ConvertUri(string path, string originPath, string originUri) +{ + if (originPath.length() > path.length()) { + return "error"; + } + + if (path.find(originPath) != path.npos) { + if (originUri[originUri.length() - 1] == '/') { + originUri = originUri.substr(0, originUri.length() - 1); + } + path.replace(0, originPath.length(), originUri); + } else { + return "error"; + } + + return path; +} + +void MkdirExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncMkdirCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + if (GetRealPath(path) == ENOENT) { + path = UriToAbsolute(path); + if (asyncCallbackInfo->recursive && Mkdirs(path)) { + asyncCallbackInfo->result = SUCCESS; + } else if (mkdir((char *)path.c_str(), DIR_FAULT_PERM) != FAILED) { + asyncCallbackInfo->result = SUCCESS; + } + } +} + +void MkdirComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncMkdirCallbackInfo *)data; + + if (asyncCallbackInfo->result == SUCCESS) { + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr); + } else if (asyncCallbackInfo->result == FAILED) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "make directory failed", FILE_IO_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void RmdirExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncRmdirCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + int statPath = GetRealPath(path); + if (statPath == COMMON_NUM::ZERO) { + if (asyncCallbackInfo->recursive && Rmdirs(path)) { + asyncCallbackInfo->result = SUCCESS; + } else if (remove((char *)path.c_str()) != FAILED) { + asyncCallbackInfo->result = SUCCESS; + } + } else if (statPath == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + } +} + +void RmdirComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncRmdirCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "remove directory failed", FILE_IO_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void GetExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncGetCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + struct stat buf; + int statPath = GetRealPath(path); + if (statPath == COMMON_NUM::ZERO && stat((char *)path.c_str(), &buf) == COMMON_NUM::ZERO) { + asyncCallbackInfo->length = buf.st_size; + asyncCallbackInfo->lastMT = buf.st_mtime * COMMON_NUM::THOUSAND + + (int64_t)((buf.st_mtim).tv_nsec / COMMON_NUM::MILLION); + asyncCallbackInfo->url = path; + std::vector subFiles; + bool rec = asyncCallbackInfo->recursive; + if ((buf.st_mode & S_IFMT) == S_IFDIR && GetFileNames(path, subFiles, rec, false)) { + (asyncCallbackInfo->subFiles).assign(subFiles.begin(), subFiles.end()); + asyncCallbackInfo->type = TYPE_DIR; + asyncCallbackInfo->result = SUCCESS; + } else if ((buf.st_mode & S_IFMT) == S_IFREG) { + asyncCallbackInfo->type = TYPE_FILE; + asyncCallbackInfo->result = SUCCESS; + } + } else if (statPath == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + } +} + +void GetComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncGetCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + napi_value subFilesNapi = nullptr; + napi_create_array(env, &subFilesNapi); + int32_t i = 0; + for (auto filename : asyncCallbackInfo->subFiles) { + napi_set_property( + env, subFilesNapi, NVal::CreateInt32(env, i).val_, + NVal::CreateUTF8String( + env, ConvertUri(filename, asyncCallbackInfo->url, asyncCallbackInfo->originUri).c_str()) + .val_); + i = i + 1; + } + NVal objn = NVal::CreateObject(env); + objn.AddProp("lastModifiedTime", NVal::CreateInt64(env, asyncCallbackInfo->lastMT).val_); + objn.AddProp("length", NVal::CreateInt32(env, asyncCallbackInfo->length).val_); + objn.AddProp("uri", NVal::CreateUTF8String(env, asyncCallbackInfo->originUri).val_); + objn.AddProp("type", NVal::CreateUTF8String(env, asyncCallbackInfo->type).val_); + objn.AddProp("subFiles", subFilesNapi); + + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "get file failed", FILE_IO_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void ListExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncListCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + std::vector fileNames; + struct stat buf; + int statPath = GetRealPath(path); + if (statPath == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + } else if (statPath != COMMON_NUM::ZERO || stat((char *)path.c_str(), &buf) != COMMON_NUM::ZERO) { + asyncCallbackInfo->errorType = FILE_IO_ERROR; + } else if ((buf.st_mode & S_IFMT) == S_IFREG) { + asyncCallbackInfo->result = SUCCESS; + } else { + asyncCallbackInfo->url = path; + bool getStat = GetFileNames(path, fileNames, false, true); + if (!getStat) { + asyncCallbackInfo->errorType = FILE_IO_ERROR; + } else { + vector fileList; + for (auto ph : fileNames) { + struct stat tmp; + int r = stat(ph.c_str(), &tmp); + FileInfo fi; + if (r == 0 && S_ISDIR(tmp.st_mode)) { + fi.type = TYPE_DIR; + } else if (r == 0 && (tmp.st_mode & S_IFMT) == S_IFREG) { + fi.type = TYPE_FILE; + } + fi.length = tmp.st_size; + fi.lastModifiedTime = tmp.st_mtime * COMMON_NUM::THOUSAND + + (int64_t)((tmp.st_mtim).tv_nsec / COMMON_NUM::MILLION); + fi.uri = ph; + fileList.push_back(fi); + } + (asyncCallbackInfo->fileList).assign(fileList.begin(), fileList.end()); + asyncCallbackInfo->result = SUCCESS; + } + } +} + +void ListComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncListCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + napi_value fileListNapi; + napi_create_array(env, &fileListNapi); + int32_t i = 0; + for (auto fileInfo : asyncCallbackInfo->fileList) { + NVal objt = NVal::CreateObject(env); + objt.AddProp("lastModifiedTime", NVal::CreateInt64(env, fileInfo.lastModifiedTime).val_); + objt.AddProp("length", NVal::CreateInt32(env, fileInfo.length).val_); + string uriTojs = ConvertUri(fileInfo.uri, asyncCallbackInfo->url, asyncCallbackInfo->originUri); + objt.AddProp("uri", NVal::CreateUTF8String(env, uriTojs).val_); + objt.AddProp("type", NVal::CreateUTF8String(env, fileInfo.type).val_); + + napi_set_property(env, fileListNapi, NVal::CreateInt32(env, i).val_, objt.val_); + i = i + 1; + } + NVal objn = NVal::CreateObject(env); + objn.AddProp("fileList", fileListNapi); + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "list file failed", FILE_IO_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +int FileCopy(const string& srcPath, const string& dstPath) +{ + bool ret = FILE_IO_ERROR; + string src = srcPath; + string dest = dstPath; + if (GetRealPath(src) == 0) { + if (GetRealPath(dest) == ENOENT) { + FDGuard sfd; + sfd.SetFD(open((char *)src.c_str(), O_RDONLY)); + struct stat attrSrc; + if (stat((char *)src.c_str(), &attrSrc) == FAILED) { + return FILE_IO_ERROR; + } + dest = UriToAbsolute(dest); + FDGuard ofd; + ofd.SetFD(open((char *)dest.c_str(), O_WRONLY | O_CREAT, attrSrc.st_mode)); + if (sfd.GetFD() == FAILED || ofd.GetFD() == FAILED) { + return FILE_IO_ERROR; + } + + if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, attrSrc.st_size) != FAILED) { + ret = SUCCESS; + } else { + remove((char *)dest.c_str()); + } + } else if (GetRealPath(dest) == 0) { + return (dest == src) ? SUCCESS : FILE_IO_ERROR; + } + } + return ret; +} + +int DirCopy(const string& srcPath, const string& dstPath) +{ + string src = srcPath; + string dest = dstPath; + if (GetRealPath(src) == ENOENT) { + return FILE_PATH_ERROR; + } + if (GetRealPath(dest) == ENOENT) { + struct stat attrSrc; + if (stat((char *)src.c_str(), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { + return FILE_IO_ERROR; + } + dest = UriToAbsolute(dest); + if (mkdir(dest.c_str(), attrSrc.st_mode) == FAILED) { + return FILE_IO_ERROR; + } + } else { + return (dest == src) ? SUCCESS : FILE_IO_ERROR; + } + return SUCCESS; +} + +void CopyExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncCopyCallbackInfo *)data; + string path = asyncCallbackInfo->url; + string pathDst = asyncCallbackInfo->urlDst; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + if (GetRealPath(path) == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + return; + } + + struct stat statbf; + if (stat((char *)path.c_str(), &statbf) == FAILED) { + asyncCallbackInfo->errorType = FILE_IO_ERROR; + return; + } + + int retval; + if (S_ISREG(statbf.st_mode)) { + retval = FileCopy(path, pathDst); + if (retval == SUCCESS) { + asyncCallbackInfo->result = SUCCESS; + } else { + asyncCallbackInfo->errorType = retval; + } + } else if (S_ISDIR(statbf.st_mode)) { + retval = DirCopy(path, pathDst); + if (retval == SUCCESS) { + asyncCallbackInfo->result = SUCCESS; + } else { + asyncCallbackInfo->errorType = retval; + } + } +} + +void CopyComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncCopyCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, + NVal::CreateUTF8String(env, asyncCallbackInfo->originDst).val_); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "copy file failed", FILE_IO_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +int DirMove(const string& srcPath, const string& dstPath) +{ + string src = srcPath; + string dest = dstPath; + if (GetRealPath(src) == ENOENT) { + return FILE_PATH_ERROR; + } + + auto res = GetRealPath(dest); + if (res == 0 && dest == src) { + return SUCCESS; + } else if (res != ENOENT) { + return FILE_PATH_ERROR; + } + + struct stat attrSrc; + if (stat((char *)src.c_str(), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { + return FILE_IO_ERROR; + } + dest = UriToAbsolute(dest); + if (FAILED == mkdir(dest.c_str(), attrSrc.st_mode)) { + return FILE_IO_ERROR; + } + DIR *dirp = opendir(src.c_str()); + if (dirp == nullptr) { + return FILE_IO_ERROR; + } + struct dirent *entp; + while ((entp = readdir(dirp)) != nullptr) { + if (string(entp->d_name) == "." || string(entp->d_name) == "..") { + continue; + } + string srcBuf = src + "/" + string(entp->d_name); + string dstBuf = dest + "/" + string(entp->d_name); + if (entp->d_type == DT_DIR && DirMove(srcBuf.c_str(), dstBuf.c_str()) != SUCCESS) { + closedir(dirp); + return FILE_IO_ERROR; + } + + if (entp->d_type == DT_REG) { + if (FileCopy(srcBuf.c_str(), dstBuf.c_str()) != SUCCESS) { + closedir(dirp); + return FILE_IO_ERROR; + } else { + remove(srcBuf.c_str()); + } + } + } + closedir(dirp); + rmdir(src.c_str()); + + return SUCCESS; +} + +void MoveExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncMoveCallbackInfo *)data; + string path = asyncCallbackInfo->url; + string pathDst = asyncCallbackInfo->urlDst; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + if (GetRealPath(path) == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + return; + } + + struct stat statbf; + if (stat((char *)path.c_str(), &statbf) == FAILED) { + asyncCallbackInfo->errorType = FILE_IO_ERROR; + return; + } + + if (S_ISREG(statbf.st_mode)) { + int retval = FileCopy(path, pathDst); + if (retval == SUCCESS) { + asyncCallbackInfo->result = SUCCESS; + remove((char *)path.c_str()); + } else { + asyncCallbackInfo->errorType = retval; + } + } else if (S_ISDIR(statbf.st_mode)) { + int retval = DirMove(path, pathDst); + if (retval == SUCCESS) { + asyncCallbackInfo->result = SUCCESS; + } else { + asyncCallbackInfo->errorType = retval; + } + } +} + +void MoveComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncMoveCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, + NVal::CreateUTF8String(env, asyncCallbackInfo->originDst).val_); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "move file failed", FILE_IO_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void DeleteExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncDeleteCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + int statPath = GetRealPath(path); + if (statPath == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + } else if (statPath == COMMON_NUM::ZERO && remove((char *)path.c_str()) != FAILED) { + asyncCallbackInfo->result = SUCCESS; + } else { + asyncCallbackInfo->errorType = FILE_IO_ERROR; + } +} + +void DeleteComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncDeleteCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "delete file failed", FILE_IO_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void AccessExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncAccessCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + int statPath = GetRealPath(path); + if (statPath == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + } else if (statPath == COMMON_NUM::ZERO) { + asyncCallbackInfo->result = SUCCESS; + } else { + asyncCallbackInfo->errorType = FILE_IO_ERROR; + } +} + +void AccessComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncAccessCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "access file failed", FILE_IO_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void WriteTextExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncWriteCallbackInfo *)data; + string path = asyncCallbackInfo->url; + string text = asyncCallbackInfo->text; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + int fd = -1; + int statPath = GetRealPath(path); + if (statPath == COMMON_NUM::ZERO || statPath == ENOENT) { + if (asyncCallbackInfo->append) { + fd = open(path.c_str(), O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); + } else { + fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); + } + if (fd != FAILED) { + if (write(fd, text.c_str(), text.length()) != FAILED) { + asyncCallbackInfo->result = SUCCESS; + } + close(fd); + } + } +} + +void WriteTextComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncWriteCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "write file failed", FILE_IO_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void WriteArrayBufferExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncWriteBufferCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + int fd = -1; + int statPath = GetRealPath(path); + if (statPath == COMMON_NUM::ZERO || statPath == ENOENT) { + if (asyncCallbackInfo->append) { + fd = open(path.c_str(), O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); + if (fd == FAILED) { + return; + } + } else { + fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); + if (fd == FAILED) { + return; + } + lseek(fd, asyncCallbackInfo->position, SEEK_CUR); + } + if (write(fd, asyncCallbackInfo->buf, asyncCallbackInfo->length) != FAILED) { + asyncCallbackInfo->result = SUCCESS; + } + close(fd); + } +} + +void WriteArrayBufferComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncWriteBufferCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ZERO, nullptr); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "write file failed", FILE_IO_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->bufferAddress); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void ReadTextExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncReadCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + int statPath = GetRealPath(path); + if (statPath == COMMON_NUM::ZERO) { + FDGuard fdg; + fdg.SetFD(open(path.c_str(), O_RDONLY)); + struct stat buf; + int result = stat((char *)path.c_str(), &buf); + if (fdg.GetFD() != FAILED && result != FAILED) { + auto buffer = std::make_unique(buf.st_size + 1); + if (buffer == nullptr) { + UniError(ENOMEM).ThrowErr(env); + return; + } + if (read(fdg.GetFD(), buffer.get(), buf.st_size) != FAILED) { + asyncCallbackInfo->result = SUCCESS; + asyncCallbackInfo->contents = std::string(buffer.get()); + } + } + } else if (statPath == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + } +} + +void ReadTextComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncReadCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + NVal objn = NVal::CreateObject(env); + objn.AddProp("text", NVal::CreateUTF8String(env, asyncCallbackInfo->contents).val_); + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "read file failed", FILE_IO_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +void ReadArrayBufferExec(napi_env env, void *data) +{ + auto *asyncCallbackInfo = (AsyncReadBufferCallbackInfo *)data; + string path = asyncCallbackInfo->url; + asyncCallbackInfo->result = FAILED; + asyncCallbackInfo->errorType = FILE_IO_ERROR; + int statPath = GetRealPath(path); + if (statPath == COMMON_NUM::ZERO) { + FDGuard fdg; + fdg.SetFD(open(path.c_str(), O_RDONLY)); + struct stat buf; + int result = stat((char *)path.c_str(), &buf); + if (fdg.GetFD() != FAILED && result != FAILED) { + int32_t begin = (buf.st_size < asyncCallbackInfo->position) ? buf.st_size : asyncCallbackInfo->position; + int32_t len = + (asyncCallbackInfo->length == COMMON_NUM::ZERO) ? (buf.st_size - begin) : asyncCallbackInfo->length; + auto buffer = std::make_unique(len + 1); + if (buffer == nullptr) { + UniError(ENOMEM).ThrowErr(env); + return; + } + lseek(fdg.GetFD(), begin, SEEK_CUR); + if (read(fdg.GetFD(), buffer.get(), len) != FAILED) { + asyncCallbackInfo->result = SUCCESS; + asyncCallbackInfo->len = len; + asyncCallbackInfo->contents = std::string(buffer.get()); + } + } + } else if (statPath == ENOENT) { + asyncCallbackInfo->errorType = FILE_PATH_ERROR; + } +} + +void ReadArrayBufferComp(napi_env env, napi_status status, void *data) +{ + auto *asyncCallbackInfo = (AsyncReadBufferCallbackInfo *)data; + if (asyncCallbackInfo->result == SUCCESS) { + napi_value typeArr = nullptr; + napi_create_array(env, &typeArr); + for (int32_t i = 0; i < asyncCallbackInfo->len; ++i) { + napi_set_property(env, typeArr, NVal::CreateInt32(env, i).val_, + NVal::CreateInt32(env, (int32_t)(asyncCallbackInfo->contents)[i]).val_); + } + NVal objn = NVal::CreateObject(env); + objn.AddProp("buffer", typeArr); + CallBackSuccess(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO], COMMON_NUM::ONE, objn.val_); + } else if (asyncCallbackInfo->errorType == FILE_IO_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "read file failed", FILE_IO_ERROR); + } else if (asyncCallbackInfo->errorType == FILE_PATH_ERROR) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "file not exist", FILE_PATH_ERROR); + } + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ZERO]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::ONE]); + napi_delete_reference(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; +} + +napi_value FileNExporter::Mkdir(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + auto *asyncCallbackInfo = new AsyncMkdirCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + bool recursive = false; + tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool(); + if (!succ) { + HILOGE("Unpacking parameters recursive failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->recursive = recursive; + asyncCallbackInfo->url = path; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, MkdirExec, MkdirComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::Rmdir(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + auto *asyncCallbackInfo = new AsyncRmdirCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + bool recursive = false; + tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool(); + if (!succ) { + HILOGE("Unpacking parameters recursive failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->recursive = recursive; + asyncCallbackInfo->url = path; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, RmdirExec, RmdirComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::Get(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto *asyncCallbackInfo = new AsyncGetCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + bool succ = false; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri = nullptr; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + bool recursive = false; + tie(succ, recursive) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("recursive").ToBool(); + if (!succ) { + HILOGE("Unpacking parameters recursive failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + asyncCallbackInfo->originUri = path; + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->recursive = recursive; + asyncCallbackInfo->url = path; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, GetExec, GetComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::List(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto *asyncCallbackInfo = new AsyncListCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + bool succ = false; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri = nullptr; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + asyncCallbackInfo->originUri = path; + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->url = path; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ListExec, ListComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::Copy(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + auto *asyncCallbackInfo = new AsyncCopyCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr srcUri, dstUri; + tie(succ, srcUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("srcUri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters srcUri failed"); + } + + tie(succ, dstUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("dstUri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters dstUri failed"); + } + + string srcPath = ((srcUri == nullptr) ? "" : (srcUri.get())); + string dstPath = ((dstUri == nullptr) ? "" : (dstUri.get())); + asyncCallbackInfo->originDst = dstPath; + if (!CheckUri(env, srcPath) || !CheckUri(env, dstPath)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->url = srcPath; + asyncCallbackInfo->urlDst = dstPath; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, CopyExec, CopyComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::Move(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + auto *asyncCallbackInfo = new AsyncMoveCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr srcUri, dstUri; + tie(succ, srcUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("srcUri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters srcUri failed"); + } + + tie(succ, dstUri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("dstUri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters dstUri failed"); + } + + string srcPath = ((srcUri == nullptr) ? "" : (srcUri.get())); + string dstPath = ((dstUri == nullptr) ? "" : (dstUri.get())); + asyncCallbackInfo->originDst = dstPath; + if (!CheckUri(env, srcPath) || !CheckUri(env, dstPath)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->url = srcPath; + asyncCallbackInfo->urlDst = dstPath; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, MoveExec, MoveComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::Delete(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + auto *asyncCallbackInfo = new AsyncDeleteCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->url = path; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, DeleteExec, DeleteComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::Access(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + AsyncAccessCallbackInfo *asyncCallbackInfo = new AsyncAccessCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->url = path; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, AccessExec, AccessComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::WriteText(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto *asyncCallbackInfo = new AsyncWriteCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + bool succ = false; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri, text, encoding; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + tie(succ, text, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("text").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters text failed"); + } + + tie(succ, encoding, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("encoding").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters encoding failed"); + } + + bool append = false; + tie(succ, append) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("append").ToBool(); + if (!succ) { + HILOGE("Unpacking parameters append failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + string encode = (encoding == nullptr) ? ENCODING_UTF8 : encoding.get(); + transform(encode.begin(), encode.end(), encode.begin(), ::tolower); + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + if (encode != ENCODING_UTF8) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "write file failed", FILE_IO_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + string content = text.get(); + asyncCallbackInfo->url = path; + asyncCallbackInfo->text = content; + asyncCallbackInfo->append = append; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, WriteTextExec, WriteTextComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::WriteArrayBuffer(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + auto *asyncCallbackInfo = new AsyncWriteBufferCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + int32_t position = 0; + tie(succ, position) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("position").ToInt32(); + if (!succ) { + HILOGE("Unpacking parameters position failed"); + } + + bool append = false; + tie(succ, append) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("append").ToBool(); + if (!succ) { + HILOGE("Unpacking parameters append failed"); + } + + void *buffer = nullptr; + size_t bufLength = 0; + napi_ref bufferRef = nullptr; + NVal bufNapi = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("buffer"); + tie(succ, buffer, bufLength) = bufNapi.ToTypedArray(); + napi_create_reference(env, bufNapi.val_, 1, &bufferRef); + + string path = (uri == nullptr) ? "" : uri.get(); + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + int32_t bufLen { bufLength }; + asyncCallbackInfo->url = path; + asyncCallbackInfo->position = position; + asyncCallbackInfo->append = append; + asyncCallbackInfo->buf = buffer; + asyncCallbackInfo->length = bufLen; + asyncCallbackInfo->bufferAddress = bufferRef; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, WriteArrayBufferExec, + WriteArrayBufferComp, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::ReadText(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + bool succ = false; + auto *asyncCallbackInfo = new AsyncReadCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri, encoding; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + tie(succ, encoding, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("encoding").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters encoding failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + string encode = (encoding == nullptr) ? ENCODING_UTF8 : encoding.get(); + transform(encode.begin(), encode.end(), encode.begin(), ::tolower); + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + if (encode != ENCODING_UTF8) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "read file failed", FILE_IO_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->url = path; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ReadTextExec, ReadTextComp, + (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + return NVal::CreateUndefined(env).val_; +} + +napi_value FileNExporter::ReadArrayBuffer(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto *asyncCallbackInfo = new AsyncReadBufferCallbackInfo { + .env = env, + .asyncWork = nullptr, + }; + bool succ = false; + tie(succ, asyncCallbackInfo->callback[COMMON_NUM::ZERO], asyncCallbackInfo->callback[COMMON_NUM::ONE], + asyncCallbackInfo->callback[COMMON_NUM::TWO]) = CommonFunc::GetCallbackHandles(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + HILOGE("Unpacking napi callback failed"); + } + + unique_ptr uri; + tie(succ, uri, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("Unpacking parameters uri failed"); + } + + int position = 0; + tie(succ, position) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("position").ToInt32(); + if (!succ) { + HILOGE("Unpacking parameters position failed"); + } + + int length = 0; + tie(succ, length) = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("length").ToInt32(); + if (!succ) { + HILOGE("Unpacking parameters length failed"); + } + + string path = (uri == nullptr) ? "" : uri.get(); + if (!CheckUri(env, path)) { + CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); + CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + delete asyncCallbackInfo; + return nullptr; + } + asyncCallbackInfo->url = path; + asyncCallbackInfo->length = length; + asyncCallbackInfo->position = position; + + napi_create_async_work(env, nullptr, NVal::CreateUTF8String(env, "ResourceName").val_, ReadArrayBufferExec, + ReadArrayBufferComp, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork); + napi_queue_async_work(env, asyncCallbackInfo->asyncWork); + return NVal::CreateUndefined(env).val_; +} + +bool FileNExporter::Export() +{ + return exports_.AddProp({ + NVal::DeclareNapiFunction("mkdir", Mkdir), + NVal::DeclareNapiFunction("rmdir", Rmdir), + NVal::DeclareNapiFunction("get", Get), + NVal::DeclareNapiFunction("list", List), + NVal::DeclareNapiFunction("copy", Copy), + NVal::DeclareNapiFunction("move", Move), + NVal::DeclareNapiFunction("delete", Delete), + NVal::DeclareNapiFunction("access", Access), + NVal::DeclareNapiFunction("writeText", WriteText), + NVal::DeclareNapiFunction("writeArrayBuffer", WriteArrayBuffer), + NVal::DeclareNapiFunction("readText", ReadText), + NVal::DeclareNapiFunction("readArrayBuffer", ReadArrayBuffer), + }); +} + +string FileNExporter::GetClassName() +{ + return FileNExporter::className_; +} + +FileNExporter::FileNExporter(napi_env env, napi_value exports) + : NExporter(env, exports) +{} + +FileNExporter::~FileNExporter() {} +} // namespace ModuleFile +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.h b/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..b9760b8a5c75ee115c0bc81e3f16e46339401a74 --- /dev/null +++ b/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FILE_CLASS_FILE_FILE_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILE_CLASS_FILE_FILE_N_EXPORTER_H + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFile { +namespace { + constexpr int32_t PARAMS_NUMBER_THREE = 3; + constexpr int32_t DEFAULT_RESULT = -100; +} +enum COMMON_NUM { + ZERO = 0, + ONE = 1, + TWO = 2, + THOUSAND = 1000, + MILLION = 1000000, +}; + +struct FileInfo { + int32_t length = 0; + int64_t lastModifiedTime = 0; + std::string type = ""; + std::string uri = ""; +}; + +struct AsyncAccessCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + std::string url = ""; + int errorType = -1; + int result = DEFAULT_RESULT; +}; + +struct AsyncMkdirCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + bool recursive = false; + std::string url = ""; + int result = DEFAULT_RESULT; + int errorType = -1; +}; + +struct AsyncRmdirCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + bool recursive = false; + std::string url = ""; + int result = DEFAULT_RESULT; + int errorType = -1; +}; + +struct AsyncGetCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + bool recursive = false; + std::string url = ""; + std::string originUri = ""; + int result = DEFAULT_RESULT; + int errorType = -1; + int32_t length = 0; + int64_t lastMT = 0; + std::string type = ""; + std::vector subFiles; +}; + +struct AsyncListCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + bool recursive = false; + std::string url = ""; + std::string originUri = ""; + int result = DEFAULT_RESULT; + int errorType = -1; + std::vector fileList; +}; + +struct AsyncCopyCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + std::string url = ""; + std::string urlDst = ""; + std::string originDst = ""; + int result = DEFAULT_RESULT; + int errorType = -1; +}; + +struct AsyncMoveCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + std::string url = ""; + std::string urlDst = ""; + std::string originDst = ""; + int result = DEFAULT_RESULT; + int errorType = -1; +}; + +struct AsyncDeleteCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + std::string url = ""; + int result = DEFAULT_RESULT; + int errorType = -1; +}; + +struct AsyncWriteCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + std::string url = ""; + std::string text = ""; + bool append = false; + int result = DEFAULT_RESULT; + int errorType = -1; +}; + +struct AsyncWriteBufferCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + std::string url = ""; + bool append = false; + int result = DEFAULT_RESULT; + int errorType = -1; + int32_t length = 0; + int32_t position = 0; + void* buf = nullptr; + napi_ref bufferAddress = nullptr; +}; + +struct AsyncReadCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + std::string url = ""; + int result = DEFAULT_RESULT; + int errorType = -1; + std::string contents = ""; +}; + +struct AsyncReadBufferCallbackInfo { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref callback[PARAMS_NUMBER_THREE] = { 0 }; + std::string url = ""; + int length = 0; + int position = 0; + int result = DEFAULT_RESULT; + int errorType = -1; + int32_t len = 0; + std::string contents = ""; +}; + +class FileNExporter final : public NExporter { +public: + inline static const std::string className_ = "File"; + static napi_value Mkdir(napi_env env, napi_callback_info info); + static napi_value Rmdir(napi_env env, napi_callback_info info); + static napi_value Get(napi_env env, napi_callback_info info); + static napi_value List(napi_env env, napi_callback_info info); + static napi_value Copy(napi_env env, napi_callback_info info); + static napi_value Move(napi_env env, napi_callback_info info); + static napi_value Delete(napi_env env, napi_callback_info info); + static napi_value Access(napi_env env, napi_callback_info info); + static napi_value WriteText(napi_env env, napi_callback_info info); + static napi_value WriteArrayBuffer(napi_env env, napi_callback_info info); + static napi_value ReadText(napi_env env, napi_callback_info info); + static napi_value ReadArrayBuffer(napi_env env, napi_callback_info info); + + bool Export() override; + + std::string GetClassName() override; + + FileNExporter(napi_env env, napi_value exports); + ~FileNExporter() override; +}; +} // namespace ModuleFile +} // namespace DistributedFS +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILE_CLASS_FILE_FILE_N_EXPORTER_H diff --git a/interfaces/kits/js/src/mod_file/common_func.cpp b/interfaces/kits/js/src/mod_file/common_func.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a9fa3d399a5552adb98a1ff64d32c852a96ad7e --- /dev/null +++ b/interfaces/kits/js/src/mod_file/common_func.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_func.h" + +#include "../common/napi/n_func_arg.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFile { +using namespace std; + +tuple CommonFunc::GetCallbackHandles(napi_env env, napi_value object) +{ + bool succ = false; + NVal prop = NVal(env, object); + napi_value successProp, failProp, completeProp; + napi_ref successHandle = nullptr; + napi_ref failHandle = nullptr; + napi_ref completeHandle = nullptr; + const string success = "success"; + const string fail = "fail"; + const string complete = "complete"; + + successProp = prop.GetProp(success).val_; + if (successProp != nullptr) { + napi_create_reference(env, successProp, 1, &successHandle); + succ = true; + } + + failProp = prop.GetProp(fail).val_; + if (succ && failProp != nullptr) { + napi_create_reference(env, failProp, 1, &failHandle); + succ = true; + } + + completeProp = prop.GetProp(complete).val_; + if (succ && completeProp != nullptr) { + napi_create_reference(env, completeProp, 1, &completeHandle); + succ = true; + } + + return { succ, successHandle, failHandle, completeHandle }; +} +} // namespace ModuleFile +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_file/common_func.h b/interfaces/kits/js/src/mod_file/common_func.h new file mode 100644 index 0000000000000000000000000000000000000000..207411602e2346198b7edc1aae12e0ae06f0f160 --- /dev/null +++ b/interfaces/kits/js/src/mod_file/common_func.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FILE_COMMON_FUNC_H +#define INTERFACES_KITS_JS_SRC_MOD_FILE_COMMON_FUNC_H + +#include "../common/napi/n_val.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFile { +struct CommonFunc { + static std::tuple GetCallbackHandles(napi_env env, + napi_value object); +}; +} // namespace ModuleFile +} // namespace DistributedFS +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILE_COMMON_FUNC_H diff --git a/interfaces/kits/js/src/mod_file/module.cpp b/interfaces/kits/js/src/mod_file/module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6defa937f97fcb345b47afdeddd7957dbbadf02c --- /dev/null +++ b/interfaces/kits/js/src/mod_file/module.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "../common/log.h" +#include "class_file/file_n_exporter.h" + +using namespace std; + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFile { +static napi_value Export(napi_env env, napi_value exports) +{ + std::vector > products; + products.emplace_back(make_unique(env, exports)); + + for (auto && product : products) { + if (!product->Export()) { + HILOGE("INNER BUG. Failed to export class %{public}s for module file", product->GetClassName().c_str()); + return nullptr; + } else { + HILOGE("Class %{public}s for module file has been exported", product->GetClassName().c_str()); + } + } + return exports; +} + +NAPI_MODULE(file, Export) +} // namespace ModuleFile +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file