diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 8b4b5914d370b082410495c9c74cf5457ed27e20..41e0fa1fb1c09711a95b7e1ce7f61ba2607211f6 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -99,6 +99,37 @@ ohos_shared_library("fileio") { external_deps = [ "hiviewdfx_hilog_native:libhilog" ] } +ohos_shared_library("hash") { + subsystem_name = "filemanagement" + part_name = "file_api" + + relative_install_dir = "module" + + include_dirs = [ + "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/file_helper", + "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi", + "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi/n_async", + ] + + sources = file_common_src + sources += [ + "src/common/file_helper/hash_file.cpp", + "src/mod_hash/properties/hash.cpp", + "src/mod_hash/properties/prop_n_exporter.cpp", + ] + + deps = [ + "//foundation/arkui/napi:ace_napi", + "//foundation/filemanagement/file_api/interfaces/kits/native:remote_uri_native", + "//foundation/filemanagement/file_api/utils/filemgmt_libhilog", + "//foundation/filemanagement/file_api/utils/filemgmt_libn", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/openssl:libcrypto_static", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] +} + ohos_shared_library("fs") { subsystem_name = "filemanagement" part_name = "file_api" @@ -113,17 +144,21 @@ ohos_shared_library("fs") { sources = file_common_src sources += [ - "src/mod_fileio/class_file/file_n_exporter.cpp", "src/mod_fileio/class_stat_v9/stat_n_exporter_v9.cpp", - "src/mod_fileio/common_func.cpp", "src/mod_fileio/module_v9.cpp", "src/mod_fileio/properties/open_v9.cpp", "src/mod_fileio/properties/prop_n_exporter_v9.cpp", "src/mod_fileio/properties/stat_v9.cpp", "src/mod_fileio/properties/truncate_v9.cpp", + "src/mod_fs/class_file/file_n_exporter.cpp", + "src/mod_fs/common_func.cpp", ] - deps = [ "//foundation/arkui/napi:ace_napi" ] + deps = [ + "//foundation/arkui/napi:ace_napi", + "//foundation/filemanagement/file_api/utils/filemgmt_libhilog", + "//foundation/filemanagement/file_api/utils/filemgmt_libn", + ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] } @@ -271,6 +306,7 @@ group("build_kits_js") { ":file", ":fileio", ":fs", + ":hash", ":securitylabel", ":statfs", ] diff --git a/interfaces/kits/js/src/mod_fs/class_file/file_entity.h b/interfaces/kits/js/src/mod_fs/class_file/file_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..9895f1fced72bf6278d615a7735a7183ad08abc0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/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_fs/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d3a591ef55d85d58041a1c077eea5c530d96faa2 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp @@ -0,0 +1,114 @@ +/* + * 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::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), + }; + + 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_fs/class_file/file_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..03559aac8f95efd899f10ec52ecde873ea0a6e98 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.h @@ -0,0 +1,39 @@ +/* + * 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); + 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_fs/common_func.cpp b/interfaces/kits/js/src/mod_fs/common_func.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c69329202229ec71ec89cc5511474c726025a330 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/common_func.cpp @@ -0,0 +1,401 @@ +/* + * 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 "common_func.h" + +#include +#include +#include +#include +#include + +#include "../common/log.h" +#include "../common/napi/n_class.h" +#include "../common/napi/n_func_arg.h" +#include "../common/napi/n_val.h" +#include "../../../../../utils/filemgmt_libn/include/n_error.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +void InitOpenMode(napi_env env, napi_value exports) +{ + char propertyName[] = "OpenMode"; + napi_property_descriptor desc[] = { + DECLARE_NAPI_STATIC_PROPERTY("READ_ONLY", NVal::CreateInt32(env, RDONLY).val_), + DECLARE_NAPI_STATIC_PROPERTY("WRITE_ONLY", NVal::CreateInt32(env, WRONLY).val_), + DECLARE_NAPI_STATIC_PROPERTY("READ_WRITE", NVal::CreateInt32(env, RDWR).val_), + DECLARE_NAPI_STATIC_PROPERTY("CREATE", NVal::CreateInt32(env, CREATE).val_), + DECLARE_NAPI_STATIC_PROPERTY("TRUNC", NVal::CreateInt32(env, TRUNC).val_), + DECLARE_NAPI_STATIC_PROPERTY("APPEND", NVal::CreateInt32(env, APPEND).val_), + DECLARE_NAPI_STATIC_PROPERTY("NONBLOCK", NVal::CreateInt32(env, NONBLOCK).val_), + DECLARE_NAPI_STATIC_PROPERTY("DIR", NVal::CreateInt32(env, DIRECTORY).val_), + DECLARE_NAPI_STATIC_PROPERTY("NOFOLLOW", NVal::CreateInt32(env, NOFOLLOW).val_), + DECLARE_NAPI_STATIC_PROPERTY("SYNC", NVal::CreateInt32(env, SYNC).val_), + }; + napi_value obj = nullptr; + napi_create_object(env, &obj); + napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc); + napi_set_named_property(env, exports, propertyName, obj); +} + +static tuple GetActualBuf(napi_env env, void *rawBuf, int64_t bufLen, NVal op) +{ + bool succ = false; + void *realBuf = nullptr; + int64_t opOffset = 0; + if (op.HasProp("offset")) { + tie(succ, opOffset) = op.GetProp("offset").ToInt64(); + if (!succ || opOffset < 0) { + HILOGE("Invalid option.offset, positive integer is desired"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, opOffset }; + } else if (opOffset > bufLen) { + HILOGE("Invalid option.offset, buffer limit exceeded"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, opOffset }; + } else { + realBuf = static_cast(rawBuf) + opOffset; + } + } else { + realBuf = rawBuf; + } + + return { true, realBuf, opOffset }; +} + +static tuple GetActualLen(napi_env env, int64_t bufLen, int64_t bufOff, NVal op) +{ + bool succ = false; + int64_t retLen; + + if (op.HasProp("length")) { + int64_t opLength; + tie(succ, opLength) = op.GetProp("length").ToInt64(); + if (!succ) { + HILOGE("Invalid option.length, expect integer"); + NError(EINVAL).ThrowErr(env); + return { false, 0 }; + } + if (opLength < 0) { + retLen = bufLen - bufOff; + } else if (opLength > bufLen - bufOff) { + HILOGE("Invalid option.length, buffer limit exceeded"); + NError(EINVAL).ThrowErr(env); + return { false, 0 }; + } else { + retLen = opLength; + } + } else { + retLen = bufLen - bufOff; + } + + return { true, retLen }; +} + +static tuple GetActualLenV9(napi_env env, int64_t bufLen, int64_t bufOff, NVal op) +{ + bool succ = false; + int64_t retLen; + + if (op.HasProp("length")) { + int64_t opLength; + tie(succ, opLength) = op.GetProp("length").ToInt64(); + if (!succ) { + HILOGE("Invalid option.length, expect integer"); + NError(EINVAL).ThrowErr(env); + return { false, 0 }; + } + if (opLength < 0) { + retLen = bufLen - bufOff; + } else if (opLength > bufLen - bufOff) { + HILOGE("Invalid option.length, buffer limit exceeded"); + NError(EINVAL).ThrowErr(env); + return { false, 0 }; + } else { + retLen = opLength; + } + } else { + retLen = bufLen - bufOff; + } + + return { true, retLen }; +} + +int CommonFunc::ConvertJsFlags(int &flags) +{ + static constexpr int USR_O_RDONLY = 00; + static constexpr int USR_O_WRONLY = 01; + static constexpr int USR_O_RDWR = 02; + static constexpr int USR_O_CREAT = 0100; + static constexpr int USR_O_EXCL = 0200; + static constexpr int USR_O_TRUNC = 01000; + static constexpr int USR_O_APPEND = 02000; + static constexpr int USR_O_NONBLOCK = 04000; + static constexpr int USR_O_DIRECTORY = 0200000; + static constexpr int USR_O_NOFOLLOW = 0400000; + static constexpr int USR_O_SYNC = 04010000; + + int flagsABI = 0; + flagsABI |= ((flags & USR_O_RDONLY) == USR_O_RDONLY) ? O_RDONLY : 0; + flagsABI |= ((flags & USR_O_WRONLY) == USR_O_WRONLY) ? O_WRONLY : 0; + flagsABI |= ((flags & USR_O_RDWR) == USR_O_RDWR) ? O_RDWR : 0; + flagsABI |= ((flags & USR_O_CREAT) == USR_O_CREAT) ? O_CREAT : 0; + flagsABI |= ((flags & USR_O_EXCL) == USR_O_EXCL) ? O_EXCL : 0; + flagsABI |= ((flags & USR_O_TRUNC) == USR_O_TRUNC) ? O_TRUNC : 0; + flagsABI |= ((flags & USR_O_APPEND) == USR_O_APPEND) ? O_APPEND : 0; + flagsABI |= ((flags & USR_O_NONBLOCK) == USR_O_NONBLOCK) ? O_NONBLOCK : 0; + flagsABI |= ((flags & USR_O_DIRECTORY) == USR_O_DIRECTORY) ? O_DIRECTORY : 0; + flagsABI |= ((flags & USR_O_NOFOLLOW) == USR_O_NOFOLLOW) ? O_NOFOLLOW : 0; + flagsABI |= ((flags & USR_O_SYNC) == USR_O_SYNC) ? O_SYNC : 0; + flags = flagsABI; + return flagsABI; +} + +tuple, unique_ptr> CommonFunc::GetCopyPathArg(napi_env env, + napi_value srcPath, + napi_value dstPath) +{ + bool succ = false; + unique_ptr src; + tie(succ, src, ignore) = NVal(env, srcPath).ToUTF8String(); + if (!succ) { + return { false, nullptr, nullptr }; + } + + unique_ptr dest; + tie(succ, dest, ignore) = NVal(env, dstPath).ToUTF8String(); + if (!succ) { + return { false, nullptr, nullptr }; + } + return make_tuple(true, move(src), move(dest)); +} + +tuple CommonFunc::GetReadArg(napi_env env, + napi_value readBuf, + napi_value option) +{ + bool succ = false; + void *retBuf = nullptr; + int64_t retLen = 0; + bool posAssigned = false; + int64_t position = 0; + + NVal txt(env, readBuf); + void *buf = nullptr; + int64_t bufLen = 0; + int offset = 0; + tie(succ, buf, bufLen) = txt.ToArraybuffer(); + if (!succ) { + HILOGE("Invalid read buffer, expect arraybuffer"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, 0, posAssigned, position, offset }; + } + + NVal op = NVal(env, option); + tie(succ, retBuf, offset) = GetActualBuf(env, buf, bufLen, op); + if (!succ) { + return { false, nullptr, 0, posAssigned, position, offset }; + } + + int64_t bufOff = static_cast(retBuf) - static_cast(buf); + tie(succ, retLen) = GetActualLen(env, bufLen, bufOff, op); + if (!succ) { + return { false, nullptr, 0, posAssigned, position, offset }; + } + + if (op.HasProp("position")) { + tie(succ, position) = op.GetProp("position").ToInt64(); + if (succ && position >= 0) { + posAssigned = true; + } else { + HILOGE("option.position shall be positive number"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, 0, posAssigned, position, offset }; + } + } + + return { true, retBuf, retLen, posAssigned, position, offset }; +} + +static tuple, int64_t> DecodeString(napi_env env, NVal jsStr, NVal encoding) +{ + unique_ptr buf; + if (!jsStr.TypeIs(napi_string)) { + return { false, nullptr, 0 }; + } + + bool succ = false; + if (!encoding) { + return jsStr.ToUTF8String(); + } + + unique_ptr encodingBuf; + tie(succ, encodingBuf, ignore) = encoding.ToUTF8String(); + if (!succ) { + return { false, nullptr, 0 }; + } + string encodingStr(encodingBuf.release()); + if (encodingStr == "utf-8") { + return jsStr.ToUTF8String(); + } else if (encodingStr == "utf-16") { + return jsStr.ToUTF16String(); + } else { + return { false, nullptr, 0 }; + } +} + +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; + bool hasPos = false; + int64_t retPos = 0; + + bool succ = false; + void *buf = nullptr; + int64_t bufLen = 0; + 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) { + HILOGE("Illegal write buffer or encoding"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + } else { + buf = bufferGuard.get(); + } + + tie(succ, retBuf, ignore) = GetActualBuf(env, buf, bufLen, op); + if (!succ) { + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + + int64_t bufOff = static_cast(retBuf) - static_cast(buf); + tie(succ, retLen) = GetActualLen(env, bufLen, bufOff, op); + if (!succ) { + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + + if (op.HasProp("position")) { + int32_t position = 0; + tie(succ, position) = op.GetProp("position").ToInt32(); + if (!succ || position < 0) { + HILOGE("option.position shall be positive number"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + hasPos = true; + retPos = position; + } 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) { + HILOGE("Invalid read buffer, expect arraybuffer"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, 0, posAssigned, position }; + } + NVal op = NVal(env, option); + tie(succ, retLen) = GetActualLenV9(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 { + HILOGE("option.offset shall be positive number"); + NError(EINVAL).ThrowErr(env); + 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; + + 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) { + HILOGE("Illegal write buffer or encoding"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + } else { + buf = bufferGuard.get(); + } + tie(succ, retLen) = GetActualLenV9(env, bufLen, 0, op); + if (!succ) { + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + + if (op.HasProp("offset")) { + int32_t position = 0; + tie(succ, position) = op.GetProp("offset").ToInt32(); + if (!succ || position < 0) { + HILOGE("option.offset shall be positive number"); + NError(EINVAL).ThrowErr(env); + 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_fs/common_func.h b/interfaces/kits/js/src/mod_fs/common_func.h new file mode 100644 index 0000000000000000000000000000000000000000..4a8a2e39e80d94bd25ea42f33753dc5274f54f48 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -0,0 +1,57 @@ +/* + * 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_COMMON_FUNC_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_COMMON_FUNC_H + +#include "../common/napi/uni_header.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +constexpr int64_t INVALID_POSITION = std::numeric_limits::max(); +constexpr int RDONLY = 00; +constexpr int WRONLY = 01; +constexpr int RDWR = 02; +constexpr int CREATE = 0100; +constexpr int TRUNC = 01000; +constexpr int APPEND = 02000; +constexpr int NONBLOCK = 04000; +constexpr int DIRECTORY = 0200000; +constexpr int NOFOLLOW = 0400000; +constexpr int SYNC = 04010000; + +void InitOpenMode(napi_env env, napi_value exports); + +struct CommonFunc { + static int ConvertJsFlags(int &flags); + static std::tuple GetReadArg(napi_env env, + 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); +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/properties/hash.cpp b/interfaces/kits/js/src/mod_hash/properties/hash.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6db34c38cf2be88dfbfd2ca41f603397984a1b73 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/properties/hash.cpp @@ -0,0 +1,133 @@ +/* + * 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 "hash.h" + +#include +#include +#include + +#include "../../common/log.h" +#include "../../common/file_helper/hash_file.h" +#include "../../../../utils/filemgmt_libn/include/n_error.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +enum HASH_ALGORITHM_TYPE { + HASH_ALGORITHM_TYPE_MD5, + HASH_ALGORITHM_TYPE_SHA1, + HASH_ALGORITHM_TYPE_SHA256, + HASH_ALGORITHM_TYPE_UNSUPPORTED, +}; + +static HASH_ALGORITHM_TYPE GetHashAlgorithm(const unique_ptr &alg, const size_t algLen) +{ + if (algLen == string_view("md5").length() && string_view(alg.get()).compare("md5") == 0) { + return HASH_ALGORITHM_TYPE_MD5; + } else if (algLen == string_view("sha1").length() && string_view(alg.get()).compare("sha1") == 0) { + return HASH_ALGORITHM_TYPE_SHA1; + } else if (algLen == string_view("sha256").length() && string_view(alg.get()).compare("sha256") == 0) { + return HASH_ALGORITHM_TYPE_SHA256; + } else { + return HASH_ALGORITHM_TYPE_UNSUPPORTED; + } +} + +static tuple, HASH_ALGORITHM_TYPE, bool> GetHashArgs(napi_env env, const NFuncArg &funcArg) +{ + bool isPromise = false; + auto [resGetFirstArg, path, unused] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!resGetFirstArg) { + HILOGE("Invalid path"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + auto [resGetSecondArg, alg, algLen] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + HILOGE("Invalid algorithm"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + HASH_ALGORITHM_TYPE algType = GetHashAlgorithm(alg, algLen); + if (algType == HASH_ALGORITHM_TYPE_UNSUPPORTED) { + HILOGE("Invalid algorithm"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + if (funcArg.GetArgc() == NARG_CNT::THREE && !NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function)) { + HILOGE("Invalid callback"); + NError(EINVAL).ThrowErr(env); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + isPromise = funcArg.GetArgc() == NARG_CNT::TWO; + return { true, move(path), algType, isPromise }; +} + +napi_value Hash::Async(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, fpath, algType, isPromise] = GetHashArgs(env, funcArg); + if (!succ) { + return nullptr; + } + + auto arg = make_shared(); + auto cbExec = [fpath = string(fpath.release()), arg, algType = algType](napi_env env) -> UniError { + int ret = EIO; + string &res = *arg; + if (algType == HASH_ALGORITHM_TYPE_MD5) { + tie(ret, res) = HashFile::HashWithMD5(fpath); + } else if (algType == HASH_ALGORITHM_TYPE_SHA1) { + tie(ret, res) = HashFile::HashWithSHA1(fpath); + } else if (algType == HASH_ALGORITHM_TYPE_SHA256) { + tie(ret, res) = HashFile::HashWithSHA256(fpath); + } + return UniError(ret); + }; + + auto cbComplete = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { NVal(env, err.GetNapiErr(env)) }; + } + + return { NVal::CreateUTF8String(env, *arg) }; + }; + + const string procedureName = "FileIOHash"; + NVal thisVar(env, funcArg.GetThisVar()); + if (isPromise) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; + } +} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/properties/hash.h b/interfaces/kits/js/src/mod_hash/properties/hash.h new file mode 100644 index 0000000000000000000000000000000000000000..9178365072709ce0f45fec5612e71a653ad32ae3 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/properties/hash.h @@ -0,0 +1,34 @@ +/* + * 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_HASH_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_HASH_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 Hash final { +public: + static napi_value Async(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_hash/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_hash/properties/prop_n_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9f80a096ad7471c4f2eb9ff9d2dda56094b94875 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/properties/prop_n_exporter.cpp @@ -0,0 +1,39 @@ +/* + * 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 "prop_n_exporter.h" + +#include "hash.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +bool PropNExporter::Export() +{ + return exports_.AddProp({ + NVal::DeclareNapiFunction("hash", Hash::Async), + }); +} + +string PropNExporter::GetClassName() +{ + return PropNExporter::className_; +} + +PropNExporter::PropNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/properties/prop_n_exporter.h b/interfaces/kits/js/src/mod_hash/properties/prop_n_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..4f48a37e92a4bda65225d16073e5e102b08da7e3 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/properties/prop_n_exporter.h @@ -0,0 +1,38 @@ +/* + * 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_PROP_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_PROP_N_EXPORTER_H + +#include "../../common/napi/n_exporter.h" +#include "../../common/napi/n_val.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { + +class PropNExporter final : public NExporter { +public: + inline static const std::string className_ = "__properities__"; + bool Export() override; + std::string GetClassName() override; + + PropNExporter(napi_env env, napi_value exports); + ~PropNExporter() = default; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file diff --git a/utils/filemgmt_libn/include/n_error.h b/utils/filemgmt_libn/include/n_error.h index 82343d36715d30f58d70e29ff0b4b73f669280fd..fbe0cb9ca9c5ef7f5c804c619f4417dc9e9248e7 100644 --- a/utils/filemgmt_libn/include/n_error.h +++ b/utils/filemgmt_libn/include/n_error.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "n_napi.h" @@ -26,21 +27,134 @@ namespace OHOS { namespace FileManagement { namespace LibN { constexpr int ERRNO_NOERR = 0; +constexpr int FILEIO_SYS_CAP_TAG = 13900000; +const std::string FILEIO_TAG_ERR_CODE = "code"; +const std::string FILEIO_TAG_ERR_MSG = "message"; + +enum ELegacy { + ELEGACY_INVAL = 202, + ELEGACY_IO = 300, + ELEGACY_NOENT = 301, +}; + +enum ErrCodeSystem { + ERR_CODE_SYSTEM_LEGACY, + ERR_CODE_SYSTEM_POSIX, +}; + + +enum ErrCodeSuffix { + E_PERM = 1, + E_NOENT, + E_SRCH, + E_INTR, + E_IO, + E_NXIO, + E_2BIG, + E_BADF, + E_CHILD, + E_AGAIN, + E_NOMEM, + E_ACCES, + E_FAULT, + E_BUSY, + E_EXIST, + E_XDEV, + E_NODEV, + E_NOTDIR, + E_ISDIR, + E_INVAL, + E_NFILE, + E_MFILE, + E_TXTBSY, + E_FBIG, + E_NOSPC, + E_SPIPE, + E_ROFS, + E_MLINK, + E_DEADLK, + E_NAMETOOLONG, + E_NOSYS, + E_NOTEMPTY, + E_LOOP, + E_WOULDBLOCK, + E_BADR, + E_NOSTR, + E_NODATA, + E_OVERFLOW, + E_BADFD, + E_RESTART, + E_DQUOT, + E_UKERR +}; + +const std::unordered_map> errCodeTable { + { EPERM, { FILEIO_SYS_CAP_TAG + E_PERM, "Operation not permitted" } }, + { ENOENT, { FILEIO_SYS_CAP_TAG + E_NOENT, "No such file or directory" } }, + { ESRCH, { FILEIO_SYS_CAP_TAG + E_SRCH, "No such process" } }, + { EINTR, { FILEIO_SYS_CAP_TAG + E_INTR, "Interrupted system call" } }, + { EIO, { FILEIO_SYS_CAP_TAG + E_IO, "I/O error" } }, + { ENXIO, { FILEIO_SYS_CAP_TAG + E_NXIO, "No such device or address" } }, + { E2BIG, { FILEIO_SYS_CAP_TAG + E_2BIG, "Arg list too long" } }, + { EBADF, { FILEIO_SYS_CAP_TAG + E_BADF, "Bad file descriptor" } }, + { ECHILD, { FILEIO_SYS_CAP_TAG + E_CHILD, "No child processes" } }, + { EAGAIN, { FILEIO_SYS_CAP_TAG + E_AGAIN, "Try again" } }, + { ENOMEM, { FILEIO_SYS_CAP_TAG + E_NOMEM, "Out of memory" } }, + { EACCES, { FILEIO_SYS_CAP_TAG + E_ACCES, "Permission denied" } }, + { EFAULT, { FILEIO_SYS_CAP_TAG + E_FAULT, "Bad address" } }, + { EBUSY, { FILEIO_SYS_CAP_TAG + E_BUSY, "Device or resource busy" } }, + { EEXIST, { FILEIO_SYS_CAP_TAG + E_EXIST, "File exists" } }, + { EXDEV, { FILEIO_SYS_CAP_TAG + E_XDEV, "Cross-device link" } }, + { ENODEV, { FILEIO_SYS_CAP_TAG + E_NODEV, "No such device" } }, + { ENOTDIR, { FILEIO_SYS_CAP_TAG + E_NOTDIR, "Not a directory" } }, + { EISDIR, { FILEIO_SYS_CAP_TAG + E_ISDIR, "Is a directory" } }, + { EINVAL, { FILEIO_SYS_CAP_TAG + E_INVAL, "Invalid argument" } }, + { ENFILE, { FILEIO_SYS_CAP_TAG + E_NFILE, "File table overflow" } }, + { EMFILE, { FILEIO_SYS_CAP_TAG + E_MFILE, "Too many open files" } }, + { ETXTBSY, { FILEIO_SYS_CAP_TAG + E_TXTBSY, "Text file busy" } }, + { EFBIG, { FILEIO_SYS_CAP_TAG + E_FBIG, "File too large" } }, + { ENOSPC, { FILEIO_SYS_CAP_TAG + E_NOSPC, "No space left on device" } }, + { ESPIPE, { FILEIO_SYS_CAP_TAG + E_SPIPE, "Illegal seek" } }, + { EROFS, { FILEIO_SYS_CAP_TAG + E_ROFS, "Read-only file system" } }, + { EMLINK, { FILEIO_SYS_CAP_TAG + E_MLINK, "Too many links" } }, + { EDEADLK, { FILEIO_SYS_CAP_TAG + E_DEADLK, "Resource deadlock would occur" } }, + { ENAMETOOLONG, { FILEIO_SYS_CAP_TAG + E_NAMETOOLONG, "File name too long" } }, + { ENOSYS, { FILEIO_SYS_CAP_TAG + E_NOSYS, "Function not implemented" } }, + { ENOTEMPTY, { FILEIO_SYS_CAP_TAG + E_NOTEMPTY, "Directory not empty" } }, + { ELOOP, { FILEIO_SYS_CAP_TAG + E_LOOP, "Too many symbolic links encountered" } }, + { EWOULDBLOCK, { FILEIO_SYS_CAP_TAG + E_WOULDBLOCK, "Operation would block" } }, + { EBADR, { FILEIO_SYS_CAP_TAG + E_BADR, "Invalid request descriptor" } }, + { ENOSTR, { FILEIO_SYS_CAP_TAG + E_NOSTR, "Device not a stream" } }, + { ENODATA, { FILEIO_SYS_CAP_TAG + E_NODATA, "No data available" } }, + { EOVERFLOW, { FILEIO_SYS_CAP_TAG + E_OVERFLOW, "Value too large for defined data type" } }, + { EBADFD, { FILEIO_SYS_CAP_TAG + E_BADFD, "File descriptor in bad state" } }, + { ERESTART, { FILEIO_SYS_CAP_TAG + E_RESTART, "Interrupted system call should be restarted" } }, + { EDQUOT, { FILEIO_SYS_CAP_TAG + E_DQUOT, "Quota exceeded" } }, + { -1, { FILEIO_SYS_CAP_TAG + E_UKERR, "Unknown error" } } +}; class NError { public: NError(); - NError(int ePosix); - NError(std::function()> errGen); + explicit NError(int ePosix); + explicit NError(std::function()> errGen); ~NError() = default; explicit operator bool() const; + + void SetErrno(int ePosix); + int GetErrno(ErrCodeSystem cs); + + std::string GetDefaultErrstr(); napi_value GetNapiErr(napi_env env); + napi_value GetNapiErr(napi_env env, std::string errMsg); void ThrowErr(napi_env env); + void ThrowErr(napi_env env, int code); void ThrowErr(napi_env env, std::string errMsg); private: int errno_ = ERRNO_NOERR; std::string errMsg_; + ErrCodeSystem codingSystem_ = ERR_CODE_SYSTEM_POSIX; }; } // namespace LibN } // namespace FileManagement diff --git a/utils/filemgmt_libn/src/n_error.cpp b/utils/filemgmt_libn/src/n_error.cpp index 88fff79c06db7d291464396d61cbb1a55167c408..12a0bee50533c3e42b2f58a7892c3d84d09fb471 100644 --- a/utils/filemgmt_libn/src/n_error.cpp +++ b/utils/filemgmt_libn/src/n_error.cpp @@ -25,9 +25,22 @@ namespace FileManagement { namespace LibN { using namespace std; +static napi_value GenerateBusinessError(napi_env env, int32_t errCode, string errMsg) +{ + napi_value businessError = nullptr; + napi_value code = nullptr; + napi_value msg = nullptr; + code = NVal::CreateInt32(env, errCode).val_; + msg = NVal::CreateUTF8String(env, errMsg).val_; + napi_create_error(env, nullptr, msg, &businessError); + napi_set_named_property(env, businessError, FILEIO_TAG_ERR_CODE.c_str(), code); + napi_set_named_property(env, businessError, FILEIO_TAG_ERR_MSG.c_str(), msg); + return businessError; +} + NError::NError() {} -NError::NError(int ePosix) : errno_(ePosix), errMsg_(strerror(errno_)) {} +NError::NError(int ePosix) : errno_(ePosix), codingSystem_(ERR_CODE_SYSTEM_POSIX) {} NError::NError(std::function()> errGen) { @@ -39,19 +52,87 @@ NError::operator bool() const return errno_ != ERRNO_NOERR; } +int NError::GetErrno(ErrCodeSystem cs) +{ + if (errno_ == ERRNO_NOERR) { + return ERRNO_NOERR; + } + + if (cs == codingSystem_) { + return errno_; + } + + if (cs == ERR_CODE_SYSTEM_POSIX) { + return EINVAL; + } + + return ELEGACY_INVAL; +} + +void NError::SetErrno(int ePosix) +{ + errno_ = ePosix; + codingSystem_ = ERR_CODE_SYSTEM_POSIX; +} + +std::string NError::GetDefaultErrstr() +{ + if (codingSystem_ != ERR_CODE_SYSTEM_POSIX) { + return "BUG: Curious coding system"; + } + return strerror(GetErrno(ERR_CODE_SYSTEM_POSIX)); +} + napi_value NError::GetNapiErr(napi_env env) { - napi_value code = NVal::CreateUTF8String(env, to_string(errno_)).val_; - napi_value msg = NVal::CreateUTF8String(env, errMsg_).val_; + int errCode = GetErrno(codingSystem_); + if (errCode == ERRNO_NOERR) { + return nullptr; + } + int32_t code; + string msg; + if (errCodeTable.find(errCode) != errCodeTable.end()) { + code = errCodeTable.at(errCode).first; + msg = errCodeTable.at(errCode).second; + } else { + code = errCodeTable.at(-1).first; + msg = errCodeTable.at(-1).second; + } + return GenerateBusinessError(env, code, msg); +} + +napi_value NError::GetNapiErr(napi_env env, string errMsg) +{ + int errCode = GetErrno(codingSystem_); + if (errCode == ERRNO_NOERR) { + return nullptr; + } + napi_value code = NVal::CreateUTF8String(env, to_string(errCode)).val_; + napi_value msg = NVal::CreateUTF8String(env, errMsg).val_; napi_value res = nullptr; napi_status createRes = napi_create_error(env, code, msg, &res); if (createRes) { - HILOGE("Failed to create an exception, msg = %{public}s", errMsg_.c_str()); + HILOGE("Failed to create an exception, msg = %{public}s", errMsg.c_str()); } return res; } +void NError::ThrowErr(napi_env env, int code) +{ + napi_value tmp = nullptr; + napi_get_and_clear_last_exception(env, &tmp); + if (errCodeTable.find(code) == errCodeTable.end()) { + code = -1; + } + napi_status throwStatus = napi_throw(env, GenerateBusinessError(env, errCodeTable.at(code).first, + errCodeTable.at(code).second)); + if (throwStatus != napi_ok) { + HILOGE("Failed to throw an exception, %{public}d, code = %{public}s", throwStatus, + errCodeTable.at(code).second.c_str()); + } +} + void NError::ThrowErr(napi_env env, string errMsg) { napi_value tmp = nullptr; @@ -65,7 +146,21 @@ void NError::ThrowErr(napi_env env, string errMsg) void NError::ThrowErr(napi_env env) { - ThrowErr(env, errMsg_); + napi_value tmp = nullptr; + napi_get_and_clear_last_exception(env, &tmp); + int32_t code; + string msg; + if (errCodeTable.find(errno_) != errCodeTable.end()) { + code = errCodeTable.at(errno_).first; + msg = errCodeTable.at(errno_).second; + } else { + code = errCodeTable.at(-1).first; + msg = errCodeTable.at(-1).second; + } + napi_status throwStatus = napi_throw(env, GenerateBusinessError(env, code, msg)); + if (throwStatus != napi_ok) { + HILOGE("Failed to throw an exception, %{public}d, code = %{public}s", throwStatus, msg.c_str()); + } } } // namespace LibN } // namespace FileManagement