diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 9334220be9d28e01972e60ed84bec52d044d4e8a..687f8ab1cc337256e8c51d30ce5af7604311eefb 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -663,6 +663,8 @@ ohos_shared_library("ani_fs_class") { "src/mod_fs/ani", "src/mod_fs/class_file", "src/mod_fs/class_file/ani", + "src/mod_fs/class_readeriterator", + "src/mod_fs/class_readeriterator/ani", "src/mod_fs/class_stat", "src/mod_fs/class_stat/ani", "src/mod_fs/properties", @@ -676,6 +678,9 @@ ohos_shared_library("ani_fs_class") { "src/mod_fs/ani/bind_function_class.cpp", "src/mod_fs/class_file/ani/file_ani.cpp", "src/mod_fs/class_file/fs_file.cpp", + "src/mod_fs/class_readeriterator/ani/reader_iterator_ani.cpp", + "src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.cpp", + "src/mod_fs/class_readeriterator/fs_reader_iterator.cpp", "src/mod_fs/class_stat/ani/stat_ani.cpp", "src/mod_fs/class_stat/fs_stat.cpp", "src/mod_fs/fs_utils.cpp", @@ -688,6 +693,7 @@ ohos_shared_library("ani_fs_class") { "src/mod_fs/properties/ani/move_ani.cpp", "src/mod_fs/properties/ani/open_ani.cpp", "src/mod_fs/properties/ani/read_ani.cpp", + "src/mod_fs/properties/ani/read_lines_ani.cpp", "src/mod_fs/properties/ani/read_text_ani.cpp", "src/mod_fs/properties/ani/rmdir_ani.cpp", "src/mod_fs/properties/ani/truncate_ani.cpp", @@ -700,6 +706,7 @@ ohos_shared_library("ani_fs_class") { "src/mod_fs/properties/move_core.cpp", "src/mod_fs/properties/open_core.cpp", "src/mod_fs/properties/read_core.cpp", + "src/mod_fs/properties/read_lines_core.cpp", "src/mod_fs/properties/read_text_core.cpp", "src/mod_fs/properties/rmdir_core.cpp", "src/mod_fs/properties/stat_core.cpp", diff --git a/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp b/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp index 065495c9ade9c4c775ce494fa218d0c382077459..e94639c375ad8ac99a37d2b2a56d4b7f1b6327cb 100644 --- a/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp +++ b/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp @@ -28,7 +28,9 @@ #include "move_ani.h" #include "open_ani.h" #include "read_ani.h" +#include "read_lines_ani.h" #include "read_text_ani.h" +#include "reader_iterator_ani.h" #include "rmdir_ani.h" #include "stat_ani.h" #include "truncate_ani.h" @@ -51,6 +53,17 @@ static ani_status BindFileMethods(ani_env *env) return BindClass(env, className, methods); } +static ani_status BindReaderIteratorMethods(ani_env *env) +{ + static const char *className = "L@ohos/file/fs/ReaderIteratorInner;"; + + std::array methods = { + ani_native_function { "next", nullptr, reinterpret_cast(ReaderIteratorAni::Next) }, + }; + + return BindClass(env, className, methods); +} + static ani_status BindStatClassMethods(ani_env *env) { static const char *className = "L@ohos/file/fs/StatInner;"; @@ -81,6 +94,7 @@ static ani_status BindStaticMethods(ani_env *env) ani_native_function { "mkdirSync", "Lstd/core/String;Z:V", reinterpret_cast(MkdirkAni::MkdirSync1) }, ani_native_function { "moveFileSync", nullptr, reinterpret_cast(MoveAni::MoveFileSync) }, ani_native_function { "openSync", nullptr, reinterpret_cast(OpenAni::OpenSync) }, + ani_native_function { "readlinesSync", nullptr, reinterpret_cast(ReadLinesAni::ReadLinesSync) }, ani_native_function { "readSync", nullptr, reinterpret_cast(ReadAni::ReadSync) }, ani_native_function { "readTextSync", nullptr, reinterpret_cast(ReadTextAni::ReadTextSync) }, ani_native_function { "rmdirSync", nullptr, reinterpret_cast(RmdirAni::RmdirSync) }, @@ -123,6 +137,12 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) return status; }; + status = BindReaderIteratorMethods(env); + if (status != ANI_OK) { + HILOGE("Cannot bind native methods for ReaderIterator Class"); + return status; + }; + status = BindStatClassMethods(env); if (status != ANI_OK) { HILOGE("Cannot bind native methods for Stat Class!"); diff --git a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets index 67eb95add30a0cd803f0542ae46c90f870189651..5d0bbfe7db84a706b5bee559ae0085dedf57c396 100644 --- a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets +++ b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets @@ -325,6 +325,58 @@ function read(fd: number, buffer: ArrayBuffer, options: ReadOptions, callback: A }); } +function readLinesSync(filePath: string, options?: Options): ReaderIterator { + return FileIoImpl.readlinesSync(filePath, options) +} + +function readLines(filePath: string, options?: Options): Promise { + return new Promise((resolve: (result: ReaderIterator) => void, reject: (e: BusinessError) => void) => { + if (options === undefined) { + let promise = taskpool.execute(FileIoImpl.readlinesSync, filePath); + promise.then((ret: NullishType): void => { + let it = ret as ReaderIterator; + resolve(it); + }).catch((e: BusinessError): void => { + reject(e); + }); + } else { + let promise = taskpool.execute(FileIoImpl.readlinesSync, filePath, options); + promise.then((ret: NullishType): void => { + let it = ret as ReaderIterator; + resolve(it); + }).catch((e: BusinessError): void => { + reject(e); + }); + } + }); +} + +function readLines(filePath: string, callback: AsyncCallback): void { + let promise = taskpool.execute(FileIoImpl.readlinesSync, filePath); + promise.then((ret: NullishType): void => { + let e = new BusinessError(); + e.code = 0; + let it = ret as ReaderIterator; + callback(e, it); + }).catch((e: BusinessError): void => { + let r: ReaderIterator = new ReaderIteratorInner(0); + callback(e, r); + }); +} + +function readLines(filePath: string, options: Options, callback: AsyncCallback): void { + let promise = taskpool.execute(FileIoImpl.readlinesSync, filePath, options); + promise.then((ret: NullishType): void => { + let e = new BusinessError(); + e.code = 0; + let it = ret as ReaderIterator; + callback(e, it); + }).catch((e: BusinessError): void => { + let r: ReaderIterator = new ReaderIteratorInner(0); + callback(e, r); + }); +} + function rmdirSync(path: string): void { return FileIoImpl.rmdirSync(path) } @@ -507,6 +559,10 @@ export interface ListFileOptions { filter?: Filter; } +export interface Options { + encoding?: string; +} + export interface ReadOptions { offset?: number; length?: number; @@ -569,6 +625,40 @@ enum LocationType { CLOUD = 2 } +export interface ReaderIteratorResult { + done: boolean; + value: string; +} + +class ReaderIteratorResultInner implements ReaderIteratorResult { + private nativePtr: long = 0; + + constructor(ptr: long) { + if (this.nativePtr === 0) { + this.nativePtr = ptr; + } + } + + done: boolean = false; + value: string = ""; +} + +export interface ReaderIterator { + next(): ReaderIteratorResult; +} + +class ReaderIteratorInner implements ReaderIterator { + private nativePtr: long = 0; + + constructor(ptr: long) { + if (this.nativePtr === 0) { + this.nativePtr = ptr; + } + } + + native next(): ReaderIteratorResult; +} + export interface Stat { ino: bigint; mode: number; @@ -645,6 +735,8 @@ class FileIoImpl { static native openSync(path: String, mode?: number): File; + static native readlinesSync(filePath: string, options?: Options): ReaderIterator; + static native readSync(fd: number, buffer: ArrayBuffer, options?: ReadOptions): number; static native readTextSync(filePath: string, options?: ReadTextOptions): string; diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.cpp b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5f8b55b93c91b0b2b2c1b9a046cdc2968dab24f --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.cpp @@ -0,0 +1,94 @@ +/* + * 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 "reader_iterator_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "reader_iterator_result_ani.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace std; + +ani_object ReaderIteratorAni::Wrap(ani_env *env, const FsReaderIterator *it) +{ + static const char *className = "L@ohos/file/fs/ReaderIteratorInner;"; + + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + HILOGE("Cannot find class %s", className); + return nullptr; + } + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", "J:V", &ctor)) { + HILOGE("Cannot find constructor method for class %s", className); + return nullptr; + } + ani_long ptr = static_cast(reinterpret_cast(it)); + ani_object obj; + if (ANI_OK != env->Object_New(cls, ctor, &obj, ptr)) { + HILOGE("New %s obj Failed!", className); + return nullptr; + } + + return obj; +} + +FsReaderIterator *ReaderIteratorAni::Unwrap(ani_env *env, ani_object object) +{ + ani_long nativePtr; + auto ret = env->Object_GetFieldByName_Long(object, "nativePtr", &nativePtr); + if (ret != ANI_OK) { + HILOGE("Unwrap fsReaderIterator err: %{private}d", ret); + return nullptr; + } + uintptr_t ptrValue = static_cast(nativePtr); + FsReaderIterator *readeriterator = reinterpret_cast(ptrValue); + return readeriterator; +} + +ani_object ReaderIteratorAni::Next(ani_env *env, [[maybe_unused]] ani_object object) +{ + auto fsReaderIterator = Unwrap(env, object); + if (fsReaderIterator == nullptr) { + ErrorHandler::Throw(env, UNKNOWN_ERR); + return ANI_FALSE; + } + + auto ret = fsReaderIterator->Next(); + if (!ret.IsSuccess()) { + HILOGE("Cannot get readeriterator next!"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return {}; + } + auto nextRet = ret.GetData().value(); + auto result = ReaderIteratorResultAni::Wrap(env, &nextRet); + if (result == nullptr) { + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return result; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.h b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..31d70abc24f16b2ddc84c4bd627c20580e0ce001 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.h @@ -0,0 +1,39 @@ +/* + * 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_READER_ITERATOR_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_READER_ITERATOR_ANI_H + +#include + +#include "fs_reader_iterator.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class ReaderIteratorAni final { +public: + static ani_object Wrap(ani_env *env, const FsReaderIterator *it); + static FsReaderIterator *Unwrap(ani_env *env, ani_object object); + static ani_object Next(ani_env *env, [[maybe_unused]] ani_object object); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_READER_ITERATOR_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.cpp b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ea8f121b13ffdf8bf88536279e737b91519685b --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.cpp @@ -0,0 +1,68 @@ +/* + * 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 "reader_iterator_result_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace std; + +ani_object ReaderIteratorResultAni::Wrap(ani_env *env, const ReaderIteratorResult *result) +{ + static const char *className = "L@ohos/file/fs/ReaderIteratorResultInner;"; + + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + HILOGE("Cannot find class %s", className); + return nullptr; + } + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", "J:V", &ctor)) { + HILOGE("Cannot find constructor method for class %s", className); + return nullptr; + } + ani_long ptr = static_cast(reinterpret_cast(result)); + ani_object obj; + if (ANI_OK != env->Object_New(cls, ctor, &obj, ptr)) { + HILOGE("New %s obj Failed!", className); + return nullptr; + } + + const auto &done = result->done; + if (ANI_OK != AniHelper::SetPropertyValue(env, cls, obj, "done", static_cast(done))) { + HILOGE("Set 'done' field value failed!"); + return nullptr; + } + + const auto &value = result->value; + if (ANI_OK != AniHelper::SetPropertyValue(env, cls, obj, "value", value)) { + HILOGE("Set 'value' field value failed!"); + return nullptr; + } + + return obj; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.h b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..0f683784654fe6da7db2415df97312043de59b9c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.h @@ -0,0 +1,37 @@ +/* + * 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_READER_ITERATOR_RESULT_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_READER_ITERATOR_RESULT_ANI_H + +#include + +#include "fs_reader_iterator.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class ReaderIteratorResultAni final { +public: + static ani_object Wrap(ani_env *env, const ReaderIteratorResult *result); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_READER_ITERATOR_RESULT_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/fs_reader_iterator.cpp b/interfaces/kits/js/src/mod_fs/class_readeriterator/fs_reader_iterator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..80321d51f126f318d7ae4fd8c78ba76db64ff928 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/fs_reader_iterator.cpp @@ -0,0 +1,70 @@ +/* + * 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 "fs_reader_iterator.h" + +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "rust_file.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; + +FsResult FsReaderIterator::Constructor() +{ + auto entity = CreateUniquePtr(); + if (entity == nullptr) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + + FsReaderIterator *it = new FsReaderIterator(move(entity)); + + if (it == nullptr) { + HILOGE("Failed to create FsReaderIterator object on heap."); + return FsResult::Error(ENOMEM); + } + return FsResult::Success(move(it)); +} + +FsResult FsReaderIterator::Next() +{ + if (entity == nullptr) { + HILOGE("Failed to get reader iterator entity"); + return FsResult::Error(UNKNOWN_ERR); + } + + Str *str = NextLine(entity->iterator); + if (str == nullptr && entity->offset != 0) { + HILOGE("Failed to get next line, error:%{public}d", errno); + return FsResult::Error(errno); + } + + ReaderIteratorResult result; + bool done = entity->offset == 0; + result.done = done; + if (str != nullptr) { + std::string value(str->str, str->len); + result.value = value; + entity->offset -= static_cast(str->len); + } else { + result.value = ""; + } + StrFree(str); + + return FsResult::Success(move(result)); +} + +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/fs_reader_iterator.h b/interfaces/kits/js/src/mod_fs/class_readeriterator/fs_reader_iterator.h new file mode 100644 index 0000000000000000000000000000000000000000..bc534da09eb0acbaa8261bfe599580c6fdbda9aa --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/fs_reader_iterator.h @@ -0,0 +1,45 @@ +/* + * 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_CLASS_READERITERATOR_FS_READERITERATOR_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_READERITERATOR_FS_READERITERATOR_H + +#include "filemgmt_libfs.h" +#include "readeriterator_entity.h" + +namespace OHOS::FileManagement::ModuleFileIO { + +struct ReaderIteratorResult { + bool done; + std::string value; +}; + +class FsReaderIterator final { +public: + static FsResult Constructor(); + + ReaderIteratorEntity *GetReaderIteratorEntity() const + { + return entity.get(); + } + + FsResult Next(); + +private: + unique_ptr entity; + explicit FsReaderIterator(unique_ptr entity) : entity(move(entity)) {}; +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_READERITERATOR_FS_READERITERATOR_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/read_lines_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/read_lines_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49b26f784cd53a4650918a391e78cf725a63d9cd --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/read_lines_ani.cpp @@ -0,0 +1,85 @@ +/* + * 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_lines_ani.h" + +#include "ani_helper.h" +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "read_lines_core.h" +#include "reader_iterator_ani.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace OHOS::FileManagement::ModuleFileIO; + +static tuple> ToReadLinesOptions(ani_env *env, ani_object obj) +{ + Options options; + + ani_boolean isUndefined; + env->Reference_IsUndefined(obj, &isUndefined); + if (isUndefined) { + return { true, nullopt }; + } + + auto [succEncoding, encoding] = AniHelper::ParseEncoding(env, obj); + if (!succEncoding) { + HILOGE("Illegal option.encoding parameter"); + return { false, nullopt }; + } + options.encoding = encoding.value(); + + return { true, make_optional(move(options)) }; +} + +ani_object ReadLinesAni::ReadLinesSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_object options) +{ + auto [succPath, filePath] = TypeConverter::ToUTF8String(env, path); + if (!succPath) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + auto [succMode, opt] = ToReadLinesOptions(env, options); + if (!succMode) { + HILOGE("Invalid options"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + FsResult ret = ReadLinesCore::DoReadLines(filePath, opt); + if (!ret.IsSuccess()) { + HILOGE("Readlines failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return nullptr; + } + const FsReaderIterator *readerIterator = ret.GetData().value(); + auto result = ReaderIteratorAni::Wrap(env, move(readerIterator)); + if (result == nullptr) { + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return result; +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/read_lines_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/read_lines_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..b51c301dd473a8223462f70e4d43ce8d8eada1ec --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/read_lines_ani.h @@ -0,0 +1,35 @@ +/* + * 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_READ_LINES_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_READ_LINES_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class ReadLinesAni final { +public: + static ani_object ReadLinesSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_object options); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_READ_LINES_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/read_lines_core.cpp b/interfaces/kits/js/src/mod_fs/properties/read_lines_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..819215c30e9be4c365a6315fc8e078ade722960e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_lines_core.cpp @@ -0,0 +1,110 @@ +/* + * 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_lines_core.h" + +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "rust_file.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +static int CheckOptionArg(optional option) +{ + auto encoding = option->encoding; + if (encoding != "utf-8") { + return EINVAL; + } + + return ERRNO_NOERR; +} + +static int GetFileSize(const string &path, int64_t &offset) +{ + std::unique_ptr readLinesReq = { new uv_fs_t, FsUtils::FsReqCleanup }; + if (!readLinesReq) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + + int ret = uv_fs_stat(nullptr, readLinesReq.get(), path.c_str(), nullptr); + if (ret < 0) { + HILOGE("Failed to get file stat by path"); + return ret; + } + + offset = static_cast(readLinesReq->statbuf.st_size); + return ERRNO_NOERR; +} + +static FsResult InstantiateReaderIterator(void *iterator, int64_t offset) +{ + if (iterator == nullptr) { + HILOGE("Invalid argument iterator"); + return FsResult::Error(EINVAL); + } + + auto readeriterator = FsReaderIterator::Constructor(); + if (!readeriterator.IsSuccess()) { + HILOGE("Failed to instantiate class ReaderIterator"); + return FsResult::Error(UNKNOWN_ERR); + } + + auto readerIteratorEntity = readeriterator.GetData().value()->GetReaderIteratorEntity(); + if (!readerIteratorEntity) { + HILOGE("Failed to get readerIteratorEntity"); + return FsResult::Error(UNKNOWN_ERR); + } + readerIteratorEntity->iterator = iterator; + readerIteratorEntity->offset = offset; + return FsResult::Success(readeriterator.GetData().value()); +} + +FsResult ReadLinesCore::DoReadLines(const string &path, optional option) +{ + if (option.has_value()) { + int ret = CheckOptionArg(option); + if (ret) { + HILOGE("Invalid option.encoding parameter"); + return FsResult::Error(ret); + } + } + + auto iterator = ::ReaderIterator(path.c_str()); + if (iterator == nullptr) { + HILOGE("Failed to read lines of the file, error: %{public}d", errno); + return FsResult::Error(errno); + } + + int64_t offset = 0; + int ret = GetFileSize(path, offset); + if (ret != 0) { + HILOGE("Failed to get size of the file"); + return FsResult::Error(ret); + } + auto readeriterator = InstantiateReaderIterator(iterator, offset); + if (!readeriterator.IsSuccess()) { + return FsResult::Error(ENOMEM); + } + return FsResult::Success(readeriterator.GetData().value()); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/read_lines_core.h b/interfaces/kits/js/src/mod_fs/properties/read_lines_core.h new file mode 100644 index 0000000000000000000000000000000000000000..a450cc43188f2765786fde02ed8a2c8d07166ae9 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_lines_core.h @@ -0,0 +1,44 @@ +/* + * 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_LINES_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_READ_LINES_CORE_H + +#include + +#include "filemgmt_libfs.h" +#include "fs_reader_iterator.h" +#include "fs_utils.h" +#include "readeriterator_entity.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +struct Options final { + std::string encoding; +}; + +class ReadLinesCore final { +public: + static FsResult DoReadLines( + const std::string &path, std::optional option = std::nullopt); +}; + +const std::string PROCEDURE_READLINES_NAME = "FileIOReadLines"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_READ_LINES_CORE_H \ No newline at end of file