From 00b7bbf376c1d90c0d04c5026ba522c88306a128 Mon Sep 17 00:00:00 2001 From: maokelong95 Date: Sat, 16 Jul 2022 10:13:03 +0800 Subject: [PATCH] =?UTF-8?q?file=5Fapi=E5=8A=9F=E8=83=BD=E4=BD=BF=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: maokelong95 --- .../mod_fileio/class_constants/constants.cpp | 191 +++++++++ .../mod_fileio/class_constants/constants.h | 38 ++ .../js/src/mod_fileio/class_dir/dir_entity.h | 32 ++ .../mod_fileio/class_dir/dir_n_exporter.cpp | 309 ++++++++++++++ .../src/mod_fileio/class_dir/dir_n_exporter.h | 45 ++ .../mod_fileio/class_dirent/dirent_entity.h | 30 ++ .../class_dirent/dirent_n_exporter.cpp | 170 ++++++++ .../class_dirent/dirent_n_exporter.h | 49 +++ .../src/mod_fileio/class_stat/stat_entity.h | 30 ++ .../mod_fileio/class_stat/stat_n_exporter.cpp | 369 ++++++++++++++++ .../mod_fileio/class_stat/stat_n_exporter.h | 61 +++ .../js/src/mod_fileio/class_stream/flush.cpp | 101 +++++ .../js/src/mod_fileio/class_stream/flush.h | 32 ++ .../mod_fileio/class_stream/stream_entity.h | 28 ++ .../class_stream/stream_n_exporter.cpp | 400 ++++++++++++++++++ .../class_stream/stream_n_exporter.h | 48 +++ 16 files changed, 1933 insertions(+) create mode 100644 interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/class_constants/constants.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_dir/dir_entity.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_dirent/dirent_entity.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_stat/stat_entity.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_stream/flush.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/class_stream/flush.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_stream/stream_entity.h create mode 100644 interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.h diff --git a/interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp b/interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp new file mode 100644 index 000000000..162b4360a --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_constants/constants.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2021-2022 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 "constants.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "../../common/log.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/uni_error.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +napi_value Constants::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool Constants::Export() +{ + // access + napi_value F_OK_ = nullptr; + napi_create_int32(exports_.env_, 0, &F_OK_); // 0 F_OK + napi_value R_OK_ = nullptr; + napi_create_int32(exports_.env_, 4, &R_OK_); // 4 R_OK + napi_value W_OK_ = nullptr; + napi_create_int32(exports_.env_, 2, &W_OK_); // 2 W_OK + napi_value X_OK_ = nullptr; + napi_create_int32(exports_.env_, 1, &X_OK_); // 1 X_OK + + // open + napi_value O_RDONLY_ = nullptr; + napi_create_int32(exports_.env_, 0, &O_RDONLY_); // 0 O_RDONLY + napi_value O_WRONLY_ = nullptr; + napi_create_int32(exports_.env_, 1, &O_WRONLY_); // 1 O_WRONLY + napi_value O_RDWR_ = nullptr; + napi_create_int32(exports_.env_, 2, &O_RDWR_); // 2 O_RDWR + napi_value O_CREAT_ = nullptr; + napi_create_int32(exports_.env_, 0o100, &O_CREAT_); // 0o100 O_CREAT + napi_value O_EXCL_ = nullptr; + napi_create_int32(exports_.env_, 0o200, &O_EXCL_); // 0o200 O_EXCL + napi_value O_TRUNC_ = nullptr; + napi_create_int32(exports_.env_, 0o1000, &O_TRUNC_); // 0o1000 O_TRUNC + napi_value O_APPEND_ = nullptr; + napi_create_int32(exports_.env_, 0o2000, &O_APPEND_); // 0o2000 O_APPEND + napi_value O_NONBLOCK_ = nullptr; + napi_create_int32(exports_.env_, 0o4000, &O_NONBLOCK_); // 0o4000 O_NONBLOCK + napi_value O_DIRECTORY_ = nullptr; + napi_create_int32(exports_.env_, 0o200000, &O_DIRECTORY_); // 0o200000 O_DIRECTORY + napi_value O_NOFOLLOW_ = nullptr; + napi_create_int32(exports_.env_, 0o400000, &O_NOFOLLOW_); // 0o400000 O_NOFOLLOW + napi_value O_SYNC_ = nullptr; + napi_create_int32(exports_.env_, 0o4010000, &O_SYNC_); // 0o4010000 O_SYNC + + // stat + napi_value S_IFMT_ = nullptr; + napi_create_int32(exports_.env_, 0o170000, &S_IFMT_); // 0o170000 S_IFMT + napi_value S_IFSOCK_ = nullptr; + napi_create_int32(exports_.env_, 0o140000, &S_IFSOCK_); // 0o140000 S_IFSOCK + napi_value S_IFLNK_ = nullptr; + napi_create_int32(exports_.env_, 0o120000, &S_IFLNK_); // 0o120000 S_IFLNK + napi_value S_IFREG_ = nullptr; + napi_create_int32(exports_.env_, 0o100000, &S_IFREG_); // 0o100000 S_IFREG + napi_value S_IFBLK_ = nullptr; + napi_create_int32(exports_.env_, 0o060000, &S_IFBLK_); // 0o060000 S_IFBLK + napi_value S_IFDIR_ = nullptr; + napi_create_int32(exports_.env_, 0o040000, &S_IFDIR_); // 0o040000 S_IFDIR + napi_value S_IFCHR_ = nullptr; + napi_create_int32(exports_.env_, 0o020000, &S_IFCHR_); // 0o020000 S_IFCHR + napi_value S_IFIFO_ = nullptr; + napi_create_int32(exports_.env_, 0o010000, &S_IFIFO_); // 0o010000 S_IFIFO + napi_value S_IRWXU_ = nullptr; + napi_create_int32(exports_.env_, 0o0700, &S_IRWXU_); // 0o0700 S_IRWXU + napi_value S_IRUSR_ = nullptr; + napi_create_int32(exports_.env_, 0o0400, &S_IRUSR_); // 0o0400 S_IRUSR + napi_value S_IWUSR_ = nullptr; + napi_create_int32(exports_.env_, 0o0200, &S_IWUSR_); // 0o0200 S_IWUSR + napi_value S_IXUSR_ = nullptr; + napi_create_int32(exports_.env_, 0o0100, &S_IXUSR_); // 0o0100 S_IXUSR + napi_value S_IRWXG_ = nullptr; + napi_create_int32(exports_.env_, 0o0070, &S_IRWXG_); // 0o0070 S_IRWXG + napi_value S_IRGRP_ = nullptr; + napi_create_int32(exports_.env_, 0o0040, &S_IRGRP_); // 0o0040 S_IRGRP + napi_value S_IWGRP_ = nullptr; + napi_create_int32(exports_.env_, 0o0020, &S_IWGRP_); // 0o0020 S_IWGRP + napi_value S_IXGRP_ = nullptr; + napi_create_int32(exports_.env_, 0o0010, &S_IXGRP_); // 0o0010 S_IXGRP + napi_value S_IRWXO_ = nullptr; + napi_create_int32(exports_.env_, 0o0007, &S_IRWXO_); // 0o0007 S_IRWXO + napi_value S_IROTH_ = nullptr; + napi_create_int32(exports_.env_, 0o0004, &S_IROTH_); // 0o0004 S_IROTH + napi_value S_IWOTH_ = nullptr; + napi_create_int32(exports_.env_, 0o0002, &S_IWOTH_); // 0o0002 S_IWOTH + napi_value S_IXOTH_ = nullptr; + napi_create_int32(exports_.env_, 0o0001, &S_IXOTH_); // 0o0001 S_IXOTH + + vector props = { + NVal::DeclareNapiStaticProperty("F_OK", F_OK_), + NVal::DeclareNapiStaticProperty("R_OK", R_OK_), + NVal::DeclareNapiStaticProperty("W_OK", W_OK_), + NVal::DeclareNapiStaticProperty("X_OK", X_OK_), + NVal::DeclareNapiStaticProperty("O_RDONLY", O_RDONLY_), + NVal::DeclareNapiStaticProperty("O_WRONLY", O_WRONLY_), + NVal::DeclareNapiStaticProperty("O_RDWR", O_RDWR_), + NVal::DeclareNapiStaticProperty("O_CREAT", O_CREAT_), + NVal::DeclareNapiStaticProperty("O_EXCL", O_EXCL_), + NVal::DeclareNapiStaticProperty("O_TRUNC", O_TRUNC_), + NVal::DeclareNapiStaticProperty("O_APPEND", O_APPEND_), + NVal::DeclareNapiStaticProperty("O_NONBLOCK", O_NONBLOCK_), + NVal::DeclareNapiStaticProperty("O_DIRECTORY", O_DIRECTORY_), + NVal::DeclareNapiStaticProperty("O_NOFOLLOW", O_NOFOLLOW_), + NVal::DeclareNapiStaticProperty("O_SYNC", O_SYNC_), + NVal::DeclareNapiStaticProperty("S_IFMT", S_IFMT_), + NVal::DeclareNapiStaticProperty("S_IFSOCK", S_IFSOCK_), + NVal::DeclareNapiStaticProperty("S_IFLNK", S_IFLNK_), + NVal::DeclareNapiStaticProperty("S_IFREG", S_IFREG_), + NVal::DeclareNapiStaticProperty("S_IFBLK", S_IFBLK_), + NVal::DeclareNapiStaticProperty("S_IFDIR", S_IFDIR_), + NVal::DeclareNapiStaticProperty("S_IFCHR", S_IFCHR_), + NVal::DeclareNapiStaticProperty("S_IFIFO", S_IFIFO_), + NVal::DeclareNapiStaticProperty("S_IRWXU", S_IRWXU_), + NVal::DeclareNapiStaticProperty("S_IRUSR", S_IRUSR_), + NVal::DeclareNapiStaticProperty("S_IWUSR", S_IWUSR_), + NVal::DeclareNapiStaticProperty("S_IXUSR", S_IXUSR_), + NVal::DeclareNapiStaticProperty("S_IRWXG", S_IRWXG_), + NVal::DeclareNapiStaticProperty("S_IRGRP", S_IRGRP_), + NVal::DeclareNapiStaticProperty("S_IWGRP", S_IWGRP_), + NVal::DeclareNapiStaticProperty("S_IXGRP", S_IXGRP_), + NVal::DeclareNapiStaticProperty("S_IRWXO", S_IRWXO_), + NVal::DeclareNapiStaticProperty("S_IROTH", S_IROTH_), + NVal::DeclareNapiStaticProperty("S_IWOTH", S_IWOTH_), + NVal::DeclareNapiStaticProperty("S_IXOTH", S_IXOTH_), + }; + + string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, Constants::Constructor, std::move(props)); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class"); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string Constants::GetClassName() +{ + return Constants::className_; +} + +Constants::Constants(napi_env env, napi_value exports) : NExporter(env, exports) {} +Constants::~Constants() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/class_constants/constants.h b/interfaces/kits/js/src/mod_fileio/class_constants/constants.h new file mode 100644 index 000000000..59da2b0bf --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_constants/constants.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021-2022 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_FILEIO_CLASS_CONSTANTS_CONSTANTS_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_CONSTANTS_CONSTANTS_H + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class Constants final : public NExporter { +public: + inline static const std::string className_ = "Constants"; + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info info); + + Constants(napi_env env, napi_value exports); + ~Constants() override; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif diff --git a/interfaces/kits/js/src/mod_fileio/class_dir/dir_entity.h b/interfaces/kits/js/src/mod_fileio/class_dir/dir_entity.h new file mode 100644 index 000000000..ca5e77040 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_dir/dir_entity.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 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_FILEIO_CLASS_DIR_DIR_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_DIR_DIR_ENTITY_H + +#include +#include + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +struct DirEntity { + std::mutex lock_; + std::unique_ptr> dir_ = { nullptr, closedir }; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_DIR_DIR_ENTITY_H diff --git a/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp new file mode 100644 index 000000000..bbc53799d --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2021-2022 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 "dir_n_exporter.h" + +#include +#include +#include +#include +#include + +#include "dir_entity.h" +#include "securec.h" +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../class_dirent/dirent_entity.h" +#include "../class_dirent/dirent_n_exporter.h" +#include "../common_func.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +static DirEntity *GetDirEntity(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto dirEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!dirEntity) { + UniError(EIO).ThrowErr(env, "Cannot get entity of Dir"); + return nullptr; + } + return dirEntity; +} + +napi_value DirNExporter::CloseSync(napi_env env, napi_callback_info info) +{ + DirEntity *dirEntity = GetDirEntity(env, info); + if (!dirEntity || !dirEntity->dir_) { + UniError(EBADF).ThrowErr(env, "Dir has been closed yet"); + return nullptr; + } + + dirEntity->dir_.reset(); + return nullptr; +} + +napi_value DirNExporter::Close(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto dirEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (dirEntity == nullptr) { + UniError(EIO).ThrowErr(env, "Cannot get entity of Dir"); + return nullptr; + } + + if (dirEntity->dir_ == nullptr) { + UniError(EBADF).ThrowErr(env, "Dir has been closed yet"); + return nullptr; + } + + auto cbExec = [dirEntity](napi_env env) -> UniError { + DIR *dir = dirEntity->dir_.release(); + int ret = closedir(dir); + if (ret == -1) { + return UniError(errno); + } else { + return UniError(ERRNO_NOERR); + } + }; + auto cbCompl = [](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUndefined(env); + } + }; + + NVal thisVar(env, funcArg.GetThisVar()); + static const string procedureName = "fileioDirClose"; + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; + } + + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; +} + +struct DirReadArgs { + NRef thisptrRef_; + struct dirent dirRes = { + .d_ino = 0, + .d_off = 0, + .d_reclen = 0, + .d_type = 0, + .d_name = { '\0' }, + }; + explicit DirReadArgs(NVal obj) : thisptrRef_(obj) {} +}; + +static NVal DoReadComplete(napi_env env, UniError err, shared_ptr arg) +{ + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + napi_value objDirent = NClass::InstantiateClass(env, DirentNExporter::className_, {}); + if (!objDirent) { + return { env, UniError(EINVAL).GetNapiErr(env) }; + } + auto direntEntity = NClass::GetEntityOf(env, objDirent); + if (!direntEntity) { + return { env, UniError(EINVAL).GetNapiErr(env) }; + } + + if (strlen(arg->dirRes.d_name) == 0) { + return { env, nullptr }; + } else { + direntEntity->dirent_ = arg->dirRes; + return { env, objDirent }; + } + } +} + +napi_value DirNExporter::Read(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto dirEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!dirEntity) { + UniError(EIO).ThrowErr(env, "Cannot get entity of Dir"); + return nullptr; + } + + if (!dirEntity || !dirEntity->dir_) { + UniError(EBADF).ThrowErr(env, "Dir has been closed yet"); + return nullptr; + } + + DIR *dir = dirEntity->dir_.get(); + if (dir == nullptr) { + return nullptr; + } + auto arg = make_shared(NVal(env, funcArg.GetThisVar())); + auto cbExec = [arg, dir, dirEntity](napi_env env) -> UniError { + struct dirent tmpDirent; + lock_guard(dirEntity->lock_); + errno = 0; + dirent *res = nullptr; + do { + res = readdir(dir); + if (res == nullptr && errno) { + return UniError(errno); + } else if (res == nullptr) { + return UniError(ERRNO_NOERR); + } else if (string(res->d_name) == "." || string(res->d_name) == "..") { + continue; + } else { + tmpDirent = *res; + break; + } + } while (true); + + arg->dirRes = tmpDirent; + return UniError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + return DoReadComplete(env, err, arg); + }; + NVal thisVar(env, funcArg.GetThisVar()); + const string procedureName = "fileioDirRead"; + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; + } +} + +napi_value DirNExporter::ReadSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + DirEntity *dirEntity = GetDirEntity(env, info); + if (!dirEntity || !dirEntity->dir_) { + UniError(EBADF).ThrowErr(env, "Dir has been closed yet"); + return nullptr; + } + + struct dirent tmpDirent; + { + lock_guard(dirEntity->lock_); + errno = 0; + dirent *res = nullptr; + do { + res = readdir(dirEntity->dir_.get()); + if (res == nullptr && errno) { + UniError(errno).ThrowErr(env); + return nullptr; + } else if (res == nullptr) { + return NVal::CreateUndefined(env).val_; + } else if (string(res->d_name) == "." || string(res->d_name) == "..") { + continue; + } else { + tmpDirent = *res; + break; + } + } while (true); + } + + napi_value objDirent = NClass::InstantiateClass(env, DirentNExporter::className_, {}); + if (!objDirent) { + return nullptr; + } + + auto direntEntity = NClass::GetEntityOf(env, objDirent); + if (!direntEntity) { + return nullptr; + } + direntEntity->dirent_ = tmpDirent; + + return objDirent; +} + +napi_value DirNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto dirEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(dirEntity))) { + UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj dir"); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool DirNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("readSync", ReadSync), + NVal::DeclareNapiFunction("closeSync", CloseSync), + NVal::DeclareNapiFunction("read", Read), + NVal::DeclareNapiFunction("close", Close), + }; + + string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, DirNExporter::Constructor, std::move(props)); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class Dirent"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class Dirent"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string DirNExporter::GetClassName() +{ + return DirNExporter::className_; +} + +DirNExporter::DirNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +DirNExporter::~DirNExporter() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.h b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.h new file mode 100644 index 000000000..156ef5578 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_dir/dir_n_exporter.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021-2022 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_FILEIO_CLASS_DIR_DIR_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_DIR_DIR_N_EXPORTER_H + +#include + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class DirNExporter final : public NExporter { +public: + inline static const std::string className_ = "Dir"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info info); + + static napi_value CloseSync(napi_env env, napi_callback_info info); + static napi_value ReadSync(napi_env env, napi_callback_info info); + static napi_value Read(napi_env env, napi_callback_info info); + static napi_value Close(napi_env env, napi_callback_info info); + DirNExporter(napi_env env, napi_value exports); + ~DirNExporter() override; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif diff --git a/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_entity.h b/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_entity.h new file mode 100644 index 000000000..d92fa69a2 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_entity.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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_FILEIO_CLASS_DIRENT_DIRENT_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_DIRENT_DIRENT_ENTITY_H + +#include + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +struct DirentEntity { + struct dirent dirent_; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_DIRENT_DIRENT_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.cpp new file mode 100644 index 000000000..9961eeb20 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2021-2022 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 "dirent_n_exporter.h" + +#include +#include +#include +#include +#include + +#include "securec.h" +#include "../../common/log.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/uni_error.h" +#include "../common_func.h" +#include "dirent_entity.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +static DirentEntity *GetDirentEntity(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto direntEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!direntEntity) { + UniError(EIO).ThrowErr(env, "Cannot get entity of Dirent"); + return nullptr; + } + return direntEntity; +} + +static napi_value CheckDirentDType(napi_env env, napi_callback_info info, unsigned char dType) +{ + DirentEntity *direntEntity = GetDirentEntity(env, info); + if (!direntEntity) { + return nullptr; + } + + return NVal::CreateBool(env, direntEntity->dirent_.d_type == dType).val_; +} + +napi_value DirentNExporter::isBlockDevice(napi_env env, napi_callback_info info) +{ + return CheckDirentDType(env, info, DT_BLK); +} + +napi_value DirentNExporter::isCharacterDevice(napi_env env, napi_callback_info info) +{ + return CheckDirentDType(env, info, DT_CHR); +} + +napi_value DirentNExporter::isDirectory(napi_env env, napi_callback_info info) +{ + return CheckDirentDType(env, info, DT_DIR); +} + +napi_value DirentNExporter::isFIFO(napi_env env, napi_callback_info info) +{ + return CheckDirentDType(env, info, DT_FIFO); +} + +napi_value DirentNExporter::isFile(napi_env env, napi_callback_info info) +{ + return CheckDirentDType(env, info, DT_REG); +} + +napi_value DirentNExporter::isSocket(napi_env env, napi_callback_info info) +{ + return CheckDirentDType(env, info, DT_SOCK); +} + +napi_value DirentNExporter::isSymbolicLink(napi_env env, napi_callback_info info) +{ + return CheckDirentDType(env, info, DT_LNK); +} + +napi_value DirentNExporter::GetName(napi_env env, napi_callback_info info) +{ + DirentEntity *direntEntity = GetDirentEntity(env, info); + if (!direntEntity) { + return nullptr; + } + return NVal::CreateUTF8String(env, direntEntity->dirent_.d_name).val_; +} + +napi_value DirentNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto direntEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(direntEntity))) { + stringstream ss; + ss << "INNER BUG. Failed to wrap entity for obj dirent"; + UniError(EIO).ThrowErr(env, ss.str()); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool DirentNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("isBlockDevice", isBlockDevice), + NVal::DeclareNapiFunction("isCharacterDevice", isCharacterDevice), + NVal::DeclareNapiFunction("isDirectory", isDirectory), + NVal::DeclareNapiFunction("isFIFO", isFIFO), + NVal::DeclareNapiFunction("isFile", isFile), + NVal::DeclareNapiFunction("isSocket", isSocket), + NVal::DeclareNapiFunction("isSymbolicLink", isSymbolicLink), + + NVal::DeclareNapiGetter("name", GetName), + }; + + string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, + className, + DirentNExporter::Constructor, + std::move(props)); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class Dirent"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class Dirent"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string DirentNExporter::GetClassName() +{ + return DirentNExporter::className_; +} + +DirentNExporter::DirentNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +DirentNExporter::~DirentNExporter() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.h b/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.h new file mode 100644 index 000000000..0f60629e0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_dirent/dirent_n_exporter.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 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_FILEIO_CLASS_DIRENT_DIRENT_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_DIRENT_DIRENT_N_EXPORTER_H + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class DirentNExporter final : public NExporter { +public: + inline static const std::string className_ = "Dirent"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + + static napi_value isBlockDevice(napi_env env, napi_callback_info cbinfo); + static napi_value isCharacterDevice(napi_env env, napi_callback_info cbinfo); + static napi_value isDirectory(napi_env env, napi_callback_info cbinfo); + static napi_value isFIFO(napi_env env, napi_callback_info cbinfo); + static napi_value isFile(napi_env env, napi_callback_info cbinfo); + static napi_value isSocket(napi_env env, napi_callback_info cbinfo); + static napi_value isSymbolicLink(napi_env env, napi_callback_info cbinfo); + + static napi_value GetName(napi_env env, napi_callback_info cbinfo); + + DirentNExporter(napi_env env, napi_value exports); + ~DirentNExporter() override; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_DIRENT_DIRENT_N_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_stat/stat_entity.h b/interfaces/kits/js/src/mod_fileio/class_stat/stat_entity.h new file mode 100644 index 000000000..a82c30f75 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_stat/stat_entity.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 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_FILEIO_CLASS_STAT_STAT_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STAT_STAT_ENTITY_H + +#include + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +struct StatEntity { + struct stat stat_; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.cpp new file mode 100644 index 000000000..85295fc4e --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.cpp @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2021 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 "stat_n_exporter.h" + +#include +#include +#include +#include +#include + +#include "securec.h" +#include "../../common/log.h" +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/uni_error.h" +#include "stat_entity.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +static napi_value CheckStatMode(napi_env env, napi_callback_info info, mode_t mode) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + bool check = (statEntity->stat_.st_mode & S_IFMT) == mode; + return NVal::CreateBool(env, check).val_; +} + +napi_value StatNExporter::IsBlockDevice(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFBLK); +} + +napi_value StatNExporter::IsCharacterDevice(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFCHR); +} + +napi_value StatNExporter::IsDirectory(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFDIR); +} + +napi_value StatNExporter::IsFIFO(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFIFO); +} + +napi_value StatNExporter::IsFile(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFREG); +} + +napi_value StatNExporter::IsSocket(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFSOCK); +} + +napi_value StatNExporter::IsSymbolicLink(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFLNK); +} + +napi_value StatNExporter::GetDev(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_dev).val_; +} + +napi_value StatNExporter::GetIno(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_ino).val_; +} + +napi_value StatNExporter::GetMode(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_mode).val_; +} + +napi_value StatNExporter::GetNlink(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_nlink).val_; +} + +napi_value StatNExporter::GetUid(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_uid).val_; +} + +napi_value StatNExporter::GetGid(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_gid).val_; +} + +napi_value StatNExporter::GetRdev(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_rdev).val_; +} + +napi_value StatNExporter::GetSize(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_size).val_; +} + +napi_value StatNExporter::GetBlksize(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_blksize).val_; +} + +napi_value StatNExporter::GetBlocks(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_blocks).val_; +} + +napi_value StatNExporter::GetAtime(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_atim.tv_sec).val_; +} + +napi_value StatNExporter::GetMtime(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_mtim.tv_sec).val_; +} + +napi_value StatNExporter::GetCtime(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto statEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!statEntity) { + return nullptr; + } + + return NVal::CreateInt64(env, statEntity->stat_.st_ctim.tv_sec).val_; +} + +napi_value StatNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + unique_ptr statEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(statEntity))) { + stringstream ss; + ss << "INNER BUG. Failed to wrap entity for obj stat"; + UniError(EIO).ThrowErr(env, ss.str()); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool StatNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("isBlockDevice", IsBlockDevice), + NVal::DeclareNapiFunction("isCharacterDevice", IsCharacterDevice), + NVal::DeclareNapiFunction("isDirectory", IsDirectory), + NVal::DeclareNapiFunction("isFIFO", IsFIFO), + NVal::DeclareNapiFunction("isFile", IsFile), + NVal::DeclareNapiFunction("isSocket", IsSocket), + NVal::DeclareNapiFunction("isSymbolicLink", IsSymbolicLink), + + NVal::DeclareNapiGetter("dev", GetDev), + NVal::DeclareNapiGetter("ino", GetIno), + NVal::DeclareNapiGetter("mode", GetMode), + NVal::DeclareNapiGetter("nlink", GetNlink), + NVal::DeclareNapiGetter("uid", GetUid), + NVal::DeclareNapiGetter("gid", GetGid), + NVal::DeclareNapiGetter("rdev", GetRdev), + NVal::DeclareNapiGetter("size", GetSize), + NVal::DeclareNapiGetter("blksize", GetBlksize), + NVal::DeclareNapiGetter("blocks", GetBlocks), + NVal::DeclareNapiGetter("atime", GetAtime), + NVal::DeclareNapiGetter("mtime", GetMtime), + NVal::DeclareNapiGetter("ctime", GetCtime), + }; + + string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, StatNExporter::Constructor, std::move(props)); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class"); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string StatNExporter::GetClassName() +{ + return StatNExporter::className_; +} + +StatNExporter::StatNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +StatNExporter::~StatNExporter() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.h b/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.h new file mode 100644 index 000000000..430485664 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_stat/stat_n_exporter.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 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_FILEIO_CLASS_STAT_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STAT_N_EXPORTER_H + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class StatNExporter final : public NExporter { +public: + inline static const std::string className_ = "Stat"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + + static napi_value IsBlockDevice(napi_env env, napi_callback_info cbinfo); + static napi_value IsCharacterDevice(napi_env env, napi_callback_info cbinfo); + static napi_value IsDirectory(napi_env env, napi_callback_info cbinfo); + static napi_value IsFIFO(napi_env env, napi_callback_info cbinfo); + static napi_value IsFile(napi_env env, napi_callback_info cbinfo); + static napi_value IsSocket(napi_env env, napi_callback_info cbinfo); + static napi_value IsSymbolicLink(napi_env env, napi_callback_info cbinfo); + + static napi_value GetDev(napi_env env, napi_callback_info cbinfo); + static napi_value GetIno(napi_env env, napi_callback_info cbinfo); + static napi_value GetMode(napi_env env, napi_callback_info cbinfo); + static napi_value GetNlink(napi_env env, napi_callback_info cbinfo); + static napi_value GetUid(napi_env env, napi_callback_info cbinfo); + static napi_value GetGid(napi_env env, napi_callback_info cbinfo); + static napi_value GetRdev(napi_env env, napi_callback_info cbinfo); + static napi_value GetSize(napi_env env, napi_callback_info cbinfo); + static napi_value GetBlksize(napi_env env, napi_callback_info cbinfo); + static napi_value GetBlocks(napi_env env, napi_callback_info cbinfo); + static napi_value GetAtime(napi_env env, napi_callback_info cbinfo); + static napi_value GetMtime(napi_env env, napi_callback_info cbinfo); + static napi_value GetCtime(napi_env env, napi_callback_info cbinfo); + + StatNExporter(napi_env env, napi_value exports); + ~StatNExporter() override; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STAT_N_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_stream/flush.cpp b/interfaces/kits/js/src/mod_fileio/class_stream/flush.cpp new file mode 100644 index 000000000..590b47e95 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_stream/flush.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2021 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 "flush.h" + +#include +#include + +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/napi/n_val.h" +#include "../../common/uni_error.h" + +#include "../class_stat/stat_entity.h" +#include "../class_stat/stat_n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +struct StreamEntity { + std::unique_ptr fp = { nullptr, fclose }; +}; + +napi_value Flush::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + UniError(EBADF).ThrowErr(env, "Stream may has been closed"); + return nullptr; + } + + int ret = fflush(streamEntity->fp.get()); + if (ret == -1) { + UniError(errno).ThrowErr(env); + return nullptr; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value Flush::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + UniError(EBADF).ThrowErr(env, "Stream may has been closed"); + return nullptr; + } + + auto cbExec = [streamEntity](napi_env env) -> UniError { + int ret = fflush(streamEntity->fp.get()); + if (ret == -1) { + return UniError(errno); + } else { + return UniError(ERRNO_NOERR); + } + }; + auto cbCompl = [](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + string procedureName = "fileIOFlush"; + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_stream/flush.h b/interfaces/kits/js/src/mod_fileio/class_stream/flush.h new file mode 100644 index 000000000..c616571b3 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_stream/flush.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 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_FILEIO_CLASS_STREAM_FLUSH_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_FLUSH_H + +#include "../../common/napi/uni_header.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class Flush final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_stream/stream_entity.h b/interfaces/kits/js/src/mod_fileio/class_stream/stream_entity.h new file mode 100644 index 000000000..1c010e015 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_stream/stream_entity.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 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_FILEIO_CLASS_STREAM_STREAM_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +struct StreamEntity { + std::unique_ptr fp = { nullptr, fclose }; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.cpp new file mode 100644 index 000000000..cdcbf78fe --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.cpp @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2021 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 "stream_n_exporter.h" + +#include +#include +#include +#include +#include +#include +#include "flush.h" +#include "securec.h" + +#include "../../common/log.h" +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.h" +#include "../../common/napi/n_class.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/uni_error.h" +#include "../common_func.h" +#include "stream_entity.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + /* To get entity */ + bool succ = false; + FILE *filp = nullptr; + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + UniError(EBADF).ThrowErr(env, "Stream may have been closed"); + return nullptr; + } else { + filp = streamEntity->fp.get(); + } + + void *buf = nullptr; + int64_t len; + bool hasPos = false; + int64_t pos; + tie(succ, buf, len, hasPos, pos, ignore) = + CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + return nullptr; + } + + if (hasPos && (fseek(filp, pos, SEEK_SET) == -1)) { + UniError(errno).ThrowErr(env); + return nullptr; + } + + size_t actLen = fread(buf, 1, len, filp); + if (actLen != static_cast(len) && ferror(filp)) { + UniError(errno).ThrowErr(env); + } + + return NVal::CreateInt64(env, actLen).val_; +} + +napi_value StreamNExporter::CloseSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + UniError(EINVAL).ThrowErr(env, "Stream may have been closed yet"); + return nullptr; + } + streamEntity->fp.reset(); + return NVal::CreateUndefined(env).val_; +} + +napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + bool succ = false; + FILE *filp = nullptr; + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + UniError(EBADF).ThrowErr(env, "Stream may has been closed"); + return nullptr; + } else { + filp = streamEntity->fp.get(); + } + + void *buf = nullptr; + size_t len; + size_t position; + unique_ptr bufGuard; + bool hasPos = false; + tie(succ, bufGuard, buf, len, hasPos, position) = + CommonFunc::GetWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + return nullptr; + } + if (hasPos && (fseek(filp, position, SEEK_SET) == -1)) { + UniError(errno).ThrowErr(env); + return nullptr; + } + + size_t writeLen = fwrite(buf, 1, len, filp); + if (writeLen != len) { + UniError(errno).ThrowErr(env); + return nullptr; + } + + 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; +}; + +napi_value StreamNExporter::Write(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + bool succ = false; + FILE *filp = nullptr; + bool hasPosition = false; + size_t position; + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + UniError(EBADF).ThrowErr(env, "Stream may has been closed"); + return nullptr; + } + filp = streamEntity->fp.get(); + + unique_ptr bufGuard; + void *buf = nullptr; + size_t len; + tie(succ, bufGuard, buf, len, hasPosition, position) = + CommonFunc::GetWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + return nullptr; + } + + shared_ptr arg; + if (bufGuard) { + arg = make_shared(move(bufGuard)); + } else { + arg = make_shared(NVal(env, funcArg[NARG_POS::FIRST])); + } + + auto cbExec = [arg, buf, len, filp, hasPosition, position](napi_env env) -> UniError { + if (hasPosition && (fseek(filp, position, SEEK_SET) == -1)) { + UniError(errno).ThrowErr(env); + return UniError(errno); + } + arg->actLen = fwrite(buf, 1, len, filp); + if (arg->actLen != static_cast(len) && ferror(filp)) { + return UniError(errno); + } + return UniError(ERRNO_NOERR); + }; + + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateInt64(env, arg->actLen) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() != NARG_CNT::THREE) { + return NAsyncWorkPromise(env, thisVar).Schedule("FileIOStreamWrite", cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIOStreamWrite", cbExec, cbCompl).val_; + } + + return NVal::CreateUndefined(env).val_; +} + +struct AsyncReadArg { + size_t lenRead { 0 }; + NRef refReadBuf; + int offset { 0 }; + + explicit AsyncReadArg(NVal jsReadBuf) : refReadBuf(jsReadBuf) {} + ~AsyncReadArg() = default; +}; + +napi_value StreamNExporter::Read(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + /* To get entity */ + FILE *filp = nullptr; + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + UniError(EBADF).ThrowErr(env, "Stream may have been closed"); + return nullptr; + } else { + filp = streamEntity->fp.get(); + } + + bool succ = false; + void *buf = nullptr; + int64_t len; + bool hasPosition = false; + size_t position; + int offset; + tie(succ, buf, len, hasPosition, position, offset) = + CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Failed GetReadArg"); + return nullptr; + } + + auto arg = make_shared(NVal(env, funcArg[NARG_POS::FIRST])); + auto cbExec = [arg, buf, position, filp, len, hasPosition, offset](napi_env env) -> UniError { + if (hasPosition && (fseek(filp, position, SEEK_SET) == -1)) { + UniError(errno).ThrowErr(env); + return UniError(errno); + } + size_t actLen = fread(buf, 1, len, filp); + if (actLen != static_cast(len) && ferror(filp)) { + return UniError(errno); + } else { + arg->lenRead = actLen; + arg->offset = offset; + return UniError(ERRNO_NOERR); + } + }; + + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + NVal obj = NVal::CreateObject(env); + obj.AddProp({ + NVal::DeclareNapiProperty("bytesRead", NVal::CreateInt64(env, arg->lenRead).val_), + NVal::DeclareNapiProperty("buffer", arg->refReadBuf.Deref(env).val_), + NVal::DeclareNapiProperty("offset", NVal::CreateInt64(env, arg->offset).val_) + }); + return { obj }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() != NARG_CNT::THREE) { + return NAsyncWorkPromise(env, thisVar).Schedule("FileIOStreamRead", cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIOStreamRead", cbExec, cbCompl).val_; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value StreamNExporter::Close(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!streamEntity || !streamEntity->fp) { + UniError(EBADF).ThrowErr(env, "Stream may has been closed"); + return nullptr; + } + + auto cbExec = [streamEntity](napi_env env) -> UniError { + auto filp = streamEntity->fp.release(); + if (!fclose(filp)) { + return UniError(ERRNO_NOERR); + } else { + return UniError(errno); + } + }; + + auto cbCompl = [](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUndefined(env); + } + }; + + string procedureName = "FileIOStreamClose"; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value StreamNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + unique_ptr streamEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(streamEntity))) { + stringstream ss; + ss << "INNER BUG. Failed to wrap entity for obj stat"; + UniError(EIO).ThrowErr(env, ss.str()); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool StreamNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("writeSync", WriteSync), + NVal::DeclareNapiFunction("flush", Flush::Async), + NVal::DeclareNapiFunction("flushSync", Flush::Sync), + NVal::DeclareNapiFunction("readSync", ReadSync), + NVal::DeclareNapiFunction("closeSync", CloseSync), + NVal::DeclareNapiFunction("write", Write), + NVal::DeclareNapiFunction("read", Read), + NVal::DeclareNapiFunction("close", Close), + }; + + string className = GetClassName(); + bool succ = false; + napi_value cls = nullptr; + tie(succ, cls) = NClass::DefineClass(exports_.env_, className, StreamNExporter::Constructor, move(props)); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to define class"); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, cls); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_, "INNER BUG. Failed to save class"); + return false; + } + + return exports_.AddProp(className, cls); +} + +string StreamNExporter::GetClassName() +{ + return StreamNExporter::className_; +} + +StreamNExporter::StreamNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +StreamNExporter::~StreamNExporter() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.h b/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.h new file mode 100644 index 000000000..3cfe4d2d2 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_stream/stream_n_exporter.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 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_FILEIO_CLASS_STREAM_STREAM_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_N_EXPORTER_H + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class StreamNExporter final : public NExporter { +public: + inline static const std::string className_ = "Stream"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + + static napi_value WriteSync(napi_env env, napi_callback_info cbinfo); + static napi_value FlushSync(napi_env env, napi_callback_info cbinfo); + static napi_value ReadSync(napi_env env, napi_callback_info cbinfo); + static napi_value CloseSync(napi_env env, napi_callback_info cbinfo); + + static napi_value Write(napi_env env, napi_callback_info cbinfo); + static napi_value Read(napi_env env, napi_callback_info cbinfo); + static napi_value Close(napi_env env, napi_callback_info cbinfo); + + StreamNExporter(napi_env env, napi_value exports); + ~StreamNExporter() override; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file -- Gitee