diff --git a/bundle.json b/bundle.json index ab34a9cc7fdb1b02661b94bb8d5d8f859dd15062..8d2e75611380e1e9fabf8851c6fb4857ef9d4ff0 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 039aa4ed611572e20e9e0e5bdd7ba56437096a5f..5dfea39befa94dc3c84586eff0ff45fc49cbb47b 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 9325a4b00b0ab8dbb0f63fecd32700f0976555cb..36e610de8d6b3457a20683d60ed8f5d6ebefdf93 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 0000000000000000000000000000000000000000..694b6f0d20f78718753955e42f1e80c5b942dfbd --- /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 48eb794a145f22d6c76a30a57268eb52b69023df..57ba9edcd5d5f79ff961ab96094a75d76c124977 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_async/n_async_work_promise.cpp b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp index cd4a7ed082f4c166b28b5e3d576351989aea8bfe..978096042049ff119f58a94e75f6ac166c2ddb8a 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/common/napi/n_val.cpp b/interfaces/kits/js/src/common/napi/n_val.cpp index d5bfbf42f27c6de61dd4f473f82dc69cdd3d51e9..93d99676add750f90cec3b0abb05090fa990d71c 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 9d46fca4a1b95ed769f01984c15f232ae8f0de24..ae6da67958f57441391d382c96eb48cee3ab4367 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 fb7493c8268a38f669e8eaaf6d3542f41813b822..68db46d2498fb2900d41bc0644fad6ca27386235 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 9633bbbbe2cce80cf33f7414b5e63881e83db69d..345365037b35e7d5068d9a74c9836de3c9e92107 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; } @@ -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_constants/constants.cpp b/interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp index 162b4360af56b52cdf63ae16c8f2037355b934c2..f046d8e849d58b86c07cab27d068a227cbb98b86 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 bbc53799dfb739ced5c8eebdd098e598562dcd0c..43bae0a641fe559f119748a490977681cc3a716a 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; @@ -253,6 +250,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 +426,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 156ef5578fbd96560b99346b509a74611f986555..a40ed03d2b542f5ef501fdd4cd3c922bae2d2e2f 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 9961eeb209046d866445faac578c622f2fda9284..1e316221e6d8c15637328887382ebb4d623e0370 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 0000000000000000000000000000000000000000..2081bffab3e3c07005c4a3077eb973c818c40c5a --- /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_; + size_t fpointer = 0; +}; +} // 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 0000000000000000000000000000000000000000..f3f513c05eda5982855310a4ca753f9537e9cbb3 --- /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_ == 0) { + 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 { true, 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 { true, 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"); + return nullptr; + } + 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"); + return nullptr; + } + 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_; + } +} + +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_; + } +} + +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 0000000000000000000000000000000000000000..bd89a1b9c9d581bbff8a1bae84f1d481b5753e23 --- /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 85295fc4ea279fbec7ee13dabc76c3c984b1fde1..a414041eb18d21554c18b07ede59b17c14841736 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 cdcbf78feb2096f1ee0b9e8a2a2a73e2ca8d2742..f9d6960b858f73d554ce6bfcd907950f535b1172 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 f6c456ed1a23f58e07cb35190fe20a7eb63e007d..2947b10cb50e5d108cb3d81e27eb5ee9e53f8274 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,10 +113,10 @@ bool WatcherNExporter::Export() }; string className = GetClassName(); - auto [resDefineClass, classValue) = NClass::DefineClass(exports_.env_, - className, - WatcherNExporter::Constructor, - std::move(props)); + auto [resDefineClass, classValue] = NClass::DefineClass(exports_.env_, + 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 d8d8e857708f67597853021d73f28d3d0f1740b8..b54748f122373b989e8e90fb46978572aa275f6e 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,33 +67,65 @@ 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 }; } +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) + 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 }; } - tie(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 }; } @@ -103,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 }; } } @@ -145,16 +184,16 @@ static tuple, int64_t> DecodeString(napi_env env, NVal return { false, nullptr, 0 }; } + bool succ = false; if (!encoding) { return jsStr.ToUTF8String(); } unique_ptr encodingBuf; - auto [resToUTF8String, encodingBuf, unuse] = encoding.ToUTF8String(); - if (!resToUTF8String) { + tie(succ, encodingBuf, ignore) = encoding.ToUTF8String(); + if (!succ) { return { false, nullptr, 0 }; } - string encodingStr(encodingBuf.release()); if (encodingStr == "utf-8") { return jsStr.ToUTF8String(); @@ -169,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 f968bb40bc22cbcfbf4eaf5660b41e63ece5d70b..337826536d5244b74bb98cd90915b019d52bae0e 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,6 +24,7 @@ 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); diff --git a/interfaces/kits/js/src/mod_fileio/module.cpp b/interfaces/kits/js/src/mod_fileio/module.cpp index 51bd91fd03f73edb66e6f11f8baf9335e6633b5f..b26592acb850f6dab3a0cae722cf4d1e66adcd5d 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 3bc5a6364f2b7c4c977d71c1ff7a8f1dac429b0b..cf8b348de8db2f164fefbd5b0c81c5193fe13814 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 f6b4fff5afffb2e2d1f246cb80a44d374af01fe4..12d0edd046d0a4b3b0bf65dd3199633c9c12b5f1 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 44a7cf3915d5d57ce81d3580f2c25d8375d684b5..202ad04bc0780ab1eda99d2bc6aa314667b7fe3f 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 0000000000000000000000000000000000000000..8fa4fbaa701aac4a32025e37c8c3b72dd89abcbc --- /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 0000000000000000000000000000000000000000..f4a9b36bad948ea71a3070f7da973396fa6ff6b7 --- /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 df19686d80e9e159948c5efdfc13863a1741cd53..316884c55765a382b618e7911bfb22ff22a1e40f 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, "", "" }; @@ -76,7 +76,7 @@ napi_value CreateStream::Sync(napi_env env, napi_callback_info info) 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 fe2dcbcfba5083dfc743b667c013264b544316a1..c1aca5c124ec2676ddcbf6a66c58c5be681f1237 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 e2576eea74ea2bf043adf718cac6688db2325f99..1af80004f68ac1910f1e50c86094fec26f389fe6 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 8c7c739120e6d36351913a494756a59b99c0b359..6ed9509800b4ee1e8b7fb3a6983ac2db63a090a1 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 dddce67daf690b23481358a86bf908e899a06901..f10adee6a31d8c86aa89d790f28e490781a9539d 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 = 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 34e01a1b2602486e1d1f8afb14b5268a5ddb52c3..82525267f3a36c2449f98135077750d270c1dc1c 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 aa25b2e6ce550e098ae88a38096755ec4da94b6e..060d94f18c73b4c2e01eb5db1c4c5a564513e5a8 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 d325a8d0edd23408066993daec7fd6d14a3a576b..6b936eab7dd3b070f70d4bc253b2592ea37861f9 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 1dfe4cbf4264e4463c80afe714ac7e71abf1f754..a024642b246d9c6bdeee872c8cc55bd34e289188 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 @@ -18,10 +18,12 @@ #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" #include "../../common/napi/n_func_arg.h" + namespace OHOS { namespace DistributedFS { namespace ModuleFileIO { @@ -41,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) @@ -63,24 +67,28 @@ 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)) { + return NVal::CreateInt64(env, fd).val_; + } + size_t argc = funcArg.GetArgc(); if (argc != NARG_CNT::THREE) { size_t flagsFirst { flags }; @@ -90,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; } @@ -99,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; } @@ -108,9 +121,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); @@ -125,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) }; @@ -171,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 fc2b21be78148527d5fe6e6f5b84bdec76cc3898..0a08765bf6b29bca255cacad6a01c93404689831 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" @@ -23,6 +26,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 +44,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" @@ -63,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; } @@ -74,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; } @@ -92,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 }; } @@ -119,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 }; @@ -142,8 +152,12 @@ 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; } @@ -184,13 +198,16 @@ 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](napi_env env) -> UniError { if (unlink(path.c_str()) == -1) { return UniError(errno); @@ -214,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) @@ -226,25 +241,25 @@ 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, mode](napi_env env) -> UniError { if (mkdir(path.c_str(), mode) == -1) { return UniError(errno); @@ -278,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; } @@ -289,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; } @@ -314,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; } @@ -343,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"); } @@ -376,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; } @@ -420,15 +453,22 @@ 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; } @@ -441,7 +481,6 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) } else { actLen = read(fd, buf, len); } - if (actLen == -1) { return UniError(errno); } else { @@ -506,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 (!resGetWriteArgresGetWriteArg) { + if (!succ) { UniError(EINVAL).ThrowErr(env, "Failed GetWriteArg"); return nullptr; } @@ -525,7 +571,6 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) } else { arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); } - auto cbExec = [arg, buf, len, fd, position](napi_env env) -> UniError { return WriteExec(arg, buf, len, fd, position); }; @@ -564,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; } @@ -586,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; } @@ -626,6 +680,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 +713,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 +726,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 0000000000000000000000000000000000000000..ef9f615335535f868a6b94f54e2aae47c0179852 --- /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 0000000000000000000000000000000000000000..e08fdcbfddbdb82b8117879ec2eb5ef6cd56c828 --- /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 0000000000000000000000000000000000000000..66dd48e58ad5565925a3944aaa72fb9b1144adea --- /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 0000000000000000000000000000000000000000..b63e528d1cf3ddff2a0323910d1848ec48589cea --- /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 26cded63e7f0b65f08f5930b4974c8f16958c88d..25a0fda8183dc4b1b8afcb48ddac7d63099eea96 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 77b4c50f16f5c390cd62a2d45e1e68120f59211d..5e47c8be9845b45d9b01733a065ce69532a38137 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 ""; } diff --git a/interfaces/kits/native/BUILD.gn b/interfaces/kits/native/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b700811c7cfa55a02193c7390d128ae2e9eddd00 --- /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 0000000000000000000000000000000000000000..1c53d491c8bdd86bd2b28eb4a74cdcbbf1aeb8f6 --- /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 0000000000000000000000000000000000000000..af2377c9b947d4903f21c3d38fa190cdd4f15a2c --- /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