From 823cec226b1a116ce1c61fe05e66987a036d3f85 Mon Sep 17 00:00:00 2001 From: gaoshunli Date: Wed, 28 Sep 2022 14:26:52 +0800 Subject: [PATCH 1/2] =?UTF-8?q?file=5Fapi=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: gaoshunli --- bundle.json | 31 +- file_api.gni | 4 +- interfaces/kits/js/BUILD.gn | 5 + interfaces/kits/js/src/common/file_filter.h | 174 ++++++++ interfaces/kits/js/src/common/log.h | 4 +- interfaces/kits/js/src/common/napi/n_val.cpp | 42 ++ interfaces/kits/js/src/common/napi/n_val.h | 6 +- interfaces/kits/js/src/common/uni_error.cpp | 8 +- .../mod_file/class_file/file_n_exporter.cpp | 32 +- .../mod_fileio/class_constants/constants.cpp | 71 ++- .../mod_fileio/class_dir/dir_n_exporter.cpp | 157 +++++++ .../src/mod_fileio/class_dir/dir_n_exporter.h | 3 + .../class_dirent/dirent_n_exporter.cpp | 4 +- .../randomaccessfile_entity.h | 33 ++ .../randomaccessfile_n_exporter.cpp | 416 ++++++++++++++++++ .../randomaccessfile_n_exporter.h | 52 +++ .../mod_fileio/class_stat/stat_n_exporter.cpp | 6 +- .../class_stream/stream_n_exporter.cpp | 6 +- .../class_watcher/watcher_n_exporter.cpp | 2 +- .../kits/js/src/mod_fileio/common_func.cpp | 33 +- .../kits/js/src/mod_fileio/common_func.h | 7 +- interfaces/kits/js/src/mod_fileio/module.cpp | 4 +- .../js/src/mod_fileio/properties/chmod.cpp | 2 +- .../js/src/mod_fileio/properties/chown.cpp | 4 +- .../js/src/mod_fileio/properties/close.cpp | 2 +- .../properties/create_randomaccessfile.cpp | 213 +++++++++ .../properties/create_randomaccessfile.h | 33 ++ .../mod_fileio/properties/create_stream.cpp | 5 +- .../js/src/mod_fileio/properties/fchmod.cpp | 2 +- .../js/src/mod_fileio/properties/fchown.cpp | 4 +- .../src/mod_fileio/properties/fdatasync.cpp | 2 +- .../mod_fileio/properties/fdopen_stream.cpp | 4 +- .../js/src/mod_fileio/properties/fstat.cpp | 4 +- .../js/src/mod_fileio/properties/fsync.cpp | 2 +- .../src/mod_fileio/properties/ftruncate.cpp | 3 +- .../js/src/mod_fileio/properties/open.cpp | 14 +- .../mod_fileio/properties/prop_n_exporter.cpp | 30 +- .../js/src/mod_fileio/properties/read_dir.cpp | 131 ++++++ .../js/src/mod_fileio/properties/read_dir.h | 33 ++ .../js/src/mod_fileio/properties/rmdirent.cpp | 142 ++++++ .../js/src/mod_fileio/properties/rmdirent.h | 33 ++ .../js/src/mod_fileio/properties/stat.cpp | 6 +- .../js/src/mod_securitylabel/security_label.h | 8 +- 43 files changed, 1660 insertions(+), 117 deletions(-) create mode 100644 interfaces/kits/js/src/common/file_filter.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_entity.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.h create mode 100644 interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.h create mode 100644 interfaces/kits/js/src/mod_fileio/properties/read_dir.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/properties/read_dir.h create mode 100644 interfaces/kits/js/src/mod_fileio/properties/rmdirent.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/properties/rmdirent.h diff --git a/bundle.json b/bundle.json index ab34a9cc7..8d2e75611 100644 --- a/bundle.json +++ b/bundle.json @@ -12,22 +12,49 @@ "component": { "name": "file_api", "subsystem": "filemanagement", - "syscap": [], + "syscap": [ + "SystemCapability.FileManagement.File.FileIO", + "SystemCapability.FileManagement.File.Environment", + "SystemCapability.FileManagement.File.DistributedFile" + ], "features": [], "adapted_system_type": ["standard"], "rom": "", "ram": "", "deps": { "components": [ + "ability_base", "ability_manager", + "appexecfwk_base", + "appexecfwk_core", + "want", "libhilog", + "ipc_core", "ace_napi", "samgr_proxy" + ], + "third_party": [ + "e2fsprogs" ] }, "build": { - "sub_component": [ + "group_type": { + "base_group": [], + "fwk_group": [ "//foundation/filemanagement/file_api/interfaces/kits/js:build_kits_js" + ], + "service_group": [] + }, + "inner_kits": [ + { + "name": "//foundation/filemanagement/file_api/interfaces/kits/native:remote_uri_native", + "header": { + "header_files": [ + "remote_uri.h" + ], + "header_base": "//foundation/filemanagement/file_api/interfaces/kits/native/remote_uri" + } + } ] } } diff --git a/file_api.gni b/file_api.gni index 039aa4ed6..5dfea39be 100644 --- a/file_api.gni +++ b/file_api.gni @@ -11,5 +11,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -aafwk_kits_path = "//foundation/ability/ability_runtime/frameworks/kits" -aafwk_path = "//foundation/ability/ability_runtime" +aafwk_kits_path = "//foundation/ability/ability_runtime/frameworks/native" +aafwk_path = "${aafwk_kits_path}/frameworks/kits" diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 9325a4b00..36e610de8 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -48,6 +48,7 @@ ohos_shared_library("fileio") { "src/mod_fileio/class_constants/constants.cpp", "src/mod_fileio/class_dir/dir_n_exporter.cpp", "src/mod_fileio/class_dirent/dirent_n_exporter.cpp", + "src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp", "src/mod_fileio/class_stat/stat_n_exporter.cpp", "src/mod_fileio/class_stream/flush.cpp", "src/mod_fileio/class_stream/stream_n_exporter.cpp", @@ -58,6 +59,7 @@ ohos_shared_library("fileio") { "src/mod_fileio/properties/chown.cpp", "src/mod_fileio/properties/close.cpp", "src/mod_fileio/properties/copy_file.cpp", + "src/mod_fileio/properties/create_randomaccessfile.cpp", "src/mod_fileio/properties/create_stream.cpp", "src/mod_fileio/properties/fchmod.cpp", "src/mod_fileio/properties/fchown.cpp", @@ -76,9 +78,11 @@ ohos_shared_library("fileio") { "src/mod_fileio/properties/open_dir.cpp", "src/mod_fileio/properties/posix_fallocate.cpp", "src/mod_fileio/properties/prop_n_exporter.cpp", + "src/mod_fileio/properties/read_dir.cpp", "src/mod_fileio/properties/read_text.cpp", "src/mod_fileio/properties/rename.cpp", "src/mod_fileio/properties/rmdir.cpp", + "src/mod_fileio/properties/rmdirent.cpp", "src/mod_fileio/properties/stat.cpp", "src/mod_fileio/properties/symlink.cpp", "src/mod_fileio/properties/truncate.cpp", @@ -87,6 +91,7 @@ ohos_shared_library("fileio") { deps = [ "//foundation/arkui/napi:ace_napi", + "//foundation/filemanagement/file_api/interfaces/kits/native:remote_uri_native", "//third_party/bounds_checking_function:libsec_static", "//third_party/openssl:libcrypto_static", ] diff --git a/interfaces/kits/js/src/common/file_filter.h b/interfaces/kits/js/src/common/file_filter.h new file mode 100644 index 000000000..694b6f0d2 --- /dev/null +++ b/interfaces/kits/js/src/common/file_filter.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 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 FILE_FILTER_H +#define FILE_FILTER_H + +#include +#include + +#include "parcel.h" + +namespace OHOS { +namespace DistributedFS { +class FileFilter : public Parcelable { +public: + FileFilter() = default; + ~FileFilter() = default; + + FileFilter(std::vector suffix, std::vector displayName, + std::vector mimeType, int64_t fileSizeOver, + double lastModifiedAfter, bool excludeMedia, bool hasFilter) + : suffix_(suffix), displayName_(displayName), mimeType_(mimeType), fileSizeOver_(fileSizeOver), + lastModifiedAfter_(lastModifiedAfter), excludeMedia_(excludeMedia), hasFilter_(hasFilter) {} + explicit FileFilter(std::vector suffix): suffix_(suffix) {} + FileFilter(const FileFilter &filter) = default; + FileFilter &operator=(const FileFilter& filter) = default; + + void SetSuffix(const std::vector &suffix) + { + suffix_ = suffix; + } + + std::vector GetSuffix() const + { + return suffix_; + } + + void SetDisplayName(const std::vector &displayName) + { + displayName_ = displayName; + } + + std::vector GetDisplayName() const + { + return displayName_; + } + + void SetMimeType(const std::vector &mimeType) + { + mimeType_ = mimeType; + } + + std::vector GetMimeType() const + { + return mimeType_; + } + + void SetFileSizeOver(const int64_t &fileSizeOver) + { + fileSizeOver_ = fileSizeOver; + } + + int64_t GetFileSizeOver() const + { + return fileSizeOver_; + } + + void SetLastModifiedAfter(const double &lastModifiedAfter) + { + lastModifiedAfter_ = lastModifiedAfter; + } + + double GetLastModifiedAfter() const + { + return lastModifiedAfter_; + } + + void SetExcludeMedia(const bool &excludeMedia) + { + excludeMedia_ = excludeMedia; + } + + bool GetExcludeMedia() const + { + return excludeMedia_; + } + + void SetHasFilter(const bool &hasFilter) + { + hasFilter_ = hasFilter; + } + + bool GetHasFilter() const + { + return hasFilter_; + } + + bool Marshalling(Parcel &parcel) const + { + if (!parcel.WriteStringVector(suffix_)) { + return false; + } + if (!parcel.WriteStringVector(displayName_)) { + return false; + } + if (!parcel.WriteStringVector(mimeType_)) { + return false; + } + if (!parcel.WriteInt64(fileSizeOver_)) { + return false; + } + if (!parcel.WriteDouble(lastModifiedAfter_)) { + return false; + } + if (!parcel.WriteBool(excludeMedia_)) { + return false; + } + if (!parcel.WriteBool(hasFilter_)) { + return false; + } + return true; + } + + static FileFilter* Unmarshalling(Parcel &parcel) + { + auto obj = new (std::nothrow) FileFilter(); + if (obj != nullptr && !obj->ReadFromParcel(parcel)) { + delete obj; + obj = nullptr; + } + return obj; + } + + bool ReadFromParcel(Parcel &parcel) + { + if (!parcel.ReadStringVector(&suffix_)) { + return false; + } + if (!parcel.ReadStringVector(&displayName_)) { + return false; + } + if (!parcel.ReadStringVector(&mimeType_)) { + return false; + } + fileSizeOver_ = parcel.ReadInt64(); + lastModifiedAfter_ = parcel.ReadDouble(); + excludeMedia_ = parcel.ReadBool(); + hasFilter_ = parcel.ReadBool(); + return true; + } + +private: + std::vector suffix_ = std::vector(); + std::vector displayName_ = std::vector(); + std::vector mimeType_ = std::vector(); + int64_t fileSizeOver_ = 0; + double lastModifiedAfter_ = 0; + bool excludeMedia_ = false; + bool hasFilter_ = false; +}; +} // namespace DistributedFS +} // namespace OHOS +#endif // FILE_FILTER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/common/log.h b/interfaces/kits/js/src/common/log.h index 48eb794a1..57ba9edcd 100644 --- a/interfaces/kits/js/src/common/log.h +++ b/interfaces/kits/js/src/common/log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -28,7 +28,7 @@ namespace OHOS { namespace DistributedFS { #ifndef FILE_SUBSYSTEM_DEBUG_LOCAL static constexpr int FILEIO_DOMAIN_ID = 0; -static constexpr OHOS::HiviewDFX::HiLogLabel FILEIO_LABEL = { LOG_CORE, FILEIO_DOMAIN_ID, "distributedfilejs" }; +static constexpr OHOS::HiviewDFX::HiLogLabel FILEIO_LABEL = { LOG_CORE, FILEIO_DOMAIN_ID, "file_api" }; #ifdef HILOGD #undef HILOGD diff --git a/interfaces/kits/js/src/common/napi/n_val.cpp b/interfaces/kits/js/src/common/napi/n_val.cpp index d5bfbf42f..93d99676a 100644 --- a/interfaces/kits/js/src/common/napi/n_val.cpp +++ b/interfaces/kits/js/src/common/napi/n_val.cpp @@ -124,6 +124,36 @@ tuple NVal::ToInt64() const return make_tuple(status == napi_ok, res); } +tuple NVal::ToDouble() const +{ + double res = 0; + napi_status status = napi_get_value_double(env_, val_, &res); + return make_tuple(status == napi_ok, res); +} + +tuple NVal::ToUint64() const +{ + uint64_t res = 0; + bool lossless = false; + napi_status status = napi_get_value_bigint_uint64(env_, val_, &res, &lossless); + return make_tuple(status == napi_ok, res, lossless); +} + +tuple, uint32_t> NVal::ToStringArray() +{ + napi_status status; + uint32_t size; + status = napi_get_array_length(env_, val_, &size); + vector stringArray; + napi_value result; + for (uint32_t i = 0; i < size; i++) { + status = napi_get_element(env_, val_, i, &result); + auto [succ, str, ignore] = NVal(env_, result).ToUTF8String(); + stringArray.push_back(string(str.get())); + } + return make_tuple(status == napi_ok, stringArray, size); +} + tuple NVal::ToArraybuffer() const { void *buf = nullptr; @@ -265,6 +295,18 @@ NVal NVal::CreateUint8Array(napi_env env, void *buf, size_t bufLen) return { env, output_array }; } +NVal NVal::CreateArrayString(napi_env env, vector strs) +{ + napi_value res = nullptr; + napi_create_array(env, &res); + for (size_t i = 0; i < strs.size(); i++) { + napi_value filename; + napi_create_string_utf8(env, strs[i].c_str(), strs[i].length(), &filename); + napi_set_element(env, res, i, filename); + } + return {env, res}; +} + tuple NVal::CreateArrayBuffer(napi_env env, size_t len) { napi_value val; diff --git a/interfaces/kits/js/src/common/napi/n_val.h b/interfaces/kits/js/src/common/napi/n_val.h index 9d46fca4a..ae6da6795 100644 --- a/interfaces/kits/js/src/common/napi/n_val.h +++ b/interfaces/kits/js/src/common/napi/n_val.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -46,6 +46,9 @@ public: std::tuple ToInt64() const; std::tuple ToArraybuffer() const; std::tuple ToTypedArray() const; + std::tuple, uint32_t> ToStringArray(); + std::tuple ToUint64() const; + std::tuple ToDouble() const; /* Static helpers to create js objects */ static NVal CreateUndefined(napi_env env); @@ -56,6 +59,7 @@ public: static NVal CreateUTF8String(napi_env env, std::string str); static NVal CreateUTF8String(napi_env env, const char* str, ssize_t len); static NVal CreateUint8Array(napi_env env, void *buf, size_t bufLen); + static NVal CreateArrayString(napi_env env, std::vector strs); static std::tuple CreateArrayBuffer(napi_env env, size_t len); /* SHOULD ONLY BE USED FOR OBJECT */ bool HasProp(std::string propName) const; diff --git a/interfaces/kits/js/src/common/uni_error.cpp b/interfaces/kits/js/src/common/uni_error.cpp index fb7493c82..68db46d24 100644 --- a/interfaces/kits/js/src/common/uni_error.cpp +++ b/interfaces/kits/js/src/common/uni_error.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -82,7 +82,11 @@ napi_value UniError::GetNapiErr(napi_env env) napi_value UniError::GetNapiErr(napi_env env, string errMsg) { - napi_value code = NVal::CreateUTF8String(env, to_string(GetErrno(codingSystem_))).val_; + int errCode = GetErrno(codingSystem_); + if (errCode == ERRNO_NOERR) { + return nullptr; + } + napi_value code = NVal::CreateUTF8String(env, to_string(errCode)).val_; napi_value msg = NVal::CreateUTF8String(env, errMsg).val_; napi_value res = nullptr; 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 index 9633bbbbe..35c465e20 100644 --- 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 @@ -280,7 +280,7 @@ void MkdirExec(napi_env env, void *data) path = UriToAbsolute(path); if (asyncCallbackInfo->recursive && Mkdirs(path)) { asyncCallbackInfo->result = SUCCESS; - } else if (mkdir((char *)path.c_str(), DIR_FAULT_PERM) != FAILED) { + } else if (mkdir(const_cast(path.c_str()), DIR_FAULT_PERM) != FAILED) { asyncCallbackInfo->result = SUCCESS; } } @@ -313,7 +313,7 @@ void RmdirExec(napi_env env, void *data) if (statPath == COMMON_NUM::ZERO) { if (asyncCallbackInfo->recursive && Rmdirs(path)) { asyncCallbackInfo->result = SUCCESS; - } else if (remove((char *)path.c_str()) != FAILED) { + } else if (remove(const_cast(path.c_str())) != FAILED) { asyncCallbackInfo->result = SUCCESS; } } else if (statPath == ENOENT) { @@ -347,7 +347,7 @@ void GetExec(napi_env env, void *data) 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) { + if (statPath == COMMON_NUM::ZERO && stat(const_cast(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); @@ -413,7 +413,7 @@ void ListExec(napi_env env, void *data) 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) { + } else if (statPath != COMMON_NUM::ZERO || stat(const_cast(path.c_str()), &buf) != COMMON_NUM::ZERO) { asyncCallbackInfo->errorType = FILE_IO_ERROR; } else if ((buf.st_mode & S_IFMT) == S_IFREG) { asyncCallbackInfo->result = SUCCESS; @@ -487,14 +487,14 @@ int FileCopy(const string& srcPath, const string& dstPath) if (GetRealPath(src) == 0) { if (GetRealPath(dest) == ENOENT) { FDGuard sfd; - sfd.SetFD(open((char *)src.c_str(), O_RDONLY)); + sfd.SetFD(open(const_cast(src.c_str()), O_RDONLY)); struct stat attrSrc; - if (stat((char *)src.c_str(), &attrSrc) == FAILED) { + if (stat(const_cast(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)); + ofd.SetFD(open(const_cast(dest.c_str()), O_WRONLY | O_CREAT, attrSrc.st_mode)); if (sfd.GetFD() == FAILED || ofd.GetFD() == FAILED) { return FILE_IO_ERROR; } @@ -502,7 +502,7 @@ int FileCopy(const string& srcPath, const string& dstPath) if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, attrSrc.st_size) != FAILED) { ret = SUCCESS; } else { - remove((char *)dest.c_str()); + remove(const_cast(dest.c_str())); } } else if (GetRealPath(dest) == 0) { return (dest == src) ? SUCCESS : FILE_IO_ERROR; @@ -520,7 +520,7 @@ int DirCopy(const string& srcPath, const string& dstPath) } if (GetRealPath(dest) == ENOENT) { struct stat attrSrc; - if (stat((char *)src.c_str(), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { + if (stat(const_cast(src.c_str()), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { return FILE_IO_ERROR; } dest = UriToAbsolute(dest); @@ -546,7 +546,7 @@ void CopyExec(napi_env env, void *data) } struct stat statbf; - if (stat((char *)path.c_str(), &statbf) == FAILED) { + if (stat(const_cast(path.c_str()), &statbf) == FAILED) { asyncCallbackInfo->errorType = FILE_IO_ERROR; return; } @@ -604,7 +604,7 @@ int DirMove(const string& srcPath, const string& dstPath) } struct stat attrSrc; - if (stat((char *)src.c_str(), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { + if (stat(const_cast(src.c_str()), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { return FILE_IO_ERROR; } dest = UriToAbsolute(dest); @@ -655,7 +655,7 @@ void MoveExec(napi_env env, void *data) } struct stat statbf; - if (stat((char *)path.c_str(), &statbf) == FAILED) { + if (stat(const_cast(path.c_str()), &statbf) == FAILED) { asyncCallbackInfo->errorType = FILE_IO_ERROR; return; } @@ -664,7 +664,7 @@ void MoveExec(napi_env env, void *data) int retval = FileCopy(path, pathDst); if (retval == SUCCESS) { asyncCallbackInfo->result = SUCCESS; - remove((char *)path.c_str()); + remove(const_cast(path.c_str())); } else { asyncCallbackInfo->errorType = retval; } @@ -705,7 +705,7 @@ void DeleteExec(napi_env env, void *data) int statPath = GetRealPath(path); if (statPath == ENOENT) { asyncCallbackInfo->errorType = FILE_PATH_ERROR; - } else if (statPath == COMMON_NUM::ZERO && remove((char *)path.c_str()) != FAILED) { + } else if (statPath == COMMON_NUM::ZERO && remove(const_cast(path.c_str())) != FAILED) { asyncCallbackInfo->result = SUCCESS; } else { asyncCallbackInfo->errorType = FILE_IO_ERROR; @@ -859,7 +859,7 @@ void ReadTextExec(napi_env env, void *data) FDGuard fdg; fdg.SetFD(open(path.c_str(), O_RDONLY)); struct stat buf; - int result = stat((char *)path.c_str(), &buf); + int result = stat(const_cast(path.c_str()), &buf); if (fdg.GetFD() != FAILED && result != FAILED) { auto buffer = std::make_unique(buf.st_size + 1); if (buffer == nullptr) { @@ -907,7 +907,7 @@ void ReadArrayBufferExec(napi_env env, void *data) FDGuard fdg; fdg.SetFD(open(path.c_str(), O_RDONLY)); struct stat buf; - int result = stat((char *)path.c_str(), &buf); + int result = stat(const_cast(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 = diff --git a/interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp b/interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp index 162b4360a..f046d8e84 100644 --- a/interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp @@ -50,79 +50,78 @@ bool Constants::Export() { // access napi_value F_OK_ = nullptr; - napi_create_int32(exports_.env_, 0, &F_OK_); // 0 F_OK + napi_create_int32(exports_.env_, F_OK, &F_OK_); // 0 F_OK napi_value R_OK_ = nullptr; - napi_create_int32(exports_.env_, 4, &R_OK_); // 4 R_OK + napi_create_int32(exports_.env_, R_OK, &R_OK_); // 4 R_OK napi_value W_OK_ = nullptr; - napi_create_int32(exports_.env_, 2, &W_OK_); // 2 W_OK + napi_create_int32(exports_.env_, W_OK, &W_OK_); // 2 W_OK napi_value X_OK_ = nullptr; - napi_create_int32(exports_.env_, 1, &X_OK_); // 1 X_OK - + napi_create_int32(exports_.env_, X_OK, &X_OK_); // 1 X_OK // open napi_value O_RDONLY_ = nullptr; - napi_create_int32(exports_.env_, 0, &O_RDONLY_); // 0 O_RDONLY + napi_create_int32(exports_.env_, O_RDONLY, &O_RDONLY_); // 0 O_RDONLY napi_value O_WRONLY_ = nullptr; - napi_create_int32(exports_.env_, 1, &O_WRONLY_); // 1 O_WRONLY + napi_create_int32(exports_.env_, O_WRONLY, &O_WRONLY_); // 1 O_WRONLY napi_value O_RDWR_ = nullptr; - napi_create_int32(exports_.env_, 2, &O_RDWR_); // 2 O_RDWR + napi_create_int32(exports_.env_, O_RDWR, &O_RDWR_); // 2 O_RDWR napi_value O_CREAT_ = nullptr; - napi_create_int32(exports_.env_, 0o100, &O_CREAT_); // 0o100 O_CREAT + napi_create_int32(exports_.env_, O_CREAT, &O_CREAT_); // 0o100 O_CREAT napi_value O_EXCL_ = nullptr; - napi_create_int32(exports_.env_, 0o200, &O_EXCL_); // 0o200 O_EXCL + napi_create_int32(exports_.env_, O_EXCL, &O_EXCL_); // 0o200 O_EXCL napi_value O_TRUNC_ = nullptr; - napi_create_int32(exports_.env_, 0o1000, &O_TRUNC_); // 0o1000 O_TRUNC + napi_create_int32(exports_.env_, O_TRUNC, &O_TRUNC_); // 0o1000 O_TRUNC napi_value O_APPEND_ = nullptr; - napi_create_int32(exports_.env_, 0o2000, &O_APPEND_); // 0o2000 O_APPEND + napi_create_int32(exports_.env_, O_APPEND, &O_APPEND_); // 0o2000 O_APPEND napi_value O_NONBLOCK_ = nullptr; - napi_create_int32(exports_.env_, 0o4000, &O_NONBLOCK_); // 0o4000 O_NONBLOCK + napi_create_int32(exports_.env_, O_NONBLOCK, &O_NONBLOCK_); // 0o4000 O_NONBLOCK napi_value O_DIRECTORY_ = nullptr; - napi_create_int32(exports_.env_, 0o200000, &O_DIRECTORY_); // 0o200000 O_DIRECTORY + napi_create_int32(exports_.env_, O_DIRECTORY, &O_DIRECTORY_); // 0o200000 O_DIRECTORY napi_value O_NOFOLLOW_ = nullptr; - napi_create_int32(exports_.env_, 0o400000, &O_NOFOLLOW_); // 0o400000 O_NOFOLLOW + napi_create_int32(exports_.env_, O_NOFOLLOW, &O_NOFOLLOW_); // 0o400000 O_NOFOLLOW napi_value O_SYNC_ = nullptr; - napi_create_int32(exports_.env_, 0o4010000, &O_SYNC_); // 0o4010000 O_SYNC + napi_create_int32(exports_.env_, O_SYNC, &O_SYNC_); // 0o4010000 O_SYNC // stat napi_value S_IFMT_ = nullptr; - napi_create_int32(exports_.env_, 0o170000, &S_IFMT_); // 0o170000 S_IFMT + napi_create_int32(exports_.env_, S_IFMT, &S_IFMT_); // 0o170000 S_IFMT napi_value S_IFSOCK_ = nullptr; - napi_create_int32(exports_.env_, 0o140000, &S_IFSOCK_); // 0o140000 S_IFSOCK + napi_create_int32(exports_.env_, S_IFSOCK, &S_IFSOCK_); // 0o140000 S_IFSOCK napi_value S_IFLNK_ = nullptr; - napi_create_int32(exports_.env_, 0o120000, &S_IFLNK_); // 0o120000 S_IFLNK + napi_create_int32(exports_.env_, S_IFLNK, &S_IFLNK_); // 0o120000 S_IFLNK napi_value S_IFREG_ = nullptr; - napi_create_int32(exports_.env_, 0o100000, &S_IFREG_); // 0o100000 S_IFREG + napi_create_int32(exports_.env_, S_IFREG, &S_IFREG_); // 0o100000 S_IFREG napi_value S_IFBLK_ = nullptr; - napi_create_int32(exports_.env_, 0o060000, &S_IFBLK_); // 0o060000 S_IFBLK + napi_create_int32(exports_.env_, S_IFBLK, &S_IFBLK_); // 0o060000 S_IFBLK napi_value S_IFDIR_ = nullptr; - napi_create_int32(exports_.env_, 0o040000, &S_IFDIR_); // 0o040000 S_IFDIR + napi_create_int32(exports_.env_, S_IFDIR, &S_IFDIR_); // 0o040000 S_IFDIR napi_value S_IFCHR_ = nullptr; - napi_create_int32(exports_.env_, 0o020000, &S_IFCHR_); // 0o020000 S_IFCHR + napi_create_int32(exports_.env_, S_IFCHR, &S_IFCHR_); // 0o020000 S_IFCHR napi_value S_IFIFO_ = nullptr; - napi_create_int32(exports_.env_, 0o010000, &S_IFIFO_); // 0o010000 S_IFIFO + napi_create_int32(exports_.env_, S_IFIFO, &S_IFIFO_); // 0o010000 S_IFIFO napi_value S_IRWXU_ = nullptr; - napi_create_int32(exports_.env_, 0o0700, &S_IRWXU_); // 0o0700 S_IRWXU + napi_create_int32(exports_.env_, S_IRWXU, &S_IRWXU_); // 0o0700 S_IRWXU napi_value S_IRUSR_ = nullptr; - napi_create_int32(exports_.env_, 0o0400, &S_IRUSR_); // 0o0400 S_IRUSR + napi_create_int32(exports_.env_, S_IRUSR, &S_IRUSR_); // 0o0400 S_IRUSR napi_value S_IWUSR_ = nullptr; - napi_create_int32(exports_.env_, 0o0200, &S_IWUSR_); // 0o0200 S_IWUSR + napi_create_int32(exports_.env_, S_IWUSR, &S_IWUSR_); // 0o0200 S_IWUSR napi_value S_IXUSR_ = nullptr; - napi_create_int32(exports_.env_, 0o0100, &S_IXUSR_); // 0o0100 S_IXUSR + napi_create_int32(exports_.env_, S_IXUSR, &S_IXUSR_); // 0o0100 S_IXUSR napi_value S_IRWXG_ = nullptr; - napi_create_int32(exports_.env_, 0o0070, &S_IRWXG_); // 0o0070 S_IRWXG + napi_create_int32(exports_.env_, S_IRWXG, &S_IRWXG_); // 0o0070 S_IRWXG napi_value S_IRGRP_ = nullptr; - napi_create_int32(exports_.env_, 0o0040, &S_IRGRP_); // 0o0040 S_IRGRP + napi_create_int32(exports_.env_, S_IRGRP, &S_IRGRP_); // 0o0040 S_IRGRP napi_value S_IWGRP_ = nullptr; - napi_create_int32(exports_.env_, 0o0020, &S_IWGRP_); // 0o0020 S_IWGRP + napi_create_int32(exports_.env_, S_IWGRP, &S_IWGRP_); // 0o0020 S_IWGRP napi_value S_IXGRP_ = nullptr; - napi_create_int32(exports_.env_, 0o0010, &S_IXGRP_); // 0o0010 S_IXGRP + napi_create_int32(exports_.env_, S_IXGRP, &S_IXGRP_); // 0o0010 S_IXGRP napi_value S_IRWXO_ = nullptr; - napi_create_int32(exports_.env_, 0o0007, &S_IRWXO_); // 0o0007 S_IRWXO + napi_create_int32(exports_.env_, S_IRWXO, &S_IRWXO_); // 0o0007 S_IRWXO napi_value S_IROTH_ = nullptr; - napi_create_int32(exports_.env_, 0o0004, &S_IROTH_); // 0o0004 S_IROTH + napi_create_int32(exports_.env_, S_IROTH, &S_IROTH_); // 0o0004 S_IROTH napi_value S_IWOTH_ = nullptr; - napi_create_int32(exports_.env_, 0o0002, &S_IWOTH_); // 0o0002 S_IWOTH + napi_create_int32(exports_.env_, S_IWOTH, &S_IWOTH_); // 0o0002 S_IWOTH napi_value S_IXOTH_ = nullptr; - napi_create_int32(exports_.env_, 0o0001, &S_IXOTH_); // 0o0001 S_IXOTH + napi_create_int32(exports_.env_, S_IXOTH, &S_IXOTH_); // 0o0001 S_IXOTH vector props = { NVal::DeclareNapiStaticProperty("F_OK", F_OK_), diff --git a/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp index bbc53799d..eb3b4574d 100644 --- a/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp @@ -253,6 +253,161 @@ napi_value DirNExporter::ReadSync(napi_env env, napi_callback_info info) return objDirent; } +struct DirListFileArgs { + vector dirents; + explicit DirListFileArgs() + { + dirents = vector(); + } + ~DirListFileArgs() = default; +}; + +static DirEntity *CheckDirEntity(napi_env env, napi_value dir_entity) +{ + auto dirEntity = NClass::GetEntityOf(env, dir_entity); + if (!dirEntity) { + UniError(EIO).ThrowErr(env, "Cannot get entity of Dir"); + return nullptr; + } + + if (!dirEntity || !dirEntity->dir_) { + UniError(EBADF).ThrowErr(env, "Dir has been closed yet"); + return nullptr; + } + return dirEntity; +} + +static tuple ParseJsListNum(napi_env env, napi_value listNumFromJs) +{ + auto [succ, listNum] = NVal(env, listNumFromJs).ToInt32(); + return {succ, listNum}; +} + +static napi_value DoListFileVector2NV(napi_env env, vector dirents) +{ + napi_value res = nullptr; + napi_create_array(env, &res); + for (size_t i = 0; i < dirents.size(); i++) { + napi_value objDirent = NClass::InstantiateClass(env, DirentNExporter::className_, {}); + if (!objDirent) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + auto direntEntity = NClass::GetEntityOf(env, objDirent); + if (!direntEntity) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + direntEntity->dirent_ = dirents[i]; + napi_set_element(env, res, i, objDirent); + } + return res; +} + +static NVal DoListFileCompile(napi_env env, UniError err, shared_ptr arg) +{ + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return { env, DoListFileVector2NV(env, arg->dirents) }; + } +} + +napi_value DirNExporter::ListFile(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto dirEntity = CheckDirEntity(env, funcArg.GetThisVar()); + if (!dirEntity) { + return nullptr; + } + auto [succ, num] = ParseJsListNum(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid listNum"); + return nullptr; + } + + DIR *dir = dirEntity->dir_.get(); + auto arg = make_shared(); + int listNum = num; + auto cbExec = [arg, dir, dirEntity, listNum](napi_env env) -> UniError { + lock_guard(dirEntity->lock_); + errno = 0; + dirent *res = nullptr; + int listCount = 0; + do { + res = readdir(dir); + if (res == nullptr && errno) { + return UniError(errno); + } else if (res == nullptr) { + return UniError(ERRNO_NOERR); + } else if (string(res->d_name) == "." || string(res->d_name) == "..") { + continue; + } else { + arg->dirents.push_back(*res); + listCount++; + } + } while (listCount < listNum || listNum == 0); + return UniError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + return DoListFileCompile(env, err, arg); + }; + NVal thisVar(env, funcArg.GetThisVar()); + + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(listfileProcedureName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(listfileProcedureName, cbExec, cbCompl).val_; + } +} + +napi_value DirNExporter::ListFileSync(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 dirEntity = CheckDirEntity(env, funcArg.GetThisVar()); + if (!dirEntity) { + return nullptr; + } + auto [succ, listNum] = ParseJsListNum(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid listNum"); + return nullptr; + } + + vector dirents; + { + lock_guard(dirEntity->lock_); + errno = 0; + dirent *res = nullptr; + int listCount = 0; + auto dir = dirEntity->dir_.get(); + do { + res = readdir(dir); + if (res == nullptr && errno) { + UniError(errno).ThrowErr(env); + return nullptr; + } else if (res == nullptr) { + break; + } else if (string(res->d_name) == "." || string(res->d_name) == "..") { + continue; + } else { + dirents.push_back(*res); + listCount++; + } + } while (listCount < listNum || listNum == 0); + } + return DoListFileVector2NV(env, dirents); +} + napi_value DirNExporter::Constructor(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -274,8 +429,10 @@ bool DirNExporter::Export() vector props = { NVal::DeclareNapiFunction("readSync", ReadSync), NVal::DeclareNapiFunction("closeSync", CloseSync), + NVal::DeclareNapiFunction("listfileSync", ListFileSync), NVal::DeclareNapiFunction("read", Read), NVal::DeclareNapiFunction("close", Close), + NVal::DeclareNapiFunction("listfile", ListFile), }; string className = GetClassName(); diff --git a/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.h b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.h index 156ef5578..a40ed03d2 100644 --- a/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.h +++ b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.h @@ -34,11 +34,14 @@ public: static napi_value CloseSync(napi_env env, napi_callback_info info); static napi_value ReadSync(napi_env env, napi_callback_info info); + static napi_value ListFileSync(napi_env env, napi_callback_info info); static napi_value Read(napi_env env, napi_callback_info info); static napi_value Close(napi_env env, napi_callback_info info); + static napi_value ListFile(napi_env env, napi_callback_info info); DirNExporter(napi_env env, napi_value exports); ~DirNExporter() override; }; +const std::string listfileProcedureName = "fileioDirListFile"; } // namespace ModuleFileIO } // namespace DistributedFS } // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.cpp index 9961eeb20..1e316221e 100644 --- a/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.cpp @@ -114,9 +114,7 @@ napi_value DirentNExporter::Constructor(napi_env env, napi_callback_info info) auto direntEntity = make_unique(); if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(direntEntity))) { - stringstream ss; - ss << "INNER BUG. Failed to wrap entity for obj dirent"; - UniError(EIO).ThrowErr(env, ss.str()); + UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj dirent"); return nullptr; } return funcArg.GetThisVar(); diff --git a/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_entity.h b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_entity.h new file mode 100644 index 000000000..2a7dceae9 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_entity.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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_FILEIO_CLASS_RANDOMACCESSFILE_RANDOMACCESSFILE_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_RANDOMACCESSFILE_RANDOMACCESSFILE_ENTITY_H + +#include + +#include "../../common/file_helper/fd_guard.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +struct RandomAccessFileEntity { + std::unique_ptr fd_ = { nullptr }; + size_t fpointer; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp new file mode 100644 index 000000000..44025ed32 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp @@ -0,0 +1,416 @@ +/* + * Copyright (c) 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 "randomaccessfile_n_exporter.h" + +#include +#include +#include +#include +#include +#include + +#include "../../common/log.h" +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/uni_error.h" +#include "../common_func.h" +#include "randomaccessfile_entity.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +static RandomAccessFileEntity *GetRAFEntity(napi_env env, napi_value raf_entity) +{ + auto rafEntity = NClass::GetEntityOf(env, raf_entity); + if (!rafEntity) { + UniError(EINVAL).ThrowErr(env, "Cannot get entity of RandomAccessFile"); + return nullptr; + } + if (!rafEntity->fd_) { + UniError(EINVAL).ThrowErr(env, "RandomAccessFile has been closed yet"); + return nullptr; + } + return rafEntity; +} + +static tuple ParseJsFP(napi_env env, napi_value FPFromJs) +{ + auto [succ, fp] = NVal(env, FPFromJs).ToInt32(); + return { succ, fp }; +} + +static tuple GetRAFReadArg(napi_env env, + napi_value ReadBuf, napi_value option) +{ + bool succ = false, hasPos = false; + void *buf = nullptr; + size_t len, pos, offset; + tie(succ, buf, len, hasPos, pos, offset) = CommonFunc::GetReadArg(env, ReadBuf, option); + if (!succ) { + return { false, nullptr, 0, false, 0, 0 }; + } + return { succ, buf, len, hasPos, pos, offset }; +} + +static tuple GetRAFWriteArg(napi_env env, + napi_value WriteBuf, napi_value option) +{ + bool succ = false, hasPos = false; + void *buf = nullptr; + size_t len, pos; + tie(succ, ignore, buf, len, hasPos, pos) = CommonFunc::GetWriteArg(env, WriteBuf, option); + if (!succ) { + return { false, nullptr, 0, false, 0 }; + } + return { succ, buf, len, hasPos, pos }; +} + +static size_t DoReadRAF(napi_env env, void* buf, size_t len, int fd, size_t pos) +{ + uv_loop_s *loop = nullptr; + uv_fs_t read_req; + napi_get_uv_event_loop(env, &loop); + uv_buf_t iov = uv_buf_init(static_cast(buf), len); + size_t ret = uv_fs_read(loop, &read_req, fd, &iov, 1, pos, NULL); + uv_fs_req_cleanup(&read_req); + return ret; +} + +static size_t DoWriteRAF(napi_env env, void* buf, size_t len, int fd, size_t pos) +{ + uv_loop_s *loop = nullptr; + uv_fs_t write_req; + napi_get_uv_event_loop(env, &loop); + uv_buf_t iov = uv_buf_init(static_cast(buf), len); + size_t ret = uv_fs_write(loop, &write_req, fd, &iov, 1, pos, NULL); + uv_fs_req_cleanup(&write_req); + return ret; +} + +napi_value RandomAccessFileNExporter::GetFD(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto rafEntity = GetRAFEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + return NVal::CreateInt32(env, rafEntity->fd_.get()->GetFD()).val_; +} + +napi_value RandomAccessFileNExporter::GetFPointer(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto rafEntity = GetRAFEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + return NVal::CreateInt64(env, rafEntity->fpointer).val_; +} + +napi_value RandomAccessFileNExporter::SetFilePointerSync(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 rafEntity = GetRAFEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + auto [succ, fp] = ParseJsFP(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid fpointer"); + } + rafEntity->fpointer = fp; + return NVal::CreateUndefined(env).val_; +} + +napi_value RandomAccessFileNExporter::ReadSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto rafEntity = GetRAFEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + auto [succ, buf, len, hasPos, pos, ignore] = + GetRAFReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid buffer/options"); + } + ssize_t actLen = DoReadRAF(env, buf, len, rafEntity->fd_.get()->GetFD(), rafEntity->fpointer + pos); + if (actLen < 0) { + UniError(errno).ThrowErr(env); + return nullptr; + } + rafEntity->fpointer += actLen; + return NVal::CreateInt64(env, actLen).val_; +} + +struct AsyncIOReadArg { + ssize_t lenRead { 0 }; + int offset { 0 }; + NRef refReadBuf; + + explicit AsyncIOReadArg(NVal jsReadBuf) : refReadBuf(jsReadBuf) {} + ~AsyncIOReadArg() = default; +}; + +napi_value RandomAccessFileNExporter::Read(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto rafEntity = GetRAFEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + bool succ = false, hasPos = false; + size_t len, pos, offset; + void* buf = nullptr; + tie(succ, buf, len, hasPos, pos, offset) = GetRAFReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid buffer/options"); + return nullptr; + } + + auto arg = make_shared(NVal(env, funcArg[NARG_POS::FIRST])); + auto cbExec = [arg, buf, len, hasPos, pos, offset, rafEntity](napi_env env) -> UniError { + ssize_t actLen = DoReadRAF(env, buf, len, rafEntity->fd_.get()->GetFD(), rafEntity->fpointer + pos); + if (actLen < 0) { + return UniError(errno); + } + arg->lenRead = actLen; + arg->offset = offset; + rafEntity->fpointer += actLen; + return UniError(ERRNO_NOERR); + }; + + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + NVal obj = NVal::CreateObject(env); + obj.AddProp( + { NVal::DeclareNapiProperty("bytesRead", NVal::CreateInt64(env, arg->lenRead).val_), + NVal::DeclareNapiProperty("buffer", arg->refReadBuf.Deref(env).val_), + NVal::DeclareNapiProperty("offset", NVal::CreateInt64(env, arg->offset).val_) + }); + return { obj }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && + !NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function))) { + return NAsyncWorkPromise(env, thisVar).Schedule(readProcedureName, cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::TWO) ? NARG_POS::SECOND : NARG_POS::THIRD); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(readProcedureName, cbExec, cbCompl).val_; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value RandomAccessFileNExporter::WriteSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rafEntity = GetRAFEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + + bool succ = false, hasPos = false; + void *buf = nullptr; + size_t len, pos; + tie(succ, buf, len, hasPos, pos) = GetRAFWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid buffer/options"); + return nullptr; + } + if (hasPos) { + pos = rafEntity->fpointer + pos; + } else { + pos = rafEntity->fpointer; + } + ssize_t writeLen = DoWriteRAF(env, buf, len, rafEntity->fd_.get()->GetFD(), pos); + if (writeLen < 0) { + UniError(errno).ThrowErr(env); + return nullptr; + } + rafEntity->fpointer += writeLen; + return NVal::CreateInt64(env, writeLen).val_; +} + +struct AsyncIOWriteArg { + NRef refWriteArrayBuf_; + size_t actLen = 0; + explicit AsyncIOWriteArg(NVal refWriteArrayBuf) : refWriteArrayBuf_(refWriteArrayBuf) {} + ~AsyncIOWriteArg() = default; +}; + +napi_value RandomAccessFileNExporter::Write(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rafEntity = GetRAFEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + bool succ = false, hasPos = false; + void *buf = nullptr; + size_t len, pos; + tie(succ, buf, len, hasPos, pos) = GetRAFWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid buffer/options"); + return nullptr; + } + if (hasPos) { + pos = rafEntity->fpointer + pos; + } else { + pos = rafEntity->fpointer; + } + + auto arg = make_shared(NVal(env, funcArg[NARG_POS::FIRST])); + auto cbExec = [arg, buf, len, fd = rafEntity->fd_.get()->GetFD(), pos, rafEntity](napi_env env) -> UniError { + size_t writeLen = DoWriteRAF(env, buf, len, fd, pos); + if (writeLen < 0) { + return UniError(errno); + } + arg->actLen = writeLen; + rafEntity->fpointer += writeLen; + return UniError(ERRNO_NOERR); + }; + + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return { NVal::CreateInt64(env, arg->actLen) }; + } + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && + !NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function))) { + return NAsyncWorkPromise(env, thisVar).Schedule(writeProcedureName, cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::TWO) ? NARG_POS::SECOND : NARG_POS::THIRD); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(writeProcedureName, cbExec, cbCompl).val_; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value RandomAccessFileNExporter::CloseSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto rafEntity = GetRAFEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + rafEntity->fd_.reset(); + return NVal::CreateUndefined(env).val_; +} + +napi_value RandomAccessFileNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rafEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(rafEntity))) { + UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj RandomAccessFile"); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool RandomAccessFileNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("read", Read), + NVal::DeclareNapiFunction("readSync", ReadSync), + NVal::DeclareNapiFunction("write", Write), + NVal::DeclareNapiFunction("writeSync", WriteSync), + NVal::DeclareNapiFunction("setFilePointerSync", SetFilePointerSync), + NVal::DeclareNapiFunction("closeSync", CloseSync), + NVal::DeclareNapiGetter("fd", GetFD), + NVal::DeclareNapiGetter("fpointer", GetFPointer), + }; + + string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + RandomAccessFileNExporter::Constructor, move(props)); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class"); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string RandomAccessFileNExporter::GetClassName() +{ + return RandomAccessFileNExporter::className_; +} + +RandomAccessFileNExporter::RandomAccessFileNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +RandomAccessFileNExporter::~RandomAccessFileNExporter() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.h b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.h new file mode 100644 index 000000000..bd89a1b9c --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 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_FILEIO_CLASS_RANDOMACCESSFILE_RANDOMACCESSFILE_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_RANDOMACCESSFILE_RANDOMACCESSFILE_N_EXPORTER_H + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class RandomAccessFileNExporter final : public NExporter { +public: + inline static const std::string className_ = "RandomAccessFile"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + + static napi_value SetFilePointerSync(napi_env env, napi_callback_info cbinfo); + static napi_value WriteSync(napi_env env, napi_callback_info cbinfo); + static napi_value ReadSync(napi_env env, napi_callback_info cbinfo); + static napi_value CloseSync(napi_env env, napi_callback_info cbinfo); + + static napi_value Write(napi_env env, napi_callback_info cbinfo); + static napi_value Read(napi_env env, napi_callback_info cbinfo); + + static napi_value GetFD(napi_env env, napi_callback_info cbinfo); + static napi_value GetFPointer(napi_env env, napi_callback_info cbinfo); + + RandomAccessFileNExporter(napi_env env, napi_value exports); + ~RandomAccessFileNExporter() override; +}; +const std::string readProcedureName = "FileIORandomAccessFileRead"; +const std::string writeProcedureName = "FileIORandomAccessFileWrite"; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.cpp index 85295fc4e..a414041eb 100644 --- a/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -305,9 +305,7 @@ napi_value StatNExporter::Constructor(napi_env env, napi_callback_info info) unique_ptr statEntity = make_unique(); if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(statEntity))) { - stringstream ss; - ss << "INNER BUG. Failed to wrap entity for obj stat"; - UniError(EIO).ThrowErr(env, ss.str()); + UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj stat"); return nullptr; } return funcArg.GetThisVar(); diff --git a/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.cpp index cdcbf78fe..f9d6960b8 100644 --- a/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -349,9 +349,7 @@ napi_value StreamNExporter::Constructor(napi_env env, napi_callback_info info) unique_ptr streamEntity = make_unique(); if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(streamEntity))) { - stringstream ss; - ss << "INNER BUG. Failed to wrap entity for obj stat"; - UniError(EIO).ThrowErr(env, ss.str()); + UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj stream"); return nullptr; } return funcArg.GetThisVar(); diff --git a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp index f6c456ed1..6e3b1381d 100644 --- a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp @@ -113,7 +113,7 @@ bool WatcherNExporter::Export() }; string className = GetClassName(); - auto [resDefineClass, classValue) = NClass::DefineClass(exports_.env_, + auto [resDefineClass, classValue] = NClass::DefineClass(exports_.env_, className, WatcherNExporter::Constructor, std::move(props)); diff --git a/interfaces/kits/js/src/mod_fileio/common_func.cpp b/interfaces/kits/js/src/mod_fileio/common_func.cpp index d8d8e8577..f7c70288e 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.cpp +++ b/interfaces/kits/js/src/mod_fileio/common_func.cpp @@ -82,6 +82,36 @@ static tuple GetActualLen(napi_env env, int64_t bufLen, int64_t bu return { true, retLen }; } +int CommonFunc::ConvertJsFlags(int &flags) +{ + static constexpr int USR_O_RDONLY = 00; + static constexpr int USR_O_WRONLY = 01; + static constexpr int USR_O_RDWR = 02; + static constexpr int USR_O_CREAT = 0100; + static constexpr int USR_O_EXCL = 0200; + static constexpr int USR_O_TRUNC = 01000; + static constexpr int USR_O_APPEND = 02000; + static constexpr int USR_O_NONBLOCK = 04000; + static constexpr int USR_O_DIRECTORY = 0200000; + static constexpr int USR_O_NOFOLLOW = 0400000; + static constexpr int USR_O_SYNC = 04010000; + + int flagsABI = 0; + flagsABI |= ((flags & USR_O_RDONLY) == USR_O_RDONLY) ? O_RDONLY : 0; + flagsABI |= ((flags & USR_O_WRONLY) == USR_O_WRONLY) ? O_WRONLY : 0; + flagsABI |= ((flags & USR_O_RDWR) == USR_O_RDWR) ? O_RDWR : 0; + flagsABI |= ((flags & USR_O_CREAT) == USR_O_CREAT) ? O_CREAT : 0; + flagsABI |= ((flags & USR_O_EXCL) == USR_O_EXCL) ? O_EXCL : 0; + flagsABI |= ((flags & USR_O_TRUNC) == USR_O_TRUNC) ? O_TRUNC : 0; + flagsABI |= ((flags & USR_O_APPEND) == USR_O_APPEND) ? O_APPEND : 0; + flagsABI |= ((flags & USR_O_NONBLOCK) == USR_O_NONBLOCK) ? O_NONBLOCK : 0; + flagsABI |= ((flags & USR_O_DIRECTORY) == USR_O_DIRECTORY) ? O_DIRECTORY : 0; + flagsABI |= ((flags & USR_O_NOFOLLOW) == USR_O_NOFOLLOW) ? O_NOFOLLOW : 0; + flagsABI |= ((flags & USR_O_SYNC) == USR_O_SYNC) ? O_SYNC : 0; + flags = flagsABI; + return flagsABI; +} + tuple, unique_ptr> CommonFunc::GetCopyPathArg(napi_env env, napi_value srcPath, napi_value dstPath) @@ -91,7 +121,7 @@ tuple, unique_ptr> CommonFunc::GetCopyPathArg(n return { false, nullptr, nullptr }; } - tie(res, dest, useless) = NVal(env, dstPath).ToUTF8String(); + auto [res, dest, useless] = NVal(env, dstPath).ToUTF8String(); if (!res) { return { false, nullptr, nullptr }; } @@ -149,7 +179,6 @@ static tuple, int64_t> DecodeString(napi_env env, NVal return jsStr.ToUTF8String(); } - unique_ptr encodingBuf; auto [resToUTF8String, encodingBuf, unuse] = encoding.ToUTF8String(); if (!resToUTF8String) { return { false, nullptr, 0 }; diff --git a/interfaces/kits/js/src/mod_fileio/common_func.h b/interfaces/kits/js/src/mod_fileio/common_func.h index f968bb40b..a8aff6739 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.h +++ b/interfaces/kits/js/src/mod_fileio/common_func.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -24,9 +24,10 @@ namespace ModuleFileIO { constexpr int64_t INVALID_POSITION = std::numeric_limits::max(); struct CommonFunc { + static int ConvertJsFlags(int &flags); static std::tuple GetReadArg(napi_env env, - napi_value readBuf, - napi_value option); + napi_value readBuf, + napi_value option); static std::tuple, void *, int64_t, bool, int64_t> GetWriteArg(napi_env env, napi_value argWBuf, napi_value argOption); diff --git a/interfaces/kits/js/src/mod_fileio/module.cpp b/interfaces/kits/js/src/mod_fileio/module.cpp index 51bd91fd0..b26592acb 100644 --- a/interfaces/kits/js/src/mod_fileio/module.cpp +++ b/interfaces/kits/js/src/mod_fileio/module.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -20,6 +20,7 @@ #include "class_constants/constants.h" #include "class_dir/dir_n_exporter.h" #include "class_dirent/dirent_n_exporter.h" +#include "class_randomaccessfile/randomaccessfile_n_exporter.h" #include "class_stat/stat_n_exporter.h" #include "class_stream/stream_n_exporter.h" #include "class_watcher/watcher_n_exporter.h" @@ -36,6 +37,7 @@ static napi_value Export(napi_env env, napi_value exports) products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); diff --git a/interfaces/kits/js/src/mod_fileio/properties/chmod.cpp b/interfaces/kits/js/src/mod_fileio/properties/chmod.cpp index 3bc5a6364..cf8b348de 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/chmod.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/chmod.cpp @@ -77,7 +77,7 @@ napi_value Chmod::Async(napi_env env, napi_callback_info info) } string path = tmp.get(); - auto cbExec = [path, mode](napi_env env) -> UniError { + auto cbExec = [path = path, mode = mode](napi_env env) -> UniError { if (chmod(path.c_str(), mode) == -1) { return UniError(errno); } else { diff --git a/interfaces/kits/js/src/mod_fileio/properties/chown.cpp b/interfaces/kits/js/src/mod_fileio/properties/chown.cpp index f6b4fff5a..12d0edd04 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/chown.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/chown.cpp @@ -48,7 +48,7 @@ static tuple GetChownArg(napi_env env, const NFuncArg &f return { false, "", -1, -1 }; } - return { succ, path.get(), owner, group }; + return { true, path.get(), owner, group }; } napi_value Chown::Sync(napi_env env, napi_callback_info info) @@ -85,7 +85,7 @@ napi_value Chown::Async(napi_env env, napi_callback_info info) return nullptr; } - auto cbExec = [path, owner, group](napi_env env) -> UniError { + auto cbExec = [path = path, owner = owner, group = group](napi_env env) -> UniError { if (chown(path.c_str(), owner, group) == -1) { return UniError(errno); } else { diff --git a/interfaces/kits/js/src/mod_fileio/properties/close.cpp b/interfaces/kits/js/src/mod_fileio/properties/close.cpp index 44a7cf391..202ad04bc 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/close.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/close.cpp @@ -63,7 +63,7 @@ napi_value Close::Async(napi_env env, napi_callback_info info) return nullptr; } - auto cbExec = [fd](napi_env env) -> UniError { + auto cbExec = [fd = fd](napi_env env) -> UniError { int ret = close(fd); if (ret == -1) { return UniError(errno); diff --git a/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.cpp b/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.cpp new file mode 100644 index 000000000..8fa4fbaa7 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) 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 "create_randomaccessfile.h" + +#include +#include +#include +#include +#include +#include + +#include "../../common/log.h" +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/uni_error.h" +#include "../common_func.h" + +#include "../class_randomaccessfile/randomaccessfile_entity.h" +#include "../class_randomaccessfile/randomaccessfile_n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +struct FileInfo { + bool isPath = false; + unique_ptr path; + FDGuard fdg; +}; + +static bool CheckFilePath(napi_env env, string path) +{ + if (access(path.c_str(), 0) == 0) { + struct stat fileStat; + int ret = stat(path.c_str(), &fileStat); + if (ret != 0) { + UniError(errno).ThrowErr(env, "Cannot stat filepath"); + return false; + } + if ((fileStat.st_mode & S_IFMT) != S_IFREG) { + UniError(EINVAL).ThrowErr(env, "Invalid filepath"); + return false; + } + } + return true; +} + +static tuple ParseJsFileAndFP(napi_env env, napi_value pathOrFdFromJsArg, napi_value FPFromJs) +{ + auto [succ, fp] = NVal(env, FPFromJs).ToInt32(); + if (succ) { + auto [isPath, path, ignore] = NVal(env, pathOrFdFromJsArg).ToUTF8String(); + if (isPath) { + if (CheckFilePath(env, string(path.get()))) { + return { true, FileInfo { true, move(path), {} }, fp }; + } + return { false, FileInfo { false, {}, {} }, -1 }; + } + auto [isFd, fd] = NVal(env, pathOrFdFromJsArg).ToInt32(); + if (isFd) { + if (fd < 0) { + UniError(EINVAL).ThrowErr(env, "Invalid fd"); + return { false, FileInfo { false, {}, {} }, -1 }; + } + return { true, FileInfo { false, {}, { fd, false } }, fp }; + } + UniError(EINVAL).ThrowErr(env, "The first argument requires filepath/fd"); + } + UniError(EINVAL).ThrowErr(env, "Invalid fp"); + return { false, FileInfo { false, {}, {} }, -1 }; +}; + +static tuple GetJsFlags(napi_env env, const NFuncArg &funcArg, FileInfo &fileInfo) +{ + int flags = O_RDONLY; + bool succ = false; + if (fileInfo.isPath) { + if (funcArg.GetArgc() >= NARG_CNT::THREE && !NVal(env, funcArg[NARG_POS::THIRD]).TypeIs(napi_function)) { + tie(succ, flags) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid flags"); + return { false, flags }; + } + (void)CommonFunc::ConvertJsFlags(flags); + } + } + return { true, flags }; +} + +static NVal InstantiateRandomAccessFile(napi_env env, int fd, size_t fp) +{ + napi_value objRAF = NClass::InstantiateClass(env, RandomAccessFileNExporter::className_, {}); + if (!objRAF) { + UniError(EIO).ThrowErr(env, "Cannot instantiate randomaccessfile"); + return NVal(); + } + + auto rafEntity = NClass::GetEntityOf(env, objRAF); + if (!rafEntity) { + UniError(EIO).ThrowErr(env, "Cannot instantiate randomaccessfile because of void entity"); + return NVal(); + } + auto fdg = make_unique(fd); + rafEntity->fd_.swap(fdg); + rafEntity->fpointer = fp; + return { env, objRAF }; +} + +napi_value CreateRandomAccessFile::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto [succ, fileInfo, fp] = ParseJsFileAndFP(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + return nullptr; + } + + if (fileInfo.isPath) { + auto [succFlags, flags] = GetJsFlags(env, funcArg, fileInfo); + if (!succFlags) { + return nullptr; + } + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(env, &loop); + uv_fs_t open_req; + int ret = uv_fs_open(loop, &open_req, fileInfo.path.get(), flags, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP, NULL); + if (ret < 0) { + UniError(errno).ThrowErr(env); + return nullptr; + } + fileInfo.fdg.SetFD(open_req.result, false); + uv_fs_req_cleanup(&open_req); + } + return InstantiateRandomAccessFile(env, fileInfo.fdg.GetFD(), fp).val_; +} + +struct AsyncCreateRandomAccessFileArg { + int fd; + size_t fp; +}; + +napi_value CreateRandomAccessFile::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::FOUR)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + auto [succ, fileInfo, fp] = ParseJsFileAndFP(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + return nullptr; + } + auto [succFlags, flags] = GetJsFlags(env, funcArg, fileInfo); + if (!succFlags) { + return nullptr; + } + auto arg = make_shared(); + auto cbExec = [arg, fileInfo = make_shared(move(fileInfo)), fp = fp, flags = + flags](napi_env env) -> UniError { + if (fileInfo->isPath) { + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(env, &loop); + uv_fs_t open_req; + int ret = uv_fs_open(loop, &open_req, fileInfo->path.get(), flags, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP, NULL); + if (ret < 0) { + return UniError(errno); + } + fileInfo->fdg.SetFD(open_req.result, false); + uv_fs_req_cleanup(&open_req); + } + arg->fd = fileInfo->fdg.GetFD(); + arg->fp = fp; + return UniError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return InstantiateRandomAccessFile(env, arg->fd, arg->fp); + }; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO || (funcArg.GetArgc() == NARG_CNT::THREE && + NVal(env, funcArg[NARG_POS::THIRD]).TypeIs(napi_number))) { + return NAsyncWorkPromise(env, thisVar).Schedule(createRAFProcedureName, cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::FOUR) ? NARG_POS::FOURTH : NARG_POS::THIRD); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(createRAFProcedureName, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.h b/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.h new file mode 100644 index 000000000..f4a9b36ba --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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_FILEIO_PROPERTIES_CREATE_RANDOMACCESSFILE_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_CREATE_RANDOMACCESSFILE_H + +#include "../../common/napi/uni_header.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class CreateRandomAccessFile final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; +const std::string createRAFProcedureName = "FileIOCreateRandomAccessFile"; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/create_stream.cpp b/interfaces/kits/js/src/mod_fileio/properties/create_stream.cpp index df19686d8..47c5ff44b 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/create_stream.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/create_stream.cpp @@ -59,7 +59,7 @@ static tuple GetCreateStreamArgs(napi_env env, const NFunc return { false, "", "" }; } - tie(resGetSecondArg, mode, useless) = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + auto [resGetSecondArg, mode, useless] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); if (!resGetSecondArg) { UniError(EINVAL).ThrowErr(env, "Invalid mode"); return { false, "", "" }; @@ -75,8 +75,7 @@ napi_value CreateStream::Sync(napi_env env, napi_callback_info info) UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; } - - auto [resGetCreateStreamArgs, argPath, argMode) = GetCreateStreamArgs(env, funcArg); + auto [resGetCreateStreamArgs, argPath, argMode] = GetCreateStreamArgs(env, funcArg); if (!resGetCreateStreamArgs) { return nullptr; } diff --git a/interfaces/kits/js/src/mod_fileio/properties/fchmod.cpp b/interfaces/kits/js/src/mod_fileio/properties/fchmod.cpp index fe2dcbcfb..c1aca5c12 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/fchmod.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/fchmod.cpp @@ -77,7 +77,7 @@ napi_value Fchmod::Async(napi_env env, napi_callback_info info) UniError(EINVAL).ThrowErr(env, "Invalid owner"); } - auto cbExec = [fd, mode](napi_env env) -> UniError { + auto cbExec = [fd = fd, mode = mode](napi_env env) -> UniError { int ret = fchmod(fd, mode); if (ret == -1) { return UniError(errno); diff --git a/interfaces/kits/js/src/mod_fileio/properties/fchown.cpp b/interfaces/kits/js/src/mod_fileio/properties/fchown.cpp index e2576eea7..1af80004f 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/fchown.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/fchown.cpp @@ -79,12 +79,12 @@ napi_value Fchown::Async(napi_env env, napi_callback_info info) UniError(EINVAL).ThrowErr(env, "Invalid owner"); } - auto (resGetThirdArg, group] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); + auto [resGetThirdArg, group] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); if (!resGetThirdArg) { UniError(EINVAL).ThrowErr(env, "Invalid group"); } - auto cbExec = [fd, owner, group](napi_env env) -> UniError { + auto cbExec = [fd = fd, owner = owner, group = group](napi_env env) -> UniError { int ret = fchown(fd, owner, group); if (ret == -1) { return UniError(errno); diff --git a/interfaces/kits/js/src/mod_fileio/properties/fdatasync.cpp b/interfaces/kits/js/src/mod_fileio/properties/fdatasync.cpp index 8c7c73912..6ed950980 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/fdatasync.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/fdatasync.cpp @@ -66,7 +66,7 @@ napi_value Fdatasync::Async(napi_env env, napi_callback_info info) return nullptr; } - auto cbExec = [fd](napi_env env) -> UniError { + auto cbExec = [fd = fd](napi_env env) -> UniError { int ret = fdatasync(fd); if (ret == -1) { return UniError(errno); diff --git a/interfaces/kits/js/src/mod_fileio/properties/fdopen_stream.cpp b/interfaces/kits/js/src/mod_fileio/properties/fdopen_stream.cpp index dddce67da..a76d6eb1f 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/fdopen_stream.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/fdopen_stream.cpp @@ -106,7 +106,7 @@ napi_value FdopenStream::Async(napi_env env, napi_callback_info info) } auto arg = make_shared(); - auto cbExec = [arg, fd, mode = move(mode)](napi_env env) -> UniError { + auto cbExec = [arg = arg, fd = fd, mode = move(mode)](napi_env env) -> UniError { arg->fp = { fdopen(fd, mode.c_str()), fclose }; if (!arg->fp) { return UniError(errno); @@ -115,7 +115,7 @@ napi_value FdopenStream::Async(napi_env env, napi_callback_info info) } }; - auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + auto cbCompl = [arg = arg](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } diff --git a/interfaces/kits/js/src/mod_fileio/properties/fstat.cpp b/interfaces/kits/js/src/mod_fileio/properties/fstat.cpp index 34e01a1b2..82525267f 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/fstat.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/fstat.cpp @@ -87,7 +87,7 @@ napi_value Fstat::Async(napi_env env, napi_callback_info info) } auto arg = make_shared(); - auto cbExec = [fd, arg](napi_env env) -> UniError { + auto cbExec = [fd = fd, arg = arg](napi_env env) -> UniError { if (fstat(fd, &arg->stat_)) { return UniError(errno); } else { @@ -95,7 +95,7 @@ napi_value Fstat::Async(napi_env env, napi_callback_info info) } }; - auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + auto cbCompl = [arg = arg](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } diff --git a/interfaces/kits/js/src/mod_fileio/properties/fsync.cpp b/interfaces/kits/js/src/mod_fileio/properties/fsync.cpp index aa25b2e6c..060d94f18 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/fsync.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/fsync.cpp @@ -64,7 +64,7 @@ napi_value Fsync::Async(napi_env env, napi_callback_info info) return nullptr; } - auto cbExec = [fd](napi_env env) -> UniError { + auto cbExec = [fd = fd](napi_env env) -> UniError { if (fsync(fd) == -1) { return UniError(errno); } else { diff --git a/interfaces/kits/js/src/mod_fileio/properties/ftruncate.cpp b/interfaces/kits/js/src/mod_fileio/properties/ftruncate.cpp index d325a8d0e..6b936eab7 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/ftruncate.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/ftruncate.cpp @@ -47,6 +47,7 @@ napi_value Ftruncate::Sync(napi_env env, napi_callback_info info) ret = ftruncate(fd, 0); } else { int len; + bool succ = false; tie(succ, len) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid len"); @@ -88,7 +89,7 @@ napi_value Ftruncate::Async(napi_env env, napi_callback_info info) len = length; } - auto cbExec = [fd, len](napi_env env) -> UniError { + auto cbExec = [fd = fd, len = len](napi_env env) -> UniError { int ret = ftruncate(fd, len); if (ret == -1) { return UniError(errno); diff --git a/interfaces/kits/js/src/mod_fileio/properties/open.cpp b/interfaces/kits/js/src/mod_fileio/properties/open.cpp index 1dfe4cbf4..3c50a7a68 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/open.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/open.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "remote_uri.h" #include "../../common/napi/n_async/n_async_work_callback.h" #include "../../common/napi/n_async/n_async_work_promise.h" @@ -81,6 +82,10 @@ napi_value Open::Sync(napi_env env, napi_callback_info info) (void)AdaptToAbi(flags); int fd = -1; + if (ModuleRemoteUri::RemoteUri::IsRemoteUri(path.get(), fd, flags)) { + return NVal::CreateInt64(env, fd).val_; + } + size_t argc = funcArg.GetArgc(); if (argc != NARG_CNT::THREE) { size_t flagsFirst { flags }; @@ -108,9 +113,12 @@ napi_value Open::Sync(napi_env env, napi_callback_info info) static UniError DoOpenExec(const std::string& path, const int flags, const int mode, shared_ptr arg) { - int ret = open(path.c_str(), flags, mode); - *arg = ret; - if (ret == -1) { + int fd = -1; + if (!ModuleRemoteUri::RemoteUri::IsRemoteUri(path, fd, flags)) { + fd = open(path.c_str(), flags, mode); + } + *arg = fd; + if (fd == -1) { return UniError(errno); } else { return UniError(ERRNO_NOERR); diff --git a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp index fc2b21be7..6ed6538e2 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp @@ -23,6 +23,7 @@ #include "chown.h" #include "close.h" #include "copy_file.h" +#include "create_randomaccessfile.h" #include "create_stream.h" #include "fchmod.h" #include "fchown.h" @@ -40,9 +41,11 @@ #include "open.h" #include "open_dir.h" #include "posix_fallocate.h" +#include "read_dir.h" #include "read_text.h" #include "rename.h" #include "rmdir.h" +#include "rmdirent.h" #include "stat.h" #include "symlink.h" #include "truncate.h" @@ -148,7 +151,7 @@ napi_value PropNExporter::Access(napi_env env, napi_callback_info info) return nullptr; } - auto cbExec = [path = move(path), mode](napi_env env) -> UniError { + auto cbExec = [path = move(path), mode = move(mode)](napi_env env) -> UniError { int ret = access(path.c_str(), mode); if (ret == -1) { return UniError(errno); @@ -191,7 +194,7 @@ napi_value PropNExporter::Unlink(napi_env env, napi_callback_info info) } string path = tmp.get(); - auto cbExec = [path](napi_env env) -> UniError { + auto cbExec = [path = move(path)](napi_env env) -> UniError { if (unlink(path.c_str()) == -1) { return UniError(errno); } else { @@ -245,7 +248,7 @@ napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) mode = modes; } - auto cbExec = [path, mode](napi_env env) -> UniError { + auto cbExec = [path = move(path), mode = move(mode)](napi_env env) -> UniError { if (mkdir(path.c_str(), mode) == -1) { return UniError(errno); } @@ -434,7 +437,8 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) } auto arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); - auto cbExec = [arg, buf, len, fd, hasPos, pos, offset](napi_env env) -> UniError { + auto cbExec = [ + arg = arg, buf = buf, len = len, fd = fd, hasPos = hasPos, pos = pos, offset = offset](napi_env env) -> UniError { ssize_t actLen; if (hasPos) { actLen = pread(fd, buf, len, pos); @@ -451,7 +455,7 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) } }; - auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + auto cbCompl = [arg = arg](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } @@ -514,7 +518,7 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) auto [resGetWriteArg, bufGuard, buf, len, hasPos, position] = CommonFunc::GetWriteArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!resGetWriteArgresGetWriteArg) { + if (!resGetWriteArg) { UniError(EINVAL).ThrowErr(env, "Failed GetWriteArg"); return nullptr; } @@ -526,11 +530,11 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); } - auto cbExec = [arg, buf, len, fd, position](napi_env env) -> UniError { + auto cbExec = [arg = arg, buf = buf, len = len, fd = fd, position = position](napi_env env) -> UniError { return WriteExec(arg, buf, len, fd, position); }; - auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + auto cbCompl = [arg = arg](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } @@ -626,6 +630,8 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("closeSync", Close::Sync), NVal::DeclareNapiFunction("copyFile", CopyFile::Async), NVal::DeclareNapiFunction("copyFileSync", CopyFile::Sync), + NVal::DeclareNapiFunction("createRandomAccessFile", CreateRandomAccessFile::Async), + NVal::DeclareNapiFunction("createRandomAccessFileSync", CreateRandomAccessFile::Sync), NVal::DeclareNapiFunction("createStream", CreateStream::Async), NVal::DeclareNapiFunction("createStreamSync", CreateStream::Sync), NVal::DeclareNapiFunction("createWatcher", Watcher::CreateWatcher), @@ -657,9 +663,11 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("mkdtemp", Mkdtemp::Async), NVal::DeclareNapiFunction("mkdtempSync", Mkdtemp::Sync), NVal::DeclareNapiFunction("open", Open::Async), + NVal::DeclareNapiFunction("openSync", Open::Sync), NVal::DeclareNapiFunction("opendir", OpenDir::Async), NVal::DeclareNapiFunction("opendirSync", OpenDir::Sync), - NVal::DeclareNapiFunction("openSync", Open::Sync), + NVal::DeclareNapiFunction("readdir", ReadDir::Async), + NVal::DeclareNapiFunction("readdirSync", ReadDir::Sync), NVal::DeclareNapiFunction("posixFallocate", PosixFallocate::Async), NVal::DeclareNapiFunction("posixFallocateSync", PosixFallocate::Sync), NVal::DeclareNapiFunction("read", Read), @@ -668,8 +676,8 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("readTextSync", ReadText::Sync), NVal::DeclareNapiFunction("rename", Rename::Async), NVal::DeclareNapiFunction("renameSync", Rename::Sync), - NVal::DeclareNapiFunction("rmdir", Rmdir::Async), - NVal::DeclareNapiFunction("rmdirSync", Rmdir::Sync), + NVal::DeclareNapiFunction("rmdir", Rmdirent::Async), + NVal::DeclareNapiFunction("rmdirSync", Rmdirent::Sync), NVal::DeclareNapiFunction("stat", Stat::Async), NVal::DeclareNapiFunction("statSync", Stat::Sync), NVal::DeclareNapiFunction("symlink", Symlink::Async), diff --git a/interfaces/kits/js/src/mod_fileio/properties/read_dir.cpp b/interfaces/kits/js/src/mod_fileio/properties/read_dir.cpp new file mode 100644 index 000000000..ef9f61533 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/read_dir.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 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 "read_dir.h" + +#include +#include +#include +#include + +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.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" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +static tuple> ParseJsPath(napi_env env, napi_value pathFromJs) +{ + auto [succ, path, ignore] = NVal(env, pathFromJs).ToUTF8String(); + return {succ, move(path)}; +} + +static bool VerifyFilePath(char* path) +{ + return strcmp(path, ".") != 0 && strcmp(path, "..") != 0; +} + +napi_value ReadDir::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + return nullptr; + } + auto [succ, path] = ParseJsPath(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid path"); + return nullptr; + } + unique_ptr> dir = { opendir(path.get()), closedir }; + if (!dir) { + UniError(errno).ThrowErr(env); + return nullptr; + } + vector dirFiles; + struct dirent* entry = readdir(dir.get()); + while (entry) { + if (VerifyFilePath(entry->d_name)) { + dirFiles.push_back(entry->d_name); + } + entry = readdir(dir.get()); + } + return NVal::CreateArrayString(env, dirFiles).val_; +} + +struct ReadDirArgs { + vector dirFiles; + explicit ReadDirArgs() + { + dirFiles = vector(); + } + ~ReadDirArgs() = default; +}; + +napi_value ReadDir::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + string path; + auto [succ, tmp] = ParseJsPath(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid path"); + return nullptr; + } + path = tmp.get(); + auto arg = make_shared(); + auto cbExec = [arg, path](napi_env env) -> UniError { + unique_ptr> dir = { opendir(path.c_str()), closedir }; + if (!dir) { + return UniError(errno); + } + struct dirent* entry = readdir(dir.get()); + vector dirnames; + while (entry) { + if (VerifyFilePath(entry->d_name)) { + dirnames.push_back(entry->d_name); + } + entry = readdir(dir.get()); + } + arg->dirFiles = dirnames; + return UniError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateArrayString(env, arg->dirFiles); + } + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(readdirProcedureName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(readdirProcedureName, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/read_dir.h b/interfaces/kits/js/src/mod_fileio/properties/read_dir.h new file mode 100644 index 000000000..e08fdcbfd --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/read_dir.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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_FILEIO_PROPERTIES_READ_DIR_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_READ_DIR_H + +#include "../../common/napi/uni_header.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class ReadDir final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; +const std::string readdirProcedureName = "fileIOReadDir"; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/rmdirent.cpp b/interfaces/kits/js/src/mod_fileio/properties/rmdirent.cpp new file mode 100644 index 000000000..66dd48e58 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/rmdirent.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 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 "rmdirent.h" + +#include +#include +#include +#include +#include +#include + +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.h" +#include "../../common/napi/n_func_arg.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +static tuple> ParseJsPath(napi_env env, napi_value pathFromJs) +{ + auto [succ, path, ignore] = NVal(env, pathFromJs).ToUTF8String(); + return {succ, move(path)}; +} + +static UniError rmdirent(napi_env env, string path) +{ + if (rmdir(path.c_str()) == 0) { + return UniError(ERRNO_NOERR); + } + auto dir = opendir(path.c_str()); + if (!dir) { + return UniError(errno); + } + struct dirent* entry = readdir(dir); + while (entry) { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { + entry = readdir(dir); + continue; + } + struct stat fileInformation; + string filePath = path + '/'; + filePath.insert(filePath.length(), entry->d_name); + if (stat(filePath.c_str(), &fileInformation) != 0) { + closedir(dir); + return UniError(errno); + } + if ((fileInformation.st_mode & S_IFMT) == S_IFDIR) { + auto err = rmdirent(env, filePath); + if (err) { + closedir(dir); + return err; + } + } else { + if (unlink(filePath.c_str()) != 0) { + closedir(dir); + return UniError(errno); + } + } + entry = readdir(dir); + } + closedir(dir); + if (rmdir(path.c_str()) != 0) { + return UniError(errno); + } + return UniError(ERRNO_NOERR); +} + +napi_value Rmdirent::Sync(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 [succ, path] = ParseJsPath(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid path"); + return nullptr; + } + + auto err = rmdirent(env, string(path.get())); + if (err) { + err.ThrowErr(env); + return nullptr; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value Rmdirent::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto [succ, path] = ParseJsPath(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid path"); + return nullptr; + } + + auto cbExec = [path = string(path.get())](napi_env env) -> UniError { + return rmdirent(env, path); + }; + auto cbCompl = [](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUndefined(env); + } + }; + + NVal thisVar(env, funcArg.GetThisVar()); + size_t argc = funcArg.GetArgc(); + if (argc == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(rmdirProcedureName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(rmdirProcedureName, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/rmdirent.h b/interfaces/kits/js/src/mod_fileio/properties/rmdirent.h new file mode 100644 index 000000000..b63e528d1 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/rmdirent.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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_FILEIO_PROPERTIES_RMDIRENT_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_RMDIRENT_H + +#include "../../common/napi/n_val.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class Rmdirent final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); + static napi_value Async(napi_env env, napi_callback_info info); +}; +const std::string rmdirProcedureName = "FileIORmDirent"; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/stat.cpp b/interfaces/kits/js/src/mod_fileio/properties/stat.cpp index 26cded63e..25a0fda81 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/stat.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/stat.cpp @@ -40,7 +40,7 @@ napi_value Stat::Sync(napi_env env, napi_callback_info info) return nullptr; } - aut [resGetFirstArg, pathPtr, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + auto [resGetFirstArg, pathPtr, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); if (!resGetFirstArg) { UniError(EINVAL).ThrowErr(env, "The first argument requires type string"); return nullptr; @@ -87,7 +87,7 @@ napi_value Stat::Async(napi_env env, napi_callback_info info) string path = tmp.get(); auto arg = make_shared(); - auto cbExec = [arg, path](napi_env env) -> UniError { + auto cbExec = [arg = arg, path = path](napi_env env) -> UniError { if (stat(path.c_str(), &arg->stat_)) { return UniError(errno); } else { @@ -95,7 +95,7 @@ napi_value Stat::Async(napi_env env, napi_callback_info info) } }; - auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + auto cbCompl = [arg = arg](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } diff --git a/interfaces/kits/js/src/mod_securitylabel/security_label.h b/interfaces/kits/js/src/mod_securitylabel/security_label.h index 77b4c50f1..5e47c8be9 100644 --- a/interfaces/kits/js/src/mod_securitylabel/security_label.h +++ b/interfaces/kits/js/src/mod_securitylabel/security_label.h @@ -25,11 +25,11 @@ namespace OHOS { namespace DistributedFS { namespace ModuleSecurityLabel { +const char XATTR_KEY[] = {"user.security"}; +const std::string DEFAULT_DATA_LEVEL = "s3"; +const std::set DATA_LEVEL = {"s0", "s1", "s2", "s3", "s4"}; class SecurityLabel { public: - static const char XATTR_KEY[] {"user.security"}; - static const std::string DEFAULT_DATA_LEVEL = "s3"; - static const std::set DATA_LEVEL = {"s0", "s1", "s2", "s3", "s4"}; static bool SetSecurityLabel(const std::string &path, const std::string &dataLevel) { if (DATA_LEVEL.count(dataLevel) != 1) { @@ -43,7 +43,7 @@ public: static std::string GetSecurityLabel(const std::string &path) { - auto xattrValueSize = getxattr(path.c_str(), XATTR_KEY, NULL, 0); + auto xattrValueSize = getxattr(path.c_str(), XATTR_KEY, nullptr, 0); if (xattrValueSize == -1 || errno == ENOTSUP) { return ""; } -- Gitee From 09ef2bbc7768f1069d6da7fbb68867781376b2f3 Mon Sep 17 00:00:00 2001 From: gaoshunli Date: Thu, 29 Sep 2022 11:33:04 +0800 Subject: [PATCH 2/2] Running XTS successfully Signed-off-by: gaoshunli --- .../napi/n_async/n_async_work_promise.cpp | 4 +- .../mod_file/class_file/file_n_exporter.cpp | 245 ++++-------------- .../mod_fileio/class_dir/dir_n_exporter.cpp | 13 +- .../randomaccessfile_entity.h | 4 +- .../randomaccessfile_n_exporter.cpp | 10 +- .../class_watcher/watcher_n_exporter.cpp | 6 +- .../kits/js/src/mod_fileio/common_func.cpp | 90 ++++--- .../kits/js/src/mod_fileio/common_func.h | 4 +- .../mod_fileio/properties/create_stream.cpp | 1 + .../mod_fileio/properties/fdopen_stream.cpp | 2 +- .../js/src/mod_fileio/properties/open.cpp | 78 +++--- .../mod_fileio/properties/prop_n_exporter.cpp | 182 ++++++++----- interfaces/kits/native/BUILD.gn | 43 +++ .../kits/native/remote_uri/remote_uri.cpp | 86 ++++++ .../kits/native/remote_uri/remote_uri.h | 42 +++ 15 files changed, 459 insertions(+), 351 deletions(-) create mode 100644 interfaces/kits/native/BUILD.gn create mode 100644 interfaces/kits/native/remote_uri/remote_uri.cpp create mode 100644 interfaces/kits/native/remote_uri/remote_uri.h diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp index cd4a7ed08..978096042 100644 --- a/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp @@ -45,12 +45,12 @@ static void PromiseOnComplete(napi_env env, napi_status status, void *data) } if (!ctx->res_.TypeIsError(true)) { - napi_status status = napi_resolve_deferred(env, ctx->deferred_, ctx->res_.val_); + status = napi_resolve_deferred(env, ctx->deferred_, ctx->res_.val_); if (status != napi_ok) { HILOGE("Internal BUG, cannot resolve promise for %{public}d", status); } } else { - napi_status status = napi_reject_deferred(env, ctx->deferred_, ctx->res_.val_); + status = napi_reject_deferred(env, ctx->deferred_, ctx->res_.val_); if (status != napi_ok) { HILOGE("Internal BUG, cannot reject promise for %{public}d", status); } 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 index 35c465e20..345365037 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * 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 @@ -32,7 +32,6 @@ #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" @@ -43,19 +42,17 @@ 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"; -} + +constexpr int SUCCESS = 0; +constexpr int FAILED = -1; +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 SPLITE_ZERO = 0; +const string TYPE_FILE = "file"; +const string TYPE_DIR = "dir"; +const string ENCODING_UTF8 = "utf-8"; void CallBackSuccess(napi_env env, napi_ref successFuncRef, int32_t count, napi_value obj) { @@ -72,7 +69,7 @@ void CallBackSuccess(napi_env env, napi_ref successFuncRef, int32_t count, napi_ void CallBackError(napi_env env, napi_ref failFuncRef, string errorProp, int errorCode) { - napi_value argvFail[PARAMS_NUMBER_TWO] = { 0 }; + napi_value argvFail[2] = { 0 }; napi_value results = nullptr; napi_value failFunc = nullptr; napi_value global = nullptr; @@ -99,54 +96,41 @@ void CallComplete(napi_env env, napi_ref completeFuncRef) napi_call_function(env, global, completeFunc, COMMON_NUM::ZERO, nullptr, &results); } -vector SplitString(const string &path) +bool CheckUri(napi_env env, string &path) { + constexpr int spilteOne = 1; + constexpr int spilteTwo = 2; + constexpr int spilteThree = 3; + string pathOrigin = path; vector uriSplit; + string pattern = "/"; if (path == "") { - HILOGE("Parameter path is empty"); - return uriSplit; + return false; } - - string pattern = "/"; - string pathTmp = path + pattern; + string pathTmp = pathOrigin + pattern; size_t pos = pathTmp.find(pattern); while (pos != pathTmp.npos) { - string temp = pathTmp.substr(SPLIT_ZERO, pos); + string temp = pathTmp.substr(SPLITE_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"); + if (uriSplit[SPLITE_ZERO] != "internal:" || uriSplit[spilteOne] != "" || uriSplit.size() <= spilteThree) { 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") { + if (abilityContext && uriSplit[spilteTwo] == "app") { path = abilityContext->GetFilesDir(); - } else if (abilityContext && uriSplit[splitTwo] == "cache") { + } else if (abilityContext && uriSplit[spilteTwo] == "cache") { path = abilityContext->GetCacheDir(); } else { - HILOGE("Failed to get URI path"); return false; } - for (size_t i = splitThree; i < uriSplit.size(); ++i) { + for (size_t i = spilteThree; i < uriSplit.size(); ++i) { path = path + "/" + uriSplit[i]; } return true; @@ -165,7 +149,17 @@ int GetRealPath(string &path) string UriToAbsolute(string path) { stack uriResult; - vector uriSplit = SplitString(path); + vector uriSplit; + string pattern = "/"; + + string pathTmp = path + pattern; + size_t pos = pathTmp.find(pattern); + while (pos != pathTmp.npos) { + string temp = pathTmp.substr(SPLITE_ZERO, pos); + uriSplit.push_back(temp); + pathTmp = pathTmp.substr(pos + 1, pathTmp.size()); + pos = pathTmp.find(pattern); + } for (auto urisp : uriSplit) { if (urisp == "." || urisp == "") { continue; @@ -183,12 +177,11 @@ string UriToAbsolute(string path) return path; } -bool GetFileNames(const string &path, vector &filenames, bool rec, bool isList) +bool GetFileNames(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) { @@ -213,14 +206,12 @@ bool Mkdirs(string path) 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; @@ -231,7 +222,6 @@ 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) { @@ -246,7 +236,6 @@ bool Rmdirs(string path) } closedir(pDir); if (rmdir(path.c_str()) != 0) { - HILOGE("delete a directory %{public}s failed", path.c_str()); return false; } return true; @@ -254,10 +243,6 @@ bool Rmdirs(string path) 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); @@ -266,7 +251,6 @@ string ConvertUri(string path, string originPath, string originUri) } else { return "error"; } - return path; } @@ -280,7 +264,7 @@ void MkdirExec(napi_env env, void *data) path = UriToAbsolute(path); if (asyncCallbackInfo->recursive && Mkdirs(path)) { asyncCallbackInfo->result = SUCCESS; - } else if (mkdir(const_cast(path.c_str()), DIR_FAULT_PERM) != FAILED) { + } else if (mkdir((char *)path.c_str(), DIR_FAULT_PERM) != FAILED) { asyncCallbackInfo->result = SUCCESS; } } @@ -313,7 +297,7 @@ void RmdirExec(napi_env env, void *data) if (statPath == COMMON_NUM::ZERO) { if (asyncCallbackInfo->recursive && Rmdirs(path)) { asyncCallbackInfo->result = SUCCESS; - } else if (remove(const_cast(path.c_str())) != FAILED) { + } else if (remove((char *)path.c_str()) != FAILED) { asyncCallbackInfo->result = SUCCESS; } } else if (statPath == ENOENT) { @@ -347,7 +331,7 @@ void GetExec(napi_env env, void *data) asyncCallbackInfo->errorType = FILE_IO_ERROR; struct stat buf; int statPath = GetRealPath(path); - if (statPath == COMMON_NUM::ZERO && stat(const_cast(path.c_str()), &buf) == COMMON_NUM::ZERO) { + 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); @@ -413,7 +397,7 @@ void ListExec(napi_env env, void *data) int statPath = GetRealPath(path); if (statPath == ENOENT) { asyncCallbackInfo->errorType = FILE_PATH_ERROR; - } else if (statPath != COMMON_NUM::ZERO || stat(const_cast(path.c_str()), &buf) != COMMON_NUM::ZERO) { + } 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; @@ -487,14 +471,14 @@ int FileCopy(const string& srcPath, const string& dstPath) if (GetRealPath(src) == 0) { if (GetRealPath(dest) == ENOENT) { FDGuard sfd; - sfd.SetFD(open(const_cast(src.c_str()), O_RDONLY)); + sfd.SetFD(open((char *)src.c_str(), O_RDONLY)); struct stat attrSrc; - if (stat(const_cast(src.c_str()), &attrSrc) == FAILED) { + if (stat((char *)src.c_str(), &attrSrc) == FAILED) { return FILE_IO_ERROR; } dest = UriToAbsolute(dest); FDGuard ofd; - ofd.SetFD(open(const_cast(dest.c_str()), O_WRONLY | O_CREAT, attrSrc.st_mode)); + 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; } @@ -502,7 +486,7 @@ int FileCopy(const string& srcPath, const string& dstPath) if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, attrSrc.st_size) != FAILED) { ret = SUCCESS; } else { - remove(const_cast(dest.c_str())); + remove((char *)dest.c_str()); } } else if (GetRealPath(dest) == 0) { return (dest == src) ? SUCCESS : FILE_IO_ERROR; @@ -520,7 +504,7 @@ int DirCopy(const string& srcPath, const string& dstPath) } if (GetRealPath(dest) == ENOENT) { struct stat attrSrc; - if (stat(const_cast(src.c_str()), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { + if (stat((char *)src.c_str(), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { return FILE_IO_ERROR; } dest = UriToAbsolute(dest); @@ -546,7 +530,7 @@ void CopyExec(napi_env env, void *data) } struct stat statbf; - if (stat(const_cast(path.c_str()), &statbf) == FAILED) { + if (stat((char *)path.c_str(), &statbf) == FAILED) { asyncCallbackInfo->errorType = FILE_IO_ERROR; return; } @@ -604,7 +588,7 @@ int DirMove(const string& srcPath, const string& dstPath) } struct stat attrSrc; - if (stat(const_cast(src.c_str()), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { + if (stat((char *)src.c_str(), &attrSrc) == FAILED || !S_ISDIR(attrSrc.st_mode)) { return FILE_IO_ERROR; } dest = UriToAbsolute(dest); @@ -655,7 +639,7 @@ void MoveExec(napi_env env, void *data) } struct stat statbf; - if (stat(const_cast(path.c_str()), &statbf) == FAILED) { + if (stat((char *)path.c_str(), &statbf) == FAILED) { asyncCallbackInfo->errorType = FILE_IO_ERROR; return; } @@ -664,7 +648,7 @@ void MoveExec(napi_env env, void *data) int retval = FileCopy(path, pathDst); if (retval == SUCCESS) { asyncCallbackInfo->result = SUCCESS; - remove(const_cast(path.c_str())); + remove((char *)path.c_str()); } else { asyncCallbackInfo->errorType = retval; } @@ -705,7 +689,7 @@ void DeleteExec(napi_env env, void *data) int statPath = GetRealPath(path); if (statPath == ENOENT) { asyncCallbackInfo->errorType = FILE_PATH_ERROR; - } else if (statPath == COMMON_NUM::ZERO && remove(const_cast(path.c_str())) != FAILED) { + } else if (statPath == COMMON_NUM::ZERO && remove((char *)path.c_str()) != FAILED) { asyncCallbackInfo->result = SUCCESS; } else { asyncCallbackInfo->errorType = FILE_IO_ERROR; @@ -859,7 +843,7 @@ void ReadTextExec(napi_env env, void *data) FDGuard fdg; fdg.SetFD(open(path.c_str(), O_RDONLY)); struct stat buf; - int result = stat(const_cast(path.c_str()), &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) { @@ -907,7 +891,7 @@ void ReadArrayBufferExec(napi_env env, void *data) FDGuard fdg; fdg.SetFD(open(path.c_str(), O_RDONLY)); struct stat buf; - int result = stat(const_cast(path.c_str()), &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 = @@ -969,21 +953,12 @@ napi_value FileNExporter::Mkdir(napi_env env, napi_callback_info info) }; 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)) { @@ -1015,21 +990,12 @@ napi_value FileNExporter::Rmdir(napi_env env, napi_callback_info info) }; 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)) { @@ -1062,22 +1028,11 @@ napi_value FileNExporter::Get(napi_env env, napi_callback_info info) 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)) { @@ -1110,15 +1065,9 @@ napi_value FileNExporter::List(napi_env env, napi_callback_info info) 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; @@ -1151,21 +1100,10 @@ napi_value FileNExporter::Copy(napi_env env, napi_callback_info info) }; 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; @@ -1198,20 +1136,10 @@ napi_value FileNExporter::Move(napi_env env, napi_callback_info info) }; 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())); @@ -1245,15 +1173,9 @@ napi_value FileNExporter::Delete(napi_env env, napi_callback_info info) }; 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)) { @@ -1285,15 +1207,9 @@ napi_value FileNExporter::Access(napi_env env, napi_callback_info info) }; 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)) { @@ -1324,31 +1240,14 @@ napi_value FileNExporter::WriteText(napi_env env, napi_callback_info info) 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(); @@ -1390,27 +1289,15 @@ napi_value FileNExporter::WriteArrayBuffer(napi_env env, napi_callback_info info }; 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; @@ -1454,20 +1341,10 @@ napi_value FileNExporter::ReadText(napi_env env, napi_callback_info info) }; 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(); @@ -1506,27 +1383,15 @@ napi_value FileNExporter::ReadArrayBuffer(napi_env env, napi_callback_info info) 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)) { @@ -1575,4 +1440,4 @@ FileNExporter::FileNExporter(napi_env env, napi_value exports) FileNExporter::~FileNExporter() {} } // namespace ModuleFile } // namespace DistributedFS -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp index eb3b4574d..43bae0a64 100644 --- a/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp @@ -73,7 +73,7 @@ napi_value DirNExporter::Close(napi_env env, napi_callback_info info) } auto dirEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (dirEntity == nullptr) { + if (!dirEntity) { UniError(EIO).ThrowErr(env, "Cannot get entity of Dir"); return nullptr; } @@ -104,10 +104,10 @@ napi_value DirNExporter::Close(napi_env env, napi_callback_info info) static const string procedureName = "fileioDirClose"; if (funcArg.GetArgc() == NARG_CNT::ZERO) { return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; } - - NVal cb(env, funcArg[NARG_POS::FIRST]); - return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; } struct DirReadArgs { @@ -137,7 +137,7 @@ static NVal DoReadComplete(napi_env env, UniError err, shared_ptr a } if (strlen(arg->dirRes.d_name) == 0) { - return { env, nullptr }; + return { env, NVal::CreateUndefined(env).val_ }; } else { direntEntity->dirent_ = arg->dirRes; return { env, objDirent }; @@ -165,9 +165,6 @@ napi_value DirNExporter::Read(napi_env env, napi_callback_info info) } DIR *dir = dirEntity->dir_.get(); - if (dir == nullptr) { - return nullptr; - } auto arg = make_shared(NVal(env, funcArg.GetThisVar())); auto cbExec = [arg, dir, dirEntity](napi_env env) -> UniError { struct dirent tmpDirent; diff --git a/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_entity.h b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_entity.h index 2a7dceae9..2081bffab 100644 --- a/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_entity.h +++ b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_entity.h @@ -24,8 +24,8 @@ namespace OHOS { namespace DistributedFS { namespace ModuleFileIO { struct RandomAccessFileEntity { - std::unique_ptr fd_ = { nullptr }; - size_t fpointer; + std::unique_ptr fd_; + size_t fpointer = 0; }; } // namespace ModuleFileIO } // namespace DistributedFS diff --git a/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp index 44025ed32..f3f513c05 100644 --- a/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp @@ -43,7 +43,7 @@ static RandomAccessFileEntity *GetRAFEntity(napi_env env, napi_value raf_entity) UniError(EINVAL).ThrowErr(env, "Cannot get entity of RandomAccessFile"); return nullptr; } - if (!rafEntity->fd_) { + if (rafEntity->fd_ == 0) { UniError(EINVAL).ThrowErr(env, "RandomAccessFile has been closed yet"); return nullptr; } @@ -66,7 +66,7 @@ static tuple GetRAFReadArg(napi_env e if (!succ) { return { false, nullptr, 0, false, 0, 0 }; } - return { succ, buf, len, hasPos, pos, offset }; + return { true, buf, len, hasPos, pos, offset }; } static tuple GetRAFWriteArg(napi_env env, @@ -79,7 +79,7 @@ static tuple GetRAFWriteArg(napi_env env, if (!succ) { return { false, nullptr, 0, false, 0 }; } - return { succ, buf, len, hasPos, pos }; + return { true, buf, len, hasPos, pos }; } static size_t DoReadRAF(napi_env env, void* buf, size_t len, int fd, size_t pos) @@ -146,6 +146,7 @@ napi_value RandomAccessFileNExporter::SetFilePointerSync(napi_env env, napi_call auto [succ, fp] = ParseJsFP(env, funcArg[NARG_POS::FIRST]); if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid fpointer"); + return nullptr; } rafEntity->fpointer = fp; return NVal::CreateUndefined(env).val_; @@ -166,6 +167,7 @@ napi_value RandomAccessFileNExporter::ReadSync(napi_env env, napi_callback_info GetRAFReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid buffer/options"); + return nullptr; } ssize_t actLen = DoReadRAF(env, buf, len, rafEntity->fd_.get()->GetFD(), rafEntity->fpointer + pos); if (actLen < 0) { @@ -239,7 +241,6 @@ napi_value RandomAccessFileNExporter::Read(napi_env env, napi_callback_info info NVal cb(env, funcArg[cbIdx]); return NAsyncWorkCallback(env, thisVar, cb).Schedule(readProcedureName, cbExec, cbCompl).val_; } - return NVal::CreateUndefined(env).val_; } napi_value RandomAccessFileNExporter::WriteSync(napi_env env, napi_callback_info info) @@ -338,7 +339,6 @@ napi_value RandomAccessFileNExporter::Write(napi_env env, napi_callback_info inf NVal cb(env, funcArg[cbIdx]); return NAsyncWorkCallback(env, thisVar, cb).Schedule(writeProcedureName, cbExec, cbCompl).val_; } - return NVal::CreateUndefined(env).val_; } napi_value RandomAccessFileNExporter::CloseSync(napi_env env, napi_callback_info info) diff --git a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp index 6e3b1381d..2947b10cb 100644 --- a/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_watcher/watcher_n_exporter.cpp @@ -114,9 +114,9 @@ bool WatcherNExporter::Export() string className = GetClassName(); auto [resDefineClass, classValue] = NClass::DefineClass(exports_.env_, - className, - WatcherNExporter::Constructor, - std::move(props)); + className, + WatcherNExporter::Constructor, + std::move(props)); if (!resDefineClass) { UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class"); return false; diff --git a/interfaces/kits/js/src/mod_fileio/common_func.cpp b/interfaces/kits/js/src/mod_fileio/common_func.cpp index f7c70288e..b54748f12 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.cpp +++ b/interfaces/kits/js/src/mod_fileio/common_func.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * 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 @@ -59,6 +59,7 @@ static tuple GetActualLen(napi_env env, int64_t bufLen, int64_t bu { bool succ = false; int64_t retLen; + if (op.HasProp("length")) { int64_t opLength; tie(succ, opLength) = op.GetProp("length").ToInt64(); @@ -66,17 +67,16 @@ static tuple GetActualLen(napi_env env, int64_t bufLen, int64_t bu UniError(EINVAL).ThrowErr(env, "Invalid option.length, expect integer"); return { false, 0 }; } - if (opLength < 0) { - retLen = (bufLen > bufOff) ? bufLen - bufOff : 0; - } else if ((bufLen > opLength) && (bufOff > bufLen - opLength)) { + retLen = bufLen - bufOff; + } else if (opLength + bufOff > bufLen) { UniError(EINVAL).ThrowErr(env, "Invalid option.length, buffer limit exceeded"); return { false, 0 }; } else { retLen = opLength; } } else { - retLen = (bufLen > bufOff) ? bufLen - bufOff : 0; + retLen = bufLen - bufOff; } return { true, retLen }; @@ -113,16 +113,19 @@ int CommonFunc::ConvertJsFlags(int &flags) } tuple, unique_ptr> CommonFunc::GetCopyPathArg(napi_env env, - napi_value srcPath, - napi_value dstPath) + napi_value srcPath, + napi_value dstPath) { - auto [succ, src, unuse] = NVal(env, srcPath).ToUTF8String(); + bool succ = false; + unique_ptr src; + tie(succ, src, ignore) = NVal(env, srcPath).ToUTF8String(); if (!succ) { return { false, nullptr, nullptr }; } - auto [res, dest, useless] = NVal(env, dstPath).ToUTF8String(); - if (!res) { + unique_ptr dest; + tie(succ, dest, ignore) = NVal(env, dstPath).ToUTF8String(); + if (!succ) { return { false, nullptr, nullptr }; } @@ -133,35 +136,41 @@ tuple CommonFunc::GetReadArg(napi_env napi_value readBuf, napi_value option) { + bool succ = false; + void *retBuf = nullptr; + int64_t retLen = 0; bool posAssigned = false; int64_t position = 0; + NVal txt(env, readBuf); - auto [resToArraybuffer, buf, bufLen] = txt.ToArraybuffer(); - if (!resToArraybuffer) { + void *buf = nullptr; + int64_t bufLen = 0; + int offset = 0; + tie(succ, buf, bufLen) = txt.ToArraybuffer(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid read buffer, expect arraybuffer"); - return { false, nullptr, 0, posAssigned, position, 0 }; + return { false, nullptr, 0, posAssigned, position, offset }; } NVal op = NVal(env, option); - auto [resGetActualBuf, retBuf, offset] = GetActualBuf(env, buf, bufLen, op); - if (!resGetActualBuf) { - return { false, nullptr, 0, posAssigned, position, 0 }; + tie(succ, retBuf, offset) = GetActualBuf(env, buf, bufLen, op); + if (!succ) { + return { false, nullptr, 0, posAssigned, position, offset }; } int64_t bufOff = static_cast(retBuf) - static_cast(buf); - auto [resGetActualLen, retLen] = GetActualLen(env, bufLen, bufOff, op); - if (!resGetActualLen) { - return { false, nullptr, 0, posAssigned, position, 0 }; + tie(succ, retLen) = GetActualLen(env, bufLen, bufOff, op); + if (!succ) { + return { false, nullptr, 0, posAssigned, position, offset }; } if (op.HasProp("position")) { - auto [resGetProp, pos] = op.GetProp("position").ToInt64(); - if (resGetProp && pos >= 0) { + tie(succ, position) = op.GetProp("position").ToInt64(); + if (succ && position >= 0) { posAssigned = true; - position = pos; } else { UniError(EINVAL).ThrowErr(env, "option.position shall be positive number"); - return { false, nullptr, 0, posAssigned, position, 0 }; + return { false, nullptr, 0, posAssigned, position, offset }; } } @@ -175,15 +184,16 @@ static tuple, int64_t> DecodeString(napi_env env, NVal return { false, nullptr, 0 }; } + bool succ = false; if (!encoding) { return jsStr.ToUTF8String(); } - auto [resToUTF8String, encodingBuf, unuse] = encoding.ToUTF8String(); - if (!resToUTF8String) { + unique_ptr encodingBuf; + tie(succ, encodingBuf, ignore) = encoding.ToUTF8String(); + if (!succ) { return { false, nullptr, 0 }; } - string encodingStr(encodingBuf.release()); if (encodingStr == "utf-8") { return jsStr.ToUTF8String(); @@ -198,38 +208,44 @@ tuple, void *, int64_t, bool, int64_t> CommonFunc::GetW napi_value argWBuf, napi_value argOption) { + void *retBuf = nullptr; + int64_t retLen = 0; bool hasPos = false; int64_t retPos = 0; + bool succ = false; void *buf = nullptr; + int64_t bufLen = 0; NVal op(env, argOption); NVal jsBuffer(env, argWBuf); - auto [resDecodeString, bufferGuard, bufLen] = DecodeString(env, jsBuffer, op.GetProp("encoding")); - if (!resDecodeString) { + unique_ptr bufferGuard; + tie(succ, bufferGuard, bufLen) = DecodeString(env, jsBuffer, op.GetProp("encoding")); + if (!succ) { tie(succ, buf, bufLen) = NVal(env, argWBuf).ToArraybuffer(); if (!succ) { UniError(EINVAL).ThrowErr(env, "Illegal write buffer or encoding"); - return { false, nullptr, nullptr, 0, false, 0 }; + return { false, nullptr, nullptr, 0, hasPos, retPos }; } } else { buf = bufferGuard.get(); } - auto [resGetActualBuf, retBuf, unused] = GetActualBuf(env, buf, bufLen, op); - if (!resGetActualBuf) { - return { false, nullptr, nullptr, 0, false, 0 }; + tie(succ, retBuf, ignore) = GetActualBuf(env, buf, bufLen, op); + if (!succ) { + return { false, nullptr, nullptr, 0, hasPos, retPos }; } int64_t bufOff = static_cast(retBuf) - static_cast(buf); - auto [resGetActualLen, retLen] = GetActualLen(env, bufLen, bufOff, op); - if (!resGetActualLen) { - return { false, nullptr, nullptr, 0, false, 0 }; + tie(succ, retLen) = GetActualLen(env, bufLen, bufOff, op); + if (!succ) { + return { false, nullptr, nullptr, 0, hasPos, retPos }; } /* To parse options - Where to begin writing */ if (op.HasProp("position")) { - auto [resGetProp, position] = op.GetProp("position").ToInt32(); - if (!resGetProp || position < 0) { + int32_t position = 0; + tie(succ, position) = op.GetProp("position").ToInt32(); + if (!succ || position < 0) { UniError(EINVAL).ThrowErr(env, "option.position shall be positive number"); return { false, nullptr, nullptr, 0, hasPos, retPos }; } diff --git a/interfaces/kits/js/src/mod_fileio/common_func.h b/interfaces/kits/js/src/mod_fileio/common_func.h index a8aff6739..337826536 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.h +++ b/interfaces/kits/js/src/mod_fileio/common_func.h @@ -26,8 +26,8 @@ constexpr int64_t INVALID_POSITION = std::numeric_limits GetReadArg(napi_env env, - napi_value readBuf, - napi_value option); + napi_value readBuf, + napi_value option); static std::tuple, void *, int64_t, bool, int64_t> GetWriteArg(napi_env env, napi_value argWBuf, napi_value argOption); diff --git a/interfaces/kits/js/src/mod_fileio/properties/create_stream.cpp b/interfaces/kits/js/src/mod_fileio/properties/create_stream.cpp index 47c5ff44b..316884c55 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/create_stream.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/create_stream.cpp @@ -75,6 +75,7 @@ napi_value CreateStream::Sync(napi_env env, napi_callback_info info) UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; } + auto [resGetCreateStreamArgs, argPath, argMode] = GetCreateStreamArgs(env, funcArg); if (!resGetCreateStreamArgs) { return nullptr; diff --git a/interfaces/kits/js/src/mod_fileio/properties/fdopen_stream.cpp b/interfaces/kits/js/src/mod_fileio/properties/fdopen_stream.cpp index a76d6eb1f..f10adee6a 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/fdopen_stream.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/fdopen_stream.cpp @@ -106,7 +106,7 @@ napi_value FdopenStream::Async(napi_env env, napi_callback_info info) } auto arg = make_shared(); - auto cbExec = [arg = arg, fd = fd, mode = move(mode)](napi_env env) -> UniError { + auto cbExec = [arg = arg, fd = fd, mode = mode](napi_env env) -> UniError { arg->fp = { fdopen(fd, mode.c_str()), fclose }; if (!arg->fp) { return UniError(errno); diff --git a/interfaces/kits/js/src/mod_fileio/properties/open.cpp b/interfaces/kits/js/src/mod_fileio/properties/open.cpp index 3c50a7a68..a024642b2 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/open.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/open.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * 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 @@ -23,6 +23,7 @@ #include "../../common/napi/n_async/n_async_work_callback.h" #include "../../common/napi/n_async/n_async_work_promise.h" #include "../../common/napi/n_func_arg.h" + namespace OHOS { namespace DistributedFS { namespace ModuleFileIO { @@ -42,18 +43,20 @@ int AdaptToAbi(int &flags) static constexpr int USR_O_NOFOLLOW = 0400000; static constexpr int USR_O_SYNC = 04010000; - flags |= ((flags & USR_O_RDONLY) == USR_O_RDONLY) ? O_RDONLY : 0; - flags |= ((flags & USR_O_WRONLY) == USR_O_WRONLY) ? O_WRONLY : 0; - flags |= ((flags & USR_O_RDWR) == USR_O_RDWR) ? O_RDWR : 0; - flags |= ((flags & USR_O_CREAT) == USR_O_CREAT) ? O_CREAT : 0; - flags |= ((flags & USR_O_EXCL) == USR_O_EXCL) ? O_EXCL : 0; - flags |= ((flags & USR_O_TRUNC) == USR_O_TRUNC) ? O_TRUNC : 0; - flags |= ((flags & USR_O_APPEND) == USR_O_APPEND) ? O_APPEND : 0; - flags |= ((flags & USR_O_NONBLOCK) == USR_O_NONBLOCK) ? O_NONBLOCK : 0; - flags |= ((flags & USR_O_DIRECTORY) == USR_O_DIRECTORY) ? O_DIRECTORY : 0; - flags |= ((flags & USR_O_NOFOLLOW) == USR_O_NOFOLLOW) ? O_NOFOLLOW : 0; - flags |= ((flags & USR_O_SYNC) == USR_O_SYNC) ? O_SYNC : 0; - return flags; + int flagsABI = 0; + flagsABI |= ((flags & USR_O_RDONLY) == USR_O_RDONLY) ? O_RDONLY : 0; + flagsABI |= ((flags & USR_O_WRONLY) == USR_O_WRONLY) ? O_WRONLY : 0; + flagsABI |= ((flags & USR_O_RDWR) == USR_O_RDWR) ? O_RDWR : 0; + flagsABI |= ((flags & USR_O_CREAT) == USR_O_CREAT) ? O_CREAT : 0; + flagsABI |= ((flags & USR_O_EXCL) == USR_O_EXCL) ? O_EXCL : 0; + flagsABI |= ((flags & USR_O_TRUNC) == USR_O_TRUNC) ? O_TRUNC : 0; + flagsABI |= ((flags & USR_O_APPEND) == USR_O_APPEND) ? O_APPEND : 0; + flagsABI |= ((flags & USR_O_NONBLOCK) == USR_O_NONBLOCK) ? O_NONBLOCK : 0; + flagsABI |= ((flags & USR_O_DIRECTORY) == USR_O_DIRECTORY) ? O_DIRECTORY : 0; + flagsABI |= ((flags & USR_O_NOFOLLOW) == USR_O_NOFOLLOW) ? O_NOFOLLOW : 0; + flagsABI |= ((flags & USR_O_SYNC) == USR_O_SYNC) ? O_SYNC : 0; + flags = flagsABI; + return flagsABI; } napi_value Open::Sync(napi_env env, napi_callback_info info) @@ -64,22 +67,22 @@ napi_value Open::Sync(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!resGetFirstArg) { + bool succ = false; + unique_ptr path; + tie(succ, path, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid path"); return nullptr; } int flags = O_RDONLY; if (funcArg.GetArgc() >= NARG_CNT::TWO) { - auto [resGetSecondArg, flg] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); - if (!resGetSecondArg) { + tie(succ, flags) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid flags"); return nullptr; } - flags = flg; } - (void)AdaptToAbi(flags); int fd = -1; if (ModuleRemoteUri::RemoteUri::IsRemoteUri(path.get(), fd, flags)) { @@ -95,8 +98,9 @@ napi_value Open::Sync(napi_env env, napi_callback_info info) } fd = open(path.get(), flags); } else { - auto [resGetThirdArg, mode] = NVal(env, funcArg.GetArg(NARG_POS::THIRD)).ToInt32(); - if (!resGetThirdArg) { + int mode; + tie(succ, mode) = NVal(env, funcArg.GetArg(NARG_POS::THIRD)).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid mode"); return nullptr; } @@ -104,6 +108,10 @@ napi_value Open::Sync(napi_env env, napi_callback_info info) } if (fd == -1) { + if (errno == ENAMETOOLONG) { + UniError(errno).ThrowErr(env, "Filename too long"); + return nullptr; + } UniError(errno).ThrowErr(env); return nullptr; } @@ -133,42 +141,43 @@ napi_value Open::Async(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!resGetFirstArg) { + auto [succ, path, unuse] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid path"); return nullptr; } int flags = O_RDONLY; - size_t argc = funcArg.GetArgc(); - if (argc >= NARG_CNT::TWO && !NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function)) { - auto [resGetSecondArg, flg] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); - if (!resGetSecondArg) { + if (funcArg.GetArgc() >= NARG_CNT::TWO && !NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function)) { + tie(succ, flags) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid flags"); return nullptr; } - flags = flg; + (void)AdaptToAbi(flags); } int mode = 0; + size_t argc = funcArg.GetArgc(); if (argc == NARG_CNT::FOUR || (argc == NARG_CNT::THREE && NVal(env, funcArg[NARG_POS::THIRD]).TypeIs(napi_number))) { - auto [resGetThirdArg, modes] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); - if (!resGetThirdArg) { + tie(succ, mode) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid mode"); return nullptr; } - mode = modes; } - (void)AdaptToAbi(flags); auto arg = make_shared(); - auto cbExec = [path = string(path.get()), flags = flags, mode = mode, arg](napi_env env) -> UniError { + auto cbExec = [path = string(path.get()), flags, mode, arg](napi_env env) -> UniError { return DoOpenExec(path, flags, mode, arg); }; auto cbComplCallback = [arg](napi_env env, UniError err) -> NVal { if (err) { + if (err.GetErrno(ERR_CODE_SYSTEM_POSIX) == ENAMETOOLONG) { + return {env, err.GetNapiErr(env, "Filename too long")}; + } return { env, err.GetNapiErr(env) }; } return { NVal::CreateInt64(env, *arg) }; @@ -179,8 +188,7 @@ napi_value Open::Async(napi_env env, napi_callback_info info) (argc == NARG_CNT::THREE && (NVal(env, funcArg[NARG_POS::THIRD]).TypeIs(napi_number)))) { return NAsyncWorkPromise(env, thisVar).Schedule("FileIOOpen", cbExec, cbComplCallback).val_; } else { - size_t cbIdx = argc - 1; - NVal cb(env, funcArg[cbIdx]); + NVal cb(env, funcArg[argc - 1]); return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIOOpen", cbExec, cbComplCallback).val_; } } diff --git a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp index 6ed6538e2..0a08765bf 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp @@ -15,7 +15,10 @@ #include "prop_n_exporter.h" +#include +#include #include +#include #include #include "../common_func.h" @@ -66,8 +69,10 @@ napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!resGetFirstArg) { + bool succ = false; + unique_ptr path; + tie(succ, path, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid path"); return nullptr; } @@ -77,8 +82,9 @@ napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) if (argc == NARG_CNT::ONE) { ret = access(path.get(), 0); } else { - auto [resGetSecondArg, mode] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); - if (!resGetSecondArg) { + int mode; + tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid mode"); return nullptr; } @@ -95,8 +101,10 @@ napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) static tuple GetAccessArgs(napi_env env, const NFuncArg &funcArg) { - auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!resGetFirstArg) { + bool succ = false; + unique_ptr path; + tie(succ, path, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid path"); return { false, nullptr, 0, false }; } @@ -122,12 +130,11 @@ static tuple GetAccessArgs(napi_env env, const NFuncArg int mode = 0; if (hasMode) { - auto [resGetSecondArg, modes] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); - if (!resGetSecondArg) { + tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid mode"); return { false, nullptr, 0, false }; } - mode = modes; } return { true, path.get(), mode, promise }; @@ -145,13 +152,17 @@ napi_value PropNExporter::Access(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetAccessArgs, path, mode, promise] = GetAccessArgs(env, funcArg); - if (!resGetAccessArgs) { + string path; + bool succ = false; + bool promise = false; + int mode; + tie(succ, path, mode, promise) = GetAccessArgs(env, funcArg); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid path"); return nullptr; } - auto cbExec = [path = move(path), mode = move(mode)](napi_env env) -> UniError { + auto cbExec = [path = move(path), mode](napi_env env) -> UniError { int ret = access(path.c_str(), mode); if (ret == -1) { return UniError(errno); @@ -187,14 +198,17 @@ napi_value PropNExporter::Unlink(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, tmp, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!resGetFirstArg) { + string path; + unique_ptr tmp; + bool succ = false; + tie(succ, tmp, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "invalid path"); return nullptr; } + path = tmp.get(); - string path = tmp.get(); - auto cbExec = [path = move(path)](napi_env env) -> UniError { + auto cbExec = [path](napi_env env) -> UniError { if (unlink(path.c_str()) == -1) { return UniError(errno); } else { @@ -217,8 +231,6 @@ napi_value PropNExporter::Unlink(napi_env env, napi_callback_info info) NVal cb(env, funcArg[NARG_POS::SECOND]); return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; } - - return NVal::CreateUndefined(env).val_; } napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) @@ -229,26 +241,26 @@ napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, tmp, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!resGetFirstArg) { + string path; + unique_ptr tmp; + bool succ = false; + tie(succ, tmp, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid path"); return nullptr; } - - string path = tmp.get(); + path = tmp.get(); int mode = 0775; size_t argc = funcArg.GetArgc(); if ((argc == NARG_CNT::TWO && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) || argc == NARG_CNT::THREE) { - auto [resGetSecondArg, modes] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); - if (!resGetSecondArg) { + tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid mode"); return nullptr; } - mode = modes; } - - auto cbExec = [path = move(path), mode = move(mode)](napi_env env) -> UniError { + auto cbExec = [path, mode](napi_env env) -> UniError { if (mkdir(path.c_str(), mode) == -1) { return UniError(errno); } @@ -281,8 +293,10 @@ napi_value PropNExporter::MkdirSync(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!resGetFirstArg) { + bool succ = false; + unique_ptr path; + tie(succ, path, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid path"); return nullptr; } @@ -292,8 +306,9 @@ napi_value PropNExporter::MkdirSync(napi_env env, napi_callback_info info) if (argc == NARG_CNT::ONE) { ret = mkdir(path.get(), MODE_RUO_RWX); } else { - auto [resGetSecondArg, mode] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); - if (!resGetSecondArg) { + int mode; + tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid mode"); return nullptr; } @@ -317,14 +332,17 @@ napi_value PropNExporter::FchmodSync(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); - if (!resGetFirstArg) { + bool succ = false; + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid fd"); return nullptr; } - auto [resGetSecondArg, mode] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); - if (!resGetSecondArg) { + int mode; + tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid mode"); return nullptr; } @@ -346,19 +364,24 @@ napi_value PropNExporter::FchownSync(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); - if (!resGetFirstArg) { + bool succ = false; + + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid fd"); return nullptr; } - auto [resGetSecondArg, owner] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); - if (!resGetSecondArg) { + int owner; + tie(succ, owner) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid owner"); } - auto [resGetThirdArg, group] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); - if (!resGetThirdArg) { + int group; + tie(succ, group) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid group"); } @@ -379,15 +402,22 @@ napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); - if (!resGetFirstArg) { + bool succ = false; + + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid fd"); return nullptr; } - auto [resGetReadArg, buf, len, hasPos, pos, unused] = + void *buf = nullptr; + int64_t len; + bool hasPos = false; + int64_t pos; + tie(succ, buf, len, hasPos, pos, ignore) = CommonFunc::GetReadArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!resGetReadArg) { + if (!succ) { return nullptr; } @@ -423,29 +453,34 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); - if (!resGetFirstArg) { + bool succ = false; + void *buf = nullptr; + int64_t len; + int fd; + bool hasPos = false; + int64_t pos; + int offset; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid fd"); return nullptr; } - auto [resGetReadArg, buf, len, hasPos, pos, offset] = + tie(succ, buf, len, hasPos, pos, offset) = CommonFunc::GetReadArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!resGetReadArg) { + if (!succ) { UniError(EINVAL).ThrowErr(env, "Failed GetReadArg"); return nullptr; } auto arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); - auto cbExec = [ - arg = arg, buf = buf, len = len, fd = fd, hasPos = hasPos, pos = pos, offset = offset](napi_env env) -> UniError { + auto cbExec = [arg, buf, len, fd, hasPos, pos, offset](napi_env env) -> UniError { ssize_t actLen; if (hasPos) { actLen = pread(fd, buf, len, pos); } else { actLen = read(fd, buf, len); } - if (actLen == -1) { return UniError(errno); } else { @@ -455,7 +490,7 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) } }; - auto cbCompl = [arg = arg](napi_env env, UniError err) -> NVal { + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } @@ -510,15 +545,22 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); - if (!resGetFirstArg) { + bool succ = false; + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid fd"); return nullptr; } - auto [resGetWriteArg, bufGuard, buf, len, hasPos, position] = + unique_ptr bufGuard; + void *buf = nullptr; + size_t len; + size_t position; + bool hasPos = false; + tie(succ, bufGuard, buf, len, hasPos, position) = CommonFunc::GetWriteArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!resGetWriteArg) { + if (!succ) { UniError(EINVAL).ThrowErr(env, "Failed GetWriteArg"); return nullptr; } @@ -529,12 +571,11 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) } else { arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); } - - auto cbExec = [arg = arg, buf = buf, len = len, fd = fd, position = position](napi_env env) -> UniError { + auto cbExec = [arg, buf, len, fd, position](napi_env env) -> UniError { return WriteExec(arg, buf, len, fd, position); }; - auto cbCompl = [arg = arg](napi_env env, UniError err) -> NVal { + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } @@ -568,8 +609,10 @@ napi_value PropNExporter::UnlinkSync(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!resGetFirstArg) { + bool succ = false; + unique_ptr path; + tie(succ, path, ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid path"); return nullptr; } @@ -590,15 +633,22 @@ napi_value PropNExporter::WriteSync(napi_env env, napi_callback_info info) return nullptr; } - auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); - if (!resGetFirstArg) { + bool succ = false; + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid fd"); return nullptr; } - auto [resGetWriteArg, bufGuard, buf, len, hasPos, position] = + void *buf = nullptr; + size_t len; + size_t position; + unique_ptr bufGuard; + bool hasPos = false; + tie(succ, bufGuard, buf, len, hasPos, position) = CommonFunc::GetWriteArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!resGetWriteArg) { + if (!succ) { return nullptr; } diff --git a/interfaces/kits/native/BUILD.gn b/interfaces/kits/native/BUILD.gn new file mode 100644 index 000000000..b700811c7 --- /dev/null +++ b/interfaces/kits/native/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 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. + +import("//build/ohos.gni") + +config("remote_uri_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "//utils/system/safwk/native/include", + "//commonlibrary/c_utils/base/include", + "//foundation/filemanagement/file_api/interfaces/kits/native/remote_uri", + ] +} + +ohos_shared_library("remote_uri_native") { + sources = [ "//foundation/filemanagement/file_api/interfaces/kits/native/remote_uri/remote_uri.cpp" ] + + public_configs = [ ":remote_uri_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "c_utils:utils", + "ipc:ipc_core", + ] + + part_name = "file_api" + subsystem_name = "filemanagement" +} + +group("build_kits_native") { + deps = [ ":remote_uri_native" ] +} diff --git a/interfaces/kits/native/remote_uri/remote_uri.cpp b/interfaces/kits/native/remote_uri/remote_uri.cpp new file mode 100644 index 000000000..1c53d491c --- /dev/null +++ b/interfaces/kits/native/remote_uri/remote_uri.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 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 "remote_uri.h" +#include +#include +#include +#include +#include "accesstoken_kit.h" +#include "ipc_skeleton.h" +#include "hap_token_info.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleRemoteUri { + +using namespace std; + +static string GetCallingPkgName() +{ + uint32_t pid = IPCSkeleton::GetCallingTokenID(); + Security::AccessToken::HapTokenInfo tokenInfo = Security::AccessToken::HapTokenInfo(); + Security::AccessToken::AccessTokenKit::GetHapTokenInfo(pid, tokenInfo); + return tokenInfo.bundleName; +} + +bool RemoteUri::IsRemoteUri(const string& path, int &fd, const int& flags) +{ + string::size_type posDatashare = path.find(SCHEME_TAG); + string::size_type posFragment = path.find(FRAGMENT_TAG); + string::size_type posFd = path.find(FD_TAG); + if (posDatashare == string::npos || posFragment == string::npos || + posFd == string::npos) { + return false; + } + + string scheme = path.substr(0, posDatashare); + if (scheme != SCHEME) { + return false; + } + + string fragment = path.substr(posFragment + 1, REMOTE_URI_TAG.size()); + if (fragment == REMOTE_URI_TAG) { + string fdStr = path.substr(posFd + 1); + fd = atoi(fdStr.c_str()); + if (fd < 0 || flags != O_RDONLY) { + fd = -1; + } + return true; + } + return false; +} + +int RemoteUri::ConvertUri(const int &fd, string &remoteUri) +{ + if (fd < 0) { + return EINVAL; + } + string pkgName = GetCallingPkgName(); + remoteUri = SCHEME + ":///" + pkgName + "/" + FRAGMENT_TAG + + REMOTE_URI_TAG + FD_TAG + to_string(fd); + return 0; +} + +int RemoteUri::OpenRemoteUri(const string &remoteUri) +{ + int fd = -1; + (void)IsRemoteUri(remoteUri, fd); + + return fd; +} +} // namespace ModuleRemoteUri +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/native/remote_uri/remote_uri.h b/interfaces/kits/native/remote_uri/remote_uri.h new file mode 100644 index 000000000..af2377c9b --- /dev/null +++ b/interfaces/kits/native/remote_uri/remote_uri.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 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 REMOTE_URI_H +#define REMOTE_URI_H + +#include +#include + +namespace OHOS { +namespace DistributedFS { +namespace ModuleRemoteUri { +const std::string FRAGMENT_TAG = "#"; +const std::string FD_TAG = "="; +const std::string REMOTE_URI_TAG = "fdFromBinder"; +const std::string SCHEME_TAG = ":"; +const std::string SCHEME = "datashare"; +class RemoteUri { +public: + RemoteUri() {} + static bool IsRemoteUri(const std::string& path, int &fd, const int& flags = O_RDONLY); + static int ConvertUri(const int &fd, std::string &remoteUri); + static int OpenRemoteUri(const std::string &remoteUri); + ~RemoteUri() {} +}; +} // namespace ModuleRemoteUri +} // namespace DistributedFS +} // namespace OHOS + +#endif \ No newline at end of file -- Gitee