diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 8b4b5914d370b082410495c9c74cf5457ed27e20..43e101a61a69da1be74957a87e7b89fd4e37e0ea 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -99,6 +99,35 @@ 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", + "//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,14 +142,14 @@ 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_fileiov9/class_file/file_n_exporter.cpp", + "src/mod_fileiov9/common_func.cpp", ] deps = [ "//foundation/arkui/napi:ace_napi" ] @@ -271,6 +300,7 @@ group("build_kits_js") { ":file", ":fileio", ":fs", + ":hash", ":securitylabel", ":statfs", ] diff --git a/interfaces/kits/js/src/mod_fileiov9/class_file/file_entity.h b/interfaces/kits/js/src/mod_fileiov9/class_file/file_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..9a82a6f7900f8364a6a5cedc98794a94ac5a0516 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileiov9/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_fileiov9/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_fileiov9/class_file/file_n_exporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8adda7d37e005a1048ec82f7a0ce0cb35e6957e7 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileiov9/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_fileiov9/class_file/file_n_exporter.h b/interfaces/kits/js/src/mod_fileiov9/class_file/file_n_exporter.h new file mode 100644 index 0000000000000000000000000000000000000000..c77716e6123e00726a32d35851e0383bd047b8a1 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileiov9/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_fileiov9/common_func.cpp b/interfaces/kits/js/src/mod_fileiov9/common_func.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e03d5c9de20be8f1aee6957b440b41f9528f815f --- /dev/null +++ b/interfaces/kits/js/src/mod_fileiov9/common_func.cpp @@ -0,0 +1,392 @@ +/* + * 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 "../common/uni_error.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +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) { + UniError(EINVAL).ThrowErr(env, "Invalid option.offset, positive integer is desired"); + return { false, nullptr, opOffset }; + } else if (opOffset > bufLen) { + UniError(EINVAL).ThrowErr(env, "Invalid option.offset, buffer limit exceeded"); + 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) { + UniError(EINVAL).ThrowErr(env, "Invalid option.length, expect integer"); + return { false, 0 }; + } + if (opLength < 0) { + retLen = bufLen - bufOff; + } else if (opLength > bufLen - bufOff) { + UniError(EINVAL).ThrowErr(env, "Invalid option.length, buffer limit exceeded"); + 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"); + UniError(EINVAL).ThrowErr(env); + return { false, 0 }; + } + if (opLength < 0) { + retLen = bufLen - bufOff; + } else if (opLength > bufLen - bufOff) { + HILOGE("Invalid option.length, buffer limit exceeded"); + UniError(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) { + UniError(EINVAL).ThrowErr(env, "Invalid read buffer, expect arraybuffer"); + 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 { + UniError(EINVAL).ThrowErr(env, "option.position shall be positive number"); + 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) { + UniError(EINVAL).ThrowErr(env, "Illegal write buffer or encoding"); + 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) { + UniError(EINVAL).ThrowErr(env, "option.position shall be positive number"); + 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"); + UniError(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"); + UniError(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"); + UniError(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"); + UniError(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_fileiov9/common_func.h b/interfaces/kits/js/src/mod_fileiov9/common_func.h new file mode 100644 index 0000000000000000000000000000000000000000..1c17b8675c717e788fd9eeab880e59399eb1f308 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileiov9/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..35d4c11d89f1cb82b83d6cae74c5399bf7e2a2cf --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/properties/hash.cpp @@ -0,0 +1,125 @@ +/* + * 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/file_helper/hash_file.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +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) { + UniError(EINVAL).ThrowErr(env, "Invalid path"); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + auto [resGetSecondArg, alg, algLen] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!resGetSecondArg) { + UniError(EINVAL).ThrowErr(env, "Invalid algorithm"); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + HASH_ALGORITHM_TYPE algType = GetHashAlgorithm(alg, algLen); + if (algType == HASH_ALGORITHM_TYPE_UNSUPPORTED) { + UniError(EINVAL).ThrowErr(env, "Invalid algorithm"); + return { false, nullptr, HASH_ALGORITHM_TYPE_UNSUPPORTED, isPromise }; + } + + if (funcArg.GetArgc() == NARG_CNT::THREE && !NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function)) { + UniError(EINVAL).ThrowErr(env, "Invalid callback"); + 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)) { + UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + 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..8aca34ce1315691044ee8e86d9605a104a8c07d1 --- /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..cd98617e67c8889e9a30b6dd43e55f35d457ce0e --- /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..cb5a8c10582c4070e0b0c02215916b1c6ceaee9a --- /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