diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 36e610de8d6b3457a20683d60ed8f5d6ebefdf93..ca11dc4a317b91ff642d54632be8efa5266c1cea 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -48,8 +48,10 @@ ohos_shared_library("fileio") { "src/mod_fileio/class_constants/constants.cpp", "src/mod_fileio/class_dir/dir_n_exporter.cpp", "src/mod_fileio/class_dirent/dirent_n_exporter.cpp", + "src/mod_fileio/class_file/file_n_exporter.cpp", "src/mod_fileio/class_randomaccessfile/randomaccessfile_n_exporter.cpp", "src/mod_fileio/class_stat/stat_n_exporter.cpp", + "src/mod_fileio/class_statV9/statV9_n_exporter.cpp", "src/mod_fileio/class_stream/flush.cpp", "src/mod_fileio/class_stream/stream_n_exporter.cpp", "src/mod_fileio/class_watcher/watcher_n_exporter.cpp", @@ -76,6 +78,7 @@ ohos_shared_library("fileio") { "src/mod_fileio/properties/mkdtemp.cpp", "src/mod_fileio/properties/open.cpp", "src/mod_fileio/properties/open_dir.cpp", + "src/mod_fileio/properties/open_file.cpp", "src/mod_fileio/properties/posix_fallocate.cpp", "src/mod_fileio/properties/prop_n_exporter.cpp", "src/mod_fileio/properties/read_dir.cpp", @@ -84,8 +87,10 @@ ohos_shared_library("fileio") { "src/mod_fileio/properties/rmdir.cpp", "src/mod_fileio/properties/rmdirent.cpp", "src/mod_fileio/properties/stat.cpp", + "src/mod_fileio/properties/statV9.cpp", "src/mod_fileio/properties/symlink.cpp", "src/mod_fileio/properties/truncate.cpp", + "src/mod_fileio/properties/truncateV9.cpp", "src/mod_fileio/properties/watcher.cpp", ] diff --git a/interfaces/kits/js/src/mod_fileio/class_file/file_entity.h b/interfaces/kits/js/src/mod_fileio/class_file/file_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..9a82a6f7900f8364a6a5cedc98794a94ac5a0516 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_file/file_entity.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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_FILE_FILE_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_FILE_FILE_ENTITY_H + +#include + +#include "../../common/file_helper/fd_guard.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +struct FileEntity { + std::unique_ptr fd_ = { nullptr }; + std::string path_; + std::string uri_; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc805b835c182d80de4c27ac7f28f2681535298b --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 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 "file_n_exporter.h" + +#include +#include +#include +#include + +#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 "file_entity.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +static FileEntity *GetFileEntity(napi_env env, napi_value raf_entity) +{ + auto rafEntity = NClass::GetEntityOf(env, raf_entity); + if (!rafEntity) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + if (!rafEntity->fd_) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + return rafEntity; +} + +napi_value FileNExporter::GetFD(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + auto rafEntity = GetFileEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + return NVal::CreateInt32(env, rafEntity->fd_.get()->GetFD()).val_; +} + +napi_value FileNExporter::GetPath(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + auto rafEntity = GetFileEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + return NVal::CreateUTF8String(env, rafEntity->path_).val_; +} + +napi_value FileNExporter::GetUri(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + auto rafEntity = GetFileEntity(env, funcArg.GetThisVar()); + if (!rafEntity) { + return nullptr; + } + return NVal::CreateUTF8String(env, rafEntity->uri_).val_; +} + +napi_value FileNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto rafEntity = make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(rafEntity))) { + UniError(EIO).ThrowErr(env); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool FileNExporter::Export() +{ + vector props = { + NVal::DeclareNapiGetter("fd", GetFD), + NVal::DeclareNapiGetter("path", GetPath), + }; + + string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + FileNExporter::Constructor, move(props)); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string FileNExporter::GetClassName() +{ + return FileNExporter::className_; +} + +FileNExporter::FileNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} +FileNExporter::~FileNExporter() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.h b/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..ffa96ed6ddba5898be6c1368d035366568a8d426 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_file/file_n_exporter.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 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_FILE_FILE_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_FILE_FILE_N_EXPORTER_H + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class FileNExporter final : public NExporter { +public: + inline static const std::string className_ = "File"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + + static napi_value GetFD(napi_env env, napi_callback_info cbinfo); + static napi_value GetPath(napi_env env, napi_callback_info cbinfo); + static napi_value GetUri(napi_env env, napi_callback_info cbinfo); + + FileNExporter(napi_env env, napi_value exports); + ~FileNExporter() override; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_statV9/statV9_entity.h b/interfaces/kits/js/src/mod_fileio/class_statV9/statV9_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..ae0e324afd749275523a2641b44a37adbe65993d --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_statV9/statV9_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_STATV9_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STAT_STATV9_ENTITY_H + +#include + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +struct StatEntityV9 { + 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_statV9/statV9_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/class_statV9/statV9_n_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..21e569dace8242f59314d02176f789c556e1c1fc --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_statV9/statV9_n_exporter.cpp @@ -0,0 +1,302 @@ +/* + * 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 "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.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 "stat_entity.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +constexpr int S_PERMISSION = 00000777; + +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); + 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 StatV9NExporter::IsBlockDevice(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFBLK); +} + +napi_value StatV9NExporter::IsCharacterDevice(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFCHR); +} + +napi_value StatV9NExporter::IsDirectory(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFDIR); +} + +napi_value StatV9NExporter::IsFIFO(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFIFO); +} + +napi_value StatV9NExporter::IsFile(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFREG); +} + +napi_value StatV9NExporter::IsSocket(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFSOCK); +} + +napi_value StatV9NExporter::IsSymbolicLink(napi_env env, napi_callback_info info) +{ + return CheckStatMode(env, info, S_IFLNK); +} + +napi_value StatV9NExporter::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 StatV9NExporter::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 & S_PERMISSION).val_; +} + +napi_value StatV9NExporter::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 StatV9NExporter::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 StatV9NExporter::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 StatV9NExporter::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 StatV9NExporter::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 StatV9NExporter::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 StatV9NExporter::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 StatV9NExporter::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))) { + UniError(EIO).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj stat"); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool StatV9NExporter::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("ino", GetIno), + NVal::DeclareNapiGetter("mode", GetMode), + NVal::DeclareNapiGetter("uid", GetUid), + NVal::DeclareNapiGetter("gid", GetGid), + NVal::DeclareNapiGetter("size", GetSize), + NVal::DeclareNapiGetter("blksize", GetBlksize), + 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, StatV9NExporter::Constructor, std::move(props)); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + UniError(EIO).ThrowErr(exports_.env_); + return false; + } + + return exports_.AddProp(className, classValue); +} + +string StatV9NExporter::GetClassName() +{ + return StatV9NExporter::className_; +} + +StatV9NExporter::StatV9NExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +StatV9NExporter::~StatV9NExporter() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/class_statV9/statV9_n_exporter.h b/interfaces/kits/js/src/mod_fileio/class_statV9/statV9_n_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..b46c88f5d975482c1e7606e24fb0433aaa411428 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/class_statV9/statV9_n_exporter.h @@ -0,0 +1,57 @@ +/* + * 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_STATV9_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STATV9_N_EXPORTER_H + +#include "../../common/napi/n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class StatV9NExporter final : public NExporter { +public: + inline static const std::string className_ = "StatV9"; + + 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 GetIno(napi_env env, napi_callback_info cbinfo); + static napi_value GetMode(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 GetSize(napi_env env, napi_callback_info cbinfo); + static napi_value GetBlksize(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); + + StatV9NExporter(napi_env env, napi_value exports); + ~StatV9NExporter() override; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STATV9_N_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/common_func.cpp b/interfaces/kits/js/src/mod_fileio/common_func.cpp index b54748f122373b989e8e90fb46978572aa275f6e..e7d74a9bd349cdebc93511babb7458d2ddffea03 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.cpp +++ b/interfaces/kits/js/src/mod_fileio/common_func.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -113,8 +113,8 @@ int CommonFunc::ConvertJsFlags(int &flags) } tuple, unique_ptr> CommonFunc::GetCopyPathArg(napi_env env, - napi_value srcPath, - napi_value dstPath) + napi_value srcPath, + napi_value dstPath) { bool succ = false; unique_ptr src; @@ -128,8 +128,7 @@ tuple, unique_ptr> CommonFunc::GetCopyPathArg(n if (!succ) { return { false, nullptr, nullptr }; } - - return make_tuple(true, move(src), move(dest)); + return make_tuple(succ, move(src), move(dest)); } tuple CommonFunc::GetReadArg(napi_env env, @@ -138,13 +137,13 @@ tuple CommonFunc::GetReadArg(napi_env { bool succ = false; void *retBuf = nullptr; - int64_t retLen = 0; + int64_t retLen; bool posAssigned = false; - int64_t position = 0; + int64_t position; NVal txt(env, readBuf); void *buf = nullptr; - int64_t bufLen = 0; + int64_t bufLen; int offset = 0; tie(succ, buf, bufLen) = txt.ToArraybuffer(); if (!succ) { @@ -204,18 +203,20 @@ static tuple, int64_t> DecodeString(napi_env env, NVal } } +// Is everything ok? Do we need to free memory? What's the three args required by fwrite? Where to start writing? tuple, void *, int64_t, bool, int64_t> CommonFunc::GetWriteArg(napi_env env, napi_value argWBuf, napi_value argOption) { void *retBuf = nullptr; - int64_t retLen = 0; + int64_t retLen; bool hasPos = false; - int64_t retPos = 0; + int64_t retPos; + /* To get write buffer */ bool succ = false; void *buf = nullptr; - int64_t bufLen = 0; + int64_t bufLen; NVal op(env, argOption); NVal jsBuffer(env, argWBuf); unique_ptr bufferGuard; @@ -254,9 +255,90 @@ tuple, void *, int64_t, bool, int64_t> CommonFunc::GetW } else { retPos = INVALID_POSITION; } - return { true, move(bufferGuard), retBuf, retLen, hasPos, retPos }; } + +tuple CommonFunc::GetReadArgV9(napi_env env, + napi_value readBuf, + napi_value option) +{ + bool succ = false; + int64_t retLen; + bool posAssigned = false; + int64_t position; + + NVal txt(env, readBuf); + void *buf = nullptr; + int64_t bufLen; + tie(succ, buf, bufLen) = txt.ToArraybuffer(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid read buffer, expect arraybuffer"); + return { false, nullptr, 0, posAssigned, position }; + } + NVal op = NVal(env, option); + tie(succ, retLen) = GetActualLen(env, bufLen, 0, op); + if (!succ) { + return { false, nullptr, 0, posAssigned, position }; + } + + if (op.HasProp("offset")) { + tie(succ, position) = op.GetProp("offset").ToInt64(); + if (succ && position >= 0) { + posAssigned = true; + } else { + UniError(EINVAL).ThrowErr(env, "option.offset shall be positive number"); + return { false, nullptr, 0, posAssigned, position }; + } + } + + return { true, buf, retLen, posAssigned, position }; +} + +tuple, void *, int64_t, bool, int64_t> CommonFunc::GetWriteArgV9(napi_env env, + napi_value argWBuf, + napi_value argOption) +{ + int64_t retLen; + bool hasPos = false; + int64_t retPos; + /* To get write buffer */ + bool succ = false; + void *buf = nullptr; + int64_t bufLen; + NVal op(env, argOption); + NVal jsBuffer(env, argWBuf); + unique_ptr bufferGuard; + tie(succ, bufferGuard, bufLen) = DecodeString(env, jsBuffer, op.GetProp("encoding")); + if (!succ) { + tie(succ, buf, bufLen) = NVal(env, argWBuf).ToArraybuffer(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Illegal write buffer or encoding"); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + } else { + buf = bufferGuard.get(); + } + tie(succ, retLen) = GetActualLen(env, bufLen, 0, op); + if (!succ) { + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + + /* To parse options - Where to begin writing */ + if (op.HasProp("offset")) { + int32_t position = 0; + tie(succ, position) = op.GetProp("offset").ToInt32(); + if (!succ || position < 0) { + UniError(EINVAL).ThrowErr(env, "option.offset shall be positive number"); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + hasPos = true; + retPos = position; + } else { + retPos = INVALID_POSITION; + } + return { true, move(bufferGuard), buf, retLen, hasPos, retPos }; +} + } // namespace ModuleFileIO } // namespace DistributedFS } // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/common_func.h b/interfaces/kits/js/src/mod_fileio/common_func.h index 337826536d5244b74bb98cd90915b019d52bae0e..7419f9d13d7d8759f691b30a447e0d7317545cdc 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.h +++ b/interfaces/kits/js/src/mod_fileio/common_func.h @@ -26,11 +26,17 @@ constexpr int64_t INVALID_POSITION = std::numeric_limits GetReadArg(napi_env env, - napi_value readBuf, - napi_value option); + napi_value readBuf, + napi_value option); + static std::tuple GetReadArgV9(napi_env env, + napi_value readBuf, + napi_value option); static std::tuple, void *, int64_t, bool, int64_t> GetWriteArg(napi_env env, napi_value argWBuf, napi_value argOption); + static std::tuple, void *, int64_t, bool, int64_t> GetWriteArgV9(napi_env env, + napi_value argWBuf, + napi_value argOption); static std::tuple, std::unique_ptr> GetCopyPathArg(napi_env env, napi_value srcPath, napi_value dstPath); diff --git a/interfaces/kits/js/src/mod_fileio/module.cpp b/interfaces/kits/js/src/mod_fileio/module.cpp index b26592acb850f6dab3a0cae722cf4d1e66adcd5d..3c7f09f21938d03765b3cd12353bcfd2b7e6258c 100644 --- a/interfaces/kits/js/src/mod_fileio/module.cpp +++ b/interfaces/kits/js/src/mod_fileio/module.cpp @@ -20,8 +20,10 @@ #include "class_constants/constants.h" #include "class_dir/dir_n_exporter.h" #include "class_dirent/dirent_n_exporter.h" +#include "class_file/file_n_exporter.h" #include "class_randomaccessfile/randomaccessfile_n_exporter.h" #include "class_stat/stat_n_exporter.h" +#include "class_statV9/statV9_n_exporter.h" #include "class_stream/stream_n_exporter.h" #include "class_watcher/watcher_n_exporter.h" #include "properties/prop_n_exporter.h" @@ -37,8 +39,10 @@ static napi_value Export(napi_env env, napi_value exports) products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); diff --git a/interfaces/kits/js/src/mod_fileio/properties/open_file.cpp b/interfaces/kits/js/src/mod_fileio/properties/open_file.cpp new file mode 100644 index 0000000000000000000000000000000000000000..660b7957c1d6d0632997e253bf6933f8d828d07d --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/open_file.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 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 "open_file.h" + +#include +#include +#include +#include +#include + +#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 "../class_file/file_entity.h" +#include "../class_file/file_n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +static tuple GetJsFlags(napi_env env, const NFuncArg &funcArg) +{ + int mode = O_RDONLY; + bool succ = false; + if (funcArg.GetArgc() == NARG_CNT::TWO && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) { + tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { + UniError(EINVAL).ThrowErr(env, "Invalid mode"); + return { false, mode }; + } + (void)CommonFunc::ConvertJsFlags(mode); + } + return { true, mode }; +} + +static NVal InstantiateFile(napi_env env, int fd, string path) +{ + napi_value objRAF = NClass::InstantiateClass(env, FileNExporter::className_, {}); + if (!objRAF) { + UniError(EIO).ThrowErr(env, "Cannot instantiate file"); + return NVal(); + } + + auto rafEntity = NClass::GetEntityOf(env, objRAF); + if (!rafEntity) { + UniError(EIO).ThrowErr(env, "Cannot instantiate file because of void entity"); + return NVal(); + } + auto fdg = make_unique(fd); + rafEntity->fd_.swap(fdg); + rafEntity->path_ = path; + rafEntity->uri_ = path; + return { env, objRAF }; +} + +napi_value OpenFile::Sync(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; + } + auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succPath) { + return nullptr; + } + auto [succMode, mode] = GetJsFlags(env, funcArg); + if (!succMode) { + return nullptr; + } + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(env, &loop); + uv_fs_t open_req; + int ret = uv_fs_open(loop, &open_req, path.get(), mode, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, NULL); + if (ret < 0) { + UniError(errno).ThrowErr(env); + return nullptr; + } + auto File = InstantiateFile(env, open_req.result, path.get()).val_; + uv_fs_req_cleanup(&open_req); + return File; +} + +struct AsyncOpenFileArg { + int fd; + string path; + string uri; +}; + +napi_value OpenFile::Async(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; + } + auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succPath) { + return nullptr; + } + auto [succMode, mode] = GetJsFlags(env, funcArg); + if (!succMode) { + return nullptr; + } + auto arg = make_shared(); + auto cbExec = [arg, path = string(path.get()), mode = mode](napi_env env) -> UniError { + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(env, &loop); + uv_fs_t open_req; + int ret = uv_fs_open(loop, &open_req, path.c_str(), mode, S_IRUSR | + S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, NULL); + if (ret < 0) { + return UniError(errno); + } + arg->fd = open_req.result; + arg->path = path; + arg->uri = path; + uv_fs_req_cleanup(&open_req); + return UniError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return InstantiateFile(env, arg->fd, arg->path); + }; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && + NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number))) { + return NAsyncWorkPromise(env, thisVar).Schedule(openFileProcedureName, cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::THREE) ? NARG_POS::THIRD : NARG_POS::SECOND); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(openFileProcedureName, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/open_file.h b/interfaces/kits/js/src/mod_fileio/properties/open_file.h new file mode 100644 index 0000000000000000000000000000000000000000..b7c21a4f597e7e8c8bb6669ea79c870b3da2f862 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/open_file.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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_PROPERTIES_OPEN_FILE_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_OPEN_FILE_H + +#include "../../common/napi/uni_header.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class OpenFile final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; +const std::string openFileProcedureName = "FileIOOpenFile"; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp index 0a08765bf6b29bca255cacad6a01c93404689831..f4b1f5587bd071d763c539645e2c9870d090e7e7 100644 --- a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter.cpp @@ -42,6 +42,7 @@ #include "lstat.h" #include "mkdtemp.h" #include "open.h" +#include "open_file.h" #include "open_dir.h" #include "posix_fallocate.h" #include "read_dir.h" @@ -50,20 +51,21 @@ #include "rmdir.h" #include "rmdirent.h" #include "stat.h" +#include "statV9.h" #include "symlink.h" #include "truncate.h" +#include "truncateV9.h" #include "watcher.h" namespace OHOS { namespace DistributedFS { namespace ModuleFileIO { using namespace std; -namespace { - static constexpr int MODE_RUO_RWX = 0750; -} + napi_value PropNExporter::AccessSync(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; @@ -90,7 +92,6 @@ napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) } ret = access(path.get(), mode); } - if (ret == -1) { UniError(errno).ThrowErr(env); return nullptr; @@ -161,6 +162,7 @@ napi_value PropNExporter::Access(napi_env env, napi_callback_info info) UniError(EINVAL).ThrowErr(env, "Invalid path"); return nullptr; } + size_t argc = funcArg.GetArgc(); auto cbExec = [path = move(path), mode](napi_env env) -> UniError { int ret = access(path.c_str(), mode); @@ -178,21 +180,23 @@ napi_value PropNExporter::Access(napi_env env, napi_callback_info info) return NVal::CreateUndefined(env); } }; - - const string procedureName = "FileIOAccess"; + string procedureName = "FileIOAccess"; NVal thisVar(env, funcArg.GetThisVar()); if (promise) { return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; } else { - int cbInd = ((funcArg.GetArgc() == NARG_CNT::TWO) ? NARG_POS::SECOND : NARG_POS::THIRD); + int cbInd = ((argc == NARG_CNT::TWO) ? NARG_POS::SECOND : NARG_POS::THIRD); NVal cb(env, funcArg[cbInd]); return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; } + + return NVal::CreateUndefined(env).val_; } napi_value PropNExporter::Unlink(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; @@ -215,7 +219,6 @@ napi_value PropNExporter::Unlink(napi_env env, napi_callback_info info) return UniError(ERRNO_NOERR); } }; - auto cbCompl = [](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; @@ -224,13 +227,14 @@ napi_value PropNExporter::Unlink(napi_env env, napi_callback_info info) }; NVal thisVar(env, funcArg.GetThisVar()); - const string procedureName = "FileIOStreamUnlink"; + string procedureName = "FileIOStreamUnlink"; if (funcArg.GetArgc() == NARG_CNT::ONE) { return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; } else { NVal cb(env, funcArg[NARG_POS::SECOND]); return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; } + return NVal::CreateUndefined(env).val_; } napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) @@ -263,8 +267,9 @@ napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) auto cbExec = [path, mode](napi_env env) -> UniError { if (mkdir(path.c_str(), mode) == -1) { return UniError(errno); + } else { + return UniError(ERRNO_NOERR); } - return UniError(ERRNO_NOERR); }; auto cbCompl = [](napi_env env, UniError err) -> NVal { @@ -273,9 +278,8 @@ napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) } return { NVal::CreateUndefined(env) }; }; - NVal thisVar(env, funcArg.GetThisVar()); - const string procedureName = "fileioMkdir"; + string procedureName = "fileioMkdir"; if ((argc == NARG_CNT::TWO && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) || argc == NARG_CNT::ONE) { return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_; } else { @@ -283,11 +287,14 @@ napi_value PropNExporter::Mkdir(napi_env env, napi_callback_info info) NVal cb(env, funcArg[cbIdx]); return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbCompl).val_; } + + return nullptr; } napi_value PropNExporter::MkdirSync(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; @@ -304,7 +311,7 @@ napi_value PropNExporter::MkdirSync(napi_env env, napi_callback_info info) int ret = -1; size_t argc = funcArg.GetArgc(); if (argc == NARG_CNT::ONE) { - ret = mkdir(path.get(), MODE_RUO_RWX); + ret = mkdir(path.get(), 0775); } else { int mode; tie(succ, mode) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); @@ -327,6 +334,7 @@ napi_value PropNExporter::MkdirSync(napi_env env, napi_callback_info info) napi_value PropNExporter::FchmodSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO)) { UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; @@ -359,6 +367,7 @@ napi_value PropNExporter::FchmodSync(napi_env env, napi_callback_info info) napi_value PropNExporter::FchownSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::THREE)) { UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; @@ -377,12 +386,14 @@ napi_value PropNExporter::FchownSync(napi_env env, napi_callback_info info) tie(succ, owner) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid owner"); + return nullptr; } int group; tie(succ, group) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid group"); + return nullptr; } int ret = fchown(fd, owner, group); @@ -397,6 +408,7 @@ napi_value PropNExporter::FchownSync(napi_env env, napi_callback_info info) napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; @@ -415,8 +427,8 @@ napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) int64_t len; bool hasPos = false; int64_t pos; - tie(succ, buf, len, hasPos, pos, ignore) = - CommonFunc::GetReadArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + tie(succ, buf, len, hasPos, pos) = + CommonFunc::GetReadArgV9(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); if (!succ) { return nullptr; } @@ -427,7 +439,6 @@ napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) } else { actLen = read(fd, buf, len); } - if (actLen == -1) { UniError(errno).ThrowErr(env); return nullptr; @@ -437,12 +448,7 @@ napi_value PropNExporter::ReadSync(napi_env env, napi_callback_info info) } struct AsyncIOReadArg { - ssize_t lenRead { 0 }; - int offset { 0 }; - NRef refReadBuf; - - explicit AsyncIOReadArg(NVal jsReadBuf) : refReadBuf(jsReadBuf) {} - ~AsyncIOReadArg() = default; + ssize_t lenRead {0}; }; napi_value PropNExporter::Read(napi_env env, napi_callback_info info) @@ -459,22 +465,21 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) int fd; bool hasPos = false; int64_t pos; - int offset; tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ) { UniError(EINVAL).ThrowErr(env, "Invalid fd"); return nullptr; } - tie(succ, buf, len, hasPos, pos, offset) = - CommonFunc::GetReadArg(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + tie(succ, buf, len, hasPos, pos) = + CommonFunc::GetReadArgV9(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); if (!succ) { UniError(EINVAL).ThrowErr(env, "Failed GetReadArg"); return nullptr; } - auto arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); - auto cbExec = [arg, buf, len, fd, hasPos, pos, offset](napi_env env) -> UniError { + auto arg = make_shared(); + auto cbExec = [arg, buf, len, fd, hasPos, pos](napi_env env) -> UniError { ssize_t actLen; if (hasPos) { actLen = pread(fd, buf, len, pos); @@ -485,7 +490,6 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) return UniError(errno); } else { arg->lenRead = actLen; - arg->offset = offset; return UniError(ERRNO_NOERR); } }; @@ -494,13 +498,7 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) 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 }; + return { NVal::CreateInt64(env, arg->lenRead) }; }; NVal thisVar(env, funcArg.GetThisVar()); @@ -508,11 +506,10 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) bool hasOp = false; if (argc == NARG_CNT::THREE) { NVal op = NVal(env, funcArg[NARG_POS::THIRD]); - if (op.HasProp("offset") || op.HasProp("position") || op.HasProp("length")) { + if (op.HasProp("offset") || op.HasProp("length")) { hasOp = true; } } - if (argc == NARG_CNT::TWO || (argc == NARG_CNT::THREE && hasOp)) { return NAsyncWorkPromise(env, thisVar).Schedule("FileIORead", cbExec, cbCompl).val_; } else { @@ -520,6 +517,8 @@ napi_value PropNExporter::Read(napi_env env, napi_callback_info info) NVal cb(env, funcArg[cbIdx]); return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIORead", cbExec, cbCompl).val_; } + + return NVal::CreateUndefined(env).val_; } UniError PropNExporter::WriteExec(shared_ptr arg, void *buf, size_t len, int fd, size_t position) @@ -532,9 +531,9 @@ UniError PropNExporter::WriteExec(shared_ptr arg, void *buf, si if (arg->actLen == -1) { return UniError(errno); + } else { + return UniError(ERRNO_NOERR); } - - return UniError(ERRNO_NOERR); } napi_value PropNExporter::Write(napi_env env, napi_callback_info info) @@ -578,8 +577,9 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) auto cbCompl = [arg](napi_env env, UniError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; + } else { + return { NVal::CreateInt64(env, arg->actLen) }; } - return { NVal::CreateInt64(env, arg->actLen) }; }; NVal thisVar(env, funcArg.GetThisVar()); @@ -599,11 +599,14 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) NVal cb(env, funcArg[cbIdx]); return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIOWrite", cbExec, cbCompl).val_; } + + return NVal::CreateUndefined(env).val_; } napi_value PropNExporter::UnlinkSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); return nullptr; @@ -714,6 +717,8 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("mkdtempSync", Mkdtemp::Sync), NVal::DeclareNapiFunction("open", Open::Async), NVal::DeclareNapiFunction("openSync", Open::Sync), + NVal::DeclareNapiFunction("openFile", OpenFile::Async), + NVal::DeclareNapiFunction("openFileSync", OpenFile::Sync), NVal::DeclareNapiFunction("opendir", OpenDir::Async), NVal::DeclareNapiFunction("opendirSync", OpenDir::Sync), NVal::DeclareNapiFunction("readdir", ReadDir::Async), @@ -730,10 +735,14 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("rmdirSync", Rmdirent::Sync), NVal::DeclareNapiFunction("stat", Stat::Async), NVal::DeclareNapiFunction("statSync", Stat::Sync), + NVal::DeclareNapiFunction("statV9", StatV9::Async), + NVal::DeclareNapiFunction("statV9Sync", StatV9::Sync), NVal::DeclareNapiFunction("symlink", Symlink::Async), NVal::DeclareNapiFunction("symlinkSync", Symlink::Sync), NVal::DeclareNapiFunction("truncate", Truncate::Async), NVal::DeclareNapiFunction("truncateSync", Truncate::Sync), + NVal::DeclareNapiFunction("truncateV9", TruncateV9::Async), + NVal::DeclareNapiFunction("truncateV9Sync", TruncateV9::Sync), NVal::DeclareNapiFunction("unlink", Unlink), NVal::DeclareNapiFunction("unlinkSync", UnlinkSync), NVal::DeclareNapiFunction("write", Write), diff --git a/interfaces/kits/js/src/mod_fileio/properties/statV9.cpp b/interfaces/kits/js/src/mod_fileio/properties/statV9.cpp new file mode 100644 index 0000000000000000000000000000000000000000..07f54f84097d9ba8e437e946895521cdafe78269 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/statV9.cpp @@ -0,0 +1,153 @@ +/* + * 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 "statV9.h" + +#include +#include + +#include "../../common/file_helper/fd_guard.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/napi/n_val.h" +#include "../../common/uni_error.h" + +#include "../class_statV9/statV9_entity.h" +#include "../class_statV9/statV9_n_exporter.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +struct FileInfo { + bool isPath = false; + unique_ptr path; + FDGuard fdg; +}; + +static tuple ParseJsFile(napi_env env, napi_value pathOrFdFromJsArg) +{ + auto [isPath, path, ignore] = NVal(env, pathOrFdFromJsArg).ToUTF8String(); + if (isPath) { + return { true, FileInfo { true, move(path), {} } }; + } + auto [isFd, fd] = NVal(env, pathOrFdFromJsArg).ToInt32(); + if (isFd) { + if (fd < 0) { + UniError(EINVAL).ThrowErr(env); + return { false, FileInfo { false, {}, {} } }; + } + return { true, FileInfo { false, {}, { fd, false } } }; + } + UniError(EINVAL).ThrowErr(env); + return { false, FileInfo { false, {}, {} } }; +}; + +napi_value StatV9::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + return nullptr; + } + + struct stat buf; + if (fileInfo.isPath) { + if (stat(fileInfo.path.get(), &buf) != 0) { + UniError(errno).ThrowErr(env); + return nullptr; + } + } else { + if (fstat(fileInfo.fdg.GetFD(), &buf) != 0) { + UniError(errno).ThrowErr(env); + return nullptr; + } + } + + napi_value objStat = NClass::InstantiateClass(env, StatV9NExporter::className_, {}); + if (!objStat) { + UniError(EIO).ThrowErr(env); + return nullptr; + } + auto statEntity = NClass::GetEntityOf(env, objStat); + if (!statEntity) { + UniError(EIO).ThrowErr(env); + return nullptr; + } + statEntity->stat_ = buf; + return objStat; +} + +struct AsyncStatArg { + struct stat stat_; +}; + +napi_value StatV9::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + return nullptr; + } + + auto arg = make_shared(); + auto cbExec = [arg, fileInfo = make_shared(move(fileInfo))](napi_env env) -> UniError { + if (fileInfo->isPath) { + if (stat(fileInfo->path.get(), &arg->stat_) != 0) { + return UniError(errno); + } + } else { + if (fstat(fileInfo->fdg.GetFD(), &arg->stat_) != 0) { + return UniError(errno); + } + } + return UniError(ERRNO_NOERR); + }; + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + napi_value objStat = NClass::InstantiateClass(env, StatV9NExporter::className_, {}); + if (!objStat) { + return { env, UniError(EIO).GetNapiErr(env) }; + } + auto statEntity = NClass::GetEntityOf(env, objStat); + if (!statEntity) { + return { env, UniError(EIO).GetNapiErr(env) }; + } + statEntity->stat_ = arg->stat_; + return { env, objStat }; + }; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureStatName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureStatName, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/statV9.h b/interfaces/kits/js/src/mod_fileio/properties/statV9.h new file mode 100644 index 0000000000000000000000000000000000000000..4a475b361455938cc68ec029a82940f4931514e9 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/statV9.h @@ -0,0 +1,33 @@ +/* + * 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_PROPERTIES_STATV9_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_STATV9_H + +#include "../../common/napi/uni_header.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class StatV9 final { +public: + static napi_value Async(napi_env env, napi_callback_info info); + static napi_value Sync(napi_env env, napi_callback_info info); +}; +const std::string procedureStatName = "fileioStatV9"; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/truncateV9.cpp b/interfaces/kits/js/src/mod_fileio/properties/truncateV9.cpp new file mode 100644 index 0000000000000000000000000000000000000000..904dd965e434656156f6107be2df2f8d17dc1e71 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/truncateV9.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (c) 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 "truncateV9.h" + +#include +#include +#include + +#include "../../common/file_helper/fd_guard.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +struct FileInfo { + bool isPath = false; + unique_ptr path; + FDGuard fdg; +}; + +static tuple ParseJsFile(napi_env env, napi_value pathOrFdFromJsArg) +{ + auto [isPath, path, ignore] = NVal(env, pathOrFdFromJsArg).ToUTF8String(); + if (isPath) { + return { true, FileInfo { true, move(path), {} } }; + } + auto [isFd, fd] = NVal(env, pathOrFdFromJsArg).ToInt32(); + if (isFd) { + if (fd < 0) { + UniError(EINVAL).ThrowErr(env); + return { false, FileInfo { false, {}, {} } }; + } + return { true, FileInfo { false, {}, { fd, false } } }; + } + UniError(EINVAL).ThrowErr(env); + return { false, FileInfo { false, {}, {} } }; +}; + +napi_value TruncateV9::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + return nullptr; + } + int truncateLen = 0; + if (funcArg.GetArgc() == NARG_CNT::TWO) { + tie(succ, truncateLen) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + } + if (fileInfo.isPath) { + if (truncate(fileInfo.path.get(), truncateLen) != 0) { + UniError(errno).ThrowErr(env); + return nullptr; + } + } else { + if (ftruncate(fileInfo.fdg.GetFD(), truncateLen) != 0) { + UniError(errno).ThrowErr(env); + return nullptr; + } + } + return NVal::CreateUndefined(env).val_; +} + +napi_value TruncateV9::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, fileInfo] = ParseJsFile(env, funcArg[NARG_POS::FIRST]); + if (!succ) { + return nullptr; + } + int truncateLen = 0; + if (funcArg.GetArgc() > NARG_CNT::ONE && NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) { + tie(succ, truncateLen) = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32(); + if (!succ) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + } + auto cbExec = [fileInfo = make_shared(move(fileInfo)), truncateLen](napi_env env) -> UniError { + if (fileInfo->isPath) { + if (truncate(fileInfo->path.get(), truncateLen) != 0) { + return UniError(errno); + } + } else { + if (ftruncate(fileInfo->fdg.GetFD(), truncateLen) != 0) { + return UniError(errno); + } + } + 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()); + if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && + NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number))) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureTruncateName, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureTruncateName, cbExec, cbCompl).val_; + } +} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/truncateV9.h b/interfaces/kits/js/src/mod_fileio/properties/truncateV9.h new file mode 100644 index 0000000000000000000000000000000000000000..6f36bd3f8bd36496abc8f4c6509f3eade410cd02 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/truncateV9.h @@ -0,0 +1,36 @@ +/* + * 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_PROPERTIES_TRUNCATEV9_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_TRUNCATEV9_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_func_arg.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +class TruncateV9 final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); + static napi_value Async(napi_env env, napi_callback_info info); +}; +const std::string procedureTruncateName = "fileIOTruncateV9"; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file