diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp old mode 100755 new mode 100644 index 766209902c059f4c60a3f8406cd375faa1f531a7..2cc0aedb8bb538b62d16700b957f0c069ace1fba --- a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp @@ -38,7 +38,6 @@ using namespace OHOS::FileManagement::LibN; napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { HILOGE("Number of arguments unmatched"); NError(EINVAL).ThrowErr(env); @@ -69,9 +68,10 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info info) } size_t actLen = fread(buf, 1, len, filp); - if ((actLen < 0) && ferror(filp)) { + if (actLen != static_cast(len) && ferror(filp)) { HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); NError(errno).ThrowErr(env); + return nullptr; } return NVal::CreateInt64(env, actLen).val_; @@ -80,7 +80,6 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info info) napi_value StreamNExporter::CloseSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ZERO)) { HILOGE("Number of arguments unmatched"); NError(EINVAL).ThrowErr(env); @@ -94,6 +93,7 @@ napi_value StreamNExporter::CloseSync(napi_env env, napi_callback_info info) return nullptr; } streamEntity->fp.reset(); + return NVal::CreateUndefined(env).val_; } @@ -129,7 +129,7 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info info) } size_t writeLen = fwrite(buf, 1, len, filp); - if (writeLen < 0) { + if (writeLen != len && ferror(filp)) { HILOGE("Failed to fwrite with len, writeLen: %{public}zu, len: %{public}" PRId64, writeLen, len); NError(errno).ThrowErr(env); return nullptr; @@ -138,16 +138,6 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info info) return NVal::CreateInt64(env, writeLen).val_; } -struct AsyncWrtieArg { - NRef refWriteArrayBuf; - unique_ptr guardWriteStr; - size_t actLen { 0 }; - - explicit AsyncWrtieArg(NVal refWriteArrayBuf) : refWriteArrayBuf(refWriteArrayBuf) {} - explicit AsyncWrtieArg(unique_ptr &&guardWriteStr) : guardWriteStr(move(guardWriteStr)) {} - ~AsyncWrtieArg() = default; -}; - static bool HasOption(napi_env env, napi_value optionFromJsArg) { NVal op = NVal(env, optionFromJsArg); @@ -183,9 +173,12 @@ napi_value StreamNExporter::Write(napi_env env, napi_callback_info info) return nullptr; } - shared_ptr arg; - arg = make_shared(move(bufGuard)); - + auto arg = make_shared(move(bufGuard)); + if (arg == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } auto cbExec = [arg, buf = buf, len = len, filp, hasOffset = hasOffset, offset = offset]() -> NError { int ret = fseek(filp, offset, SEEK_SET); if (hasOffset && (ret < 0)) { @@ -193,7 +186,7 @@ napi_value StreamNExporter::Write(napi_env env, napi_callback_info info) return NError(errno); } arg->actLen = fwrite(buf, 1, len, filp); - if ((arg->actLen < 0) && ferror(filp)) { + if ((arg->actLen != static_cast(len)) && ferror(filp)) { HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", arg->actLen); return NError(errno); } @@ -221,14 +214,6 @@ napi_value StreamNExporter::Write(napi_env env, napi_callback_info info) } } -struct AsyncReadArg { - size_t lenRead { 0 }; - NRef refReadBuf; - - explicit AsyncReadArg(NVal jsReadBuf) : refReadBuf(jsReadBuf) {} - ~AsyncReadArg() = default; -}; - napi_value StreamNExporter::Read(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -256,6 +241,11 @@ napi_value StreamNExporter::Read(napi_env env, napi_callback_info info) } auto arg = make_shared(NVal(env, funcArg[NARG_POS::FIRST])); + if (arg == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } auto cbExec = [arg, buf = buf, len = len, filp, hasOffset = hasOffset, offset = offset]() -> NError { int ret = fseek(filp, offset, SEEK_SET); if (hasOffset && (ret < 0)) { @@ -263,7 +253,7 @@ napi_value StreamNExporter::Read(napi_env env, napi_callback_info info) return NError(errno); } size_t actLen = fread(buf, 1, len, filp); - if ((actLen < 0) && ferror(filp)) { + if (actLen != static_cast(len) && ferror(filp)) { HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); return NError(errno); } else { diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h old mode 100755 new mode 100644 index e66b597122b55a7b75b04a1191ea77579662f6b3..afb2579e6e5e80c65111c14017ea3797823a372b --- a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h @@ -43,6 +43,24 @@ public: ~StreamNExporter() override; }; +struct AsyncReadArg { + size_t lenRead { 0 }; + NRef refReadBuf; + + explicit AsyncReadArg(NVal jsReadBuf) : refReadBuf(jsReadBuf) {} + ~AsyncReadArg() = default; +}; + +struct AsyncWrtieArg { + NRef refWriteArrayBuf; + std::unique_ptr guardWriteStr; + size_t actLen { 0 }; + + explicit AsyncWrtieArg(NVal refWriteArrayBuf) : refWriteArrayBuf(refWriteArrayBuf) {} + explicit AsyncWrtieArg(std::unique_ptr &&guardWriteStr) : guardWriteStr(std::move(guardWriteStr)) {} + ~AsyncWrtieArg() = default; +}; + const std::string PROCEDURE_STREAM_WRITE_NAME = "FileIOStreamWrite"; const std::string PROCEDURE_STREAM_READ_NAME = "FileIOStreamRead"; const std::string PROCEDURE_STREAM_CLOSE_NAME = "FileIOStreamClose"; diff --git a/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp b/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp new file mode 100755 index 0000000000000000000000000000000000000000..e63178df283257f0ea7fc0861927159fb3e1c7f5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "create_stream.h" + +#include +#include + +#include "class_stream/stream_entity.h" +#include "class_stream/stream_n_exporter.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NVal InstantiateStream(napi_env env, unique_ptr fp) +{ + napi_value objStream = NClass::InstantiateClass(env, StreamNExporter::className_, {}); + if (!objStream) { + HILOGE("INNER BUG. Cannot instantiate stream"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto streamEntity = NClass::GetEntityOf(env, objStream); + if (!streamEntity) { + HILOGE("Cannot instantiate stream because of void entity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + streamEntity->fp.swap(fp); + return { env, objStream }; +} + +static tuple GetCreateStreamArgs(napi_env env, const NFuncArg &funcArg) +{ + auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + return { false, "", "" }; + } + + auto [resGetSecondArg, mode, useless] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + return { false, "", "" }; + } + + return { true, path.get(), mode.get() }; +} + +napi_value CreateStream::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetCreateStreamArgs, argPath, argMode] = GetCreateStreamArgs(env, funcArg); + if (!resGetCreateStreamArgs) { + HILOGE("Arg path and mode are required to be type of string"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + unique_ptr fp = { fopen(argPath.c_str(), argMode.c_str()), fclose }; + if (!fp) { + HILOGE("Failed to fdopen file by path"); + NError(errno).ThrowErr(env); + return nullptr; + } + + return InstantiateStream(env, move(fp)).val_; +} + +napi_value CreateStream::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetCreateStreamArgs, argPath, argMode] = GetCreateStreamArgs(env, funcArg); + if (!resGetCreateStreamArgs) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto arg = make_shared(); + if (arg == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto cbExec = [arg, argPath = move(argPath), argMode = move(argMode)]() -> NError { + arg->fp = { fopen(argPath.c_str(), argMode.c_str()), fclose }; + if (!arg->fp) { + HILOGE("Failed to fdopen file by path"); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return InstantiateStream(env, move(arg->fp)); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CREATESTREAM_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CREATESTREAM_NAME, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/create_stream.h b/interfaces/kits/js/src/mod_fs/properties/create_stream.h new file mode 100755 index 0000000000000000000000000000000000000000..9e7b01493dc6ff432791cd841773072dbdf40522 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/create_stream.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CREATE_STREAM_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CREATE_STREAM_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class CreateStream final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +struct AsyncCreateStreamArg { + std::unique_ptr fp = { nullptr, fclose }; +}; + +const std::string PROCEDURE_CREATESTREAM_NAME = "FileIOCreateStream"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CREATE_STREAM_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp new file mode 100755 index 0000000000000000000000000000000000000000..2fab9f21a5a9d230349632fca72a4705ecda6ad7 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fdopen_stream.h" + +#include +#include + +#include "class_stream/stream_entity.h" +#include "class_stream/stream_n_exporter.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +static NVal InstantiateStream(napi_env env, unique_ptr fp) +{ + napi_value objStream = NClass::InstantiateClass(env, StreamNExporter::className_, {}); + if (!objStream) { + HILOGE("INNER BUG. Cannot instantiate stream"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + auto streamEntity = NClass::GetEntityOf(env, objStream); + if (!streamEntity) { + HILOGE("Cannot instantiate stream because of void entity"); + NError(EIO).ThrowErr(env); + return NVal(); + } + + streamEntity->fp.swap(fp); + return { env, objStream }; +} + +static tuple GetFdopenStreamArgs(napi_env env, const NFuncArg &funcArg) +{ + auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!resGetFirstArg) { + return { false, -1, "" }; + } + + auto [resGetSecondArg, mode, unused] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + return { false, -1, "" }; + } + + return { true, fd, mode.get() }; +} + +napi_value FdopenStream::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetFdopenStreamArgs, fd, mode] = GetFdopenStreamArgs(env, funcArg); + if (!resGetFdopenStreamArgs) { + HILOGE("Invalid fd or mode from JS arugments"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + unique_ptr fp = { fdopen(fd, mode.c_str()), fclose }; + if (!fp) { + HILOGE("Failed to fdopen file by fd:%{public}d", fd); + NError(errno).ThrowErr(env); + return nullptr; + } + + return InstantiateStream(env, move(fp)).val_; +} + +napi_value FdopenStream::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [resGetFdopenStreamArgs, fd, mode] = GetFdopenStreamArgs(env, funcArg); + if (!resGetFdopenStreamArgs) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto arg = make_shared(); + if (arg == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto cbExec = [arg, fd = fd, mode = mode]() -> NError { + arg->fp = { fdopen(fd, mode.c_str()), fclose }; + if (!arg->fp) { + HILOGE("Failed to fdopen file by fd:%{public}d", fd); + return NError(errno); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [arg](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return InstantiateStream(env, move(arg->fp)); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_FDOPENSTREAM_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_FDOPENSTREAM_NAME, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h new file mode 100755 index 0000000000000000000000000000000000000000..ed43f3d3bd8b4a71499dfdaadbb997d42e7488f2 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class FdopenStream final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +struct AsyncFdopenStreamArg { + std::unique_ptr fp = { nullptr, fclose }; +}; + +const std::string PROCEDURE_FDOPENSTREAM_NAME = "FileIOFdopenStream"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_H \ No newline at end of file