diff --git a/interfaces/kits/js/src/mod_fs/properties/read_text_core.cpp b/interfaces/kits/js/src/mod_fs/properties/read_text_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a3d5875bc1133f41b3ae8d4737437adbe1677347 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_text_core.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2025 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_core.h" + +#include +#include +#include +#include +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +static tuple> ValidReadTextArg(const std::optional &options = nullopt) +{ + int64_t offset = -1; + int64_t len = 0; + bool hasLen = false; + unique_ptr encoding { new char[]{ "utf-8" } }; + + if (options.has_value()) { + ReadTextOptions op = options.value(); + if (op.offset.has_value()) { + offset = op.offset.value(); + if (offset < 0) { + HILOGE("Illegal option.offset parameter"); + return { false, offset, hasLen, len, nullptr }; + } + } + + if (op.length.has_value()) { + len = op.length.value(); + if (len < 0 || len > UINT_MAX) { + HILOGE("Illegal option.length parameter"); + return { false, offset, hasLen, len, nullptr }; + } + hasLen = true; + } + + if (op.encoding.has_value()) { + auto encoding = op.encoding.value(); + if (encoding != "utf-8") { + HILOGE("Illegal option.encoding parameter"); + return { false, offset, hasLen, len, nullptr }; + } + } + } + + return { true, offset, hasLen, len, move(encoding) }; +} + +static int OpenFile(const std::string& path) +{ + std::unique_ptr open_req = { + new uv_fs_t, FsUtils::FsReqCleanup + }; + if (open_req == nullptr) { + HILOGE("Failed to request heap memory."); + return -ENOMEM; + } + + return uv_fs_open(nullptr, open_req.get(), path.c_str(), O_RDONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, nullptr); +} + +static int ReadFromFile(int fd, int64_t offset, string& buffer) +{ + uv_buf_t readbuf = uv_buf_init(const_cast(buffer.c_str()), static_cast(buffer.size())); + std::unique_ptr read_req = { + new uv_fs_t, FsUtils::FsReqCleanup }; + if (read_req == nullptr) { + HILOGE("Failed to request heap memory."); + return -ENOMEM; + } + return uv_fs_read(nullptr, read_req.get(), fd, &readbuf, 1, offset, nullptr); +} + +FsResult> ReadTextCore::DoReadText(const std::string& path, const std::optional &options) +{ + auto [resGetReadTextArg, offset, hasLen, len, encoding] = ValidReadTextArg(options); + if (!resGetReadTextArg) { + return FsResult>::Error(EINVAL); + } + + OHOS::DistributedFS::FDGuard sfd; + int fd = OpenFile(path); + if (fd < 0) { + HILOGD("Failed to open file by ret: %{public}d", fd); + return FsResult>::Error(fd); + } + sfd.SetFD(fd); + + struct stat statbf; + if ((!sfd) || (fstat(sfd.GetFD(), &statbf) < 0)) { + HILOGE("Failed to get stat of file by fd: %{public}d", sfd.GetFD()); + return FsResult>::Error(errno); + } + + if (offset > statbf.st_size) { + HILOGE("Invalid offset: %{public}" PRIu64, offset); + return FsResult>::Error(EINVAL); + } + + len = (!hasLen || len > statbf.st_size) ? statbf.st_size : len; + string buffer(len, '\0'); + int readRet = ReadFromFile(sfd.GetFD(), offset, buffer); + if (readRet < 0) { + HILOGE("Failed to read file by fd: %{public}d", fd); + return FsResult>::Error(readRet); + } + + return FsResult>::Success(make_tuple(move(buffer), readRet)); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/read_text_core.h b/interfaces/kits/js/src/mod_fs/properties/read_text_core.h new file mode 100644 index 0000000000000000000000000000000000000000..bb3d332d758ccecfc5aedf44e1ec31e0192c6e45 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_text_core.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 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_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_READ_TEXT_CORE_H + +#include "fs_utils.h" +#include "filemgmt_libfs.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +struct ReadTextOptions final { + optional offset = nullopt; + optional length = nullopt; + optional encoding = nullopt; +}; + +class ReadTextCore final { +public: + static FsResult> DoReadText(const string& filePath, const optional &options = nullopt); +}; + +const string PROCEDURE_READTEXT_NAME = "FileIOReadText"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_READ_TEXT_CORE_H \ No newline at end of file