From 9b7f84a346e854e1ff5e6ffadaf87d16075a13e1 Mon Sep 17 00:00:00 2001 From: tianp Date: Thu, 21 Aug 2025 10:07:25 +0800 Subject: [PATCH] =?UTF-8?q?randomaccessfile=E7=B1=BBstream=E7=B1=BB?= =?UTF-8?q?=E7=AD=BE=E5=90=8D=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tianp Change-Id: I5a2972253a00ab5c31ce6711647e0df10038d46a --- .../src/common/ani_helper/ani_signature.cpp | 17 +- .../js/src/common/ani_helper/ani_signature.h | 17 ++ .../ani/randomaccessfile_ani.cpp | 195 ++++++++++++++---- .../ani/create_randomaccessfile_ani.cpp | 15 +- 4 files changed, 205 insertions(+), 39 deletions(-) diff --git a/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp b/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp index 439bf8dc5..1f65c2d5a 100644 --- a/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp +++ b/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp @@ -35,6 +35,11 @@ const string BoxedTypes::Boolean::unboxedSig = Builder::BuildSignatureDescriptor // BoxedTypes::Int const Type BoxedTypes::Int::classType = Builder::BuildClass("std.core.Int"); const string BoxedTypes::Int::classDesc = BoxedTypes::Int::classType.Descriptor(); +const string BoxedTypes::Int::ctorSig = Builder::BuildSignatureDescriptor({ BasicTypes::intType }); +// BoxedTypes::Long +const Type BoxedTypes::Long::classType = Builder::BuildClass("std.core.Long"); +const string BoxedTypes::Long::classDesc = BoxedTypes::Long::classType.Descriptor(); +const string BoxedTypes::Long::ctorSig = Builder::BuildSignatureDescriptor({ BasicTypes::longType }); // BoxedTypes::Double const Type BoxedTypes::Double::classType = Builder::BuildClass("std.core.Double"); const string BoxedTypes::Double::classDesc = BoxedTypes::Double::classType.Descriptor(); @@ -121,15 +126,23 @@ const string FS::WatchEventInner::ctorSig = // FS::ReadStream const Type FS::ReadStream::classType = Builder::BuildClass("@ohos.file.fs.fileIo.ReadStream"); const string FS::ReadStream::classDesc = FS::ReadStream::classType.Descriptor(); -const string FS::ReadStream::ctorSig = Builder::BuildSignatureDescriptor({ BuiltInTypes::stringType }); +const string FS::ReadStream::ctorSig = + Builder::BuildSignatureDescriptor({ BuiltInTypes::stringType, FS::ReadStreamOptionsInner::classType }); // FS::WriteStream const Type FS::WriteStream::classType = Builder::BuildClass("@ohos.file.fs.fileIo.WriteStream"); const string FS::WriteStream::classDesc = FS::WriteStream::classType.Descriptor(); -const string FS::WriteStream::ctorSig = Builder::BuildSignatureDescriptor({ BuiltInTypes::stringType }); +const string FS::WriteStream::ctorSig = + Builder::BuildSignatureDescriptor({ BuiltInTypes::stringType, FS::WriteStreamOptionsInner::classType }); // FS::AtomicFile const Type FS::AtomicFile::classType = Builder::BuildClass("@ohos.file.fs.fileIo.AtomicFile"); const string FS::AtomicFile::classDesc = FS::AtomicFile::classType.Descriptor(); const string FS::AtomicFile::ctorSig = Builder::BuildSignatureDescriptor({ BuiltInTypes::stringType }); +// FS::ReadStreamOptionsInner +const Type FS::ReadStreamOptionsInner::classType = Builder::BuildClass("@ohos.file.fs.ReadStreamOptionsInner"); +const string FS::ReadStreamOptionsInner::classDesc = FS::ReadStreamOptionsInner::classType.Descriptor(); +// FS::WriteStreamOptionsInner +const Type FS::WriteStreamOptionsInner::classType = Builder::BuildClass("@ohos.file.fs.WriteStreamOptionsInner"); +const string FS::WriteStreamOptionsInner::classDesc = FS::WriteStreamOptionsInner::classType.Descriptor(); // FS::LocationType const Type FS::LocationType::classType = Builder::BuildClass("@ohos.file.fs.fileIo.LocationType"); const string FS::LocationType::classDesc = FS::LocationType::classType.Descriptor(); diff --git a/interfaces/kits/js/src/common/ani_helper/ani_signature.h b/interfaces/kits/js/src/common/ani_helper/ani_signature.h index e27e81c2c..71ed2a8f4 100644 --- a/interfaces/kits/js/src/common/ani_helper/ani_signature.h +++ b/interfaces/kits/js/src/common/ani_helper/ani_signature.h @@ -55,6 +55,13 @@ struct Boolean : public BaseType { struct Int : public BaseType { static const Type classType; static const string classDesc; + static const string ctorSig; +}; + +struct Long : public BaseType { + static const Type classType; + static const string classDesc; + static const string ctorSig; }; struct Double : public BaseType { @@ -202,6 +209,16 @@ struct AtomicFile : public BaseType { static const string ctorSig; }; +struct ReadStreamOptionsInner : public BaseType { + static const Type classType; + static const string classDesc; +}; + +struct WriteStreamOptionsInner : public BaseType { + static const Type classType; + static const string classDesc; +}; + } // namespace FS namespace Impl { diff --git a/interfaces/kits/js/src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp b/interfaces/kits/js/src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp index 518d7c13d..e23b0e15d 100644 --- a/interfaces/kits/js/src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp @@ -39,9 +39,10 @@ static FsRandomAccessFile *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 FsRandomAccessFile err: %{private}d", ret); + HILOGE("Unwrap FsRandomAccessFile err: %{public}d", ret); return nullptr; } + uintptr_t ptrValue = static_cast(nativePtr); FsRandomAccessFile *rafFile = reinterpret_cast(ptrValue); return rafFile; @@ -108,7 +109,10 @@ static tuple ParseStringBuffer(ani_env *env, const ani_object { ani_class cls; auto classDesc = BuiltInTypes::String::classDesc.c_str(); - env->FindClass(classDesc, &cls); + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{public}s", classDesc); + return { false, {} }; + } ani_boolean isString; env->Object_InstanceOf(buf, cls, &isString); @@ -123,13 +127,17 @@ static tuple ParseArrayBuffer(ani_env *env, const ani_obj { ani_class cls; auto classDesc = BuiltInTypes::ArrayBuffer::classDesc.c_str(); - env->FindClass(classDesc, &cls); + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{public}s", classDesc); + return { false, {} }; + } ani_boolean isArrayBuffer; env->Object_InstanceOf(buf, cls, &isArrayBuffer); if (!isArrayBuffer) { return { false, {} }; } + auto result = static_cast(buf); return { true, move(result) }; } @@ -142,6 +150,7 @@ void RandomAccessFileAni::SetFilePointer(ani_env *env, [[maybe_unused]] ani_obje ErrorHandler::Throw(env, UNKNOWN_ERR); return; } + auto ret = rafFile->SetFilePointerSync(static_cast(fp)); if (!ret.IsSuccess()) { HILOGE("SetFilePointerSync failed!"); @@ -161,7 +170,7 @@ void RandomAccessFileAni::Close(ani_env *env, [[maybe_unused]] ani_object object } auto ret = rafFile->CloseSync(); if (!ret.IsSuccess()) { - HILOGE("close rafFile failed!"); + HILOGE("Close rafFile failed!"); const auto &err = ret.GetError(); ErrorHandler::Throw(env, err); return; @@ -281,27 +290,89 @@ static ani_string GetFilePath(ani_env *env, const int fd) return move(filePath); } +static ani_object CreateBoxedInt(ani_env *env, int32_t value) +{ + auto classDesc = BoxedTypes::Int::classDesc.c_str(); + ani_class cls; + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{public}s", classDesc); + return nullptr; + } + + auto ctorDesc = BoxedTypes::Int::ctorDesc.c_str(); + auto ctorSig = BoxedTypes::Int::ctorSig0.c_str(); + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %{public}s", classDesc); + return nullptr; + } + + ani_object obj; + if (ANI_OK != env->Object_New(cls, ctor, &obj, value)) { + HILOGE("New %{public}s obj Failed", classDesc); + return nullptr; + } + + return obj; +} + +static ani_object CreateBoxedLong(ani_env *env, int64_t value) +{ + auto classDesc = BoxedTypes::Long::classDesc.c_str(); + ani_class cls; + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{public}s", classDesc); + return nullptr; + } + + auto ctorDesc = BoxedTypes::Long::ctorDesc.c_str(); + auto ctorSig = BoxedTypes::Long::ctorSig0.c_str(); + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %{public}s", classDesc); + return nullptr; + } + + ani_object obj; + if (ANI_OK != env->Object_New(cls, ctor, &obj, value)) { + HILOGE("New %{public}s obj Failed", classDesc); + return nullptr; + } + + return obj; +} + static ani_object CreateReadStreamOptions(ani_env *env, int64_t start, int64_t end) { - static const char *className = "L@ohos/file/fs/ReadStreamOptionsInner;"; + auto classDesc = FS::ReadStreamOptionsInner::classDesc.c_str(); ani_class cls; - if (ANI_OK != env->FindClass(className, &cls)) { - HILOGE("Cannot find class %s", className); + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{public}s", classDesc); return nullptr; } + + auto ctorDesc = FS::ReadStreamOptionsInner::ctorDesc.c_str(); + auto ctorSig = FS::ReadStreamOptionsInner::ctorSig0.c_str(); ani_method ctor; - if (ANI_OK != env->Class_FindMethod(cls, "", ":V", &ctor)) { - HILOGE("Cannot find constructor method for class %s", className); + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %{public}s", classDesc); return nullptr; } + ani_object obj; if (ANI_OK != env->Object_New(cls, ctor, &obj)) { - HILOGE("New %s obj Failed", className); + HILOGE("New %{public}s obj Failed", classDesc); return nullptr; } if (start >= 0) { - auto ret = AniHelper::SetFieldValue(env, obj, "start", start); + auto startValue = CreateBoxedLong(env, start); + if (startValue == nullptr) { + HILOGE("Create 'start' field value failed!"); + return nullptr; + } + + auto ret = AniHelper::SetPropertyValue(env, obj, "start", startValue); if (ret != ANI_OK) { HILOGE("Set 'start' field value failed! ret: %{public}d", ret); return nullptr; @@ -309,7 +380,13 @@ static ani_object CreateReadStreamOptions(ani_env *env, int64_t start, int64_t e } if (end >= 0) { - auto ret = AniHelper::SetFieldValue(env, obj, "end", end); + auto endValue = CreateBoxedLong(env, end); + if (endValue == nullptr) { + HILOGE("Create 'end' field value failed!"); + return nullptr; + } + + auto ret = AniHelper::SetPropertyValue(env, obj, "end", endValue); if (ret != ANI_OK) { HILOGE("Set 'end' field value failed! ret: %{public}d", ret); return nullptr; @@ -321,31 +398,47 @@ static ani_object CreateReadStreamOptions(ani_env *env, int64_t start, int64_t e static ani_object CreateWriteStreamOptions(ani_env *env, int64_t start, int flags) { - static const char *className = "L@ohos/file/fs/WriteStreamOptionsInner;"; + auto classDesc = FS::WriteStreamOptionsInner::classDesc.c_str(); ani_class cls; - if (ANI_OK != env->FindClass(className, &cls)) { - HILOGE("Cannot find class %s", className); + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{public}s", classDesc); return nullptr; } + + auto ctorDesc = FS::WriteStreamOptionsInner::ctorDesc.c_str(); + auto ctorSig = FS::WriteStreamOptionsInner::ctorSig0.c_str(); ani_method ctor; - if (ANI_OK != env->Class_FindMethod(cls, "", ":V", &ctor)) { - HILOGE("Cannot find constructor method for class %s", className); + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %{public}s", classDesc); return nullptr; } + ani_object obj; if (ANI_OK != env->Object_New(cls, ctor, &obj)) { - HILOGE("New %s obj Failed", className); + HILOGE("New %{public}s obj Failed", classDesc); return nullptr; } - auto ret = AniHelper::SetFieldValue(env, obj, "mode", flags); + auto flagsValue = CreateBoxedInt(env, flags); + if (flagsValue == nullptr) { + HILOGE("Create 'mode' field value failed!"); + return nullptr; + } + + auto ret = AniHelper::SetPropertyValue(env, obj, "mode", flagsValue); if (ret != ANI_OK) { HILOGE("Set 'mode' field value failed! ret: %{public}d", ret); return nullptr; } if (start >= 0) { - ret = AniHelper::SetFieldValue(env, obj, "start", start); + auto startValue = CreateBoxedLong(env, start); + if (startValue == nullptr) { + HILOGE("Create 'start' field value failed!"); + return nullptr; + } + + ret = AniHelper::SetPropertyValue(env, obj, "start", startValue); if (ret != ANI_OK) { HILOGE("Set 'start' field value failed! ret: %{public}d", ret); return nullptr; @@ -357,20 +450,24 @@ static ani_object CreateWriteStreamOptions(ani_env *env, int64_t start, int flag static ani_object CreateReadStream(ani_env *env, ani_string filePath, ani_object options) { - static const char *className = "L@ohos/file/fs/fileIo/ReadStream;"; + auto classDesc = FS::ReadStream::classDesc.c_str(); ani_class cls; - if (ANI_OK != env->FindClass(className, &cls)) { - HILOGE("Cannot find class %s", className); + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{public}s", classDesc); return nullptr; } + + auto ctorDesc = FS::ReadStream::ctorDesc.c_str(); + auto ctorSig = FS::ReadStream::ctorSig.c_str(); ani_method ctor; - if (ANI_OK != env->Class_FindMethod(cls, "", "Lstd/core/String;L@ohos/file/fs/ReadStreamOptions;:V", &ctor)) { - HILOGE("Cannot find constructor method for class %s", className); + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %{public}s", classDesc); return nullptr; } + ani_object obj; if (ANI_OK != env->Object_New(cls, ctor, &obj, filePath, options)) { - HILOGE("New %s obj Failed", className); + HILOGE("New %{public}s obj Failed", classDesc); return nullptr; } @@ -379,21 +476,24 @@ static ani_object CreateReadStream(ani_env *env, ani_string filePath, ani_object static ani_object CreateWriteStream(ani_env *env, ani_string filePath, ani_object options) { - static const char *className = "L@ohos/file/fs/fileIo/WriteStream;"; + auto classDesc = FS::WriteStream::classDesc.c_str(); ani_class cls; - if (ANI_OK != env->FindClass(className, &cls)) { - HILOGE("Cannot find class %s", className); + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{public}s", classDesc); return nullptr; } + + auto ctorDesc = FS::WriteStream::ctorDesc.c_str(); + auto ctorSig = FS::WriteStream::ctorSig.c_str(); ani_method ctor; - if (ANI_OK != - env->Class_FindMethod(cls, "", "Lstd/core/String;L@ohos/file/fs/WriteStreamOptions;:V", &ctor)) { - HILOGE("Cannot find constructor method for class %s", className); + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %{public}s", classDesc); return nullptr; } + ani_object obj; if (ANI_OK != env->Object_New(cls, ctor, &obj, filePath, options)) { - HILOGE("New %s obj Failed", className); + HILOGE("New %{public}s obj Failed", classDesc); return nullptr; } @@ -411,11 +511,36 @@ static ani_object CreateStream(ani_env *env, const string &streamName, RandomAcc if (streamName == READ_STREAM_CLASS) { ani_object obj = CreateReadStreamOptions(env, rafEntity->start, rafEntity->end); - return CreateReadStream(env, filePath, obj); + if (obj == nullptr) { + HILOGE("Create readstreamoptions failed."); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + ani_object readStream = CreateReadStream(env, filePath, obj); + if (readStream == nullptr) { + HILOGE("Create readstream failed."); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return readStream; } + if (streamName == WRITE_STREAM_CLASS) { ani_object obj = CreateWriteStreamOptions(env, rafEntity->start, flags); - return CreateWriteStream(env, filePath, obj); + if (obj == nullptr) { + HILOGE("Create writestreamoptions failed."); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + ani_object writeStream = CreateWriteStream(env, filePath, obj); + if (writeStream == nullptr) { + HILOGE("Create writestream failed."); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return writeStream; } return nullptr; diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/create_randomaccessfile_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/create_randomaccessfile_ani.cpp index c768a226c..586c11e25 100644 --- a/interfaces/kits/js/src/mod_fs/properties/ani/create_randomaccessfile_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/ani/create_randomaccessfile_ani.cpp @@ -89,7 +89,10 @@ static tuple JudgeFile(ani_env *env, ani_object obj) { auto stringTypeDesc = BuiltInTypes::String::classDesc.c_str(); ani_class stringClass; - env->FindClass(stringTypeDesc, &stringClass); + if (ANI_OK != env->FindClass(stringTypeDesc, &stringClass)) { + HILOGE("Cannot find class %{public}s", stringTypeDesc); + return { false, false }; + } ani_boolean isString = false; env->Object_InstanceOf(obj, stringClass, &isString); if (isString) { @@ -98,7 +101,10 @@ static tuple JudgeFile(ani_env *env, ani_object obj) auto fileClassDesc = FS::FileInner::classDesc.c_str(); ani_class fileClass; - env->FindClass(fileClassDesc, &fileClass); + if (ANI_OK != env->FindClass(fileClassDesc, &fileClass)) { + HILOGE("Cannot find class %{public}s", fileClassDesc); + return { false, false }; + } ani_boolean isFile = false; env->Object_InstanceOf(obj, fileClass, &isFile); if (isFile) { @@ -140,14 +146,17 @@ static ani_object CreateRandomAccessFileByString( auto [succPath, path] = TypeConverter::ToUTF8String(env, static_cast(file)); if (!succPath) { HILOGE("Parse file path failed"); + ErrorHandler::Throw(env, EINVAL); return nullptr; } + auto [succMode, modeOp] = TypeConverter::ToOptionalInt32(env, mode); if (!succMode) { HILOGE("Invalid mode"); ErrorHandler::Throw(env, EINVAL); return nullptr; } + FsResult ret = CreateRandomAccessFileCore::DoCreateRandomAccessFile(path, modeOp, op); if (!ret.IsSuccess()) { HILOGE("CreateRandomAccessFile failed"); @@ -155,6 +164,7 @@ static ani_object CreateRandomAccessFileByString( ErrorHandler::Throw(env, err); return nullptr; } + const FsRandomAccessFile *refFile = ret.GetData().value(); auto result = Wrap(env, move(refFile)); if (result == nullptr) { @@ -200,6 +210,7 @@ ani_object CreateRandomAccessFileAni::CreateRandomAccessFileSync( ErrorHandler::Throw(env, err); return nullptr; } + const FsRandomAccessFile *refFile = ret.GetData().value(); auto result = Wrap(env, move(refFile)); if (result == nullptr) { -- Gitee