From a3438cd477cfe0372f02b0dda315a265f14d3b4c Mon Sep 17 00:00:00 2001 From: leimingqiang Date: Wed, 11 Jan 2023 22:54:02 +0800 Subject: [PATCH] sync master Signed-off-by: futurezhou --- file_api.gni | 3 + interfaces/kits/js/BUILD.gn | 82 +++-- .../napi/n_async/n_async_work_callback.cpp | 3 +- .../mod_fileio/class_dir/dir_n_exporter.cpp | 1 + .../class_dirent/dirent_n_exporter.cpp | 44 +-- .../kits/js/src/mod_fileio/common_func.h | 1 - .../properties/create_randomaccessfile.cpp | 16 +- .../js/src/mod_fs/class_file/file_entity.h | 35 ++ .../src/mod_fs/class_file/file_n_exporter.cpp | 119 +++++++ .../src/mod_fs/class_file/file_n_exporter.h | 40 +++ .../js/src/mod_fs/class_stat/stat_entity.h | 26 ++ .../src/mod_fs/class_stat/stat_n_exporter.cpp | 296 +++++++++++++++++ .../src/mod_fs/class_stat/stat_n_exporter.h | 55 ++++ interfaces/kits/js/src/mod_fs/common_func.cpp | 259 +++++++++++++++ interfaces/kits/js/src/mod_fs/common_func.h | 61 ++++ interfaces/kits/js/src/mod_fs/module.cpp | 53 ++++ .../js/src/mod_fs/properties/fdatasync.cpp | 103 ++++++ .../kits/js/src/mod_fs/properties/fdatasync.h | 28 ++ .../kits/js/src/mod_fs/properties/fsync.cpp | 100 ++++++ .../kits/js/src/mod_fs/properties/fsync.h | 28 ++ .../kits/js/src/mod_fs/properties/lstat.cpp | 126 ++++++++ .../kits/js/src/mod_fs/properties/lstat.h | 28 ++ .../kits/js/src/mod_fs/properties/open.cpp | 211 ++++++++++++ .../kits/js/src/mod_fs/properties/open.h | 45 +++ .../src/mod_fs/properties/prop_n_exporter.cpp | 300 ++++++++++++++++++ .../src/mod_fs/properties/prop_n_exporter.h | 54 ++++ .../kits/js/src/mod_fs/properties/stat.cpp | 148 +++++++++ .../kits/js/src/mod_fs/properties/stat.h | 29 ++ .../kits/js/src/mod_fs/properties/symlink.cpp | 114 +++++++ .../kits/js/src/mod_fs/properties/symlink.h | 28 ++ .../js/src/mod_fs/properties/truncate.cpp | 161 ++++++++++ .../kits/js/src/mod_fs/properties/truncate.h | 29 ++ interfaces/kits/js/src/mod_hash/hash.cpp | 133 ++++++++ interfaces/kits/js/src/mod_hash/hash.h | 56 ++++ interfaces/kits/js/src/mod_hash/module.cpp | 42 +++ utils/filemgmt_libhilog/filemgmt_libhilog.h | 14 +- utils/filemgmt_libn/include/n_error.h | 32 +- .../src/n_async/n_async_work_callback.cpp | 5 +- 38 files changed, 2834 insertions(+), 74 deletions(-) create mode 100644 interfaces/kits/js/src/mod_fs/class_file/file_entity.h create mode 100644 interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h create mode 100644 interfaces/kits/js/src/mod_fs/class_stat/stat_entity.h create mode 100644 interfaces/kits/js/src/mod_fs/class_stat/stat_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_stat/stat_n_exporter.h create mode 100644 interfaces/kits/js/src/mod_fs/common_func.cpp create mode 100644 interfaces/kits/js/src/mod_fs/common_func.h create mode 100644 interfaces/kits/js/src/mod_fs/module.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/fdatasync.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/fsync.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/fsync.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/lstat.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/lstat.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/open.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/open.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/stat.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/stat.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/symlink.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/symlink.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/truncate.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/truncate.h create mode 100644 interfaces/kits/js/src/mod_hash/hash.cpp create mode 100644 interfaces/kits/js/src/mod_hash/hash.h create mode 100644 interfaces/kits/js/src/mod_hash/module.cpp diff --git a/file_api.gni b/file_api.gni index 5dfea39be..a87deb695 100644 --- a/file_api.gni +++ b/file_api.gni @@ -13,3 +13,6 @@ aafwk_kits_path = "//foundation/ability/ability_runtime/frameworks/native" aafwk_path = "${aafwk_kits_path}/frameworks/kits" +file_api_path = "//foundation/filemanagement/file_api" +src_path = "${file_api_path}/interfaces/kits/js/src" +utils_path = "${file_api_path}/utils" diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 01f46ac7a..ca5759e89 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -92,8 +92,8 @@ 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", + "//third_party/bounds_checking_function:libsec_shared", + "//third_party/openssl:libcrypto_shared", ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] @@ -106,26 +106,30 @@ ohos_shared_library("fs") { relative_install_dir = "module/file" include_dirs = [ - "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/file_helper", - "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi", - "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi/n_async", + "${src_path}/common/file_helper", + "${src_path}/mod_fs", + "${utils_path}/filemgmt_libn/include", + "${utils_path}/filemgmt_libn/include/n_async", + "//third_party/libuv/include", ] - sources = file_common_src - sources += [ - "src/mod_fileio/class_file/file_n_exporter.cpp", - "src/mod_fileio/class_stat_v9/stat_n_exporter_v9.cpp", - "src/mod_fileio/common_func.cpp", - "src/mod_fileio/module_v9.cpp", - "src/mod_fileio/properties/open_v9.cpp", - "src/mod_fileio/properties/prop_n_exporter_v9.cpp", - "src/mod_fileio/properties/stat_v9.cpp", - "src/mod_fileio/properties/truncate_v9.cpp", + sources = [ + "src/common/file_helper/fd_guard.cpp", + "src/mod_fs/class_file/file_n_exporter.cpp", + "src/mod_fs/class_stat/stat_n_exporter.cpp", + "src/mod_fs/common_func.cpp", + "src/mod_fs/module.cpp", + "src/mod_fs/properties/lstat.cpp", + "src/mod_fs/properties/open.cpp", + "src/mod_fs/properties/prop_n_exporter.cpp", + "src/mod_fs/properties/stat.cpp", + "src/mod_fs/properties/symlink.cpp", + "src/mod_fs/properties/truncate.cpp", ] deps = [ - "//foundation/arkui/napi:ace_napi", - "//foundation/filemanagement/file_api/interfaces/kits/native:remote_uri_native", + "${file_api_path}/interfaces/kits/native:remote_uri_native", + "${utils_path}/filemgmt_libn:filemgmt_libn", ] external_deps = [ @@ -134,11 +138,37 @@ ohos_shared_library("fs") { "c_utils:utils", "data_share:datashare_common", "data_share:datashare_consumer", - "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", ] } +ohos_shared_library("hash") { + subsystem_name = "filemanagement" + part_name = "file_api" + + relative_install_dir = "module/file" + + include_dirs = [ + "${src_path}/common/file_helper", + "${utils_path}/filemgmt_libn/include", + "${utils_path}/filemgmt_libhilog", + ] + + sources = [ + "src/common/file_helper/fd_guard.cpp", + "src/common/file_helper/hash_file.cpp", + "src/mod_hash/hash.cpp", + "src/mod_hash/module.cpp", + ] + + deps = [ + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", + "${utils_path}/filemgmt_libn:filemgmt_libn", + "//third_party/bounds_checking_function:libsec_shared", + "//third_party/openssl:libcrypto_shared", + ] +} + ohos_shared_library("file") { subsystem_name = "filemanagement" part_name = "file_api" @@ -165,7 +195,7 @@ ohos_shared_library("file") { deps = [ "${aafwk_kits_path}/ability/native:abilitykit_native", "//foundation/arkui/napi:ace_napi", - "//third_party/bounds_checking_function:libsec_static", + "//third_party/bounds_checking_function:libsec_shared", ] external_deps = [ @@ -189,8 +219,6 @@ ohos_shared_library("statfs") { "//foundation/filemanagement/file_api/utils/filemgmt_libhilog", "//foundation/filemanagement/file_api/utils/filemgmt_libn", ] - - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] } ohos_shared_library("statvfs") { @@ -208,8 +236,6 @@ ohos_shared_library("statvfs") { "//foundation/filemanagement/file_api/utils/filemgmt_libhilog", "//foundation/filemanagement/file_api/utils/filemgmt_libn", ] - - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] } ohos_shared_library("environment") { @@ -218,8 +244,6 @@ ohos_shared_library("environment") { relative_install_dir = "module/file" - include_dirs = [ "//third_party/node/src" ] - sources = [ "src/mod_environment/environment_n_exporter.cpp", "src/mod_environment/environment_napi.cpp", @@ -229,10 +253,7 @@ ohos_shared_library("environment") { "//foundation/filemanagement/file_api/utils/filemgmt_libhilog", "//foundation/filemanagement/file_api/utils/filemgmt_libn", ] - - external_deps = [ - "hiviewdfx_hilog_native:libhilog", - ] + } ohos_shared_library("securitylabel") { @@ -253,8 +274,6 @@ ohos_shared_library("securitylabel") { "//foundation/filemanagement/file_api/utils/filemgmt_libhilog", "//foundation/filemanagement/file_api/utils/filemgmt_libn", ] - - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] } ohos_shared_library("document") { @@ -292,6 +311,7 @@ group("build_kits_js") { ":file", ":fileio", ":fs", + ":hash", ":securitylabel", ":statfs", ":statvfs", diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp index 0cca52412..53662897e 100644 --- a/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp @@ -71,7 +71,8 @@ static void CallbackComplete(napi_env env, napi_status status, void *data) NVal NAsyncWorkCallback::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) { if (!ctx_->cb_ || !ctx_->cb_.Deref(env_).TypeIs(napi_function)) { - UniError(EINVAL).ThrowErr(env_, "The callback shall be a function"); + HILOGE("The callback shall be a function"); + UniError(EINVAL).ThrowErr(env_); return NVal(); } 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 f4b80b4b6..30d829527 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 @@ -59,6 +59,7 @@ napi_value DirNExporter::CloseSync(napi_env env, napi_callback_info info) UniError(EBADF).ThrowErr(env, "Dir has been closed yet"); return nullptr; } + lock_guard(dirEntity->lock_); dirEntity->dir_.reset(); return nullptr; 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 1e316221e..29b78ca89 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 @@ -34,9 +34,9 @@ namespace DistributedFS { namespace ModuleFileIO { using namespace std; -static DirentEntity *GetDirentEntity(napi_env env, napi_callback_info info) +static DirentEntity *GetDirentEntity(napi_env env, napi_callback_info cbinfo) { - NFuncArg funcArg(env, info); + NFuncArg funcArg(env, cbinfo); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; @@ -50,9 +50,9 @@ static DirentEntity *GetDirentEntity(napi_env env, napi_callback_info info) return direntEntity; } -static napi_value CheckDirentDType(napi_env env, napi_callback_info info, unsigned char dType) +static napi_value CheckDirentDType(napi_env env, napi_callback_info cbinfo, unsigned char dType) { - DirentEntity *direntEntity = GetDirentEntity(env, info); + DirentEntity *direntEntity = GetDirentEntity(env, cbinfo); if (!direntEntity) { return nullptr; } @@ -60,53 +60,53 @@ static napi_value CheckDirentDType(napi_env env, napi_callback_info info, unsign return NVal::CreateBool(env, direntEntity->dirent_.d_type == dType).val_; } -napi_value DirentNExporter::isBlockDevice(napi_env env, napi_callback_info info) +napi_value DirentNExporter::isBlockDevice(napi_env env, napi_callback_info cbinfo) { - return CheckDirentDType(env, info, DT_BLK); + return CheckDirentDType(env, cbinfo, DT_BLK); } -napi_value DirentNExporter::isCharacterDevice(napi_env env, napi_callback_info info) +napi_value DirentNExporter::isCharacterDevice(napi_env env, napi_callback_info cbinfo) { - return CheckDirentDType(env, info, DT_CHR); + return CheckDirentDType(env, cbinfo, DT_CHR); } -napi_value DirentNExporter::isDirectory(napi_env env, napi_callback_info info) +napi_value DirentNExporter::isDirectory(napi_env env, napi_callback_info cbinfo) { - return CheckDirentDType(env, info, DT_DIR); + return CheckDirentDType(env, cbinfo, DT_DIR); } -napi_value DirentNExporter::isFIFO(napi_env env, napi_callback_info info) +napi_value DirentNExporter::isFIFO(napi_env env, napi_callback_info cbinfo) { - return CheckDirentDType(env, info, DT_FIFO); + return CheckDirentDType(env, cbinfo, DT_FIFO); } -napi_value DirentNExporter::isFile(napi_env env, napi_callback_info info) +napi_value DirentNExporter::isFile(napi_env env, napi_callback_info cbinfo) { - return CheckDirentDType(env, info, DT_REG); + return CheckDirentDType(env, cbinfo, DT_REG); } -napi_value DirentNExporter::isSocket(napi_env env, napi_callback_info info) +napi_value DirentNExporter::isSocket(napi_env env, napi_callback_info cbinfo) { - return CheckDirentDType(env, info, DT_SOCK); + return CheckDirentDType(env, cbinfo, DT_SOCK); } -napi_value DirentNExporter::isSymbolicLink(napi_env env, napi_callback_info info) +napi_value DirentNExporter::isSymbolicLink(napi_env env, napi_callback_info cbinfo) { - return CheckDirentDType(env, info, DT_LNK); + return CheckDirentDType(env, cbinfo, DT_LNK); } -napi_value DirentNExporter::GetName(napi_env env, napi_callback_info info) +napi_value DirentNExporter::GetName(napi_env env, napi_callback_info cbinfo) { - DirentEntity *direntEntity = GetDirentEntity(env, info); + DirentEntity *direntEntity = GetDirentEntity(env, cbinfo); if (!direntEntity) { return nullptr; } return NVal::CreateUTF8String(env, direntEntity->dirent_.d_name).val_; } -napi_value DirentNExporter::Constructor(napi_env env, napi_callback_info info) +napi_value DirentNExporter::Constructor(napi_env env, napi_callback_info cbinfo) { - NFuncArg funcArg(env, info); + NFuncArg funcArg(env, cbinfo); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; diff --git a/interfaces/kits/js/src/mod_fileio/common_func.h b/interfaces/kits/js/src/mod_fileio/common_func.h index 93296eb01..2ef467d28 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.h +++ b/interfaces/kits/js/src/mod_fileio/common_func.h @@ -22,7 +22,6 @@ namespace OHOS { namespace DistributedFS { namespace ModuleFileIO { constexpr int64_t INVALID_POSITION = std::numeric_limits::max(); - constexpr int RDONLY = 00; constexpr int WRONLY = 01; constexpr int RDWR = 02; diff --git a/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.cpp b/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.cpp index 8fa4fbaa7..461390164 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/create_randomaccessfile.cpp @@ -140,15 +140,15 @@ napi_value CreateRandomAccessFile::Sync(napi_env env, napi_callback_info info) } 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 | + uv_fs_t openReq; + int ret = uv_fs_open(loop, &openReq, 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); + fileInfo.fdg.SetFD(openReq.result, false); + uv_fs_req_cleanup(&openReq); } return InstantiateRandomAccessFile(env, fileInfo.fdg.GetFD(), fp).val_; } @@ -179,14 +179,14 @@ napi_value CreateRandomAccessFile::Async(napi_env env, napi_callback_info info) 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 | + uv_fs_t openReq; + int ret = uv_fs_open(loop, &openReq, 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); + fileInfo->fdg.SetFD(openReq.result, false); + uv_fs_req_cleanup(&openReq); } arg->fd = fileInfo->fdg.GetFD(); arg->fp = fp; diff --git a/interfaces/kits/js/src/mod_fs/class_file/file_entity.h b/interfaces/kits/js/src/mod_fs/class_file/file_entity.h new file mode 100644 index 000000000..6bedf0d00 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_file/file_entity.h @@ -0,0 +1,35 @@ +/* + * 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_FS_CLASS_FILE_FILE_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_FILE_FILE_ENTITY_H + +#include +#include + +#include "fd_guard.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +struct FileEntity { + std::unique_ptr fd_ = { nullptr }; + std::string path_; + std::string uri_; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_FILE_FILE_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp new file mode 100644 index 000000000..6d7ad806d --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp @@ -0,0 +1,119 @@ +/* + * 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 "file_entity.h" +#include "file_n_exporter.h" + +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" +#include "filemgmt_libn.h" +#include "../common_func.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static FileEntity *GetFileEntity(napi_env env, napi_value raf_entity) +{ + auto rafEntity = NClass::GetEntityOf(env, raf_entity); + if (!rafEntity) { + HILOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + if (!rafEntity->fd_) { + HILOGE("rafEntity fd is not exist"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + return rafEntity; +} + +napi_value FileNExporter::GetFD(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto rafEntity = GetFileEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + HILOGE("Failed to get file entity"); + return nullptr; + } + return NVal::CreateInt32(env, rafEntity->fd_.get()->GetFD()).val_; +} + +napi_value FileNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto rafEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(rafEntity))) { + HILOGE("Failed to set file entity"); + NError(EIO).ThrowErr(env); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool FileNExporter::Export() +{ + vector props = { + NVal::DeclareNapiGetter("fd", GetFD), + }; + + string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + FileNExporter::Constructor, move(props)); + if (!succ) { + HILOGE("Define class exceptions"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + HILOGE("Save class exceptions"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string FileNExporter::GetClassName() +{ + return FileNExporter::className_; +} + +FileNExporter::FileNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} +FileNExporter::~FileNExporter() {} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h new file mode 100644 index 000000000..f79ef539d --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h @@ -0,0 +1,40 @@ +/* + * 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_FS_CLASS_FILE_FILE_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_FILE_FILE_N_EXPORTER_H + +#include "n_exporter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::FileManagement::LibN; +class FileNExporter final : public NExporter { +public: + inline static const std::string className_ = "File"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + static napi_value GetFD(napi_env env, napi_callback_info cbinfo); + FileNExporter(napi_env env, napi_value exports); + ~FileNExporter() override; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_FILE_FILE_N_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_stat/stat_entity.h b/interfaces/kits/js/src/mod_fs/class_stat/stat_entity.h new file mode 100644 index 000000000..88f6c67f0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stat/stat_entity.h @@ -0,0 +1,26 @@ +/* + * 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_FS_CLASS_STAT_STAT_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STAT_STAT_ENTITY_H + +#include + +namespace OHOS::FileManagement::ModuleFileIO { +struct StatEntity { + struct stat stat_; +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STAT_STAT_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_stat/stat_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_stat/stat_n_exporter.cpp new file mode 100644 index 000000000..a88d6fc50 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stat/stat_n_exporter.cpp @@ -0,0 +1,296 @@ +/* + * 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 "stat_entity.h" +#include "stat_n_exporter.h" + +#include +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static napi_value CheckStatMode(napi_env env, napi_callback_info info, mode_t mode) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + bool check = (statEntity->stat_.st_mode & S_IFMT) == mode; + return NVal::CreateBool(env, check).val_; +} + +napi_value StatNExporter::IsBlockDevice(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFBLK); +} + +napi_value StatNExporter::IsCharacterDevice(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFCHR); +} + +napi_value StatNExporter::IsDirectory(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFDIR); +} + +napi_value StatNExporter::IsFIFO(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFIFO); +} + +napi_value StatNExporter::IsFile(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFREG); +} + +napi_value StatNExporter::IsSocket(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFSOCK); +} + +napi_value StatNExporter::IsSymbolicLink(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFLNK); +} + +napi_value StatNExporter::GetIno(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + return NVal::CreateBigInt64(env, statEntity->stat_.st_ino).val_; +} + +napi_value StatNExporter::GetMode(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_mode & S_PERMISSION).val_; +} + +napi_value StatNExporter::GetUid(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_uid).val_; +} + +napi_value StatNExporter::GetGid(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_gid).val_; +} + +napi_value StatNExporter::GetSize(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_size).val_; +} + +napi_value StatNExporter::GetAtime(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_atim.tv_sec).val_; +} + +napi_value StatNExporter::GetMtime(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_mtim.tv_sec).val_; +} + +napi_value StatNExporter::GetCtime(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_ctim.tv_sec).val_; +} + +napi_value StatNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + unique_ptr statEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(statEntity))) { + HILOGE("Failed to set stat entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool StatNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("isBlockDevice", IsBlockDevice), + NVal::DeclareNapiFunction("isCharacterDevice", IsCharacterDevice), + NVal::DeclareNapiFunction("isDirectory", IsDirectory), + NVal::DeclareNapiFunction("isFIFO", IsFIFO), + NVal::DeclareNapiFunction("isFile", IsFile), + NVal::DeclareNapiFunction("isSocket", IsSocket), + NVal::DeclareNapiFunction("isSymbolicLink", IsSymbolicLink), + + NVal::DeclareNapiGetter("ino", GetIno), + NVal::DeclareNapiGetter("mode", GetMode), + NVal::DeclareNapiGetter("uid", GetUid), + NVal::DeclareNapiGetter("gid", GetGid), + NVal::DeclareNapiGetter("size", GetSize), + NVal::DeclareNapiGetter("atime", GetAtime), + NVal::DeclareNapiGetter("mtime", GetMtime), + NVal::DeclareNapiGetter("ctime", GetCtime), + }; + + string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, StatNExporter::Constructor, + std::move(props)); + if (!succ) { + HILOGE("Failed to define class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + HILOGE("Failed to save class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string StatNExporter::GetClassName() +{ + return StatNExporter::className_; +} + +StatNExporter::StatNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +StatNExporter::~StatNExporter() {} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_stat/stat_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_stat/stat_n_exporter.h new file mode 100644 index 000000000..ddc4fea83 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stat/stat_n_exporter.h @@ -0,0 +1,55 @@ +/* + * 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_FS_CLASS_STAT_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STAT_N_EXPORTER_H + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace OHOS::FileManagement::LibN; + +constexpr int S_PERMISSION = 00000777; +class StatNExporter final : public NExporter { +public: + inline static const std::string className_ = "Stat"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + + static napi_value IsBlockDevice(napi_env env, napi_callback_info cbinfo); + static napi_value IsCharacterDevice(napi_env env, napi_callback_info cbinfo); + static napi_value IsDirectory(napi_env env, napi_callback_info cbinfo); + static napi_value IsFIFO(napi_env env, napi_callback_info cbinfo); + static napi_value IsFile(napi_env env, napi_callback_info cbinfo); + static napi_value IsSocket(napi_env env, napi_callback_info cbinfo); + static napi_value IsSymbolicLink(napi_env env, napi_callback_info cbinfo); + + static napi_value GetIno(napi_env env, napi_callback_info cbinfo); + static napi_value GetMode(napi_env env, napi_callback_info cbinfo); + static napi_value GetUid(napi_env env, napi_callback_info cbinfo); + static napi_value GetGid(napi_env env, napi_callback_info cbinfo); + static napi_value GetSize(napi_env env, napi_callback_info cbinfo); + static napi_value GetAtime(napi_env env, napi_callback_info cbinfo); + static napi_value GetMtime(napi_env env, napi_callback_info cbinfo); + static napi_value GetCtime(napi_env env, napi_callback_info cbinfo); + + StatNExporter(napi_env env, napi_value exports); + ~StatNExporter() override; +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STAT_N_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/common_func.cpp b/interfaces/kits/js/src/mod_fs/common_func.cpp new file mode 100644 index 000000000..b02dc3d61 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/common_func.cpp @@ -0,0 +1,259 @@ +/* + * 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 "common_func.h" + +#include +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +void InitOpenMode(napi_env env, napi_value exports) +{ + char propertyName[] = "OpenMode"; + napi_property_descriptor desc[] = { + DECLARE_NAPI_STATIC_PROPERTY("READ_ONLY", NVal::CreateInt32(env, RDONLY).val_), + DECLARE_NAPI_STATIC_PROPERTY("WRITE_ONLY", NVal::CreateInt32(env, WRONLY).val_), + DECLARE_NAPI_STATIC_PROPERTY("READ_WRITE", NVal::CreateInt32(env, RDWR).val_), + DECLARE_NAPI_STATIC_PROPERTY("CREATE", NVal::CreateInt32(env, CREATE).val_), + DECLARE_NAPI_STATIC_PROPERTY("TRUNC", NVal::CreateInt32(env, TRUNC).val_), + DECLARE_NAPI_STATIC_PROPERTY("APPEND", NVal::CreateInt32(env, APPEND).val_), + DECLARE_NAPI_STATIC_PROPERTY("NONBLOCK", NVal::CreateInt32(env, NONBLOCK).val_), + DECLARE_NAPI_STATIC_PROPERTY("DIR", NVal::CreateInt32(env, DIRECTORY).val_), + DECLARE_NAPI_STATIC_PROPERTY("NOFOLLOW", NVal::CreateInt32(env, NOFOLLOW).val_), + DECLARE_NAPI_STATIC_PROPERTY("SYNC", NVal::CreateInt32(env, SYNC).val_), + }; + napi_value obj = nullptr; + napi_status status = napi_create_object(env, &obj); + if (status != napi_ok) { + HILOGE("Failed to create object at initializing openMode"); + return; + } + status = napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc); + if (status != napi_ok) { + HILOGE("Failed to set properties of character at initializing openMode"); + return; + } + status = napi_set_named_property(env, exports, propertyName, obj); + if (status != napi_ok) { + HILOGE("Failed to set direction property at initializing openMode"); + return; + } +} + +static tuple GetActualLen(napi_env env, int64_t bufLen, int64_t bufOff, NVal op) +{ + bool succ = false; + int64_t retLen; + + if (op.HasProp("length")) { + int64_t opLength; + tie(succ, opLength) = op.GetProp("length").ToInt64(); + if (!succ) { + HILOGE("Invalid option.length, expect integer"); + NError(EINVAL).ThrowErr(env); + return { false, 0 }; + } + if (opLength < 0) { + retLen = bufLen - bufOff; + } else if (opLength > bufLen - bufOff) { + HILOGE("Invalid option.length, buffer limit exceeded"); + NError(EINVAL).ThrowErr(env); + return { false, 0 }; + } else { + retLen = opLength; + } + } else { + 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) +{ + bool succ = false; + unique_ptr src; + tie(succ, src, ignore) = NVal(env, srcPath).ToUTF8String(); + if (!succ) { + HILOGE("Failed to convert the src path to UTF-8 string"); + return { false, nullptr, nullptr }; + } + + unique_ptr dest; + tie(succ, dest, ignore) = NVal(env, dstPath).ToUTF8String(); + if (!succ) { + HILOGE("Failed to convert the dest path to UTF-8 string"); + return { false, nullptr, nullptr }; + } + return make_tuple(true, move(src), move(dest)); +} + +static tuple, int64_t> DecodeString(napi_env env, NVal jsStr, NVal encoding) +{ + unique_ptr buf; + if (!jsStr.TypeIs(napi_string)) { + HILOGE("Failed to recognize the type to a string"); + return { false, nullptr, 0 }; + } + + bool succ = false; + if (!encoding) { + return jsStr.ToUTF8String(); + } + + unique_ptr encodingBuf; + tie(succ, encodingBuf, ignore) = encoding.ToUTF8String(); + if (!succ) { + return { false, nullptr, 0 }; + } + string_view encodingStr(encodingBuf.release()); + if (encodingStr == "utf-8") { + return jsStr.ToUTF8String(); + } else if (encodingStr == "utf-16") { + return jsStr.ToUTF16String(); + } else { + HILOGE("Failed to recognize the str type"); + return { false, nullptr, 0 }; + } +} + +tuple CommonFunc::GetReadArg(napi_env env, + napi_value readBuf, napi_value option) +{ + int64_t retLen; + int64_t position; + bool succ = false; + bool posAssigned = false; + + NVal txt(env, readBuf); + void *buf = nullptr; + int64_t bufLen; + tie(succ, buf, bufLen) = txt.ToArraybuffer(); + if (!succ) { + HILOGE("Invalid read buffer, expect arraybuffer"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, 0, posAssigned, position }; + } + NVal op = NVal(env, option); + tie(succ, retLen) = GetActualLen(env, bufLen, 0, op); + if (!succ) { + HILOGE("Failed to get actual length"); + return { false, nullptr, 0, posAssigned, position }; + } + + if (op.HasProp("offset")) { + tie(succ, position) = op.GetProp("offset").ToInt64(); + if (succ && position >= 0) { + posAssigned = true; + } else { + HILOGE("option.offset shall be positive number"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, 0, posAssigned, position }; + } + } + + return { true, buf, retLen, posAssigned, position }; +} + +tuple, void *, int64_t, bool, int64_t> CommonFunc::GetWriteArg(napi_env env, + napi_value argWBuf, napi_value argOption) +{ + int64_t retLen; + int64_t retPos; + int64_t bufLen; + bool hasPos = false; + bool succ = false; + void *buf = nullptr; + NVal op(env, argOption); + NVal jsBuffer(env, argWBuf); + 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) { + HILOGE("Illegal write buffer or encoding"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + } else { + buf = bufferGuard.get(); + } + tie(succ, retLen) = GetActualLen(env, bufLen, 0, op); + if (!succ) { + HILOGE("Failed to get actual length"); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + + if (op.HasProp("offset")) { + int32_t position = 0; + tie(succ, position) = op.GetProp("offset").ToInt32(); + if (!succ || position < 0) { + HILOGE("option.offset shall be positive number"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + hasPos = true; + retPos = position; + } else { + retPos = INVALID_POSITION; + } + return { true, move(bufferGuard), buf, retLen, hasPos, retPos }; +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/common_func.h b/interfaces/kits/js/src/mod_fs/common_func.h new file mode 100644 index 000000000..0fdd7ccd5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -0,0 +1,61 @@ +/* + * 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_FS_COMMON_FUNC_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_COMMON_FUNC_H + +#include "fd_guard.h" +#include "n_val.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +constexpr int64_t INVALID_POSITION = std::numeric_limits::max(); +constexpr int RDONLY = 00; +constexpr int WRONLY = 01; +constexpr int RDWR = 02; +constexpr int CREATE = 0100; +constexpr int TRUNC = 01000; +constexpr int APPEND = 02000; +constexpr int NONBLOCK = 04000; +constexpr int DIRECTORY = 0200000; +constexpr int NOFOLLOW = 0400000; +constexpr int SYNC = 04010000; + +struct FileInfo { + bool isPath = false; + std::unique_ptr path; + DistributedFS::FDGuard fdg; +}; + +void InitOpenMode(napi_env env, napi_value exports); + +struct CommonFunc { + static int ConvertJsFlags(int &flags); + static std::tuple GetReadArg(napi_env env, + napi_value readBuf, + napi_value option); + static std::tuple, void *, int64_t, bool, int64_t> GetWriteArg(napi_env env, + napi_value argWBuf, + napi_value argOption); + static std::tuple, std::unique_ptr> GetCopyPathArg(napi_env env, + napi_value srcPath, + napi_value dstPath); +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_COMMON_FUNC_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/module.cpp b/interfaces/kits/js/src/mod_fs/module.cpp new file mode 100644 index 000000000..792cab62b --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/module.cpp @@ -0,0 +1,53 @@ +/* + * 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 "common_func.h" + +#include +#include + +#include "class_file/file_n_exporter.h" +#include "class_stat/stat_n_exporter.h" +#include "filemgmt_libhilog.h" +#include "properties/prop_n_exporter.h" + +using namespace std; + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +static napi_value Export(napi_env env, napi_value exports) +{ + InitOpenMode(env, exports); + std::vector> products; + products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); + + for (auto &&product : products) { + if (!product->Export()) { + HILOGE("INNER BUG. Failed to export class %{public}s for module fileio", product->GetClassName().c_str()); + return nullptr; + } else { + HILOGI("Class %{public}s for module fileio has been exported", product->GetClassName().c_str()); + } + } + return exports; +} + +NAPI_MODULE(fs, Export) +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp b/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp new file mode 100644 index 000000000..8def72111 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp @@ -0,0 +1,103 @@ +/* + * 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 "fdatasync.h" + +#include +#include +#include +#include + +#include + +#include "filemgmt_libhilog.h" +#include "uv.h" + + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value Fdatasync::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!resGetFirstArg) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + std::unique_ptr fdatasync_req = {new uv_fs_t, uv_fs_req_cleanup}; + int ret = uv_fs_fdatasync(nullptr, fdatasync_req.get(), fd, nullptr); + if (ret < 0) { + HILOGE("Failed to transfer data associated with file descriptor: %{public}d, ret:%{public}d", fd, ret); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value Fdatasync::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!resGetFirstArg) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [fd = fd]() -> NError { + std::unique_ptr fdatasync_req = {new uv_fs_t, uv_fs_req_cleanup}; + int ret = uv_fs_fdatasync(nullptr, fdatasync_req.get(), fd, nullptr); + if (ret < 0) { + HILOGE("Failed to transfer data associated with file descriptor: %{public}d", fd); + return NError(errno); + } else { + return NError(ERRNO_NOERR); + } + }; + + auto cbComplCallback = [](napi_env env, NError err) -> NVal { + if (err) { + return {env, err.GetNapiErr(env)}; + } + return {NVal::CreateUndefined(env)}; + }; + + const string procedureName = "FileIOFdatasync"; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplCallback).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplCallback).val_; + } +} +} // OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fdatasync.h b/interfaces/kits/js/src/mod_fs/properties/fdatasync.h new file mode 100644 index 000000000..f4c3ba0e5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdatasync.h @@ -0,0 +1,28 @@ +/* + * 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_FS_PROPERTIES_FDATASYNC_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDATASYNC_H + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class Fdatasync final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); + static napi_value Async(napi_env env, napi_callback_info info); +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDATASYNC_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fsync.cpp b/interfaces/kits/js/src/mod_fs/properties/fsync.cpp new file mode 100644 index 000000000..85405dfe4 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fsync.cpp @@ -0,0 +1,100 @@ +/* + * 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 "fsync.h" + +#include +#include +#include + +#include "filemgmt_libhilog.h" +#include "uv.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value Fsync::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!resGetFirstArg) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + std::unique_ptr fsync_req = {new uv_fs_t, uv_fs_req_cleanup}; + int ret = uv_fs_fsync(nullptr, fsync_req.get(), fd, nullptr); + if (ret < 0) { + HILOGE("Failed to transfer data associated with file descriptor: %{public}d", fd); + NError(errno).ThrowErr(env); + return nullptr; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value Fsync::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!resGetFirstArg) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [fd = fd]() -> NError { + std::unique_ptr fsync_req = {new uv_fs_t, uv_fs_req_cleanup}; + int ret = uv_fs_fsync(nullptr, fsync_req.get(), fd, nullptr); + if (ret < 0) { + HILOGE("Failed to transfer data associated with file descriptor: %{public}d", fd); + return NError(errno); + } else { + return NError(ERRNO_NOERR); + } + }; + + auto cbComplete = [](napi_env env, NError err) -> NVal { + if (err) { + return {env, err.GetNapiErr(env)}; + } else { + return NVal::CreateUndefined(env); + } + }; + + const string procedureName = "FileIOFsync"; + size_t argc = funcArg.GetArgc(); + NVal thisVar(env, funcArg.GetThisVar()); + if (argc == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; + } +} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fsync.h b/interfaces/kits/js/src/mod_fs/properties/fsync.h new file mode 100644 index 000000000..e03390978 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fsync.h @@ -0,0 +1,28 @@ +/* + * 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_FS_PROPERTIES_FSYNC_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FSYNC_H + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class Fsync final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); + static napi_value Async(napi_env env, napi_callback_info info); +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FSYNC_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/lstat.cpp b/interfaces/kits/js/src/mod_fs/properties/lstat.cpp new file mode 100644 index 000000000..06ecdf639 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/lstat.cpp @@ -0,0 +1,126 @@ +/* + * 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 "lstat.h" + +#include +#include + +#include "../common_func.h" +#include "class_stat/stat_entity.h" +#include "class_stat/stat_n_exporter.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NVal InstantiateStat(napi_env env, struct stat &buf) +{ + napi_value objStat = NClass::InstantiateClass(env, StatNExporter::className_, {}); + if (!objStat) { + HILOGE("Failed to instantiate stat class"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto statEntity = NClass::GetEntityOf(env, objStat); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + statEntity->stat_ = buf; + return { env, objStat }; +} + +napi_value Lstat::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetFirstArg, pathPtr, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + struct stat buf; + int ret = lstat(pathPtr.get(), &buf); + if (ret < 0) { + HILOGE("Failed to get stat of file by path %{public}s", pathPtr.get()); + NError(errno).ThrowErr(env); + return nullptr; + } + + auto stat = InstantiateStat(env, buf).val_; + return stat; +} + +struct AsyncStatArg { + struct stat stat_; +}; + +napi_value Lstat::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetFirstArg, tmp, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + string path = tmp.get(); + auto arg = make_shared(); + auto cbExec = [arg, path]() -> NError { + int ret = lstat(path.c_str(), &arg->stat_); + if (ret < 0) { + HILOGE("Failed to get stat of file by path: %{public}s, ret: %{public}d", path.c_str(), ret); + return NError(errno); + } else { + return NError(ERRNO_NOERR); + } + }; + + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + auto stat = InstantiateStat(env, arg->stat_); + return stat; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + const string procedureName = "FileIOLstat"; + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; + } +} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/lstat.h b/interfaces/kits/js/src/mod_fs/properties/lstat.h new file mode 100644 index 000000000..00adc4627 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/lstat.h @@ -0,0 +1,28 @@ +/* + * 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_FS_PROPERTIES_LSTAT_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_LSTAT_H + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class Lstat final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_LSTAT_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/open.cpp b/interfaces/kits/js/src/mod_fs/properties/open.cpp new file mode 100644 index 000000000..ff16921a0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/open.cpp @@ -0,0 +1,211 @@ +/* + * 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 "open.h" + +#include +#include +#include +#include +#include + +#include "../common_func.h" +#include "ability.h" +#include "class_file/file_entity.h" +#include "class_file/file_n_exporter.h" +#include "datashare_helper.h" +#include "filemgmt_libhilog.h" +#include "filemgmt_libn.h" +#include "remote_uri.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static tuple GetJsFlags(napi_env env, const NFuncArg &funcArg) +{ + int mode = O_RDONLY; + bool succ = false; + if (funcArg.GetArgc() >= NARG_CNT::TWO && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) { + tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { + HILOGE("Invalid mode"); + NError(EINVAL).ThrowErr(env); + return { false, mode }; + } + (void)CommonFunc::ConvertJsFlags(mode); + } + return { true, mode }; +} + +static NVal InstantiateFile(napi_env env, int fd, string pathOrUri, bool isUri) +{ + napi_value objFile = NClass::InstantiateClass(env, FileNExporter::className_, {}); + if (!objFile) { + HILOGE("Failed to instantiate class"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto fileEntity = NClass::GetEntityOf(env, objFile); + if (!fileEntity) { + HILOGE("Failed to get fileEntity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + auto fdg = make_unique(fd, false); + fileEntity->fd_.swap(fdg); + if (isUri) { + fileEntity->path_ = ""; + fileEntity->uri_ = pathOrUri; + } else { + fileEntity->path_ = pathOrUri; + fileEntity->uri_ = ""; + } + return { env, objFile }; +} + +static int OpenFileByDatashare(napi_env env, napi_value argv, string path) +{ + std::shared_ptr dataShareHelper = nullptr; + int fd = -1; + sptr remote = new (std::nothrow) IRemoteStub(); + if (remote == nullptr) { + return ENOMEM; + } + + dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); + Uri uri(path); + fd = dataShareHelper->OpenFile(uri, MEDIA_FILEMODE_READONLY); + return fd; +} + +napi_value Open::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succPath) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succMode, mode] = GetJsFlags(env, funcArg); + if (!succMode) { + HILOGE("Invalid mode"); + return nullptr; + } + if (DistributedFS::ModuleRemoteUri::RemoteUri::IsMediaUri(path.get())) { + auto fd = OpenFileByDatashare(env, funcArg[NARG_POS::FIRST], path.get()); + if (fd >= 0) { + auto file = InstantiateFile(env, fd, path.get(), true).val_; + return file; + } + HILOGE("Failed to open file by Datashare"); + NError(-1).ThrowErr(env); + return nullptr; + } + std::unique_ptr open_req = { new uv_fs_t, uv_fs_req_cleanup }; + int ret = uv_fs_open(uv_default_loop(), open_req.get(), path.get(), mode, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, NULL); + if (ret < 0) { + HILOGE("Failed to open file for libuv error %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + auto file = InstantiateFile(env, open_req.get()->result, path.get(), false).val_; + return file; +} + +struct AsyncOpenFileArg { + int fd; + string path; + string uri; +}; + +napi_value Open::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succPath) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succMode, mode] = GetJsFlags(env, funcArg); + if (!succMode) { + HILOGE("Invalid mode"); + return nullptr; + } + auto arg = make_shared(); + auto argv = funcArg[NARG_POS::FIRST]; + auto cbExec = [arg, argv, path = string(path.get()), mode = mode, env = env]() -> NError { + if (DistributedFS::ModuleRemoteUri::RemoteUri::IsMediaUri(path)) { + auto fd = OpenFileByDatashare(env, argv, path); + if (fd >= 0) { + arg->fd = fd; + arg->path = ""; + arg->uri = path; + return NError(ERRNO_NOERR); + } + HILOGE("Failed to open file by Datashare"); + return NError(-1); + } + std::unique_ptr open_req = { new uv_fs_t, uv_fs_req_cleanup }; + int ret = uv_fs_open(uv_default_loop(), open_req.get(), path.c_str(), mode, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, NULL); + if (ret < 0) { + HILOGE("Failed to open file for libuv error %{public}d", ret); + return NError(errno); + } + arg->fd = open_req.get()->result; + arg->path = path; + arg->uri = ""; + return NError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + bool isUri = false; + if (arg->path.empty() && arg->uri.size()) { + isUri = true; + return InstantiateFile(env, arg->fd, arg->uri, isUri); + } + return InstantiateFile(env, arg->fd, arg->path, isUri); + }; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && + NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number))) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_OPEN_NAME, cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::THREE) ? NARG_POS::THIRD : NARG_POS::SECOND); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_OPEN_NAME, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/open.h b/interfaces/kits/js/src/mod_fs/properties/open.h new file mode 100644 index 000000000..8bf564bbb --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/open.h @@ -0,0 +1,45 @@ +/* + * 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_FS_PROPERTIES_OPEN_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_OPEN_H + +#include "iremote_broker.h" +#include "../../common/napi/uni_header.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class Open final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +class FileIoToken : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.fileio.open"); + + FileIoToken() = default; + virtual ~FileIoToken() noexcept = default; +}; + +const std::string PROCEDURE_OPEN_NAME = "FileIOOpen"; +const std::string MEDIALIBRARY_DATA_URI = "datashare:///media"; +const std::string MEDIA_FILEMODE_READONLY = "r"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_OPEN_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp new file mode 100644 index 000000000..9f94a0736 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp @@ -0,0 +1,300 @@ +/* + * 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 "prop_n_exporter.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "../common_func.h" +#include "class_file/file_entity.h" +#include "class_file/file_n_exporter.h" +#include "filemgmt_libn.h" +#include "lstat.h" +#include "open.h" +#include "stat.h" +#include "symlink.h" +#include "truncate.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [res, buf, len, hasPos, pos] = + CommonFunc::GetReadArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + if (!res) { + HILOGE("Failed to resolve buf and options"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + ssize_t actLen; + uv_buf_t buffer = uv_buf_init(static_cast(buf), len); + uv_fs_t read_req; + int ret = uv_fs_read(nullptr, &read_req, fd, &buffer, 1, pos, nullptr); + if (ret < 0) { + HILOGE("Failed to read file for %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + actLen = read_req.result; + uv_fs_req_cleanup(&read_req); + + return NVal::CreateInt64(env, actLen).val_; +} + +struct AsyncIOReadArg { + ssize_t lenRead { 0 }; +}; + +static NError ReadExec(shared_ptr arg, void *buf, size_t len, int fd, size_t position) +{ + uv_buf_t buffer = uv_buf_init(static_cast(buf), len); + uv_fs_t read_req; + int ret = uv_fs_read(nullptr, &read_req, fd, &buffer, 1, static_cast(position), nullptr); + if (ret < 0) { + HILOGE("Failed to read file for %{public}d", ret); + return NError(errno); + } + arg->lenRead = read_req.result; + uv_fs_req_cleanup(&read_req); + return NError(ERRNO_NOERR); +} + +napi_value PropNExporter::Read(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::FOUR)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [res, buf, len, hasPos, pos] = + CommonFunc::GetReadArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + if (!res) { + HILOGE("Failed to resolve buf and options"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto arg = make_shared(); + auto cbExec = [arg, buf = buf, len = len, fd = fd, pos = pos, env = env]() -> NError { + return ReadExec(arg, buf, len, fd, pos); + }; + + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateInt64(env, arg->lenRead) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + bool hasOp = false; + if (funcArg.GetArgc() == NARG_CNT::THREE) { + NVal op = NVal(env, funcArg[NARG_POS::THIRD]); + if (op.HasProp("offset") || op.HasProp("length")|| !op.TypeIs(napi_function)) { + hasOp = true; + } + } + if (funcArg.GetArgc() == NARG_CNT::TWO || (funcArg.GetArgc() == NARG_CNT::THREE && hasOp)) { + return NAsyncWorkPromise(env, thisVar).Schedule("FileIORead", cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::THREE) ? NARG_POS::THIRD : NARG_POS::FOURTH); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIORead", cbExec, cbCompl).val_; + } + + return NVal::CreateUndefined(env).val_; +} + +NError PropNExporter::WriteExec(shared_ptr arg, void *buf, size_t len, int fd, size_t position) +{ + uv_buf_t buffer = uv_buf_init(static_cast(buf), len); + uv_fs_t write_req; + int ret = uv_fs_write(nullptr, &write_req, fd, &buffer, 1, static_cast(position), nullptr); + if (ret < 0) { + HILOGE("Failed to write file for %{public}d", ret); + return NError(errno); + } + arg->actLen = write_req.result; + uv_fs_req_cleanup(&write_req); + return NError(ERRNO_NOERR); +} + +napi_value PropNExporter::Write(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::FOUR)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [res, bufGuard, buf, len, hasPos, position] = + CommonFunc::GetWriteArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + if (!res) { + HILOGE("Failed to resolve buf and options"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + shared_ptr arg; + if (bufGuard) { + arg = make_shared(move(bufGuard)); + } else { + arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); + } + auto cbExec = [arg, buf = buf, len = len, fd = fd, position = position, env = env]() -> NError { + return WriteExec(arg, buf, len, fd, position); + }; + + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return { NVal::CreateInt64(env, arg->actLen) }; + } + }; + + NVal thisVar(env, funcArg.GetThisVar()); + bool hasOp = false; + if (funcArg.GetArgc() == NARG_CNT::THREE) { + NVal op = NVal(env, funcArg[NARG_POS::THIRD]); + if (op.HasProp("offset") || op.HasProp("position") || op.HasProp("length") || + op.HasProp("encoding") || !op.TypeIs(napi_function)) { + hasOp = true; + } + } + + if (funcArg.GetArgc() == NARG_CNT::TWO || (funcArg.GetArgc() == NARG_CNT::THREE && hasOp)) { + return NAsyncWorkPromise(env, thisVar).Schedule("FileIOWrite", cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::THREE) ? NARG_POS::THIRD : NARG_POS::FOURTH); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIOWrite", cbExec, cbCompl).val_; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value PropNExporter::WriteSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [res, bufGuard, buf, len, hasPos, position] = + CommonFunc::GetWriteArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + if (!res) { + HILOGE("Failed to resolve buf and options"); + return nullptr; + } + + ssize_t writeLen; + uv_buf_t buffer = uv_buf_init(static_cast(buf), len); + uv_fs_t write_req; + int ret = uv_fs_write(nullptr, &write_req, fd, &buffer, 1, static_cast(position), nullptr); + if (ret < 0) { + HILOGE("Failed to write file for %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + writeLen = write_req.result; + uv_fs_req_cleanup(&write_req); + + return NVal::CreateInt64(env, writeLen).val_; +} + +bool PropNExporter::Export() +{ + return exports_.AddProp({ + NVal::DeclareNapiFunction("lstat", Lstat::Async), + NVal::DeclareNapiFunction("lstatSync", Lstat::Sync), + NVal::DeclareNapiFunction("open", Open::Async), + NVal::DeclareNapiFunction("openSync", Open::Sync), + NVal::DeclareNapiFunction("read", Read), + NVal::DeclareNapiFunction("readSync", ReadSync), + NVal::DeclareNapiFunction("stat", Stat::Async), + NVal::DeclareNapiFunction("statSync", Stat::Sync), + NVal::DeclareNapiFunction("symlink", Symlink::Async), + NVal::DeclareNapiFunction("symlinkSync", Symlink::Sync), + NVal::DeclareNapiFunction("truncate", Truncate::Async), + NVal::DeclareNapiFunction("truncateSync", Truncate::Sync), + NVal::DeclareNapiFunction("write", Write), + NVal::DeclareNapiFunction("writeSync", WriteSync), + }); +} + +string PropNExporter::GetClassName() +{ + return PropNExporter::className_; +} + +PropNExporter::PropNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +PropNExporter::~PropNExporter() {} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.h b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.h new file mode 100644 index 000000000..0e5bb66c8 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.h @@ -0,0 +1,54 @@ +/* + * 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_FS_PROPERTIES_PROP_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_PROP_N_EXPORTER_H + +#include "filemgmt_libhilog.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::FileManagement::LibN; +struct AsyncIOWrtieArg { + NRef refWriteArrayBuf_; + std::unique_ptr guardWriteStr_; + ssize_t actLen = 0; + + explicit AsyncIOWrtieArg(NVal refWriteArrayBuf) : refWriteArrayBuf_(refWriteArrayBuf) {} + explicit AsyncIOWrtieArg(std::unique_ptr &&guardWriteStr) : guardWriteStr_(move(guardWriteStr)) {} + ~AsyncIOWrtieArg() = default; +}; + +class PropNExporter final : public NExporter { +public: + inline static const std::string className_ = "__properities__"; + + static napi_value ReadSync(napi_env env, napi_callback_info info); + static napi_value WriteSync(napi_env env, napi_callback_info info); + static napi_value Read(napi_env env, napi_callback_info info); + static napi_value Write(napi_env env, napi_callback_info info); + static NError WriteExec(std::shared_ptr arg, void *buf, size_t len, int fd, size_t position); + bool Export() override; + std::string GetClassName() override; + + PropNExporter(napi_env env, napi_value exports); + ~PropNExporter() override; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_PROP_N_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/stat.cpp b/interfaces/kits/js/src/mod_fs/properties/stat.cpp new file mode 100644 index 000000000..9028f9e25 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/stat.cpp @@ -0,0 +1,148 @@ +/* + * 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 "stat.h" + +#include +#include + +#include "../common_func.h" +#include "class_stat/stat_entity.h" +#include "class_stat/stat_n_exporter.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NVal InstantiateStat(napi_env env, struct stat &buf) +{ + napi_value objStat = NClass::InstantiateClass(env, StatNExporter::className_, {}); + if (!objStat) { + HILOGE("Failed to instantiate stat class"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto statEntity = NClass::GetEntityOf(env, objStat); + if (!statEntity) { + HILOGE("Failed to get stat entity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + statEntity->stat_ = buf; + return { env, objStat }; +} + +static tuple ParseJsFile(napi_env env, napi_value pathOrFdFromJsArg) +{ + auto [isPath, path, ignore] = NVal(env, pathOrFdFromJsArg).ToUTF8String(); + if (isPath) { + return { true, FileInfo { true, move(path), {} } }; + } + auto [isFd, fd] = NVal(env, pathOrFdFromJsArg).ToInt32(); + if (isFd) { + if (fd < 0) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return { false, FileInfo { false, {}, {} } }; + } + return { true, FileInfo { false, {}, { fd, false } } }; + } + HILOGE("Invalid parameter"); + NError(EINVAL).ThrowErr(env); + return { false, FileInfo { false, {}, {} } }; +}; + +napi_value Stat::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + return nullptr; + } + + struct stat buf; + if (fileInfo.isPath) { + if (stat(fileInfo.path.get(), &buf) < 0) { + HILOGE("Failed to stat file with path"); + NError(errno).ThrowErr(env); + return nullptr; + } + } else { + if (fstat(fileInfo.fdg.GetFD(), &buf) < 0) { + HILOGE("Failed to stat file with fd"); + NError(errno).ThrowErr(env); + return nullptr; + } + } + + auto stat = InstantiateStat(env, buf).val_; + return stat; +} + +struct AsyncStatArg { + struct stat stat_; +}; + +napi_value Stat::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + return nullptr; + } + + auto arg = make_shared(); + auto cbExec = [arg, fileInfo = make_shared(move(fileInfo))]() -> NError { + if (fileInfo->isPath) { + if (stat(fileInfo->path.get(), &arg->stat_) < 0) { + HILOGE("Failed to stat file with path"); + return NError(errno); + } + } else { + if (fstat(fileInfo->fdg.GetFD(), &arg->stat_) < 0) { + HILOGE("Failed to stat file with fd"); + return NError(errno); + } + } + return NError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + auto stat = InstantiateStat(env, arg->stat_); + return stat; + }; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STAT_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STAT_NAME, cbExec, cbCompl).val_; + } +} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/stat.h b/interfaces/kits/js/src/mod_fs/properties/stat.h new file mode 100644 index 000000000..fafdaa54e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/stat.h @@ -0,0 +1,29 @@ +/* + * 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_FS_PROPERTIES_STAT_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_STAT_H + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class Stat 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 PROCEDURE_STAT_NAME = "FileIOStat"; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_STAT_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/symlink.cpp b/interfaces/kits/js/src/mod_fs/properties/symlink.cpp new file mode 100644 index 000000000..9699168a4 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/symlink.cpp @@ -0,0 +1,114 @@ +/* + * 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 "symlink.h" + +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static tuple GetSymlinkArg(napi_env env, const NFuncArg &funcArg) +{ + auto [resGetFirstArg, src, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid src"); + NError(EINVAL).ThrowErr(env); + return { false, "", "" }; + } + + auto [resGetSecondArg, dest, useless] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + HILOGE("Invalid dest"); + NError(EINVAL).ThrowErr(env); + return { false, "", "" }; + } + + return { true, src.get(), dest.get() }; +} + +napi_value Symlink::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetSymlinkArg, oldPath, newPath] = GetSymlinkArg(env, funcArg); + if (!resGetSymlinkArg) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + if (symlink(oldPath.c_str(), newPath.c_str()) < 0) { + HILOGE("Failed to create a link for old path: %{public}s", oldPath.c_str()); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value Symlink::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetSymlinkArg, oldPath, newPath] = GetSymlinkArg(env, funcArg); + if (!resGetSymlinkArg) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [oldPath = move(oldPath), newPath = move(newPath)]() -> NError { + int ret = symlink(oldPath.c_str(), newPath.c_str()); + if (ret < 0) { + HILOGE("Failed to create a link for old path: %{public}s, ret: %{public}d", oldPath.c_str(), ret); + return NError(errno); + } else { + return NError(ERRNO_NOERR); + } + }; + + auto cbComplCallback = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + const string procedureName = "FileIOSymLink"; + NVal thisVar(env, funcArg.GetThisVar()); + size_t argc = funcArg.GetArgc(); + if (argc == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplCallback).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplCallback).val_; + } +} +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/properties/symlink.h b/interfaces/kits/js/src/mod_fs/properties/symlink.h new file mode 100644 index 000000000..0b14e8bec --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/symlink.h @@ -0,0 +1,28 @@ +/* + * 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_FS_PROPERTIES_SYMLINK_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_SYMLINK_H + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class Symlink final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_SYMLINK_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/truncate.cpp b/interfaces/kits/js/src/mod_fs/properties/truncate.cpp new file mode 100644 index 000000000..0c0e9db88 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/truncate.cpp @@ -0,0 +1,161 @@ +/* + * 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 "truncate.h" + +#include +#include +#include + +#include "../common_func.h" +#include "filemgmt_libhilog.h" +#include "uv.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static tuple ParseJsFile(napi_env env, napi_value pathOrFdFromJsArg) +{ + auto [isPath, path, ignore] = NVal(env, pathOrFdFromJsArg).ToUTF8String(); + if (isPath) { + return { true, FileInfo { true, move(path), {} } }; + } + auto [isFd, fd] = NVal(env, pathOrFdFromJsArg).ToInt32(); + if (!isFd || fd < 0) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return { false, FileInfo { false, {}, {} } }; + } + return { true, FileInfo { false, {}, { fd, false } } }; +}; + +napi_value Truncate::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + int truncateLen = 0; + if (funcArg.GetArgc() == NARG_CNT::TWO) { + tie(succ, truncateLen) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt64(); + if (!succ) { + HILOGE("Invalid truncate length"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + } + if (fileInfo.isPath) { + std::unique_ptr open_req = { new uv_fs_t, uv_fs_req_cleanup }; + int ret = uv_fs_open(nullptr, open_req.get(), fileInfo.path.get(), O_RDWR, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, nullptr); + if (ret < 0) { + NError(errno).ThrowErr(env); + return nullptr; + } + std::unique_ptr ftruncate_req = { new uv_fs_t, uv_fs_req_cleanup }; + ret = uv_fs_ftruncate(nullptr, ftruncate_req.get(), open_req.get()->result, truncateLen, nullptr); + if (ret < 0) { + HILOGE("Failed to truncate file by path"); + NError(errno).ThrowErr(env); + return nullptr; + } + } else { + std::unique_ptr ftruncate_req = { new uv_fs_t, uv_fs_req_cleanup }; + int ret = uv_fs_ftruncate(nullptr, ftruncate_req.get(), fileInfo.fdg.GetFD(), truncateLen, nullptr); + if (ret < 0) { + HILOGE("Failed to truncate file by fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + } + return NVal::CreateUndefined(env).val_; +} + +napi_value Truncate::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + return nullptr; + } + int truncateLen = 0; + if (funcArg.GetArgc() > NARG_CNT::ONE && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) { + tie(succ, truncateLen) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt64(); + if (!succ) { + HILOGE("Invalid truncate length"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + } + auto cbExec = [fileInfo = make_shared(move(fileInfo)), truncateLen, env = env]() -> NError { + using uv_fs_unique_ptr_type = std::unique_ptr; + if (fileInfo->isPath) { + uv_fs_unique_ptr_type open_req = { new uv_fs_t, uv_fs_req_cleanup }; + int ret = uv_fs_open(uv_default_loop(), open_req.get(), fileInfo->path.get(), O_RDWR, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, nullptr); + if (ret < 0) { + return NError(errno); + } + uv_fs_unique_ptr_type ftruncate_req = { new uv_fs_t, uv_fs_req_cleanup }; + ret = uv_fs_ftruncate(uv_default_loop(), ftruncate_req.get(), open_req.get()->result, truncateLen, nullptr); + if (ret < 0) { + HILOGE("Failed to truncate file by path"); + return NError(errno); + } + } else { + uv_fs_unique_ptr_type ftruncate_req = { new uv_fs_t, uv_fs_req_cleanup }; + int ret = uv_fs_ftruncate(uv_default_loop(), ftruncate_req.get(), fileInfo->fdg.GetFD(), truncateLen, nullptr); + if (ret < 0) { + HILOGE("Failed to truncate file by fd"); + return NError(errno); + } + } + return NError(ERRNO_NOERR); + }; + auto cbCompl = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUndefined(env); + } + }; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE || + (funcArg.GetArgc() == NARG_CNT::TWO && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number))) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_TRUNCATE_NAME, cbExec, cbCompl).val_; + } else { + if (funcArg.GetArgc() == NARG_CNT::ONE) { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_TRUNCATE_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_TRUNCATE_NAME, cbExec, cbCompl).val_; + } + } +} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/truncate.h b/interfaces/kits/js/src/mod_fs/properties/truncate.h new file mode 100644 index 000000000..8b0930870 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/truncate.h @@ -0,0 +1,29 @@ +/* + * 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_FS_PROPERTIES_TRUNCATE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_TRUNCATE_H + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class Truncate 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 PROCEDURE_TRUNCATE_NAME = "FileIOTruncate"; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_TRUNCATE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/hash.cpp b/interfaces/kits/js/src/mod_hash/hash.cpp new file mode 100644 index 000000000..3158df16e --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/hash.cpp @@ -0,0 +1,133 @@ +/* + * 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 "hash.h" + +#include +#include +#include + +#include "filemgmt_libhilog.h" +#include "hash_file.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static HASH_ALGORITHM_TYPE GetHashAlgorithm(const string &alg) +{ + return (algorithmMaps.find(alg) != algorithmMaps.end()) ? algorithmMaps.at(alg) : HASH_ALGORITHM_TYPE_UNSUPPORTED; +} + +static tuple, HASH_ALGORITHM_TYPE, bool> GetHashArgs(napi_env env, const NFuncArg &funcArg) +{ + bool isPromise = false; + auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + auto [resGetSecondArg, alg, ignore] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + HILOGE("Invalid algorithm"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + HASH_ALGORITHM_TYPE algType = GetHashAlgorithm(alg.get()); + if (algType == HASH_ALGORITHM_TYPE_UNSUPPORTED) { + HILOGE("Invalid algorithm"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + if (funcArg.GetArgc() == NARG_CNT::THREE && !NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function)) { + HILOGE("Invalid callback"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + isPromise = funcArg.GetArgc() == NARG_CNT::TWO; + return { true, move(path), algType, isPromise }; +} + +napi_value Hash::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, fpath, algType, isPromise] = GetHashArgs(env, funcArg); + if (!succ) { + HILOGE("Failed to get hash args"); + return nullptr; + } + + auto arg = make_shared(); + auto cbExec = [fpath = string(fpath.release()), arg, algType = algType, env = env]() -> NError { + int ret = EIO; + string &res = *arg; + if (algType == HASH_ALGORITHM_TYPE_MD5) { + tie(ret, res) = DistributedFS::HashFile::HashWithMD5(fpath); + } else if (algType == HASH_ALGORITHM_TYPE_SHA1) { + tie(ret, res) = DistributedFS::HashFile::HashWithSHA1(fpath); + } else if (algType == HASH_ALGORITHM_TYPE_SHA256) { + tie(ret, res) = DistributedFS::HashFile::HashWithSHA256(fpath); + } + return NError(ret); + }; + + auto cbComplete = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { NVal(env, err.GetNapiErr(env)) }; + } + + return { NVal::CreateUTF8String(env, *arg) }; + }; + + const string procedureName = "FileIOHash"; + NVal thisVar(env, funcArg.GetThisVar()); + if (isPromise) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; + } +} + +bool HashNExporter::Export() +{ + return exports_.AddProp({ + NVal::DeclareNapiFunction("hash", Hash::Async), + }); +} + +string HashNExporter::GetClassName() +{ + return HashNExporter::className_; +} + +HashNExporter::HashNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/hash.h b/interfaces/kits/js/src/mod_hash/hash.h new file mode 100644 index 000000000..1a9f85505 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/hash.h @@ -0,0 +1,56 @@ +/* + * 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_HASH_PROPERTIES_HASH_H +#define INTERFACES_KITS_JS_SRC_MOD_HASH_PROPERTIES_HASH_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::FileManagement::LibN; + +enum HASH_ALGORITHM_TYPE { + HASH_ALGORITHM_TYPE_MD5, + HASH_ALGORITHM_TYPE_SHA1, + HASH_ALGORITHM_TYPE_SHA256, + HASH_ALGORITHM_TYPE_UNSUPPORTED, +}; + +const std::map algorithmMaps = { + {"md5", HASH_ALGORITHM_TYPE_MD5}, + {"sha1", HASH_ALGORITHM_TYPE_SHA1}, + {"sha256", HASH_ALGORITHM_TYPE_SHA256}, +}; + +class Hash final { +public: + static napi_value Async(napi_env env, napi_callback_info info); +}; + +class HashNExporter final : public NExporter { +public: + inline static const std::string className_ = "Hash"; + bool Export() override; + std::string GetClassName() override; + + HashNExporter(napi_env env, napi_value exports); + ~HashNExporter() = default; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_HASH_PROPERTIES_HASH_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/module.cpp b/interfaces/kits/js/src/mod_hash/module.cpp new file mode 100644 index 000000000..5521fafe9 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/module.cpp @@ -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. + */ + +#include +#include + +#include "filemgmt_libhilog.h" +#include "hash.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +static napi_value Export(napi_env env, napi_value exports) +{ + std::unique_ptr products = make_unique(env, exports); + + if (!products->Export()) { + HILOGE("INNER BUG. Failed to export class %{public}s for module fileio", products->GetClassName().c_str()); + return nullptr; + } else { + HILOGI("Class %{public}s for module fileio has been exported", products->GetClassName().c_str()); + } + return exports; +} + +NAPI_MODULE(hash, Export) +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/utils/filemgmt_libhilog/filemgmt_libhilog.h b/utils/filemgmt_libhilog/filemgmt_libhilog.h index 6b21e8470..2a6d31c18 100644 --- a/utils/filemgmt_libhilog/filemgmt_libhilog.h +++ b/utils/filemgmt_libhilog/filemgmt_libhilog.h @@ -22,15 +22,9 @@ namespace OHOS { namespace FileManagement { -#ifndef LOG_DOMAIN -#define LOG_DOMAIN 0xD004388 -#endif - -#ifndef LOG_TAG -#define LOG_TAG "file_api" -#endif -static constexpr HiviewDFX::HiLogLabel FILEMGMT_LOG_LABEL = {LOG_CORE, LOG_DOMAIN, LOG_TAG}; +static constexpr int FILEFS_LOG_DOMAIN = 0xD004388; +static constexpr HiviewDFX::HiLogLabel FILEMGMT_LOG_LABEL = {LOG_CORE, FILEFS_LOG_DOMAIN, "file_api"}; #if defined __FILE_NAME__ #define FILEMGMT_FILE_NAME __FILE_NAME__ @@ -43,6 +37,10 @@ static constexpr HiviewDFX::HiLogLabel FILEMGMT_LOG_LABEL = {LOG_CORE, LOG_DOMAI HiviewDFX::HiLog::Level(FILEMGMT_LOG_LABEL, "[%{public}s:%{public}d->%{public}s] " fmt, FILEMGMT_FILE_NAME, \ __LINE__, __FUNCTION__, ##__VA_ARGS__) +#ifdef HILOGD +#undef HILOGD +#endif + #ifdef HILOGF #undef HILOGF #endif diff --git a/utils/filemgmt_libn/include/n_error.h b/utils/filemgmt_libn/include/n_error.h index 589e996e0..a60dcd610 100644 --- a/utils/filemgmt_libn/include/n_error.h +++ b/utils/filemgmt_libn/include/n_error.h @@ -84,7 +84,17 @@ enum ErrCodeSuffixOfUserFileManager { E_DISPLAYNAME = 1, E_URIM, E_SUFFIX, - E_TRASH + E_TRASH, + E_OPEN_MODE, + E_NOT_ALBUM, + E_ROOT_DIR, + E_MOVE_DENIED, + E_RENAME_DENIED, + E_RELATIVEPATH, + E_INNER_FAIL, + E_FILE_TYPE, + E_FILE_KEY, + E_INPUT }; enum ErrCodeSuffixOfStorageService { @@ -213,6 +223,26 @@ const std::unordered_map> errCodeTable { "Invalid file extension" } }, { USER_FILE_MANAGER_SYS_CAP_TAG + E_TRASH, { USER_FILE_MANAGER_SYS_CAP_TAG + E_TRASH, "File has been put into trash bin" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_OPEN_MODE, { USER_FILE_MANAGER_SYS_CAP_TAG + E_OPEN_MODE, + "Invalid open mode" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_NOT_ALBUM, { USER_FILE_MANAGER_SYS_CAP_TAG + E_NOT_ALBUM, + "The uri is not album" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_ROOT_DIR, { USER_FILE_MANAGER_SYS_CAP_TAG + E_ROOT_DIR, + "Invalid root dir" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_MOVE_DENIED, { USER_FILE_MANAGER_SYS_CAP_TAG + E_MOVE_DENIED, + "Failed to move as dir check failed" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_RENAME_DENIED, { USER_FILE_MANAGER_SYS_CAP_TAG + E_RENAME_DENIED, + "Failed to rename as dir check failed" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_RELATIVEPATH, { USER_FILE_MANAGER_SYS_CAP_TAG + E_RELATIVEPATH, + "Relative path not exist or invalid" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_INNER_FAIL, { USER_FILE_MANAGER_SYS_CAP_TAG + E_INNER_FAIL, + "MediaLibrary inner fail" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_FILE_TYPE, { USER_FILE_MANAGER_SYS_CAP_TAG + E_FILE_TYPE, + "File type is not allow in the directory" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_FILE_KEY, { USER_FILE_MANAGER_SYS_CAP_TAG + E_FILE_KEY, + "Member not exist" } }, + { USER_FILE_MANAGER_SYS_CAP_TAG + E_INPUT, { USER_FILE_MANAGER_SYS_CAP_TAG + E_INPUT, + "Wrong input parameter" } }, { STORAGE_SERVICE_SYS_CAP_TAG + E_IPCSS, { STORAGE_SERVICE_SYS_CAP_TAG + E_IPCSS, "IPC error" } }, { STORAGE_SERVICE_SYS_CAP_TAG + E_NOTSUPPORTEDFS, { STORAGE_SERVICE_SYS_CAP_TAG + E_NOTSUPPORTEDFS, "Not supported filesystem" } }, diff --git a/utils/filemgmt_libn/src/n_async/n_async_work_callback.cpp b/utils/filemgmt_libn/src/n_async/n_async_work_callback.cpp index 291d183d4..f040cfabe 100644 --- a/utils/filemgmt_libn/src/n_async/n_async_work_callback.cpp +++ b/utils/filemgmt_libn/src/n_async/n_async_work_callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -73,7 +73,8 @@ static void CallbackComplete(napi_env env, napi_status status, void *data) NVal NAsyncWorkCallback::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) { if (!ctx_->cb_ || !ctx_->cb_.Deref(env_).TypeIs(napi_function)) { - NError(EINVAL).ThrowErr(env_, "The callback should be a function"); + HILOGE("The callback should be a function"); + NError(EINVAL).ThrowErr(env_); return NVal(); } -- Gitee