From 834b671ed843da60f231dba0583116baa717937a Mon Sep 17 00:00:00 2001 From: zhuhongtao666 Date: Wed, 27 Sep 2023 01:06:37 +0800 Subject: [PATCH 1/3] =?UTF-8?q?lseek/mkdirs/utimes/getParent=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interfaces/kits/js/BUILD.gn | 5 + .../kits/js/src/mod_fs/properties/lseek.cpp | 90 +++++++++++ .../kits/js/src/mod_fs/properties/lseek.h | 33 +++++ .../kits/js/src/mod_fs/properties/mkdirs.cpp | 140 ++++++++++++++++++ .../kits/js/src/mod_fs/properties/mkdirs.h | 40 +++++ .../src/mod_fs/properties/prop_n_exporter.cpp | 11 +- .../kits/js/src/mod_fs/properties/utimes.cpp | 109 ++++++++++++++ .../kits/js/src/mod_fs/properties/utimes.h | 35 +++++ 8 files changed, 461 insertions(+), 2 deletions(-) create mode 100644 interfaces/kits/js/src/mod_fs/properties/lseek.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/lseek.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/mkdirs.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/mkdirs.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/utimes.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/utimes.h diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 4f420fad0..5e8785a02 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -114,6 +114,7 @@ ohos_shared_library("fs") { "${src_path}/mod_fs", "${utils_path}/common/include", "//third_party/libuv/include", + "${file_api_path}/interfaces/kits/rust/include", ] sources = [ @@ -133,6 +134,9 @@ ohos_shared_library("fs") { "src/mod_fs/properties/rmdirent.cpp", "src/mod_fs/properties/stat.cpp", "src/mod_fs/properties/truncate.cpp", + "src/mod_fs/properties/utimes.cpp", + "src/mod_fs/properties/lseek.cpp", + "src/mod_fs/properties/mkdirs.cpp", ] cflags_cc = [ "-std=c++17" ] @@ -140,6 +144,7 @@ ohos_shared_library("fs") { deps = [ "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", "${utils_path}/filemgmt_libn:filemgmt_libn", + "${file_api_path}/interfaces/kits/rust:rust_file", ] use_exceptions = true diff --git a/interfaces/kits/js/src/mod_fs/properties/lseek.cpp b/interfaces/kits/js/src/mod_fs/properties/lseek.cpp new file mode 100644 index 000000000..4b0e6180e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/lseek.cpp @@ -0,0 +1,90 @@ +/* + * 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 "lseek.h" +#include "common_func.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "rust_file.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +/** + * Reposition file offset. + * + * @param { number } fd - file descriptor. + * @param { number } offset - file offset. + * @param { whenceType } [whence = SEEK_SET] - directive whence. + * @throws { BusinessError } 13900008 - Bad file descriptor + * @throws { BusinessError } 13900020 - Invalid argument + * @throws { BusinessError } 13900026 - Illegal seek + * @throws { BusinessError } 13900038 - Value too large for defined data type + * @throws { BusinessError } 13900042 - Unknown error + * @syscap SystemCapability.FileManagement.File.FileIO + * @since 11 + */ +napi_value Lseek::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Lseek, Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + //1. fd - file descriptor. + auto [succ1, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ1) { + HILOGE("Lseek, Invalid fd from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + if (fcntl(fd, F_GETFD, 0) == EBADF) { + HILOGE("Lseek, Invalid fd from JS first argument"); + NError(EBADF).ThrowErr(env); + return nullptr; + } + + //2. offset - file offset. + auto [succ2, offset] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt64(); + if (!succ2) { + HILOGE("Lseek, Invalid offset from JS second argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + //3. whence - directive whence. + auto [succ3, whence] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); + if (!succ3) { + HILOGE("Lseek, Invalid whence from JS third argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + if (whence < SeekPos::START || whence > SeekPos::END) { + HILOGE("Lseek, Value too large for defined data type"); + NError(EOVERFLOW).ThrowErr(env); + return nullptr; + } + HILOGD("Lseek, fd:%{public}d, offset:%{public}lld, whence:%{public}d", fd, offset, whence); + ::Lseek(fd, offset, static_cast(whence)); + + return NVal::CreateUndefined(env).val_; +} + +} // ModuleFileIO +} // FileManagement +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/lseek.h b/interfaces/kits/js/src/mod_fs/properties/lseek.h new file mode 100644 index 000000000..3ee920300 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/lseek.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_LSEEK_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_LSEEK_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +class Lseek final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_LSEEK_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/mkdirs.cpp b/interfaces/kits/js/src/mod_fs/properties/mkdirs.cpp new file mode 100644 index 000000000..96390b816 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/mkdirs.cpp @@ -0,0 +1,140 @@ +/* + * 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 "mkdirs.h" +#include "filemgmt_libhilog.h" + +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +#include +#include "rust_file.h" +#endif + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +int Mkdirs::CheckParam(const std::string &dirPath, bool recursion) +{ + auto pos = dirPath.find('/'); + if (pos == std::string::npos) { + HILOGE("Parent path is invalid"); + return ENOTDIR; + } + + auto ret = 0; + if (!recursion) { + ret = access(dirPath.substr(0, pos - 1).c_str(), W_OK); + if (ret == EACCES) { + HILOGE("Operation not permit"); + return EPERM; + } else if (ret < 0) { + HILOGE("Operation not permit"); + return UNKROWN_ERR; + } + } + + ret = access(dirPath.c_str(), F_OK); + if (ret == 0) { + HILOGE("File exists"); + return EEXIST; + } + return ERRNO_NOERR; +} + +napi_value Mkdirs::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 [pathSuc, path, pathIgnore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!pathSuc) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [success, recursion] = NVal(env, funcArg[NARG_POS::SECOND]).ToBool(); + if (!success) { + HILOGE("Invalid recursion mode"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto ret = CheckParam(path.get(), recursion); + if (ret != ERRNO_NOERR) { + NError(ret).ThrowErr(env); + return nullptr; + } + + ::Mkdirs(path.get(), static_cast(recursion)); + return NVal::CreateUndefined(env).val_; +} + +napi_value Mkdirs::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 [pathSuc, path, pathIgnore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!pathSuc) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [success, recursion] = NVal(env, funcArg[NARG_POS::SECOND]).ToBool(); + if (!success) { + HILOGE("Invalid recursion mode"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto ret = CheckParam(path.get(), recursion); + if (ret != ERRNO_NOERR) { + NError(ret).ThrowErr(env); + return nullptr; + } + + auto cbExec = [path = path.get(), mode = static_cast(recursion)]() -> NError { + ::Mkdirs(path, mode); + 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::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_MKDIRS_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_MKDIRS_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/mkdirs.h b/interfaces/kits/js/src/mod_fs/properties/mkdirs.h new file mode 100644 index 000000000..559a66880 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/mkdirs.h @@ -0,0 +1,40 @@ +/* + * 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_MKDIRS_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_MKDIRS_H + +#include +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::FileManagement::LibN; +class Mkdirs final{ +public: + static napi_value Sync(napi_env env, napi_callback_info info); + static napi_value Async(napi_env env, napi_callback_info info); +private: + static int CheckParam(const std::string &dirPath, bool recursion); +}; + +const std::string PROCEDURE_MKDIRS_NAME = "FileIOMkdirs"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_PROP_N_EXPORTER_H + + 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 index 4bcccb9e4..a10fa11ea 100644 --- a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp @@ -39,6 +39,7 @@ #include "rmdirent.h" #include "stat.h" #include "truncate.h" +#include "mkdirs.h" #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) #include "copy_file.h" @@ -232,7 +233,7 @@ napi_value PropNExporter::UnlinkSync(napi_env env, napi_callback_info info) napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { HILOGE("Number of arguments unmatched"); NError(EINVAL).ThrowErr(env); return nullptr; @@ -271,6 +272,9 @@ napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) if (funcArg.GetArgc() == NARG_CNT::ONE) { return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_MKDIR_NAME, cbExec, cbCompl).val_; } else { + if (NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_boolean)) { + return Mkdirs::Async(env, info); + } NVal cb(env, funcArg[NARG_POS::SECOND]); return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_MKDIR_NAME, cbExec, cbCompl).val_; } @@ -279,7 +283,7 @@ napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) napi_value PropNExporter::MkdirSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ONE)) { + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { HILOGE("Number of arguments unmatched"); NError(EINVAL).ThrowErr(env); return nullptr; @@ -306,6 +310,9 @@ napi_value PropNExporter::MkdirSync(napi_env env, napi_callback_info info) return nullptr; } + if (funcArg.GetArgc() == NARG_CNT::TWO) { + return Mkdirs::Sync(env, info); + } return NVal::CreateUndefined(env).val_; } diff --git a/interfaces/kits/js/src/mod_fs/properties/utimes.cpp b/interfaces/kits/js/src/mod_fs/properties/utimes.cpp new file mode 100644 index 000000000..cf55f3ff0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/utimes.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 "utimes.h" +#include +#include "common_func.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; +/** + * Change file mtime. + * + * @param { string } path - path. + * @param { number } mtime - last modification time + * @throws { BusinessError } 13900001 - Operation not permitted + * @throws { BusinessError } 13900002 - No such file or directory + * @throws { BusinessError } 13900012 - Permission denied + * @throws { BusinessError } 13900020 - Invalid argument + * @throws { BusinessError } 13900027 - Read-only file system + * @throws { BusinessError } 13900042 - Unknown error + * @syscap SystemCapability.FileManagement.File.FileIO + * @since 11 + */ +napi_value Utimes::Sync(napi_env env, napi_callback_info info) +{ + HILOGI("Utimes enter"); + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Utimes, Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + //1. path - path. + auto [succ1, tmp, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ1) { + HILOGE("Utimes, Invalid fd from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + //2. mtime - last modification time + auto [succ2, mtime] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ2) { + HILOGE("Utimes, Invalid whence from JS second argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + char *path = tmp.get(); + HILOGD("Utimes, path:%{public}s, mtime:%{public}d", path, mtime); + std::unique_ptr utimes_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!utimes_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + + int ret = access(path, F_OK); + if (ret != 0) { + HILOGE("Utimes::Sync, No such file or directory, file %{public}s", path); + NError(ENOENT).ThrowErr(env); + return nullptr; + } + + if (access(path, R_OK) == EROFS) { + HILOGE("Utimes::Sync, Read-only file system"); + NError(EROFS).ThrowErr(env); + return nullptr; + } + + struct stat st; + ret = stat(path, &st); + if (ret != 0) { + HILOGE("Utimes::Sync, Permission denied"); + NError(EACCES).ThrowErr(env); + return nullptr; + } + + double atime = st.st_atime; + ret = uv_fs_utime(nullptr, utimes_req.get(), path, atime, mtime, nullptr); + if (ret < 0) { + HILOGE("Failed to utimes file for %{public}d", ret); + NError(UNKROWN_ERR).ThrowErr(env); + return nullptr; + } + HILOGI("Utimes success"); + return nullptr; +} + +} // ModuleFileIO +} // FileManagement +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/utimes.h b/interfaces/kits/js/src/mod_fs/properties/utimes.h new file mode 100644 index 000000000..ebe81b4ee --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/utimes.h @@ -0,0 +1,35 @@ +/* + * 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_UTIMES_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_UTIMES_H + +#include +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +class Utimes final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +const std::string PROCEDURE_UTIMES_NAME = "FileIOUtimes"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_UTIMES_H \ No newline at end of file -- Gitee From 494a362329faaccabcf44f5544e1a9a11104fb9c Mon Sep 17 00:00:00 2001 From: zhuhongtao666 Date: Wed, 27 Sep 2023 10:56:30 +0800 Subject: [PATCH 2/3] =?UTF-8?q?getParent=E6=8E=A5=E5=8F=A3=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/mod_fs/class_file/file_n_exporter.cpp | 33 +++++++++++++++++++ .../src/mod_fs/class_file/file_n_exporter.h | 1 + 2 files changed, 34 insertions(+) diff --git a/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp index 0fe49afad..22c1fca13 100644 --- a/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp @@ -27,6 +27,8 @@ #include "filemgmt_libhilog.h" #include "filemgmt_libn.h" #include "../common_func.h" +#include "rust_file.h" +#include "n_val.h" namespace OHOS { namespace FileManagement { @@ -282,10 +284,41 @@ napi_value FileNExporter::Constructor(napi_env env, napi_callback_info info) return funcArg.GetThisVar(); } +napi_value FileNExporter::GetParent(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 fileEntity = GetFileEntity(env, funcArg.GetThisVar()); + if (!fileEntity) { + HILOGE("Failed to get file entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + if (!fileEntity->fd_.get()) { + HILOGE("File has been closed"); + NError(EIO).ThrowErr(env); + return nullptr; + } + auto parentPath = ::GetParent(fileEntity->fd_.get()->GetFD()); + if (parentPath == nullptr) { + HILOGE("Invalid parent uri"); + NError(USER_FILE_SERVICE_SYS_CAP_TAG + E_URIS).ThrowErr(env); + return nullptr; + } + std::string result = std::string(parentPath->str); + StrFree(parentPath); + return NVal::CreateUTF8String(env, result).val_; +} + bool FileNExporter::Export() { vector props = { NVal::DeclareNapiGetter("fd", GetFD), + NVal::DeclareNapiFunction("getParent", GetParent), #ifndef WIN_PLATFORM NVal::DeclareNapiGetter("path", GetPath), NVal::DeclareNapiGetter("name", GetName), diff --git a/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h index 43e5278a0..39514cede 100644 --- a/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h +++ b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h @@ -37,6 +37,7 @@ public: static napi_value TryLock(napi_env env, napi_callback_info info); static napi_value UnLock(napi_env env, napi_callback_info info); #endif + static napi_value GetParent(napi_env env, napi_callback_info info); static napi_value Constructor(napi_env env, napi_callback_info info); static napi_value GetFD(napi_env env, napi_callback_info info); -- Gitee From 1b92904ac049fee77a0890f1d9f0f3d740ce523a Mon Sep 17 00:00:00 2001 From: zhuhongtao666 Date: Wed, 27 Sep 2023 14:41:13 +0800 Subject: [PATCH 3/3] add read line interface --- interfaces/kits/js/BUILD.gn | 6 +- .../readeriterator_entity.h | 43 +++++ .../readeriterator_n_exporter.cpp | 111 ++++++++++++ .../readeriterator_n_exporter.h | 42 +++++ interfaces/kits/js/src/mod_fs/module.cpp | 2 + .../src/mod_fs/properties/prop_n_exporter.cpp | 7 + .../js/src/mod_fs/properties/read_lines.cpp | 158 ++++++++++++++++++ .../js/src/mod_fs/properties/read_lines.h | 36 ++++ 8 files changed, 403 insertions(+), 2 deletions(-) create mode 100644 interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_entity.h create mode 100644 interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_n_exporter.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/read_lines.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/read_lines.h diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 5e8785a02..1754c433b 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -121,22 +121,24 @@ 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_readeriterator/readeriterator_n_exporter.cpp", "src/mod_fs/common_func.cpp", "src/mod_fs/module.cpp", "src/mod_fs/properties/close.cpp", "src/mod_fs/properties/fdatasync.cpp", "src/mod_fs/properties/fsync.cpp", + "src/mod_fs/properties/lseek.cpp", "src/mod_fs/properties/lstat.cpp", + "src/mod_fs/properties/mkdirs.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_lines.cpp", "src/mod_fs/properties/rename.cpp", "src/mod_fs/properties/rmdirent.cpp", "src/mod_fs/properties/stat.cpp", "src/mod_fs/properties/truncate.cpp", "src/mod_fs/properties/utimes.cpp", - "src/mod_fs/properties/lseek.cpp", - "src/mod_fs/properties/mkdirs.cpp", ] cflags_cc = [ "-std=c++17" ] diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_entity.h b/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_entity.h new file mode 100644 index 000000000..e95bdde70 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_entity.h @@ -0,0 +1,43 @@ +/* + * 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_CLASS_FILE_READ_ITEROR_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_FILE_READ_ITEROR_ENTITY_H + +#include +#include +#include +#include +#include +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +struct ReaderIteratorResult { + bool done_ { false }; + std::string value_ { "" }; + ReaderIteratorResult() {} + ~ReaderIteratorResult() = default; +}; + +struct ReaderIteratorEntity { + ReaderIteratorResult result_; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_FILE_READ_ITEROR_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_n_exporter.cpp new file mode 100644 index 000000000..b6c3949ad --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_n_exporter.cpp @@ -0,0 +1,111 @@ +/* + * 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 "readeriterator_n_exporter.h" +#include "readeriterator_entity.h" +#include "filemgmt_libhilog.h" +#include "file_utils.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value ReaderIteratorNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto readerIteratorEntity = CreateUniquePtr(); + if (readerIteratorEntity == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(readerIteratorEntity))) { + HILOGE("Failed to set reader iterator entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + return funcArg.GetThisVar(); +} + +napi_value ReaderIteratorNExporter::Next(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 readerIteratorEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!readerIteratorEntity) { + HILOGE("Failed to get reader iterator entity"); + return nullptr; + } + + NVal objReaderIteratorResult = NVal::CreateObject(env); + objReaderIteratorResult.AddProp("done_", NVal::CreateBool(env, readerIteratorEntity->result_.done_).val_); + objReaderIteratorResult.AddProp("value_", NVal::CreateUTF8String(env, readerIteratorEntity->result_.value_).val_); + + return objReaderIteratorResult.val_; +} + +bool ReaderIteratorNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("next", Next), + }; + +#ifdef WIN_PLATFORM + string className = GetNExporterName(); +#else + string className = GetClassName(); +#endif + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, ReaderIteratorNExporter::Constructor, + std::move(props)); + if (!succ) { + HILOGE("Failed to define class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + HILOGE("Failed to save class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + return exports_.AddProp(className, classValue); +} + +#ifdef WIN_PLATFORM +string ReaderIteratorNExporter::GetNExporterName() +#else +string ReaderIteratorNExporter::GetClassName() +#endif +{ + return ReaderIteratorNExporter::className_; +} + +ReaderIteratorNExporter::ReaderIteratorNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +ReaderIteratorNExporter::~ReaderIteratorNExporter() {} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_n_exporter.h new file mode 100644 index 000000000..30c5d7021 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/readeriterator_n_exporter.h @@ -0,0 +1,42 @@ +/* + * 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_CLASS_READERITERATOR_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_READERITERATOR_N_EXPORTER_H + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace OHOS::FileManagement::LibN; + +class ReaderIteratorNExporter final : public NExporter { +public: + inline static const std::string className_ = "ReaderIterator"; + + bool Export() override; +#ifdef WIN_PLATFORM + std::string GetNExporterName() override; +#else + std::string GetClassName() override; +#endif + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value Next(napi_env env, napi_callback_info info); + + ReaderIteratorNExporter(napi_env env, napi_value exports); + ~ReaderIteratorNExporter() override; +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_READERITERATOR_N_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/module.cpp b/interfaces/kits/js/src/mod_fs/module.cpp index 797592042..4f31876fe 100644 --- a/interfaces/kits/js/src/mod_fs/module.cpp +++ b/interfaces/kits/js/src/mod_fs/module.cpp @@ -20,6 +20,7 @@ #include "class_file/file_n_exporter.h" #include "class_stat/stat_n_exporter.h" +#include "class_readeriterator/readeriterator_n_exporter.h" #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) #include "class_randomaccessfile/randomaccessfile_n_exporter.h" #include "class_stream/stream_n_exporter.h" @@ -40,6 +41,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)); #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); 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 index a10fa11ea..308c98228 100644 --- a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp @@ -32,14 +32,17 @@ #include "fsync.h" #include "js_native_api.h" #include "js_native_api_types.h" +#include "lseek.h" #include "lstat.h" #include "mkdtemp.h" #include "open.h" +#include "read_lines.h" #include "rename.h" #include "rmdirent.h" #include "stat.h" #include "truncate.h" #include "mkdirs.h" +#include "utimes.h" #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) #include "copy_file.h" @@ -574,6 +577,7 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("fdatasyncSync", Fdatasync::Sync), NVal::DeclareNapiFunction("fsync", Fsync::Async), NVal::DeclareNapiFunction("fsyncSync", Fsync::Sync), + NVal::DeclareNapiFunction("lseek", Lseek::Sync), NVal::DeclareNapiFunction("lstat", Lstat::Async), NVal::DeclareNapiFunction("lstatSync", Lstat::Sync), NVal::DeclareNapiFunction("mkdir", Mkdir), @@ -584,6 +588,8 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("openSync", Open::Sync), NVal::DeclareNapiFunction("read", Read), NVal::DeclareNapiFunction("readSync", ReadSync), + NVal::DeclareNapiFunction("readLines", ReadLines::Async), + NVal::DeclareNapiFunction("readLinesSync", ReadLines::Sync), NVal::DeclareNapiFunction("rename", Rename::Async), NVal::DeclareNapiFunction("renameSync", Rename::Sync), NVal::DeclareNapiFunction("rmdir", Rmdirent::Async), @@ -594,6 +600,7 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("truncateSync", Truncate::Sync), NVal::DeclareNapiFunction("unlink", Unlink), NVal::DeclareNapiFunction("unlinkSync", UnlinkSync), + NVal::DeclareNapiFunction("utimes", Utimes::Sync), NVal::DeclareNapiFunction("write", Write), NVal::DeclareNapiFunction("writeSync", WriteSync), #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) diff --git a/interfaces/kits/js/src/mod_fs/properties/read_lines.cpp b/interfaces/kits/js/src/mod_fs/properties/read_lines.cpp new file mode 100644 index 000000000..f0719cc39 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_lines.cpp @@ -0,0 +1,158 @@ +/* + * 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_lines.h" +#include +#include "common_func.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "rust_file.h" +#include "class_readeriterator/readeriterator_n_exporter.h" +#include "class_readeriterator/readeriterator_entity.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NVal InstantiateReaderIterator(napi_env env, void *iterator) +{ + if (iterator == nullptr) { + HILOGE("Invalid argument iterator"); + NError(EINVAL).ThrowErr(env); + return NVal(); + } + + napi_value objReaderIterator = NClass::InstantiateClass(env, ReaderIteratorNExporter::className_, {}); + if (!objReaderIterator) { + HILOGE("Failed to instantiate class ReaderIterator"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto readerIteratorEntity = NClass::GetEntityOf(env, objReaderIterator); + if (!readerIteratorEntity) { + HILOGE("Failed to get readerIteratorEntity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + ReaderIteratorResult *it = static_cast(iterator); + readerIteratorEntity->result_.done_ = it->done_; + readerIteratorEntity->result_.value_ = it->value_; + + return { env, objReaderIterator }; +} + +struct PtrHolder +{ + void *arg; +}; + +napi_value ReadLines::Async(napi_env env, napi_callback_info info) +{ + HILOGI("ReadLines::Async enter"); + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("ReadLines, Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, tmp, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("ReadLines, Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + char *path = tmp.get(); + int ret = access(path, F_OK); + if (ret < 0) { + HILOGE("ReadLines, No such file or directory"); + NError(ENOENT).ThrowErr(env); + return nullptr; + } + + auto holder = std::make_shared(); + auto cbExec = [holder = holder, path = path]() -> NError { + holder->arg = ::ReaderIterator(path); + if (holder->arg == nullptr) { + HILOGE("Failed to ReadLines, Unknown error"); + return NError(UNKROWN_ERR); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [holder = holder](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return InstantiateReaderIterator(env, holder->arg); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_READLINES_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_READLINES_NAME, cbExec, cbCompl).val_; + } +} + +napi_value ReadLines::Sync(napi_env env, napi_callback_info info) +{ + HILOGI("ReadLines::Sync enter"); + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("ReadLinesSync, Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, tmp, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succ) { + HILOGE("ReadLinesSync, Invalid path from JS first argument"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + char *path = tmp.get(); + int ret = access(path, F_OK); + if (ret < 0) { + HILOGE("ReadLinesSync, No such file or directory"); + NError(ENOENT).ThrowErr(env); + return nullptr; + } + ret = access(path, R_OK); + if (ret == EACCES) { + HILOGE("ReadLinesSync, Permission denied"); + NError(EACCES).ThrowErr(env); + return nullptr; + } + + void *iterator = ReaderIterator(path); + if (iterator == nullptr) { + HILOGE("Failed to ReadLinesSync, Unknown error"); + NError(UNKROWN_ERR).ThrowErr(env); + return nullptr; + } + + return InstantiateReaderIterator(env, iterator).val_; +} + +} // ModuleFileIO +} // FileManagement +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/read_lines.h b/interfaces/kits/js/src/mod_fs/properties/read_lines.h new file mode 100644 index 000000000..244d86c85 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_lines.h @@ -0,0 +1,36 @@ +/* + * 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_LINES_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_READ_LINES_H + +#include +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +class ReadLines 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_READLINES_NAME = "FileIOReadLines"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_READ_LINES_H \ No newline at end of file -- Gitee