diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn old mode 100644 new mode 100755 index 4a67419f1e2341ca5d763664d10ce895e60c4c66..90795c6f80b8e4dd4e7ccf84ba9873a133fb3a53 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# Copyright (c) 2021-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 @@ -117,11 +117,23 @@ ohos_shared_library("fs") { "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/class_stream/flush.cpp", + "src/mod_fs/class_stream/stream_n_exporter.cpp", "src/mod_fs/common_func.cpp", "src/mod_fs/module.cpp", + "src/mod_fs/properties/close.cpp", + "src/mod_fs/properties/copy_file.cpp", + "src/mod_fs/properties/create_stream.cpp", + "src/mod_fs/properties/fdatasync.cpp", + "src/mod_fs/properties/fdopen_stream.cpp", + "src/mod_fs/properties/fsync.cpp", "src/mod_fs/properties/lstat.cpp", + "src/mod_fs/properties/mkdtemp.cpp", "src/mod_fs/properties/open.cpp", "src/mod_fs/properties/prop_n_exporter.cpp", + "src/mod_fs/properties/read_text.cpp", + "src/mod_fs/properties/rename.cpp", + "src/mod_fs/properties/rmdirent.cpp", "src/mod_fs/properties/stat.cpp", "src/mod_fs/properties/symlink.cpp", "src/mod_fs/properties/truncate.cpp", diff --git a/interfaces/kits/js/src/common/uni_error.cpp b/interfaces/kits/js/src/common/uni_error.cpp index 05395ca437ffa5a40f3b96b60042cd88da2ec87f..93d5e46acc9d2077c3e84eb4f395e3df27164b6e 100644 --- a/interfaces/kits/js/src/common/uni_error.cpp +++ b/interfaces/kits/js/src/common/uni_error.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -45,6 +45,9 @@ UniError::UniError(ELegacy eLegacy) : errno_(eLegacy), codingSystem_(ERR_CODE_SY UniError::UniError(int ePosix) : errno_(ePosix), codingSystem_(ERR_CODE_SYSTEM_POSIX) {} +UniError::UniError(int ePosix, bool throwCode) : errno_(ePosix), codingSystem_(ERR_CODE_SYSTEM_POSIX), + throwCode_(throwCode) {} + UniError::operator bool() const { return errno_ != ERRNO_NOERR; @@ -95,6 +98,9 @@ napi_value UniError::GetNapiErr(napi_env env) if (errCode == ERRNO_NOERR) { return nullptr; } + if (!throwCode_) { + return GetNapiErr(env, GetDefaultErrstr()); + } int32_t code; string msg; if (errCodeTable.find(errCode) != errCodeTable.end()) { @@ -109,15 +115,9 @@ napi_value UniError::GetNapiErr(napi_env env) napi_value UniError::GetNapiErr(napi_env env, string errMsg) { - int errCode = GetErrno(codingSystem_); - if (errCode == ERRNO_NOERR) { - return nullptr; - } - napi_value code = NVal::CreateUTF8String(env, to_string(errCode)).val_; napi_value msg = NVal::CreateUTF8String(env, errMsg).val_; - napi_value res = nullptr; - napi_status createRes = napi_create_error(env, code, msg, &res); + napi_status createRes = napi_create_error(env, nullptr, msg, &res); if (createRes) { HILOGE("Failed to create an exception, msg = %{public}s", errMsg.c_str()); } @@ -130,6 +130,7 @@ void UniError::ThrowErr(napi_env env) napi_get_and_clear_last_exception(env, &tmp); int32_t code; string msg; + napi_status throwStatus = napi_ok; if (errCodeTable.find(errno_) != errCodeTable.end()) { code = errCodeTable.at(errno_).first; msg = errCodeTable.at(errno_).second; @@ -137,7 +138,12 @@ void UniError::ThrowErr(napi_env env) code = errCodeTable.at(-1).first; msg = errCodeTable.at(-1).second; } - napi_status throwStatus = napi_throw(env, GenerateBusinessError(env, code, msg)); + if (!throwCode_) { + throwStatus = napi_throw_error(env, nullptr, msg.c_str()); + } else { + throwStatus = napi_throw(env, GenerateBusinessError(env, code, msg)); + } + if (throwStatus != napi_ok) { HILOGE("Failed to throw an exception, %{public}d, code = %{public}s", throwStatus, msg.c_str()); } diff --git a/interfaces/kits/js/src/common/uni_error.h b/interfaces/kits/js/src/common/uni_error.h index b9d2b7a303dff27f623747fef517cbc47a2d07b2..c6ea4dbcdee65f716436ee473a98a977c70d98d7 100644 --- a/interfaces/kits/js/src/common/uni_error.h +++ b/interfaces/kits/js/src/common/uni_error.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -134,6 +134,7 @@ public: UniError(); explicit UniError(ELegacy eLegacy); explicit UniError(int ePosix); + explicit UniError(int ePosix, bool throwCode); UniError(const UniError &) = default; ~UniError() = default; @@ -155,6 +156,7 @@ public: private: int errno_ = ERRNO_NOERR; ErrCodeSystem codingSystem_ = ERR_CODE_SYSTEM_POSIX; + bool throwCode_ = false; }; } // namespace DistributedFS } // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.cpp index 8adda7d37e005a1048ec82f7a0ce0cb35e6957e7..4eeb63358e881794c575b497ff2618a236cf0553 100644 --- a/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.cpp @@ -38,11 +38,11 @@ static FileEntity *GetFileEntity(napi_env env, napi_value raf_entity) { auto rafEntity = NClass::GetEntityOf(env, raf_entity); if (!rafEntity) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } if (!rafEntity->fd_) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } return rafEntity; @@ -52,7 +52,7 @@ napi_value FileNExporter::GetFD(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto rafEntity = GetFileEntity(env, funcArg.GetThisVar()); @@ -66,13 +66,13 @@ napi_value FileNExporter::Constructor(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto rafEntity = make_unique(); if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(rafEntity))) { - UniError(EIO).ThrowErr(env); + UniError(EIO, true).ThrowErr(env); return nullptr; } return funcArg.GetThisVar(); @@ -90,12 +90,12 @@ bool FileNExporter::Export() tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, FileNExporter::Constructor, move(props)); if (!succ) { - UniError(EIO).ThrowErr(exports_.env_); + UniError(EIO, true).ThrowErr(exports_.env_); return false; } succ = NClass::SaveClass(exports_.env_, className, classValue); if (!succ) { - UniError(EIO).ThrowErr(exports_.env_); + UniError(EIO, true).ThrowErr(exports_.env_); return false; } diff --git a/interfaces/kits/js/src/mod_fileio/class_stat_v9/stat_n_exporter_v9.cpp b/interfaces/kits/js/src/mod_fileio/class_stat_v9/stat_n_exporter_v9.cpp index ee9f5e40e7ec8cf28a905ac1d59232c9ffc31edc..fb2768f698b00b72d525ed2108c7fa2e1b354d1e 100644 --- a/interfaces/kits/js/src/mod_fileio/class_stat_v9/stat_n_exporter_v9.cpp +++ b/interfaces/kits/js/src/mod_fileio/class_stat_v9/stat_n_exporter_v9.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 @@ -42,7 +42,7 @@ static napi_value CheckStatMode(napi_env env, napi_callback_info info, mode_t mo { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -94,7 +94,7 @@ napi_value StatNExporterV9::GetIno(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -110,7 +110,7 @@ napi_value StatNExporterV9::GetMode(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -126,7 +126,7 @@ napi_value StatNExporterV9::GetUid(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -142,7 +142,7 @@ napi_value StatNExporterV9::GetGid(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -158,7 +158,7 @@ napi_value StatNExporterV9::GetSize(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -174,7 +174,7 @@ napi_value StatNExporterV9::GetBlksize(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -190,7 +190,7 @@ napi_value StatNExporterV9::GetAtime(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -206,7 +206,7 @@ napi_value StatNExporterV9::GetMtime(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -222,7 +222,7 @@ napi_value StatNExporterV9::GetCtime(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -238,13 +238,13 @@ napi_value StatNExporterV9::Constructor(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } unique_ptr statEntity = make_unique(); if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(statEntity))) { - UniError(EIO).ThrowErr(env); + UniError(EIO, true).ThrowErr(env); return nullptr; } return funcArg.GetThisVar(); @@ -278,12 +278,12 @@ bool StatNExporterV9::Export() tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, StatNExporterV9::Constructor, std::move(props)); if (!succ) { - UniError(EIO).ThrowErr(exports_.env_); + UniError(EIO, true).ThrowErr(exports_.env_); return false; } succ = NClass::SaveClass(exports_.env_, className, classValue); if (!succ) { - UniError(EIO).ThrowErr(exports_.env_); + UniError(EIO, true).ThrowErr(exports_.env_); return false; } diff --git a/interfaces/kits/js/src/mod_fileio/properties/open_v9.cpp b/interfaces/kits/js/src/mod_fileio/properties/open_v9.cpp index 34955cac21411ee8ddaca33c014f4c5182f02cfa..0ccb51d7571e87bd41ae9fe0366026e7a9db7714 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/open_v9.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/open_v9.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 @@ -46,7 +46,7 @@ static tuple GetJsFlags(napi_env env, const NFuncArg &funcArg) 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) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return { false, mode }; } (void)CommonFunc::ConvertJsFlags(mode); @@ -58,13 +58,13 @@ static NVal InstantiateFile(napi_env env, int fd, string path) { napi_value objRAF = NClass::InstantiateClass(env, FileNExporter::className_, {}); if (!objRAF) { - UniError(EIO).ThrowErr(env); + UniError(EIO, true).ThrowErr(env); return NVal(); } auto rafEntity = NClass::GetEntityOf(env, objRAF); if (!rafEntity) { - UniError(EIO).ThrowErr(env); + UniError(EIO, true).ThrowErr(env); return NVal(); } auto fdg = make_unique(fd, false); @@ -93,12 +93,12 @@ napi_value OpenV9::Sync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); if (!succPath) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto [succMode, mode] = GetJsFlags(env, funcArg); @@ -111,7 +111,7 @@ napi_value OpenV9::Sync(napi_env env, napi_callback_info info) auto File = InstantiateFile(env, fd, path.get()).val_; return File; } - UniError(-1).ThrowErr(env); + UniError(-1, true).ThrowErr(env); return nullptr; } uv_loop_s *loop = nullptr; @@ -120,7 +120,7 @@ napi_value OpenV9::Sync(napi_env env, napi_callback_info info) int ret = uv_fs_open(loop, &open_req, path.get(), mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, NULL); if (ret < 0) { - UniError(errno).ThrowErr(env); + UniError(errno, true).ThrowErr(env); return nullptr; } auto File = InstantiateFile(env, open_req.result, path.get()).val_; @@ -138,12 +138,12 @@ napi_value OpenV9::Async(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); if (!succPath) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto [succMode, mode] = GetJsFlags(env, funcArg); @@ -161,7 +161,7 @@ napi_value OpenV9::Async(napi_env env, napi_callback_info info) arg->uri = ""; return UniError(ERRNO_NOERR); } - return UniError(-1); + return UniError(-1, true); } uv_loop_s *loop = nullptr; napi_get_uv_event_loop(env, &loop); @@ -169,7 +169,7 @@ napi_value OpenV9::Async(napi_env env, napi_callback_info info) int ret = uv_fs_open(loop, &open_req, path.c_str(), mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, NULL); if (ret < 0) { - return UniError(errno); + return UniError(errno, true); } arg->fd = open_req.result; arg->path = path; diff --git a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.cpp b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.cpp index 0c94dcc946720c715ea8146b50aec648dd0bc75b..cfa371471df1878484174542329447a164cc706c 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.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 @@ -37,7 +37,7 @@ napi_value PropNExporterV9::ReadSync(napi_env env, napi_callback_info info) NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -45,7 +45,7 @@ napi_value PropNExporterV9::ReadSync(napi_env env, napi_callback_info info) int fd = 0; tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -66,7 +66,7 @@ napi_value PropNExporterV9::ReadSync(napi_env env, napi_callback_info info) actLen = read(fd, buf, len); } if (actLen == -1) { - UniError(errno).ThrowErr(env); + UniError(errno, true).ThrowErr(env); return nullptr; } @@ -86,7 +86,7 @@ static UniError ReadExec(shared_ptr arg, void *buf, size_t len, } if (arg->lenRead == -1) { - return UniError(errno); + return UniError(errno, true); } else { return UniError(ERRNO_NOERR); } @@ -96,7 +96,7 @@ napi_value PropNExporterV9::Read(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::FOUR)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -108,14 +108,14 @@ napi_value PropNExporterV9::Read(napi_env env, napi_callback_info info) int64_t pos = 0; tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } tie(succ, buf, len, hasPos, pos) = CommonFunc::GetReadArgV9(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); if (!succ) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -159,7 +159,7 @@ UniError PropNExporterV9::WriteExec(shared_ptr arg, void *buf, } if (arg->actLen == -1) { - return UniError(errno); + return UniError(errno, true); } else { return UniError(ERRNO_NOERR); } @@ -169,7 +169,7 @@ napi_value PropNExporterV9::Write(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::FOUR)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -177,7 +177,7 @@ napi_value PropNExporterV9::Write(napi_env env, napi_callback_info info) int fd; tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -189,7 +189,7 @@ napi_value PropNExporterV9::Write(napi_env env, napi_callback_info info) tie(succ, bufGuard, buf, len, hasPos, position) = CommonFunc::GetWriteArgV9(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); if (!succ) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -236,7 +236,7 @@ napi_value PropNExporterV9::WriteSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -244,7 +244,7 @@ napi_value PropNExporterV9::WriteSync(napi_env env, napi_callback_info info) int fd; tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } @@ -267,7 +267,7 @@ napi_value PropNExporterV9::WriteSync(napi_env env, napi_callback_info info) } if (writeLen == -1) { - UniError(errno).ThrowErr(env); + UniError(errno, true).ThrowErr(env); return nullptr; } diff --git a/interfaces/kits/js/src/mod_fileio/properties/stat_v9.cpp b/interfaces/kits/js/src/mod_fileio/properties/stat_v9.cpp index 86322baa783260f940c8f01f4c3c46fa0a9aa39e..e513d5530b588be4844fa73dc474940fce38e5cf 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/stat_v9.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/stat_v9.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 @@ -48,12 +48,12 @@ static tuple ParseJsFile(napi_env env, napi_value pathOrFdFromJs auto [isFd, fd] = NVal(env, pathOrFdFromJsArg).ToInt32(); if (isFd) { if (fd < 0) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return { false, FileInfo { false, {}, {} } }; } return { true, FileInfo { false, {}, { fd, false } } }; } - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return { false, FileInfo { false, {}, {} } }; }; @@ -61,7 +61,7 @@ napi_value StatV9::Sync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ONE)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); @@ -72,24 +72,24 @@ napi_value StatV9::Sync(napi_env env, napi_callback_info info) struct stat buf; if (fileInfo.isPath) { if (stat(fileInfo.path.get(), &buf) != 0) { - UniError(errno).ThrowErr(env); + UniError(errno, true).ThrowErr(env); return nullptr; } } else { if (fstat(fileInfo.fdg.GetFD(), &buf) != 0) { - UniError(errno).ThrowErr(env); + UniError(errno, true).ThrowErr(env); return nullptr; } } napi_value objStat = NClass::InstantiateClass(env, StatNExporterV9::className_, {}); if (!objStat) { - UniError(EIO).ThrowErr(env); + UniError(EIO, true).ThrowErr(env); return nullptr; } auto statEntity = NClass::GetEntityOf(env, objStat); if (!statEntity) { - UniError(EIO).ThrowErr(env); + UniError(EIO, true).ThrowErr(env); return nullptr; } statEntity->stat_ = buf; @@ -104,7 +104,7 @@ napi_value StatV9::Async(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); @@ -116,11 +116,11 @@ napi_value StatV9::Async(napi_env env, napi_callback_info info) auto cbExec = [arg, fileInfo = make_shared(move(fileInfo))](napi_env env) -> UniError { if (fileInfo->isPath) { if (stat(fileInfo->path.get(), &arg->stat_) != 0) { - return UniError(errno); + return UniError(errno, true); } } else { if (fstat(fileInfo->fdg.GetFD(), &arg->stat_) != 0) { - return UniError(errno); + return UniError(errno, true); } } return UniError(ERRNO_NOERR); @@ -131,11 +131,11 @@ napi_value StatV9::Async(napi_env env, napi_callback_info info) } napi_value objStat = NClass::InstantiateClass(env, StatNExporterV9::className_, {}); if (!objStat) { - return { env, UniError(EIO).GetNapiErr(env) }; + return { env, UniError(EIO, true).GetNapiErr(env) }; } auto statEntity = NClass::GetEntityOf(env, objStat); if (!statEntity) { - return { env, UniError(EIO).GetNapiErr(env) }; + return { env, UniError(EIO, true).GetNapiErr(env) }; } statEntity->stat_ = arg->stat_; return { env, objStat }; diff --git a/interfaces/kits/js/src/mod_fileio/properties/truncate_v9.cpp b/interfaces/kits/js/src/mod_fileio/properties/truncate_v9.cpp index fd7777b63055f1bcd2bd425f97710bbfd11d3031..c79d72d3044bdad85702d56e1f3d8a779470a493 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/truncate_v9.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/truncate_v9.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 @@ -41,12 +41,12 @@ static tuple ParseJsFile(napi_env env, napi_value pathOrFdFromJs auto [isFd, fd] = NVal(env, pathOrFdFromJsArg).ToInt32(); if (isFd) { if (fd < 0) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return { false, FileInfo { false, {}, {} } }; } return { true, FileInfo { false, {}, { fd, false } } }; } - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return { false, FileInfo { false, {}, {} } }; }; @@ -55,7 +55,7 @@ napi_value TruncateV9::Sync(napi_env env, napi_callback_info info) NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); @@ -66,18 +66,18 @@ napi_value TruncateV9::Sync(napi_env env, napi_callback_info info) if (funcArg.GetArgc() == NARG_CNT::TWO) { tie(succ, truncateLen) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); if (!succ) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } } if (fileInfo.isPath) { if (truncate(fileInfo.path.get(), truncateLen) != 0) { - UniError(errno).ThrowErr(env); + UniError(errno, true).ThrowErr(env); return nullptr; } } else { if (ftruncate(fileInfo.fdg.GetFD(), truncateLen) != 0) { - UniError(errno).ThrowErr(env); + UniError(errno, true).ThrowErr(env); return nullptr; } } @@ -88,7 +88,7 @@ napi_value TruncateV9::Async(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); @@ -99,18 +99,18 @@ napi_value TruncateV9::Async(napi_env env, napi_callback_info info) if (funcArg.GetArgc() > NARG_CNT::ONE && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) { tie(succ, truncateLen) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); if (!succ) { - UniError(EINVAL).ThrowErr(env); + UniError(EINVAL, true).ThrowErr(env); return nullptr; } } auto cbExec = [fileInfo = make_shared(move(fileInfo)), truncateLen](napi_env env) -> UniError { if (fileInfo->isPath) { if (truncate(fileInfo->path.get(), truncateLen) != 0) { - return UniError(errno); + return UniError(errno, true); } } else { if (ftruncate(fileInfo->fdg.GetFD(), truncateLen) != 0) { - return UniError(errno); + return UniError(errno, true); } } return UniError(ERRNO_NOERR); diff --git a/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp b/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp new file mode 100755 index 0000000000000000000000000000000000000000..6d21dd570eea097df208504ab5805517874a794d --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 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 + * + * 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 "flush.h" + +#include +#include + +#include "class_stat/stat_entity.h" +#include "class_stat/stat_n_exporter.h" +#include "filemgmt_libhilog.h" +#include "stream_entity.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value Flush::Sync(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 streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + HILOGE("Stream may has been closed"); + NError(EIO).ThrowErr(env); + return nullptr; + } + + int ret = fflush(streamEntity->fp.get()); + if (ret < 0) { + HILOGE("Failed to fflush file in the stream, ret: %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value Flush::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + HILOGE("Stream may has been closed"); + NError(EIO).ThrowErr(env); + return nullptr; + } + + auto cbExec = [streamEntity]() -> NError { + int ret = fflush(streamEntity->fp.get()); + if (ret < 0) { + HILOGE("Failed to fflush file in the stream"); + return NError(errno); + } else { + return NError(ERRNO_NOERR); + } + }; + auto cbCompl = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STREAM_FLUSH_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STREAM_FLUSH_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/class_stream/flush.h b/interfaces/kits/js/src/mod_fs/class_stream/flush.h new file mode 100755 index 0000000000000000000000000000000000000000..aa7be7012cdc5ecf146f7b23bd6006e1c8d0ed43 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stream/flush.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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 + * + * 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_STREAM_FLUSH_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STREAM_FLUSH_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class Flush 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_STREAM_FLUSH_NAME = "FileIOStreamFlush"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STREAM_FLUSH_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h new file mode 100755 index 0000000000000000000000000000000000000000..11cdae1dc8c70fa34f5804158e6b4c575a94ac5e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +struct StreamEntity { + std::unique_ptr fp = { nullptr, fclose }; +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..44ba3246b0882cd4d07e7c4820e35eb141c1aa15 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp @@ -0,0 +1,391 @@ +/* + * Copyright (c) 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 + * + * 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 "stream_n_exporter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common_func.h" +#include "filemgmt_libhilog.h" +#include "flush.h" +#include "stream_entity.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value StreamNExporter::ReadSync(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 streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + HILOGE("Stream may have been closed"); + NError(EIO).ThrowErr(env); + return nullptr; + } + FILE *filp = nullptr; + filp = streamEntity->fp.get(); + + auto [succ, buf, len, hasOffset, offset] = + CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + HILOGE("Failed to resolve buf and options"); + return nullptr; + } + + int ret = fseek(filp, offset, SEEK_SET); + if (hasOffset && (ret < 0)) { + HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + + size_t actLen = fread(buf, 1, len, filp); + if (actLen != static_cast(len) && ferror(filp)) { + HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateInt64(env, actLen).val_; +} + +napi_value StreamNExporter::CloseSync(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 streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + HILOGE("Stream may have been closed yet"); + NError(EIO).ThrowErr(env); + return nullptr; + } + streamEntity->fp.reset(); + (void)NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); + + return NVal::CreateUndefined(env).val_; +} + +napi_value StreamNExporter::WriteSync(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 streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + HILOGE("Stream may has been closed"); + NError(EIO).ThrowErr(env); + return nullptr; + } + FILE *filp = nullptr; + filp = streamEntity->fp.get(); + + auto [succ, bufGuard, buf, len, hasOffset, offset] = + CommonFunc::GetWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + HILOGE("Failed to resolve buf and options"); + return nullptr; + } + int ret = fseek(filp, offset, SEEK_SET); + if (hasOffset && (ret < 0)) { + HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + + size_t writeLen = fwrite(buf, 1, len, filp); + if (writeLen != len && ferror(filp)) { + HILOGE("Failed to fwrite with len, writeLen: %{public}zu, len: %{public}" PRId64, writeLen, len); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateInt64(env, writeLen).val_; +} + +static bool HasOption(napi_env env, napi_value optionFromJsArg) +{ + NVal op = NVal(env, optionFromJsArg); + if (op.HasProp("offset") || op.HasProp("length") || op.HasProp("encoding") || !op.TypeIs(napi_function)) { + return true; + } + return false; +} + +napi_value StreamNExporter::Write(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 streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + HILOGE("Stream may has been closed"); + NError(EIO).ThrowErr(env); + return nullptr; + } + + FILE *filp = nullptr; + filp = streamEntity->fp.get(); + + auto [succ, bufGuard, buf, len, hasOffset, offset] = + CommonFunc::GetWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + HILOGE("Failed to resolve buf and options"); + return nullptr; + } + + auto arg = make_shared(move(bufGuard)); + if (!arg) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto cbExec = [arg, buf = buf, len = len, filp, hasOffset = hasOffset, offset = offset]() -> NError { + int ret = fseek(filp, offset, SEEK_SET); + if (hasOffset && (ret < 0)) { + HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); + return NError(errno); + } + arg->actLen = fwrite(buf, 1, len, filp); + if ((arg->actLen != static_cast(len)) && ferror(filp)) { + HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", arg->actLen); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateInt64(env, arg->actLen) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + bool hasOp = false; + if (funcArg.GetArgc() == NARG_CNT::TWO) { + hasOp = HasOption(env, funcArg[NARG_POS::SECOND]); + } + if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && hasOp)) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STREAM_WRITE_NAME, cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::TWO) ? NARG_POS::SECOND : NARG_POS::THIRD); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STREAM_WRITE_NAME, cbExec, cbCompl).val_; + } +} + +napi_value StreamNExporter::Read(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 streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + HILOGE("Stream may have been closed"); + NError(EIO).ThrowErr(env); + return nullptr; + } + FILE *filp = nullptr; + filp = streamEntity->fp.get(); + + auto [succ, buf, len, hasOffset, offset] = + CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + HILOGE("Failed to resolve buf and options"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto arg = make_shared(NVal(env, funcArg[NARG_POS::FIRST])); + if (!arg) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto cbExec = [arg, buf = buf, len = len, filp, hasOffset = hasOffset, offset = offset]() -> NError { + int ret = fseek(filp, offset, SEEK_SET); + if (hasOffset && (ret < 0)) { + HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); + return NError(errno); + } + size_t actLen = fread(buf, 1, len, filp); + if (actLen != static_cast(len) && ferror(filp)) { + HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); + return NError(errno); + } else { + arg->lenRead = actLen; + return NError(ERRNO_NOERR); + } + }; + + 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::TWO) { + hasOp = HasOption(env, funcArg[NARG_POS::SECOND]); + } + if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && hasOp)) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STREAM_READ_NAME, cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::TWO) ? NARG_POS::SECOND : NARG_POS::THIRD); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STREAM_READ_NAME, cbExec, cbCompl).val_; + } +} + +napi_value StreamNExporter::Close(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + HILOGE("Stream may has been closed"); + NError(EIO).ThrowErr(env); + return nullptr; + } + + auto cbExec = [streamEntity]() -> NError { + auto filp = streamEntity->fp.release(); + if (!fclose(filp)) { + HILOGE("Failed to close file with filp"); + return NError(ERRNO_NOERR); + } else { + return NError(errno); + } + }; + + auto cbCompl = [arg = funcArg.GetThisVar()](napi_env env, NError err) -> NVal { + (void)NClass::RemoveEntityOfFinal(env, arg); + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUndefined(env); + } + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STREAM_CLOSE_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STREAM_CLOSE_NAME, cbExec, cbCompl).val_; + } +} + +napi_value StreamNExporter::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 streamEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(streamEntity))) { + HILOGE("INNER BUG. Failed to wrap entity for obj stream"); + NError(EIO).ThrowErr(env); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool StreamNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("writeSync", WriteSync), + NVal::DeclareNapiFunction("flush", Flush::Async), + NVal::DeclareNapiFunction("flushSync", Flush::Sync), + NVal::DeclareNapiFunction("readSync", ReadSync), + NVal::DeclareNapiFunction("closeSync", CloseSync), + NVal::DeclareNapiFunction("write", Write), + NVal::DeclareNapiFunction("read", Read), + NVal::DeclareNapiFunction("close", Close), + }; + + string className = GetClassName(); + bool succ = false; + napi_value cls = nullptr; + tie(succ, cls) = NClass::DefineClass(exports_.env_, className, StreamNExporter::Constructor, move(props)); + if (!succ) { + HILOGE("INNER BUG. Failed to define class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, cls); + if (!succ) { + HILOGE("INNER BUG. Failed to save class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + return exports_.AddProp(className, cls); +} + +string StreamNExporter::GetClassName() +{ + return StreamNExporter::className_; +} + +StreamNExporter::StreamNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +StreamNExporter::~StreamNExporter() {} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..afb2579e6e5e80c65111c14017ea3797823a372b --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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 + * + * 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_STREAM_STREAM_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STREAM_STREAM_N_EXPORTER_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::FileManagement::LibN; +class StreamNExporter final : public NExporter { +public: + inline static const std::string className_ = "FsStream"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + + static napi_value WriteSync(napi_env env, napi_callback_info cbinfo); + static napi_value ReadSync(napi_env env, napi_callback_info cbinfo); + static napi_value CloseSync(napi_env env, napi_callback_info cbinfo); + + static napi_value Write(napi_env env, napi_callback_info cbinfo); + static napi_value Read(napi_env env, napi_callback_info cbinfo); + static napi_value Close(napi_env env, napi_callback_info cbinfo); + + StreamNExporter(napi_env env, napi_value exports); + ~StreamNExporter() override; +}; + +struct AsyncReadArg { + size_t lenRead { 0 }; + NRef refReadBuf; + + explicit AsyncReadArg(NVal jsReadBuf) : refReadBuf(jsReadBuf) {} + ~AsyncReadArg() = default; +}; + +struct AsyncWrtieArg { + NRef refWriteArrayBuf; + std::unique_ptr guardWriteStr; + size_t actLen { 0 }; + + explicit AsyncWrtieArg(NVal refWriteArrayBuf) : refWriteArrayBuf(refWriteArrayBuf) {} + explicit AsyncWrtieArg(std::unique_ptr &&guardWriteStr) : guardWriteStr(std::move(guardWriteStr)) {} + ~AsyncWrtieArg() = default; +}; + +const std::string PROCEDURE_STREAM_WRITE_NAME = "FileIOStreamWrite"; +const std::string PROCEDURE_STREAM_READ_NAME = "FileIOStreamRead"; +const std::string PROCEDURE_STREAM_CLOSE_NAME = "FileIOStreamClose"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STREAM_STREAM_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 index b6dd6cbb644e91ae233621dd60f6c9ece0a2398e..d0d09582a766210e9e28e41728cc4fcbbd5b202a 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.cpp +++ b/interfaces/kits/js/src/mod_fs/common_func.cpp @@ -122,6 +122,15 @@ int CommonFunc::ConvertJsFlags(int &flags) return flagsABI; } +void CommonFunc::fs_req_cleanup(uv_fs_t* req) +{ + uv_fs_req_cleanup(req); + if (req) { + delete req; + req = nullptr; + } +} + tuple, unique_ptr> CommonFunc::GetCopyPathArg(napi_env env, napi_value srcPath, napi_value dstPath) @@ -254,6 +263,22 @@ tuple, void *, int64_t, bool, int64_t> CommonFunc::GetW } return { true, move(bufferGuard), buf, retLen, hasPos, retPos }; } + +string CommonFunc::GetModeFromFlags(int flags) +{ + const string RDONLY = "r"; + const string WRONLY = "w"; + const string APPEND = "a"; + const string TRUNC = "t"; + string mode = RDONLY; + mode += (((flags & O_RDWR) == O_RDWR) ? WRONLY : ""); + mode = (((flags & O_WRONLY) == O_WRONLY) ? WRONLY : mode); + if (mode != RDONLY) { + mode += ((flags & O_TRUNC) ? TRUNC : ""); + mode += ((flags & O_APPEND) ? APPEND : ""); + } + return mode; +} } // 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 index 91a12a41eaf71853a6ad97d4fabd884bb97f75a5..062b085e1e717155044d643b08b10a83895be39b 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.h +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -18,6 +18,7 @@ #include "fd_guard.h" #include "n_val.h" +#include "uv.h" namespace OHOS { namespace FileManagement { @@ -54,6 +55,8 @@ struct CommonFunc { static std::tuple, std::unique_ptr> GetCopyPathArg(napi_env env, napi_value srcPath, napi_value dstPath); + static void fs_req_cleanup(uv_fs_t* req); + static std::string GetModeFromFlags(int flags); }; } // namespace ModuleFileIO } // namespace FileManagement diff --git a/interfaces/kits/js/src/mod_fs/module.cpp b/interfaces/kits/js/src/mod_fs/module.cpp index 9360458390cf8afd56fb0a27db98514e9f520889..6d2ae250b87e0184b0555476b3b5c244b55b8524 100644 --- a/interfaces/kits/js/src/mod_fs/module.cpp +++ b/interfaces/kits/js/src/mod_fs/module.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 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 @@ -20,6 +20,7 @@ #include "class_file/file_n_exporter.h" #include "class_stat/stat_n_exporter.h" +#include "class_stream/stream_n_exporter.h" #include "filemgmt_libhilog.h" #include "properties/prop_n_exporter.h" @@ -35,6 +36,7 @@ static napi_value Export(napi_env env, napi_value exports) products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); for (auto &&product : products) { if (!product->Export()) { diff --git a/interfaces/kits/js/src/mod_fs/properties/close.cpp b/interfaces/kits/js/src/mod_fs/properties/close.cpp new file mode 100755 index 0000000000000000000000000000000000000000..195feb69da5d8f3bb4bdd4b46a19997a36e9a7c0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/close.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 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 + * + * 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 "close.h" + +#include +#include +#include + +#include "common_func.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static FileEntity *GetFileEntity(napi_env env, napi_value objFile) +{ + auto fileEntity = NClass::GetEntityOf(env, objFile); + if (!fileEntity) { + HILOGE("Failed to get file entity"); + return nullptr; + } + if (!fileEntity->fd_) { + HILOGE("The fd of rafEntity is not exist"); + return nullptr; + } + return fileEntity; +} + +static tuple ParseJsOperand(napi_env env, napi_value fdOrFileFromJsArg) +{ + auto [isFd, fd] = NVal(env, fdOrFileFromJsArg).ToInt32(); + if (isFd) { + return { true, FileStruct { true, fd, nullptr } }; + } + auto file = GetFileEntity(env, fdOrFileFromJsArg); + if (file) { + return { true, FileStruct { false, -1, file } }; + } + + return { false, FileStruct { false, -1, nullptr } }; +} + +napi_value Close::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, fileStruct] = ParseJsOperand(env, funcArg[NARG_POS::FIRST]); + if (!resGetFirstArg) { + HILOGI("Failed to parse fd or FileEntity from JS parameter"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + if (fileStruct.isFd) { + std::unique_ptr close_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!close_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_close(nullptr, close_req.get(), fileStruct.fd, nullptr); + if (ret < 0) { + HILOGE("Failed to close file with fd: %{public}d, ret: %{public}d", fileStruct.fd, ret); + NError(errno).ThrowErr(env); + return nullptr; + } + } else { + fileStruct.fileEntity->fd_.reset(); + } + (void)NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); + + return NVal::CreateUndefined(env).val_; +} + +napi_value Close::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, fileStruct] = ParseJsOperand(env, funcArg[NARG_POS::FIRST]); + if (!resGetFirstArg) { + HILOGI("Failed to parse JS operand"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [fileStruct = fileStruct]() -> NError { + if (fileStruct.isFd) { + std::unique_ptr close_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!close_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_close(nullptr, close_req.get(), fileStruct.fd, nullptr); + if (ret < 0) { + HILOGE("Failed to close file with ret: %{public}d", ret); + return NError(errno); + } + } else { + fileStruct.fileEntity->fd_.reset(); + } + return NError(ERRNO_NOERR); + }; + + auto cbComplete = [arg = funcArg.GetThisVar()](napi_env env, NError err) -> NVal { + (void)NClass::RemoveEntityOfFinal(env, arg); + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUndefined(env); + } + }; + + size_t argc = funcArg.GetArgc(); + NVal thisVar(env, funcArg.GetThisVar()); + if (argc == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CLOSE_NAME, cbExec, cbComplete).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CLOSE_NAME, cbExec, cbComplete).val_; + } +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/close.h b/interfaces/kits/js/src/mod_fs/properties/close.h new file mode 100755 index 0000000000000000000000000000000000000000..8fa3bab4eec2d6ddde166f96980f4eefc8cb980e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/close.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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 + * + * 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_CLOSE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CLOSE_H + +#include "class_file/file_entity.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class Close final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); + static napi_value Async(napi_env env, napi_callback_info info); +}; + +struct FileStruct { + bool isFd = false; + int fd; + FileEntity *fileEntity; +}; + +const std::string PROCEDURE_CLOSE_NAME = "FileIOClose"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CLOSE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp new file mode 100755 index 0000000000000000000000000000000000000000..029d1472b66d459d19cfeb528b76d5a675c58b07 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) 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 + * + * 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 "copy_file.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "common_func.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NError IsAllPath(FileInfo& srcFile, FileInfo& destFile) +{ + std::unique_ptr copyfile_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!copyfile_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_copyfile(nullptr, copyfile_req.get(), srcFile.path.get(), destFile.path.get(), + UV_FS_COPYFILE_FICLONE, nullptr); + if (ret < 0) { + HILOGE("Failed to copy file when all parameters are paths"); + return NError(errno); + } + return NError(ERRNO_NOERR); +} + +static NError SendFileCore(FileInfo& srcFile, FileInfo& destFile) +{ + if (srcFile.isPath) { + std::unique_ptr open_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_open(nullptr, open_req.get(), srcFile.path.get(), O_RDONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, nullptr); + if (ret < 0) { + HILOGE("Failed to open srcFile with ret: %{public}d", ret); + return NError(errno); + } + srcFile.fdg.SetFD(ret, true); + } + + struct stat statbf; + if (fstat(srcFile.fdg.GetFD(), &statbf) < 0) { + HILOGE("Failed to get stat of file by fd: %{public}d", srcFile.fdg.GetFD()); + return NError(errno); + } + + if (destFile.isPath) { + std::unique_ptr open_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_open(nullptr, open_req.get(), destFile.path.get(), O_RDWR | O_CREAT, statbf.st_mode, nullptr); + if (ret < 0) { + HILOGE("Failed to open destFile with ret: %{public}d", ret); + return NError(errno); + } + destFile.fdg.SetFD(ret, true); + } + + std::unique_ptr sendfile_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!sendfile_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_sendfile(nullptr, sendfile_req.get(), srcFile.fdg.GetFD(), destFile.fdg.GetFD(), 0, + statbf.st_size, nullptr); + if (ret < 0) { + HILOGE("Failed to sendfile by ret : %{public}d", ret); + return NError(errno); + } + + return NError(ERRNO_NOERR); +} + +static tuple ParseJsModeAndProm(napi_env env, const NFuncArg& funcArg) +{ + bool promise = false; + bool hasMode = false; + int mode = 0; + if (funcArg.GetArgc() == NARG_CNT::THREE && NVal(env, funcArg[NARG_POS::THIRD]).TypeIs(napi_number)) { + promise = true; + hasMode = true; + } else if (funcArg.GetArgc() == NARG_CNT::FOUR) { + hasMode = true; + } + + if (hasMode) { + auto [succ, mode] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); + if (!succ) { + return { false, mode, promise }; + } + } + + return { true, mode, promise }; +} + +static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg) +{ + auto [isPath, path, ignore] = pathOrFdFromJsArg.ToUTF8String(); + if (isPath) { + return { true, FileInfo{ true, move(path), {} } }; + } + + auto [isFd, fd] = pathOrFdFromJsArg.ToInt32(); + if (isFd) { + return { true, FileInfo{ false, {}, { fd, false } }}; + } + + return { false, FileInfo{ false, {}, {} } }; +}; + +napi_value CopyFile::Sync(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 [succSrc, src] = ParseJsOperand(env, { env, funcArg[NARG_POS::FIRST] }); + auto [succDest, dest] = ParseJsOperand(env, { env, funcArg[NARG_POS::SECOND] }); + if (!succSrc || !succDest) { + HILOGE("The first/second argument requires filepath/fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succMode, mode, unused] = ParseJsModeAndProm(env, funcArg); + if (!succMode) { + HILOGE("Failed to convert mode to int32"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + if (src.isPath && dest.isPath) { + auto err = IsAllPath(src, dest); + if (err) { + err.ThrowErr(env); + return nullptr; + } + } else { + auto err = SendFileCore(src, dest); + if (err) { + err.ThrowErr(env); + return nullptr; + } + } + return NVal::CreateUndefined(env).val_; +} + +napi_value CopyFile::Async(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 [succSrc, src] = ParseJsOperand(env, { env, funcArg[NARG_POS::FIRST] }); + auto [succDest, dest] = ParseJsOperand(env, { env, funcArg[NARG_POS::SECOND] }); + if (!succSrc || !succDest) { + HILOGE("The first/second argument requires filepath/fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succMode, mode, promise] = ParseJsModeAndProm(env, funcArg); + if (!succMode) { + HILOGE("Failed to convert mode to int32"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [para = make_shared(move(src), move(dest))]() -> NError { + if (para->src_.isPath && para->dest_.isPath) { + return IsAllPath(para->src_, para->dest_); + } + return SendFileCore(para->src_, para->dest_); + }; + + auto cbCompl = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO || promise) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_COPYFILE_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[((funcArg.GetArgc() == NARG_CNT::THREE) ? NARG_POS::THIRD : NARG_POS::FOURTH)]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_COPYFILE_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/copy_file.h b/interfaces/kits/js/src/mod_fs/properties/copy_file.h new file mode 100755 index 0000000000000000000000000000000000000000..fef4af34b7eb795edfb0708d80fc8bce325f933d --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_file.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 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 + * + * 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_COPY_FILE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_FILE_H + +#include "common_func.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +class CopyFile 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 Para { +public: + FileInfo src_; + FileInfo dest_; + + Para(FileInfo src, FileInfo dest) : src_(move(src)), dest_(move(dest)){}; +}; + +const string PROCEDURE_COPYFILE_NAME = "FileIOCopyFile"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_FILE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp b/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp new file mode 100755 index 0000000000000000000000000000000000000000..e63178df283257f0ea7fc0861927159fb3e1c7f5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "create_stream.h" + +#include +#include + +#include "class_stream/stream_entity.h" +#include "class_stream/stream_n_exporter.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NVal InstantiateStream(napi_env env, unique_ptr fp) +{ + napi_value objStream = NClass::InstantiateClass(env, StreamNExporter::className_, {}); + if (!objStream) { + HILOGE("INNER BUG. Cannot instantiate stream"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto streamEntity = NClass::GetEntityOf(env, objStream); + if (!streamEntity) { + HILOGE("Cannot instantiate stream because of void entity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + streamEntity->fp.swap(fp); + return { env, objStream }; +} + +static tuple GetCreateStreamArgs(napi_env env, const NFuncArg &funcArg) +{ + auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + return { false, "", "" }; + } + + auto [resGetSecondArg, mode, useless] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + return { false, "", "" }; + } + + return { true, path.get(), mode.get() }; +} + +napi_value CreateStream::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 [resGetCreateStreamArgs, argPath, argMode] = GetCreateStreamArgs(env, funcArg); + if (!resGetCreateStreamArgs) { + HILOGE("Arg path and mode are required to be type of string"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + unique_ptr fp = { fopen(argPath.c_str(), argMode.c_str()), fclose }; + if (!fp) { + HILOGE("Failed to fdopen file by path"); + NError(errno).ThrowErr(env); + return nullptr; + } + + return InstantiateStream(env, move(fp)).val_; +} + +napi_value CreateStream::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 [resGetCreateStreamArgs, argPath, argMode] = GetCreateStreamArgs(env, funcArg); + if (!resGetCreateStreamArgs) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto arg = make_shared(); + if (arg == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto cbExec = [arg, argPath = move(argPath), argMode = move(argMode)]() -> NError { + arg->fp = { fopen(argPath.c_str(), argMode.c_str()), fclose }; + if (!arg->fp) { + HILOGE("Failed to fdopen file by path"); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return InstantiateStream(env, move(arg->fp)); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CREATESTREAM_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CREATESTREAM_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/create_stream.h b/interfaces/kits/js/src/mod_fs/properties/create_stream.h new file mode 100755 index 0000000000000000000000000000000000000000..9e7b01493dc6ff432791cd841773072dbdf40522 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/create_stream.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 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 + * + * 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_CREATE_STREAM_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CREATE_STREAM_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class CreateStream final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +struct AsyncCreateStreamArg { + std::unique_ptr fp = { nullptr, fclose }; +}; + +const std::string PROCEDURE_CREATESTREAM_NAME = "FileIOCreateStream"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CREATE_STREAM_H \ 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 index 8def7211140a3cfa1e23895b68f14eee1d235d1d..f5dbc0f4f24b670de0a610e7c6e71abd6fcaf3ee 100644 --- a/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp @@ -19,12 +19,10 @@ #include #include #include - #include +#include "common_func.h" #include "filemgmt_libhilog.h" -#include "uv.h" - namespace OHOS::FileManagement::ModuleFileIO { using namespace std; @@ -46,7 +44,13 @@ napi_value Fdatasync::Sync(napi_env env, napi_callback_info info) return nullptr; } - std::unique_ptr fdatasync_req = {new uv_fs_t, uv_fs_req_cleanup}; + std::unique_ptr fdatasync_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!fdatasync_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } 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); @@ -74,7 +78,12 @@ napi_value Fdatasync::Async(napi_env env, napi_callback_info info) } auto cbExec = [fd = fd]() -> NError { - std::unique_ptr fdatasync_req = {new uv_fs_t, uv_fs_req_cleanup}; + std::unique_ptr fdatasync_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!fdatasync_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } 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); diff --git a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp new file mode 100755 index 0000000000000000000000000000000000000000..2fab9f21a5a9d230349632fca72a4705ecda6ad7 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 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 + * + * 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 "fdopen_stream.h" + +#include +#include + +#include "class_stream/stream_entity.h" +#include "class_stream/stream_n_exporter.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NVal InstantiateStream(napi_env env, unique_ptr fp) +{ + napi_value objStream = NClass::InstantiateClass(env, StreamNExporter::className_, {}); + if (!objStream) { + HILOGE("INNER BUG. Cannot instantiate stream"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto streamEntity = NClass::GetEntityOf(env, objStream); + if (!streamEntity) { + HILOGE("Cannot instantiate stream because of void entity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + streamEntity->fp.swap(fp); + return { env, objStream }; +} + +static tuple GetFdopenStreamArgs(napi_env env, const NFuncArg &funcArg) +{ + auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!resGetFirstArg) { + return { false, -1, "" }; + } + + auto [resGetSecondArg, mode, unused] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + return { false, -1, "" }; + } + + return { true, fd, mode.get() }; +} + +napi_value FdopenStream::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 [resGetFdopenStreamArgs, fd, mode] = GetFdopenStreamArgs(env, funcArg); + if (!resGetFdopenStreamArgs) { + HILOGE("Invalid fd or mode from JS arugments"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + unique_ptr fp = { fdopen(fd, mode.c_str()), fclose }; + if (!fp) { + HILOGE("Failed to fdopen file by fd:%{public}d", fd); + NError(errno).ThrowErr(env); + return nullptr; + } + + return InstantiateStream(env, move(fp)).val_; +} + +napi_value FdopenStream::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 [resGetFdopenStreamArgs, fd, mode] = GetFdopenStreamArgs(env, funcArg); + if (!resGetFdopenStreamArgs) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto arg = make_shared(); + if (arg == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto cbExec = [arg, fd = fd, mode = mode]() -> NError { + arg->fp = { fdopen(fd, mode.c_str()), fclose }; + if (!arg->fp) { + HILOGE("Failed to fdopen file by fd:%{public}d", fd); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return InstantiateStream(env, move(arg->fp)); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_FDOPENSTREAM_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_FDOPENSTREAM_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/fdopen_stream.h b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h new file mode 100755 index 0000000000000000000000000000000000000000..ed43f3d3bd8b4a71499dfdaadbb997d42e7488f2 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 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 + * + * 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_FDOPEN_STREAM_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class FdopenStream final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +struct AsyncFdopenStreamArg { + std::unique_ptr fp = { nullptr, fclose }; +}; + +const std::string PROCEDURE_FDOPENSTREAM_NAME = "FileIOFdopenStream"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_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 0000000000000000000000000000000000000000..422389c64e1cab3f7c12d5d6e159f38f3c49a20e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fsync.cpp @@ -0,0 +1,111 @@ +/* + * 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 "common_func.h" +#include "filemgmt_libhilog.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, CommonFunc::fs_req_cleanup }; + if (!fsync_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + 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, CommonFunc::fs_req_cleanup }; + if (!fsync_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + 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 0000000000000000000000000000000000000000..e033909780a250129397c17807ac877618f23faa --- /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/mkdtemp.cpp b/interfaces/kits/js/src/mod_fs/properties/mkdtemp.cpp new file mode 100755 index 0000000000000000000000000000000000000000..43ab54a2b316e8cb2b2b9309d38c9f3b86bc4da5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/mkdtemp.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 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 + * + * 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 "mkdtemp.h" + +#include "common_func.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value Mkdtemp::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, tmp, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + string path = tmp.get(); + std::unique_ptr mkdtemp_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!mkdtemp_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_mkdtemp(nullptr, mkdtemp_req.get(), const_cast(path.c_str()), nullptr); + if (ret < 0) { + HILOGE("Failed to create a temporary directory with path: %{public}s", path.c_str()); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateUTF8String(env, mkdtemp_req->path).val_; +} + +napi_value Mkdtemp::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; + } + + auto arg = make_shared(); + auto cbExec = [path = tmp.get(), arg]() -> NError { + std::unique_ptr mkdtemp_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!mkdtemp_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_mkdtemp(nullptr, mkdtemp_req.get(), const_cast(path), nullptr); + if (ret < 0) { + HILOGE("Failed to create a temporary directory with path: %{public}s", path); + return NError(errno); + } else { + *arg = mkdtemp_req->path; + return NError(ERRNO_NOERR); + } + }; + + auto cbComplete = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUTF8String(env, *arg); + } + }; + + const string procedureName = "FileIOmkdtemp"; + 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 ModuleFileIO +} // namespace FileManagement +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/properties/mkdtemp.h b/interfaces/kits/js/src/mod_fs/properties/mkdtemp.h new file mode 100755 index 0000000000000000000000000000000000000000..ac968c32e5ca7221a54cad2ae7fc13b399111f20 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/mkdtemp.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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 + * + * 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_MKDTEMP_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_MKDTEMP_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::FileManagement::LibN; + +class Mkdtemp 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 ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_MKDTEMP_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 index ff16921a08348dd2286a5baf9bd805a918457ac6..dc97db32ccb97b95f1721572323b88d6d88cb907 100644 --- a/interfaces/kits/js/src/mod_fs/properties/open.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/open.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include "../common_func.h" #include "ability.h" @@ -41,7 +40,8 @@ static tuple GetJsFlags(napi_env env, const NFuncArg &funcArg) 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) { + int invalidMode = (O_WRONLY | O_RDWR); + if (!succ || ((mode & invalidMode) == invalidMode)) { HILOGE("Invalid mode"); NError(EINVAL).ThrowErr(env); return { false, mode }; @@ -78,7 +78,7 @@ static NVal InstantiateFile(napi_env env, int fd, string pathOrUri, bool isUri) return { env, objFile }; } -static int OpenFileByDatashare(napi_env env, napi_value argv, string path) +static int OpenFileByDatashare(napi_env env, napi_value argv, string path, int flags) { std::shared_ptr dataShareHelper = nullptr; int fd = -1; @@ -89,7 +89,7 @@ static int OpenFileByDatashare(napi_env env, napi_value argv, string path) dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); Uri uri(path); - fd = dataShareHelper->OpenFile(uri, MEDIA_FILEMODE_READONLY); + fd = dataShareHelper->OpenFile(uri, CommonFunc::GetModeFromFlags(flags)); return fd; } @@ -113,7 +113,7 @@ napi_value Open::Sync(napi_env env, napi_callback_info info) return nullptr; } if (DistributedFS::ModuleRemoteUri::RemoteUri::IsMediaUri(path.get())) { - auto fd = OpenFileByDatashare(env, funcArg[NARG_POS::FIRST], path.get()); + auto fd = OpenFileByDatashare(env, funcArg[NARG_POS::FIRST], path.get(), mode); if (fd >= 0) { auto file = InstantiateFile(env, fd, path.get(), true).val_; return file; @@ -122,15 +122,21 @@ napi_value Open::Sync(napi_env env, napi_callback_info info) 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); + std::unique_ptr open_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_open(nullptr, open_req.get(), path.get(), mode, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, nullptr); 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_; + auto file = InstantiateFile(env, ret, path.get(), false).val_; return file; } @@ -163,7 +169,7 @@ napi_value Open::Async(napi_env env, napi_callback_info info) 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); + auto fd = OpenFileByDatashare(env, argv, path, mode); if (fd >= 0) { arg->fd = fd; arg->path = ""; @@ -173,14 +179,19 @@ napi_value Open::Async(napi_env env, napi_callback_info info) 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); + std::unique_ptr open_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_open(nullptr, open_req.get(), path.c_str(), mode, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, nullptr); if (ret < 0) { HILOGE("Failed to open file for libuv error %{public}d", ret); return NError(errno); } - arg->fd = open_req.get()->result; + arg->fd = ret; arg->path = path; arg->uri = ""; return NError(ERRNO_NOERR); diff --git a/interfaces/kits/js/src/mod_fs/properties/open.h b/interfaces/kits/js/src/mod_fs/properties/open.h index 8bf564bbb12504369d02c3c01223895a12c84411..4103e5408d1fb2b296257e8e8d06068e4d7c2bd3 100644 --- a/interfaces/kits/js/src/mod_fs/properties/open.h +++ b/interfaces/kits/js/src/mod_fs/properties/open.h @@ -38,7 +38,6 @@ public: 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 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 old mode 100644 new mode 100755 index 62baa52067ffbbf08b400a343c9282244a52a6db..00606c0e9aee65c32123ad709ff2581b944c65ea --- a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.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 @@ -21,14 +21,25 @@ #include #include #include -#include -#include "../common_func.h" +#include "common_func.h" #include "class_file/file_entity.h" #include "class_file/file_n_exporter.h" +#include "close.h" +#include "copy_file.h" +#include "create_stream.h" +#include "fdatasync.h" +#include "fdopen_stream.h" #include "filemgmt_libn.h" +#include "fsync.h" +#include "js_native_api.h" +#include "js_native_api_types.h" #include "lstat.h" +#include "mkdtemp.h" #include "open.h" +#include "read_text.h" +#include "rename.h" +#include "rmdirent.h" #include "stat.h" #include "symlink.h" #include "truncate.h" @@ -39,6 +50,254 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +napi_value PropNExporter::AccessSync(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, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + bool isAccess = false; + std::unique_ptr access_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!access_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_access(nullptr, access_req.get(), path.get(), 0, nullptr); + if (ret < 0 && errno != ENOENT) { + HILOGE("Failed to access file by path"); + NError(errno).ThrowErr(env); + return nullptr; + } + if (ret == 0) { + isAccess = true; + } + return NVal::CreateBool(env, isAccess).val_; +} + +napi_value PropNExporter::Access(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, tmp, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto result = make_shared(); + if (result == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto cbExec = [path = string(tmp.get()), result]() -> NError { + std::unique_ptr access_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!access_req) { + HILOGE("Failed to request heap memory."); + return NError(ENOMEM); + } + int ret = uv_fs_access(nullptr, access_req.get(), path.c_str(), 0, nullptr); + if (ret == 0) { + result->isAccess = true; + } + return (ret < 0 && errno != ENOENT) ? NError(errno) : NError(ERRNO_NOERR); + }; + + auto cbComplete = [result](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return NVal::CreateBool(env, result->isAccess); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ACCESS_NAME, cbExec, cbComplete).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_ACCESS_NAME, cbExec, cbComplete).val_; + } +} + +napi_value PropNExporter::Unlink(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, tmp, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [path = string(tmp.get())]() -> NError { + std::unique_ptr unlink_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!unlink_req) { + HILOGE("Failed to request heap memory."); + return NError(ENOMEM); + } + int ret = uv_fs_unlink(nullptr, unlink_req.get(), path.c_str(), nullptr); + if (ret < 0) { + HILOGE("Failed to unlink with path"); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_UNLINK_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_UNLINK_NAME, cbExec, cbCompl).val_; + } +} + +napi_value PropNExporter::UnlinkSync(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, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + std::unique_ptr unlink_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!unlink_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_unlink(nullptr, unlink_req.get(), path.get(), nullptr); + if (ret < 0) { + HILOGE("Failed to unlink with path"); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value PropNExporter::Mkdir(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, tmp, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [path = string(tmp.get())]() -> NError { + std::unique_ptr mkdir_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!mkdir_req) { + HILOGE("Failed to request heap memory."); + return NError(ENOMEM); + } + int ret = uv_fs_mkdir(nullptr, mkdir_req.get(), path.c_str(), DIR_DEFAULT_PERM, nullptr); + if (ret < 0) { + HILOGE("Failed to create directory"); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_MKDIR_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_MKDIR_NAME, cbExec, cbCompl).val_; + } +} + +napi_value PropNExporter::MkdirSync(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, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + std::unique_ptr mkdir_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!mkdir_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_mkdir(nullptr, mkdir_req.get(), path.get(), DIR_DEFAULT_PERM, nullptr); + if (ret < 0) { + HILOGE("Failed to create directory"); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateUndefined(env).val_; +} + napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -49,16 +308,22 @@ napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) return nullptr; } - auto [succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + bool succ = false; + int fd = 0; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { - HILOGE("Invalid fd"); + HILOGE("Invalid fd from JS first argument"); NError(EINVAL).ThrowErr(env); return nullptr; } - auto [res, buf, len, hasPos, pos] = + void *buf = nullptr; + int64_t len = 0; + bool hasOffset = false; + int64_t offset = 0; + tie(succ, buf, len, hasOffset, offset) = CommonFunc::GetReadArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!res) { + if (!succ) { HILOGE("Failed to resolve buf and options"); NError(EINVAL).ThrowErr(env); return nullptr; @@ -66,34 +331,38 @@ napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) 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); + std::unique_ptr read_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!read_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_read(nullptr, read_req.get(), fd, &buffer, 1, offset, 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); - + actLen = ret; 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) +static NError ReadExec(shared_ptr arg, void *buf, size_t len, int fd, size_t offset) { 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); + std::unique_ptr read_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!read_req) { + HILOGE("Failed to request heap memory."); + return NError(ENOMEM); + } + int ret = uv_fs_read(nullptr, read_req.get(), fd, &buffer, 1, static_cast(offset), 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); + arg->lenRead = ret; return NError(ERRNO_NOERR); } @@ -106,24 +375,35 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) return nullptr; } - auto [succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + bool succ = false; + void *buf = nullptr; + int64_t len = 0; + int fd = 0; + bool hasOffset = false; + int64_t offset = 0; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { - HILOGE("Invalid fd"); + HILOGE("Invalid fd from JS first argument"); NError(EINVAL).ThrowErr(env); return nullptr; } - auto [res, buf, len, hasPos, pos] = + tie(succ, buf, len, hasOffset, offset) = CommonFunc::GetReadArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!res) { + if (!succ) { 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 arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); + if (!arg) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto cbExec = [arg, buf = buf, len = len, fd = fd, offset = offset]() -> NError { + return ReadExec(arg, buf, len, fd, offset); }; auto cbCompl = [arg](napi_env env, NError err) -> NVal { @@ -137,32 +417,34 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) 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)) { + 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_; + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_READ_NAME, 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 NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_READ_NAME, cbExec, cbCompl).val_; } - - return NVal::CreateUndefined(env).val_; } -NError PropNExporter::WriteExec(shared_ptr arg, void *buf, size_t len, int fd, size_t position) +NError PropNExporter::WriteExec(shared_ptr arg, void *buf, size_t len, int fd, size_t offset) { 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); + std::unique_ptr write_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!write_req) { + HILOGE("Failed to request heap memory."); + return NError(ENOMEM); + } + int ret = uv_fs_write(nullptr, write_req.get(), fd, &buffer, 1, static_cast(offset), 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); + arg->actLen = ret; return NError(ERRNO_NOERR); } @@ -175,29 +457,36 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) return nullptr; } - auto [succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + bool succ = false; + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { - HILOGE("Invalid fd"); + HILOGE("Invalid fd from JS first argument"); NError(EINVAL).ThrowErr(env); return nullptr; } - auto [res, bufGuard, buf, len, hasPos, position] = + unique_ptr bufGuard; + void *buf = nullptr; + size_t len = 0; + size_t offset = 0; + bool hasOffset = false; + tie(succ, bufGuard, buf, len, hasOffset, offset) = CommonFunc::GetWriteArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!res) { + if (!succ) { 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 arg = make_shared(move(bufGuard)); + if (!arg) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; } - auto cbExec = [arg, buf = buf, len = len, fd = fd, position = position, env = env]() -> NError { - return WriteExec(arg, buf, len, fd, position); + auto cbExec = [arg, buf = buf, len = len, fd = fd, offset = offset]() -> NError { + return WriteExec(arg, buf, len, fd, offset); }; auto cbCompl = [arg](napi_env env, NError err) -> NVal { @@ -212,21 +501,18 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) 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)) { + if (op.HasProp("offset") || 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_; + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_WRITE_NAME, 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 NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_WRITE_NAME, cbExec, cbCompl).val_; } - - return NVal::CreateUndefined(env).val_; } napi_value PropNExporter::WriteSync(napi_env env, napi_callback_info info) @@ -238,50 +524,87 @@ napi_value PropNExporter::WriteSync(napi_env env, napi_callback_info info) return nullptr; } - auto [succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + bool succ = false; + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { - HILOGE("Invalid fd"); + HILOGE("Invalid fd from JS first argument"); NError(EINVAL).ThrowErr(env); return nullptr; } - auto [res, bufGuard, buf, len, hasPos, position] = + void *buf = nullptr; + size_t len = 0; + size_t offset = 0; + unique_ptr bufGuard; + bool hasOffset = false; + tie(succ, bufGuard, buf, len, hasOffset, offset) = CommonFunc::GetWriteArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); - if (!res) { + if (!succ) { 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); + std::unique_ptr write_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!write_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_write(nullptr, write_req.get(), fd, &buffer, 1, static_cast(offset), 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); - + writeLen = ret; return NVal::CreateInt64(env, writeLen).val_; } bool PropNExporter::Export() { return exports_.AddProp({ + NVal::DeclareNapiFunction("access", Access), + NVal::DeclareNapiFunction("accessSync", AccessSync), + NVal::DeclareNapiFunction("close", Close::Async), + NVal::DeclareNapiFunction("closeSync", Close::Sync), + NVal::DeclareNapiFunction("copyFile", CopyFile::Async), + NVal::DeclareNapiFunction("copyFileSync", CopyFile::Sync), + NVal::DeclareNapiFunction("createStream", CreateStream::Async), + NVal::DeclareNapiFunction("createStreamSync", CreateStream::Sync), + NVal::DeclareNapiFunction("fdatasync", Fdatasync::Async), + NVal::DeclareNapiFunction("fdatasyncSync", Fdatasync::Sync), + NVal::DeclareNapiFunction("fdopenStream", FdopenStream::Async), + NVal::DeclareNapiFunction("fdopenStreamSync", FdopenStream::Sync), + NVal::DeclareNapiFunction("fsync", Fsync::Async), + NVal::DeclareNapiFunction("fsyncSync", Fsync::Sync), NVal::DeclareNapiFunction("lstat", Lstat::Async), NVal::DeclareNapiFunction("lstatSync", Lstat::Sync), + NVal::DeclareNapiFunction("mkdir", Mkdir), + NVal::DeclareNapiFunction("mkdirSync", MkdirSync), + NVal::DeclareNapiFunction("mkdtemp", Mkdtemp::Async), + NVal::DeclareNapiFunction("mkdtempSync", Mkdtemp::Sync), NVal::DeclareNapiFunction("open", Open::Async), NVal::DeclareNapiFunction("openSync", Open::Sync), NVal::DeclareNapiFunction("read", Read), NVal::DeclareNapiFunction("readSync", ReadSync), + NVal::DeclareNapiFunction("readText", ReadText::Async), + NVal::DeclareNapiFunction("readTextSync", ReadText::Sync), + NVal::DeclareNapiFunction("rename", Rename::Async), + NVal::DeclareNapiFunction("renameSync", Rename::Sync), + NVal::DeclareNapiFunction("rmdir", Rmdirent::Async), + NVal::DeclareNapiFunction("rmdirSync", Rmdirent::Sync), NVal::DeclareNapiFunction("stat", Stat::Async), NVal::DeclareNapiFunction("statSync", Stat::Sync), NVal::DeclareNapiFunction("symlink", Symlink::Async), NVal::DeclareNapiFunction("symlinkSync", Symlink::Sync), NVal::DeclareNapiFunction("truncate", Truncate::Async), NVal::DeclareNapiFunction("truncateSync", Truncate::Sync), + NVal::DeclareNapiFunction("unlink", Unlink), + NVal::DeclareNapiFunction("unlinkSync", UnlinkSync), NVal::DeclareNapiFunction("write", Write), NVal::DeclareNapiFunction("writeSync", WriteSync), }); @@ -297,4 +620,4 @@ PropNExporter::PropNExporter(napi_env env, napi_value exports) : NExporter(env, PropNExporter::~PropNExporter() {} } // namespace ModuleFileIO } // namespace FileManagement -} // namespace OHOS +} // namespace OHOS \ No newline at end of file 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 old mode 100644 new mode 100755 index d4352746ed6a9bfd64787768e57ab02ed9db3848..dce2a3ca40a41c3b8a13839bd60b9e4674557e4e --- a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.h +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.h @@ -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 @@ -33,12 +33,30 @@ struct AsyncIOWrtieArg { ~AsyncIOWrtieArg() = default; }; +struct AsyncAccessArg { + bool isAccess = false; +}; + +struct AsyncIOReadArg { + ssize_t lenRead { 0 }; + NRef refReadBuf; + + explicit AsyncIOReadArg(NVal jsReadBuf) : refReadBuf(jsReadBuf) {} + ~AsyncIOReadArg() = default; +}; + class PropNExporter final : public NExporter { public: inline static const std::string className_ = "__properities__"; + static napi_value AccessSync(napi_env env, napi_callback_info info); + static napi_value MkdirSync(napi_env env, napi_callback_info info); static napi_value ReadSync(napi_env env, napi_callback_info info); + static napi_value UnlinkSync(napi_env env, napi_callback_info info); static napi_value WriteSync(napi_env env, napi_callback_info info); + static napi_value Access(napi_env env, napi_callback_info info); + static napi_value Unlink(napi_env env, napi_callback_info info); + static napi_value Mkdir(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); @@ -48,6 +66,13 @@ public: PropNExporter(napi_env env, napi_value exports); ~PropNExporter() override; }; + +constexpr int DIR_DEFAULT_PERM = 0770; +const std::string PROCEDURE_ACCESS_NAME = "FileIOAccess"; +const std::string PROCEDURE_UNLINK_NAME = "FileIOUnlink"; +const std::string PROCEDURE_MKDIR_NAME = "FileIOMkdir"; +const std::string PROCEDURE_READ_NAME = "FileIORead"; +const std::string PROCEDURE_WRITE_NAME = "FileIOWrite"; } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/properties/read_text.cpp b/interfaces/kits/js/src/mod_fs/properties/read_text.cpp new file mode 100755 index 0000000000000000000000000000000000000000..5ff8590e2dd0cc0096be7767c6e3732d4dee845d --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_text.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "read_text.h" + +#include +#include +#include +#include +#include + +#include "common_func.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static tuple, bool> GetReadTextArg(napi_env env, napi_value argOption) +{ + NVal op(env, argOption); + ssize_t offset = 0; + ssize_t len = 0; + bool succ = false; + bool hasOp = false; + bool hasLen = false; + unique_ptr encoding; + + if (op.HasProp("offset")) { + tie(succ, offset) = op.GetProp("offset").ToInt32(); + if (!succ || offset < 0) { + HILOGE("Illegal option.offset parameter"); + return { false, offset, hasLen, len, nullptr, hasOp }; + } + hasOp = true; + } + + if (op.HasProp("length")) { + tie(succ, len) = op.GetProp("length").ToInt32(); + if (!succ || len < 0) { + HILOGE("Illegal option.length parameter"); + return { false, offset, hasLen, len, nullptr, hasOp }; + } + hasOp = true; + hasLen = true; + } + + if (op.HasProp("encoding")) { + auto [succ, encoding, unuse] = op.GetProp("encoding").ToUTF8String(); + if (!succ) { + HILOGE("Illegal option.encoding parameter"); + return { false, offset, hasLen, len, nullptr, hasOp }; + } + hasOp = true; + } + + if (!op.TypeIs(napi_function)) { + hasOp = true; + } + + return { true, offset, hasLen, len, move(encoding), hasOp }; +} + +static NError ReadTextAsync(const std::string path, std::shared_ptr arg, ssize_t offset, + bool hasLen, ssize_t len) +{ + OHOS::DistributedFS::FDGuard sfd; + struct stat statbf; + std::unique_ptr open_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_open(nullptr, open_req.get(), path.c_str(), O_RDONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, nullptr); + if (ret < 0) { + HILOGE("Failed to open file, ret: %{public}d", ret); + return NError(errno); + } + + sfd.SetFD(ret); + if (sfd.GetFD() < 0) { + HILOGE("Failed to open file by path"); + return NError(errno); + } + if (fstat(sfd.GetFD(), &statbf) < 0) { + HILOGE("Failed to get stat of file by fd: %{public}d", sfd.GetFD()); + return NError(errno); + } + + if (offset > statbf.st_size) { + HILOGE("Invalid offset"); + return NError(EINVAL); + } + + len = (!hasLen || len > statbf.st_size) ? statbf.st_size : len; + string buffer(len, '\0'); + uv_buf_t readbuf = uv_buf_init(const_cast(buffer.c_str()), len); + std::unique_ptr read_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!read_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + arg->len = uv_fs_read(nullptr, read_req.get(), sfd.GetFD(), &readbuf, 1, offset, nullptr); + if (arg->len < 0) { + HILOGE("Failed to read file by fd: %{public}d", sfd.GetFD()); + return NError(errno); + } + arg->buffer = buffer; + return NError(ERRNO_NOERR); +} + +napi_value ReadText::Sync(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 [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetReadTextArg, offset, hasLen, len, encoding, useless] = GetReadTextArg(env, funcArg[NARG_POS::SECOND]); + if (!resGetReadTextArg) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + OHOS::DistributedFS::FDGuard sfd; + std::unique_ptr open_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_open(nullptr, open_req.get(), path.get(), O_RDONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, nullptr); + if (ret < 0) { + HILOGE("Failed to open file by ret: %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + sfd.SetFD(ret); + struct stat statbf; + if ((!sfd) || (fstat(sfd.GetFD(), &statbf) < 0)) { + HILOGE("Failed to get stat of file by fd: %{public}d", sfd.GetFD()); + NError(errno).ThrowErr(env); + return nullptr; + } + + if (offset > statbf.st_size) { + HILOGE("Invalid offset: %{public}zd", offset); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + len = (!hasLen || len > statbf.st_size) ? statbf.st_size : len; + string buffer(len, '\0'); + uv_buf_t readbuf = uv_buf_init(const_cast(buffer.c_str()), len); + std::unique_ptr read_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!read_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + ret = uv_fs_read(nullptr, read_req.get(), sfd.GetFD(), &readbuf, 1, offset, nullptr); + if (ret < 0) { + HILOGE("Failed to read file by fd: %{public}d", sfd.GetFD()); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateUTF8String(env, readbuf.base, ret).val_; +} + +napi_value ReadText::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 [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetSecondArg, offset, hasLen, len, encoding, hasOp] = GetReadTextArg(env, funcArg[NARG_POS::SECOND]); + if (!resGetSecondArg) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto arg = make_shared(NVal(env, funcArg.GetThisVar())); + auto cbExec = [path = string(path.get()), arg, offset = offset, hasLen = hasLen, len = len]() -> NError { + return ReadTextAsync(path, arg, offset, hasLen, len); + }; + + auto cbComplete = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUTF8String(env, arg->buffer.c_str(), arg->len); + } + }; + + size_t argc = funcArg.GetArgc(); + NVal thisVar(env, funcArg.GetThisVar()); + if (argc == NARG_CNT::ONE || (argc == NARG_CNT::TWO && hasOp)) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_READTEXT_NAME, cbExec, cbComplete).val_; + } else { + int cbIdx = !hasOp ? NARG_POS::SECOND : NARG_POS::THIRD; + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_READTEXT_NAME, cbExec, cbComplete).val_; + } +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/read_text.h b/interfaces/kits/js/src/mod_fs/properties/read_text.h new file mode 100755 index 0000000000000000000000000000000000000000..c6ee279feec5b8ae464910108671bcf31997d2ff --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_text.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 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 + * + * 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_READ_TEXT_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_READ_TEXT_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::FileManagement::LibN; +class ReadText final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +struct AsyncReadTextArg { + NRef _refReadBuf; + std::string buffer; + ssize_t len = 0; + + explicit AsyncReadTextArg(NVal refReadBuf) : _refReadBuf(refReadBuf){}; + ~AsyncReadTextArg() = default; +}; + +const std::string PROCEDURE_READTEXT_NAME = "FileIOReadText"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_READ_TEXT_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/rename.cpp b/interfaces/kits/js/src/mod_fs/properties/rename.cpp new file mode 100755 index 0000000000000000000000000000000000000000..dd05e02f83c4e233b216ab691ad3c31240ba6c2c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/rename.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 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 + * + * 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 "rename.h" + +#include +#include +#include + +#include "common_func.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value Rename::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 [resGetFirstArg, src, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid src"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetSecondArg, dest, useless] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + HILOGE("Invalid dest"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + std::unique_ptr rename_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!rename_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_rename(nullptr, rename_req.get(), src.get(), dest.get(), nullptr); + if (ret < 0) { + HILOGE("Failed to rename file with path"); + NError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value Rename::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 [resGetFirstArg, src, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid src"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetSecondArg, dest, useless] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + HILOGE("Invalid dest"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [opath = string(src.get()), npath = string(dest.get())]() -> NError { + std::unique_ptr rename_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!rename_req) { + HILOGE("Failed to request heap memory."); + return NError(ENOMEM); + } + int ret = uv_fs_rename(nullptr, rename_req.get(), opath.c_str(), npath.c_str(), nullptr); + if (ret < 0) { + HILOGE("Failed to rename file with path"); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbComplCallback = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + size_t argc = funcArg.GetArgc(); + if (argc == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_RENAME_NAME, cbExec, cbComplCallback).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_RENAME_NAME, cbExec, cbComplCallback).val_; + } +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/rename.h b/interfaces/kits/js/src/mod_fs/properties/rename.h new file mode 100755 index 0000000000000000000000000000000000000000..32def34f2f630b6292f6f803547560ac2f782780 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/rename.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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 + * + * 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_RENAME_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_RENAME_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class Rename 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_RENAME_NAME = "FileIORename"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_RENAME_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/rmdirent.cpp b/interfaces/kits/js/src/mod_fs/properties/rmdirent.cpp new file mode 100755 index 0000000000000000000000000000000000000000..2c31c76a7bc615534b917bd95e5b67d852b1b701 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/rmdirent.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rmdirent.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NError RmDirent(const string &fpath) +{ + std::filesystem::path strToPath(fpath); + std::uintmax_t num = std::filesystem::remove_all(strToPath); + if (!num || std::filesystem::exists(strToPath)) { + HILOGE("Failed to remove file or directory by path"); + return NError(errno); + } + + return NError(ERRNO_NOERR); +} + +napi_value Rmdirent::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, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto err = RmDirent(string(path.get())); + if (err) { + err.ThrowErr(env); + return nullptr; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value Rmdirent::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [tmpPath = string(path.get())]() -> NError { + return RmDirent(tmpPath); + }; + 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()); + size_t argc = funcArg.GetArgc(); + if (argc == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_RMDIRENT_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_RMDIRENT_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/rmdirent.h b/interfaces/kits/js/src/mod_fs/properties/rmdirent.h new file mode 100755 index 0000000000000000000000000000000000000000..d78c5d4af55fbb386ffb056ced35d224b531a061 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/rmdirent.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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 + * + * 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_RMDIRENT_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_RMDIRENT_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class Rmdirent final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); + static napi_value Async(napi_env env, napi_callback_info info); +}; +const std::string PROCEDURE_RMDIRENT_NAME = "FileIORmDirent"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_RMDIRENT_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 old mode 100644 new mode 100755 index 9699168a4a3157115ff915ad24708368e2d0ba59..0c21cc9a6eee15f012c3660522d4ee5c24a56484 --- a/interfaces/kits/js/src/mod_fs/properties/symlink.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/symlink.cpp @@ -1,114 +1,129 @@ -/* - * 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 +/* + * 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 + * + * 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 "common_func.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace 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) { + return { false, "", "" }; + } + + auto [resGetSecondArg, dest, useless] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + 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) { + HILOGE("Failed to get symlink arguments"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + std::unique_ptr symlink_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!symlink_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + int ret = uv_fs_symlink(nullptr, symlink_req.get(), oldPath.c_str(), newPath.c_str(), 0, nullptr); + if (ret < 0) { + HILOGE("Failed to create a link for old path"); + 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) { + HILOGE("Failed to get symlink arguments"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [oldPath = move(oldPath), newPath = move(newPath)]() -> NError { + std::unique_ptr symlink_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!symlink_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_symlink(nullptr, symlink_req.get(), oldPath.c_str(), newPath.c_str(), 0, nullptr); + if (ret < 0) { + HILOGE("Failed to create a link for old path"); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbComplCallback = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + size_t argc = funcArg.GetArgc(); + if (argc == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_SYMLINK_NAME, cbExec, cbComplCallback).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_SYMLINK_NAME, cbExec, cbComplCallback).val_; + } +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/properties/symlink.h b/interfaces/kits/js/src/mod_fs/properties/symlink.h old mode 100644 new mode 100755 index 0b14e8bec6259b8a39019db02047bce7a0c02c75..a25e1f4d7ff980b45eb8c6526180f23f43d51ab5 --- a/interfaces/kits/js/src/mod_fs/properties/symlink.h +++ b/interfaces/kits/js/src/mod_fs/properties/symlink.h @@ -1,28 +1,34 @@ -/* - * 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 +/* + * 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 + * + * 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 { +namespace FileManagement { +namespace 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); +}; + +const std::string PROCEDURE_SYMLINK_NAME = "FileIOSymLink"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS #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 index 0c0e9db88b19213b96c1ec9e78643484cd60fe3a..f6eb9e5600269176754e1ce03c77f4776015831f 100644 --- a/interfaces/kits/js/src/mod_fs/properties/truncate.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/truncate.cpp @@ -21,7 +21,6 @@ #include "../common_func.h" #include "filemgmt_libhilog.h" -#include "uv.h" namespace OHOS::FileManagement::ModuleFileIO { using namespace std; @@ -65,22 +64,40 @@ napi_value Truncate::Sync(napi_env env, napi_callback_info info) } } if (fileInfo.isPath) { - std::unique_ptr open_req = { new uv_fs_t, uv_fs_req_cleanup }; + std::unique_ptr open_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } 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); + std::unique_ptr ftruncate_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!ftruncate_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + ret = uv_fs_ftruncate(nullptr, ftruncate_req.get(), ret, 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 }; + std::unique_ptr ftruncate_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!ftruncate_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } int ret = uv_fs_ftruncate(nullptr, ftruncate_req.get(), fileInfo.fdg.GetFD(), truncateLen, nullptr); if (ret < 0) { HILOGE("Failed to truncate file by fd"); @@ -113,23 +130,35 @@ napi_value Truncate::Async(napi_env env, napi_callback_info info) } } auto cbExec = [fileInfo = make_shared(move(fileInfo)), truncateLen, env = env]() -> NError { - using uv_fs_unique_ptr_type = std::unique_ptr; + 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, + uv_fs_unique_ptr_type open_req = { new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + 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) { 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); + uv_fs_unique_ptr_type ftruncate_req = { new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!ftruncate_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + ret = uv_fs_ftruncate(nullptr, ftruncate_req.get(), ret, 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); + uv_fs_unique_ptr_type ftruncate_req = { new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!ftruncate_req) { + HILOGE("Failed to request heap memory."); + return NError(ERRNO_NOERR); + } + int ret = uv_fs_ftruncate(nullptr, ftruncate_req.get(), fileInfo->fdg.GetFD(), truncateLen, nullptr); if (ret < 0) { HILOGE("Failed to truncate file by fd"); return NError(errno); diff --git a/utils/filemgmt_libn/include/n_class.h b/utils/filemgmt_libn/include/n_class.h index b4ec8c75a5cd791821e1abf213328ce8fe80e466..e82bffbe819a21157047b4cdce8aa230fc0e1640 100644 --- a/utils/filemgmt_libn/include/n_class.h +++ b/utils/filemgmt_libn/include/n_class.h @@ -68,6 +68,21 @@ public: return status == napi_ok; } + template static T *RemoveEntityOfFinal(napi_env env, napi_value objStat) + { + if (!env || !objStat) { + HILOGD("Empty input: env %d,obj %d", env == nullptr, objStat == nullptr); + return nullptr; + } + T *t = nullptr; + napi_status status = napi_remove_wrap(env, objStat, (void **)&t); + if (status != napi_ok) { + HILOGD("Cannot umwrap for pointer: %d", status); + return nullptr; + } + return t; + } + private: NClass() = default; ~NClass() = default; diff --git a/utils/filemgmt_libn/include/n_error.h b/utils/filemgmt_libn/include/n_error.h index 589e996e06cac1f977e2e77bc185bb2a41353d20..a60dcd610a6367e0e327d2cd30749b003cc5d057 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" } },