From 3dec474bd62d3080836def2d8aa8d772b7b7fd83 Mon Sep 17 00:00:00 2001 From: linjun9528 Date: Fri, 2 Sep 2022 12:33:54 +0800 Subject: [PATCH 1/2] add iterator code Signed-off-by: linjun9528 --- .../include/file_access_ext_ability.h | 6 +- .../include/file_access_ext_proxy.h | 6 +- .../include/file_access_ext_stub_impl.h | 5 +- .../include/file_access_extension_info.h | 6 + .../file_access/include/file_access_helper.h | 5 +- .../include/ifile_access_ext_base.h | 6 +- .../include/js_file_access_ext_ability.h | 5 +- .../src/file_access_ext_ability.cpp | 5 +- .../file_access/src/file_access_ext_proxy.cpp | 86 ++++--- .../file_access/src/file_access_ext_stub.cpp | 52 +++-- .../src/file_access_ext_stub_impl.cpp | 9 +- .../file_access/src/file_access_helper.cpp | 18 +- .../src/js_file_access_ext_ability.cpp | 83 ++++--- .../kits/napi/file_access_module/BUILD.gn | 8 +- .../file_info/file_info_entity.h | 30 +++ .../file_info/file_iterator_entity.h | 40 ++++ .../file_info/napi_file_info_exporter.cpp | 217 ++++++++++++++++++ .../file_info/napi_file_info_exporter.h | 50 ++++ .../file_info/napi_file_iterator_exporter.cpp | 161 +++++++++++++ .../file_info/napi_file_iterator_exporter.h | 44 ++++ .../napi_fileaccess_helper.cpp | 84 +++---- .../napi_fileaccess_helper.h | 3 +- .../file_access_module/napi_notify_callback.h | 4 +- .../native_fileaccess_module.cpp | 27 ++- .../root_info/napi_root_info_exporter.cpp | 202 ++++++++++++++++ .../root_info/napi_root_info_exporter.h | 48 ++++ .../root_info/napi_root_iterator_exporter.cpp | 123 ++++++++++ .../root_info/napi_root_iterator_exporter.h | 41 ++++ .../root_info/root_info_entity.h | 30 +++ .../root_info/root_iterator_entity.h | 35 +++ .../FileExtensionAbility.ts | 15 +- utils/hilog_wrapper.h | 12 +- 32 files changed, 1274 insertions(+), 192 deletions(-) create mode 100644 interfaces/kits/napi/file_access_module/file_info/file_info_entity.h create mode 100644 interfaces/kits/napi/file_access_module/file_info/file_iterator_entity.h create mode 100644 interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.cpp create mode 100644 interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.h create mode 100644 interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp create mode 100644 interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.h create mode 100644 interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.cpp create mode 100644 interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.h create mode 100644 interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.cpp create mode 100644 interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.h create mode 100644 interfaces/kits/napi/file_access_module/root_info/root_info_entity.h create mode 100644 interfaces/kits/napi/file_access_module/root_info/root_iterator_entity.h diff --git a/frameworks/innerkits/file_access/include/file_access_ext_ability.h b/frameworks/innerkits/file_access/include/file_access_ext_ability.h index 7b9f1425..b5ccc8ee 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_ability.h @@ -46,9 +46,9 @@ public: virtual int Delete(const Uri &sourceFile); virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile); virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile); - - virtual int ListFile(const Uri &sourceFile, std::vector &fileInfo); - virtual int GetRoots(std::vector &rootInfo); + virtual int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec); + virtual int GetRoots(std::vector &rootInfoVec); virtual int Access(const Uri &uri, bool &isExist); virtual int RegisterNotify(sptr ¬ify); virtual int UnregisterNotify(sptr ¬ify); diff --git a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h index 41db3052..c543d8cf 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h @@ -42,9 +42,9 @@ public: virtual int Delete(const Uri &sourceFile) override; virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; - - virtual int ListFile(const Uri &sourceFile, std::vector &fileInfo) override; - virtual int GetRoots(std::vector &rootInfo) override; + virtual int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) override; + virtual int GetRoots(std::vector &rootInfoVec) override; virtual int Access(const Uri &uri, bool &isExist) override; virtual int RegisterNotify(sptr ¬ify) override; virtual int UnregisterNotify(sptr ¬ify) override; diff --git a/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h index 56d0c34d..e7daae40 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h @@ -40,8 +40,9 @@ public: int Delete(const Uri &sourceFile) override; int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; - int ListFile(const Uri &sourceFileUri, std::vector &fileInfo) override; - int GetRoots(std::vector &rootInfo) override; + int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) override; + int GetRoots(std::vector &rootInfoVec) override; int Access(const Uri &uri, bool &isExist) override; int RegisterNotify(sptr ¬ify) override; int UnregisterNotify(sptr ¬ify) override; diff --git a/frameworks/innerkits/file_access/include/file_access_extension_info.h b/frameworks/innerkits/file_access/include/file_access_extension_info.h index 7254fd48..0c4f6fbc 100644 --- a/frameworks/innerkits/file_access/include/file_access_extension_info.h +++ b/frameworks/innerkits/file_access/include/file_access_extension_info.h @@ -58,6 +58,12 @@ public: int64_t mtime {0}; std::string mimeType; + FileInfo() = default; + FileInfo(std::string uriIn, std::string fileNameIn, int32_t modeIn, std::string mimeTypeIn) + : uri(uriIn), fileName(fileNameIn), mode(modeIn), mimeType(mimeTypeIn) + { + } + bool ReadFromParcel(Parcel &parcel) { uri = parcel.ReadString(); diff --git a/frameworks/innerkits/file_access/include/file_access_helper.h b/frameworks/innerkits/file_access/include/file_access_helper.h index bf3da630..07139b03 100644 --- a/frameworks/innerkits/file_access/include/file_access_helper.h +++ b/frameworks/innerkits/file_access/include/file_access_helper.h @@ -65,8 +65,9 @@ public: int Delete(Uri &selectFile); int Move(Uri &sourceFile, Uri &targetParent, Uri &newFile); int Rename(Uri &sourceFile, const std::string &displayName, Uri &newFile); - int ListFile(Uri &sourceFile, std::vector &fileInfo); - int GetRoots(std::vector &rootInfo); + int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec); + int GetRoots(std::vector &rootInfoVec); int On(std::shared_ptr &callback); int Off(); private: diff --git a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h index f0b73772..465e94c4 100644 --- a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h +++ b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h @@ -52,9 +52,9 @@ public: virtual int Delete(const Uri &sourceFile) = 0; virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) = 0; virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) = 0; - - virtual int ListFile(const Uri &sourceFile, std::vector &fileInfo) = 0; - virtual int GetRoots(std::vector &rootInfo) = 0; + virtual int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) = 0; + virtual int GetRoots(std::vector &rootInfoVec) = 0; virtual int Access(const Uri &uri, bool &isExist) = 0; virtual int RegisterNotify(sptr ¬ify) = 0; virtual int UnregisterNotify(sptr ¬ify) = 0; diff --git a/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h b/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h index 486fc9a5..eab8e9b1 100644 --- a/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h @@ -66,8 +66,9 @@ public: int Delete(const Uri &sourceFile) override; int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; - int ListFile(const Uri &sourceFile, std::vector &fileInfo) override; - int GetRoots(std::vector &rootInfo) override; + int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) override; + int GetRoots(std::vector &rootInfoVec) override; int Access(const Uri &uri, bool &isExist) override; private: diff --git a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp index 63fd6541..a50988f8 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp @@ -97,13 +97,14 @@ int FileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &displ return ERR_OPERATION_NOT_SUPPORT; } -int FileAccessExtAbility::ListFile(const Uri &sourceFile, std::vector &fileInfo) +int FileAccessExtAbility::ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) { HILOG_ERROR("FileAccessExtAbility::ListFile Undefined operation"); return ERR_OPERATION_NOT_SUPPORT; } -int FileAccessExtAbility::GetRoots(std::vector &rootInfo) +int FileAccessExtAbility::GetRoots(std::vector &rootInfoVec) { HILOG_ERROR("FileAccessExtAbility::GetRoots Undefined operation"); return ERR_OPERATION_NOT_SUPPORT; diff --git a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp index 70f821c4..c5f70613 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp @@ -361,7 +361,40 @@ int FileAccessExtProxy::Rename(const Uri &sourceFile, const std::string &display return ERR_OK; } -int FileAccessExtProxy::ListFile(const Uri &sourceFile, std::vector &fileInfo) +int GetListFileResult(MessageParcel &reply, std::vector &fileInfoVec) +{ + int ret = ERR_PARCEL_FAIL; + if (!reply.ReadInt32(ret)) { + HILOG_ERROR("fail to ReadInt32 ret"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_PARCEL_FAIL; + } + + if (ret != ERR_OK) { + HILOG_ERROR("ListFile operation failed ret : %{public}d", ret); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; + } + + int64_t count = 0; + if (!reply.ReadInt64(count)) { + HILOG_ERROR("ListFile operation failed to Read count"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_INVALID_RESULT; + } + + fileInfoVec.clear(); + for (int64_t i = 0; i < count; i++) { + std::unique_ptr fileInfoPtr(reply.ReadParcelable()); + if (fileInfoPtr != nullptr) { + fileInfoVec.push_back(*fileInfoPtr); + } + } + return ERR_OK; +} + +int FileAccessExtProxy::ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile"); MessageParcel data; @@ -371,53 +404,38 @@ int FileAccessExtProxy::ListFile(const Uri &sourceFile, std::vector &f return ERR_PARCEL_FAIL; } - if (!data.WriteParcelable(&sourceFile)) { - HILOG_ERROR("fail to WriteParcelable sourceFileUri"); + if (!data.WriteParcelable(&fileInfo)) { + HILOG_ERROR("fail to WriteParcelable fileInfo"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } - MessageParcel reply; - MessageOption option; - int32_t err = Remote()->SendRequest(CMD_LIST_FILE, data, reply, option); - if (err != ERR_OK) { - HILOG_ERROR("fail to SendRequest. err: %{public}d", err); - FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return err; - } - - int ret = ERR_PARCEL_FAIL; - if (!reply.ReadInt32(ret)) { - HILOG_ERROR("fail to ReadInt32 ret"); + if (!data.WriteInt64(offset)) { + HILOG_ERROR("fail to WriteInt64 offset"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } - if (ret != ERR_OK) { - HILOG_ERROR("ListFile operation failed ret : %{public}d", ret); + if (!data.WriteInt64(maxCount)) { + HILOG_ERROR("fail to WriteInt64 maxCount"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return ret; + return ERR_PARCEL_FAIL; } - fileInfo.clear(); - uint64_t count = 0; - if (!reply.ReadUint64(count)) { - HILOG_ERROR("ListFile operation failed count : %{public}llu", count); + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest(CMD_LIST_FILE, data, reply, option); + if (err != ERR_OK) { + HILOG_ERROR("fail to SendRequest. err: %{public}d", err); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return ERR_INVALID_RESULT; + return err; } - for (uint64_t i = 0; i < count; i++) { - std::unique_ptr fileInfoPtr(reply.ReadParcelable()); - if (fileInfoPtr != nullptr) { - fileInfo.push_back(*fileInfoPtr); - } - } FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return ERR_OK; + return GetListFileResult(reply, fileInfoVec); } -int FileAccessExtProxy::GetRoots(std::vector &rootInfo) +int FileAccessExtProxy::GetRoots(std::vector &rootInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); MessageParcel data; @@ -449,18 +467,18 @@ int FileAccessExtProxy::GetRoots(std::vector &rootInfo) return ret; } - rootInfo.clear(); uint64_t count = 0; if (!reply.ReadUint64(count)) { - HILOG_ERROR("ListFile operation failed count : %{public}llu", count); + HILOG_ERROR("GetRoots operation failed to Read count"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_INVALID_RESULT; } + rootInfoVec.clear(); for (uint64_t i = 0; i < count; i++) { std::unique_ptr rootInfoPtr(reply.ReadParcelable()); if (rootInfoPtr != nullptr) { - rootInfo.push_back(*rootInfoPtr); + rootInfoVec.push_back(*rootInfoPtr); } } diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp index dddb7186..117f5659 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp @@ -308,31 +308,45 @@ ErrCode FileAccessExtStub::CmdRename(MessageParcel &data, MessageParcel &reply) ErrCode FileAccessExtStub::CmdListFile(MessageParcel &data, MessageParcel &reply) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CmdListFile"); - std::shared_ptr uri(data.ReadParcelable()); - if (uri == nullptr) { - HILOG_ERROR("Parameter ListFile fail to ReadParcelable sourceFile"); + std::shared_ptr fileInfo(data.ReadParcelable()); + if (fileInfo == nullptr) { + HILOG_ERROR("Parameter ListFile fail to ReadParcelable fileInfo"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_PARCEL_FAIL; + } + + int64_t offset = 0; + if (!data.ReadInt64(offset)) { + HILOG_ERROR("parameter ListFile offset is invalid"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_PARCEL_FAIL; + } + + int64_t maxCount = 0; + if (!data.ReadInt64()) { + HILOG_ERROR("parameter ListFile maxCount is invalid"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } - std::vector fileInfo; - int ret = ListFile(*uri, fileInfo); + std::vector vecFileInfo; + int ret = ListFile(*fileInfo, offset, maxCount, vecFileInfo); if (!reply.WriteInt32(ret)) { HILOG_ERROR("Parameter ListFile fail to WriteInt32 ret"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } - uint64_t count = fileInfo.size(); - if (!reply.WriteUint64(count)) { - HILOG_ERROR("Parameter ListFile fail to WriteUint64 count"); + int64_t count {vecFileInfo.size()}; + if (!reply.WriteInt64(count)) { + HILOG_ERROR("Parameter ListFile fail to WriteInt64 count"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } - for (uint64_t i = 0; i < count; i++) { - if (!reply.WriteParcelable(&fileInfo[i])) { - HILOG_ERROR("Parameter ListFile fail to WriteParcelable fileInfo"); + for (const auto &fileInfo : vecFileInfo) { + if (!reply.WriteParcelable(&fileInfo)) { + HILOG_ERROR("parameter ListFile fail to WriteParcelable vecFileInfo"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } @@ -346,24 +360,24 @@ ErrCode FileAccessExtStub::CmdGetRoots(MessageParcel &data, MessageParcel &reply { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CmdGetRoots"); - std::vector rootInfo; - int ret = GetRoots(rootInfo); + std::vector rootInfoVec; + int ret = GetRoots(rootInfoVec); if (!reply.WriteInt32(ret)) { HILOG_ERROR("Parameter GetRoots fail to WriteInt32 ret"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } - uint64_t count = rootInfo.size(); - if (!reply.WriteUint64(count)) { - HILOG_ERROR("Parameter GetRoots fail to WriteUint64 count"); + int64_t count {rootInfoVec.size()}; + if (!reply.WriteInt64(count)) { + HILOG_ERROR("Parameter GetRoots fail to WriteInt64 count"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } - for (uint64_t i = 0; i < count; i++) { - if (!reply.WriteParcelable(&rootInfo[i])) { - HILOG_ERROR("Parameter GetRoots fail to WriteParcelable deviceInfo"); + for (const auto &rootInfo : rootInfoVec) { + if (!reply.WriteParcelable(&rootInfo)) { + HILOG_ERROR("parameter ListFile fail to WriteParcelable rootInfo"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; } diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp index 16d8593e..201f66e5 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp @@ -110,7 +110,8 @@ int FileAccessExtStubImpl::Rename(const Uri &sourceFile, const std::string &disp return ret; } -int FileAccessExtStubImpl::ListFile(const Uri &sourceFile, std::vector &fileInfo) +int FileAccessExtStubImpl::ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile"); if (extension_ == nullptr) { @@ -119,12 +120,12 @@ int FileAccessExtStubImpl::ListFile(const Uri &sourceFile, std::vector return ERR_IPC_ERROR; } - int ret = extension_->ListFile(sourceFile, fileInfo); + int ret = extension_->ListFile(fileInfo, offset, maxCount, fileInfoVec); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ret; } -int FileAccessExtStubImpl::GetRoots(std::vector &rootInfo) +int FileAccessExtStubImpl::GetRoots(std::vector &rootInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); if (extension_ == nullptr) { @@ -133,7 +134,7 @@ int FileAccessExtStubImpl::GetRoots(std::vector &rootInfo) return ERR_IPC_ERROR; } - int ret = extension_->GetRoots(rootInfo); + int ret = extension_->GetRoots(rootInfoVec); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ret; } diff --git a/frameworks/innerkits/file_access/src/file_access_helper.cpp b/frameworks/innerkits/file_access/src/file_access_helper.cpp index 1cd50fd5..55c4cdc2 100644 --- a/frameworks/innerkits/file_access/src/file_access_helper.cpp +++ b/frameworks/innerkits/file_access/src/file_access_helper.cpp @@ -546,9 +546,11 @@ int FileAccessHelper::Rename(Uri &sourceFile, const std::string &displayName, Ur return ret; } -int FileAccessHelper::ListFile(Uri &sourceFile, std::vector &fileInfo) +int FileAccessHelper::ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile"); + Uri sourceFile(fileInfo.uri); if (!CheckUri(sourceFile)) { HILOG_ERROR("sourceFile format check error."); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); @@ -562,12 +564,18 @@ int FileAccessHelper::ListFile(Uri &sourceFile, std::vector &fileInfo) return ERR_IPC_ERROR; } - int ret = fileExtProxy->ListFile(sourceFile, fileInfo); + int ret = fileExtProxy->ListFile(fileInfo, offset, maxCount, fileInfoVec); + if (ret != ERR_OK) { + HILOG_ERROR("ListFile get result error, code:%{public}d", ret); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; + } + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); - return ret; + return ERR_OK; } -int FileAccessHelper::GetRoots(std::vector &rootInfo) +int FileAccessHelper::GetRoots(std::vector &rootInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); if (!GetProxy()) { @@ -589,7 +597,7 @@ int FileAccessHelper::GetRoots(std::vector &rootInfo) HILOG_ERROR("getRoots get fail ret:%{public}d", ret); return ret; } - rootInfo.insert(rootInfo.end(), results.begin(), results.end()); + rootInfoVec.insert(rootInfoVec.end(), results.begin(), results.end()); } return ret; diff --git a/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp b/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp index d8314f69..3dc8fec2 100644 --- a/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp @@ -674,26 +674,21 @@ int JsFileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &dis } -static bool ParserListFileJsResult(NativeEngine &engine, NativeValue *nativeValue, - std::shared_ptr>> &result) +static bool ParserListFileJsResult(NativeEngine &engine, NativeValue *nativeValue, Value> &result) { - if (result == nullptr) { - HILOG_ERROR("result is nullptr."); - return false; - } - NativeObject *obj = ConvertNativeValueTo(nativeValue); if (obj == nullptr) { HILOG_ERROR("Convert js object fail."); return false; } - bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), result->code); + bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), result.code); NativeArray *nativeArray = ConvertNativeValueTo(obj->GetProperty("infos")); if (nativeArray == nullptr) { - HILOG_ERROR("nativeArray is nullptr"); + HILOG_ERROR("Convert js array object fail."); return false; } + for (uint32_t i = 0; i < nativeArray->GetLength(); i++) { NativeValue *nativeFileInfo = nativeArray->GetElement(i); if (nativeFileInfo == nullptr) { @@ -718,12 +713,14 @@ static bool ParserListFileJsResult(NativeEngine &engine, NativeValue *nativeValu HILOG_ERROR("Convert js value fail."); return ret; } - (result->data).emplace_back(std::move(fileInfo)); + + result.data.emplace_back(std::move(fileInfo)); } return true; } -int JsFileAccessExtAbility::ListFile(const Uri &sourceFile, std::vector &fileInfo) +int JsFileAccessExtAbility::ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, + std::vector &fileInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ListFile"); auto value = std::make_shared>>(); @@ -732,32 +729,40 @@ int JsFileAccessExtAbility::ListFile(const Uri &sourceFile, std::vector bool { - NativeValue *uri = engine.CreateString(sourceFile.ToString().c_str(), sourceFile.ToString().length()); + auto argParser = [fileInfo, offset, maxCount](NativeEngine &engine, NativeValue *argv[], size_t &argc) -> bool { + NativeValue *uri = engine.CreateString(fileInfo.uri.c_str(), fileInfo.uri.length()); if (uri == nullptr) { HILOG_ERROR("create sourceFile uri native js value fail."); return false; } + NativeValue *nativeOffset = engine.CreateNumber(offset); + if (nativeOffset == nullptr) { + HILOG_ERROR("create nativeMaxNum native js value fail."); + return false; + } + + NativeValue *nativeMaxCount = engine.CreateNumber(maxCount); + if (nativeMaxCount == nullptr) { + HILOG_ERROR("create nativeMaxNum native js value fail."); + return false; + } + argv[ARGC_ZERO] = uri; - argc = ARGC_ONE; + argv[ARGC_ONE] = nativeOffset; + argv[ARGC_TWO] = nativeMaxCount; + argc = ARGC_THREE; return true; }; auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool { - std::shared_ptr>> fileInfo = std::make_shared>>(); - if (fileInfo == nullptr) { - HILOG_ERROR("new Value fail."); - return false; - } - + Value> fileInfo; bool ret = ParserListFileJsResult(engine, result, fileInfo); if (!ret) { HILOG_ERROR("Parser js value fail."); return ret; } - value->code = fileInfo->code; - value->data = std::move(fileInfo->data); + *value = std::move(fileInfo); return true; }; @@ -772,31 +777,26 @@ int JsFileAccessExtAbility::ListFile(const Uri &sourceFile, std::vectordata; + fileInfoVec = std::move(value->data); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_OK; } -static bool ParserGetRootsJsResult(NativeEngine &engine, NativeValue *nativeValue, - std::shared_ptr>> &result) +static bool ParserGetRootsJsResult(NativeEngine &engine, NativeValue *nativeValue, Value> &result) { - if (result == nullptr) { - HILOG_ERROR("result is nullptr."); - return false; - } - NativeObject *obj = ConvertNativeValueTo(nativeValue); if (obj == nullptr) { HILOG_ERROR("Convert js object fail."); return false; } - bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), result->code); + bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), result.code); NativeArray *nativeArray = ConvertNativeValueTo(obj->GetProperty("roots")); if (nativeArray == nullptr) { HILOG_ERROR("nativeArray is nullptr"); return false; } + for (uint32_t i = 0; i < nativeArray->GetLength(); i++) { NativeValue *nativeRootInfo = nativeArray->GetElement(i); if (nativeRootInfo == nullptr) { @@ -819,12 +819,13 @@ static bool ParserGetRootsJsResult(NativeEngine &engine, NativeValue *nativeValu HILOG_ERROR("Convert js value fail."); return ret; } - (result->data).emplace_back(std::move(rootInfo)); + + result.data.emplace_back(std::move(rootInfo)); } return true; } -int JsFileAccessExtAbility::GetRoots(std::vector &rootInfo) +int JsFileAccessExtAbility::GetRoots(std::vector &rootInfoVec) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "GetRoots"); auto value = std::make_shared>>(); @@ -838,20 +839,15 @@ int JsFileAccessExtAbility::GetRoots(std::vector &rootInfo) return true; }; auto retParser = [value](NativeEngine &engine, NativeValue *result) -> bool { - std::shared_ptr>> rootInfo = std::make_shared>>(); - if (rootInfo == nullptr) { - HILOG_ERROR("new Value fail."); - return false; - } - - bool ret = ParserGetRootsJsResult(engine, result, rootInfo); + Value> rootInfoVec; + bool ret = ParserGetRootsJsResult(engine, result, rootInfoVec); if (!ret) { HILOG_ERROR("Parser js value fail."); return ret; } - value->code = rootInfo->code; - value->data = std::move(rootInfo->data); + value->code = rootInfoVec.code; + value->data = std::move(rootInfoVec.data); return true; }; @@ -865,7 +861,8 @@ int JsFileAccessExtAbility::GetRoots(std::vector &rootInfo) HILOG_ERROR("fileio fail."); return ERR_FILEIO_FAIL; } - rootInfo = value->data; + + rootInfoVec = value->data; FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_OK; } diff --git a/interfaces/kits/napi/file_access_module/BUILD.gn b/interfaces/kits/napi/file_access_module/BUILD.gn index 3e556e12..b0b76b08 100644 --- a/interfaces/kits/napi/file_access_module/BUILD.gn +++ b/interfaces/kits/napi/file_access_module/BUILD.gn @@ -22,16 +22,22 @@ ohos_shared_library("fileaccess") { include_dirs = [ "./", - "${BASE_DIR}/utils", "${BASE_DIR}/interfaces/kits/napi/common", + "${BASE_DIR}/interfaces/kits/napi/file_access_module/file_info", + "${BASE_DIR}/interfaces/kits/napi/file_access_module/root_info", + "${BASE_DIR}/utils", "//foundation/distributeddatamgr/distributedfile/utils/filemgmt_libn/include", ] sources = [ "${BASE_DIR}/interfaces/kits/napi/common/file_extension_info_napi.cpp", + "file_info/napi_file_info_exporter.cpp", + "file_info/napi_file_iterator_exporter.cpp", "napi_fileaccess_helper.cpp", "napi_notify_callback.cpp", "native_fileaccess_module.cpp", + "root_info/napi_root_info_exporter.cpp", + "root_info/napi_root_iterator_exporter.cpp", ] deps = [ diff --git a/interfaces/kits/napi/file_access_module/file_info/file_info_entity.h b/interfaces/kits/napi/file_access_module/file_info/file_info_entity.h new file mode 100644 index 00000000..e668b1f6 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/file_info_entity.h @@ -0,0 +1,30 @@ +/* + * 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 FILE_INFO_ENTITY_H +#define FILE_INFO_ENTITY_H + +#include "file_access_extension_info.h" +#include "file_access_helper.h" + +namespace OHOS { +namespace FileAccessFwk { +struct FileInfoEntity { + FileAccessHelper *fileAccessHelper { nullptr }; + FileInfo fileInfo {}; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_INFO_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/file_iterator_entity.h b/interfaces/kits/napi/file_access_module/file_info/file_iterator_entity.h new file mode 100644 index 00000000..9015dfca --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/file_iterator_entity.h @@ -0,0 +1,40 @@ +/* + * 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 FILE_ITERATOR_ENTITY_H +#define FILE_ITERATOR_ENTITY_H + +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace FileAccessFwk { +constexpr int64_t MAX_COUNT = 1000; // ListFile get file's max count + +struct FileIteratorEntity { + FileAccessHelper *fileAccessHelper { nullptr }; + std::mutex entityOperateMutex; + FileInfo fileInfo {}; + std::vector fileInfoVec {}; + int64_t maxCount { MAX_COUNT }; + int64_t offset { 0 }; + int64_t pos { 0 }; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // FILE_ITERATOR_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.cpp b/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.cpp new file mode 100644 index 00000000..d53691c8 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.cpp @@ -0,0 +1,217 @@ +/* + * 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 "napi_file_info_exporter.h" + +#include "file_access_framework_errno.h" +#include "file_info_entity.h" +#include "file_iterator_entity.h" +#include "hilog_wrapper.h" +#include "napi_file_iterator_exporter.h" + +namespace OHOS { +namespace FileAccessFwk { +bool NapiFileInfoExporter::Export() +{ + std::vector props = { + NVal::DeclareNapiFunction("listFile", ListFile), + NVal::DeclareNapiGetter("uri", GetUri), + NVal::DeclareNapiGetter("fileName", GetFileName), + NVal::DeclareNapiGetter("mode", GetMode), + NVal::DeclareNapiGetter("size", GetSize), + NVal::DeclareNapiGetter("mtime", GetMtime), + NVal::DeclareNapiGetter("mimeType", GetMimeType), + }; + + std::string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + NapiFileInfoExporter::Constructor, std::move(props)); + if (!succ) { + NError(ERR_NULL_POINTER).ThrowErr(exports_.env_, "INNER BUG. Failed to define class NapiFileInfoExporter"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + NError(ERR_NULL_POINTER).ThrowErr(exports_.env_, "INNER BUG. Failed to save class NapiFileInfoExporter"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +napi_value NapiFileInfoExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileInfoEntity = std::make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(fileInfoEntity))) { + NError(ERR_NULL_POINTER).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj FileInfoEntity"); + return nullptr; + } + + return funcArg.GetThisVar(); +} + +napi_value NapiFileInfoExporter::ListFile(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (fileInfoEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of FileInfoEntity"); + return nullptr; + } + + if ((fileInfoEntity->fileInfo.mode & DOCUMENT_FLAG_REPRESENTS_DIR) != DOCUMENT_FLAG_REPRESENTS_DIR) { + HILOG_ERROR("current FileInfo is not dir."); + return NVal::CreateUndefined(env).val_; + } + + if (fileInfoEntity->fileAccessHelper == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "fileAccessHelper is null."); + return nullptr; + } + + auto objFileIteratorExporter = NClass::InstantiateClass(env, NapiFileIteratorExporter::className_, {}); + if (objFileIteratorExporter == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot instantiate class NapiFileIteratorExporter"); + return nullptr; + } + + auto fileIteratorEntity = NClass::GetEntityOf(env, objFileIteratorExporter); + if (fileIteratorEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get the entity of FileIteratorEntity"); + return nullptr; + } + + { + std::lock_guard lock(fileIteratorEntity->entityOperateMutex); + fileIteratorEntity->fileAccessHelper = fileInfoEntity->fileAccessHelper; + fileIteratorEntity->fileInfo = fileInfoEntity->fileInfo; + fileIteratorEntity->fileInfoVec.clear(); + fileIteratorEntity->maxCount = MAX_COUNT; + fileIteratorEntity->offset = 0; + fileIteratorEntity->pos = 0; + auto ret = fileInfoEntity->fileAccessHelper->ListFile(fileInfoEntity->fileInfo, fileIteratorEntity->offset, + fileIteratorEntity->maxCount, fileIteratorEntity->fileInfoVec); + if (ret != ERR_OK) { + NError(ret).ThrowErr(env, "exec ListFile fail"); + return nullptr; + } + } + + return NVal(env, objFileIteratorExporter).val_; +} + +static FileInfoEntity *GetFileInfoEntity(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (fileInfoEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of FileInfoEntity"); + return nullptr; + } + + return fileInfoEntity; +} + +napi_value NapiFileInfoExporter::GetUri(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + + return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.uri).val_; +} + +napi_value NapiFileInfoExporter::GetFileName(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + + return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.fileName).val_; +} + +napi_value NapiFileInfoExporter::GetMode(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + + return NVal::CreateInt32(env, fileInfoEntity->fileInfo.mode).val_; +} + +napi_value NapiFileInfoExporter::GetSize(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + + return NVal::CreateInt64(env, fileInfoEntity->fileInfo.size).val_; +} + +napi_value NapiFileInfoExporter::GetMtime(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + + return NVal::CreateInt64(env, fileInfoEntity->fileInfo.mtime).val_; +} + +napi_value NapiFileInfoExporter::GetMimeType(napi_env env, napi_callback_info info) +{ + auto fileInfoEntity = GetFileInfoEntity(env, info); + if (fileInfoEntity == nullptr) { + HILOG_ERROR("Failed to get entity of FileInfoEntity"); + return NVal::CreateUndefined(env).val_; + } + + return NVal::CreateUTF8String(env, fileInfoEntity->fileInfo.mimeType).val_; +} + +std::string NapiFileInfoExporter::GetClassName() +{ + return NapiFileInfoExporter::className_; +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.h b/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.h new file mode 100644 index 00000000..57264e33 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_info_exporter.h @@ -0,0 +1,50 @@ +/* + * 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 NAPI_FILE_INFO_EXPORTER_H +#define NAPI_FILE_INFO_EXPORTER_H + +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace FileManagement::LibN; + +class NapiFileInfoExporter final : public NExporter { +public: + inline static const std::string className_ = "NapiFileInfoExporter"; + + NapiFileInfoExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}; + ~NapiFileInfoExporter() = default; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value ListFile(napi_env env, napi_callback_info info); + static napi_value GetUri(napi_env env, napi_callback_info info); + static napi_value GetFileName(napi_env env, napi_callback_info info); + static napi_value GetMode(napi_env env, napi_callback_info info); + static napi_value GetSize(napi_env env, napi_callback_info info); + static napi_value GetMtime(napi_env env, napi_callback_info info); + static napi_value GetMimeType(napi_env env, napi_callback_info info); + + bool Export() override; + std::string GetClassName() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_FILE_INFO_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp new file mode 100644 index 00000000..b1a47452 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp @@ -0,0 +1,161 @@ +/* + * 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 "napi_file_iterator_exporter.h" + +#include + +#include "file_info_entity.h" +#include "file_iterator_entity.h" +#include "hilog_wrapper.h" +#include "napi_file_info_exporter.h" + +namespace OHOS { +namespace FileAccessFwk { +bool NapiFileIteratorExporter::Export() +{ + std::vector props = { + NVal::DeclareNapiFunction("next", Next), + }; + + std::string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + NapiFileIteratorExporter::Constructor, std::move(props)); + if (!succ) { + NError(ERR_NULL_POINTER).ThrowErr(exports_.env_, "INNER BUG. Failed to define class NapiFileIteratorExporter"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + NError(ERR_NULL_POINTER).ThrowErr(exports_.env_, "INNER BUG. Failed to save class NapiFileIteratorExporter"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +napi_value NapiFileIteratorExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileIteratorEntity = std::make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(fileIteratorEntity))) { + NError(ERR_NULL_POINTER).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj FileIteratorEntity"); + return nullptr; + } + + return funcArg.GetThisVar(); +} + +static int MakeResult(napi_value objFileInfoExporter, FileIteratorEntity *fileIteratorEntity, + FileInfoEntity *fileInfoEntity, napi_env env, NVal &nVal) +{ + std::lock_guard lock(fileIteratorEntity->entityOperateMutex); + bool done = true; + if (fileIteratorEntity->fileInfoVec.size() == 0) { + nVal.AddProp("value", NVal::CreateUndefined(env).val_); + nVal.AddProp("done", NVal::CreateBool(env, done).val_); + return ERR_OK; + } + + if (fileIteratorEntity->pos == fileIteratorEntity->fileInfoVec.size()) { + HILOG_ERROR("pos out of index."); + return ERR_INVALID_RESULT; + } + + fileInfoEntity->fileAccessHelper = fileIteratorEntity->fileAccessHelper; + fileInfoEntity->fileInfo = fileIteratorEntity->fileInfoVec[fileIteratorEntity->pos]; + fileIteratorEntity->pos++; + if (fileIteratorEntity->pos == fileIteratorEntity->maxCount) { + fileIteratorEntity->fileInfoVec.clear(); + fileIteratorEntity->offset += fileIteratorEntity->maxCount; + fileIteratorEntity->pos = 0; + int ret = fileIteratorEntity->fileAccessHelper->ListFile(fileIteratorEntity->fileInfo, + fileIteratorEntity->offset, fileIteratorEntity->maxCount, fileIteratorEntity->fileInfoVec); + if (ret != ERR_OK) { + HILOG_ERROR("exec ListFile fail, code:%{public}d", ret); + return ret; + } + } else if (fileIteratorEntity->pos == fileIteratorEntity->fileInfoVec.size()) { + fileIteratorEntity->fileInfoVec.clear(); + fileIteratorEntity->pos = 0; + fileIteratorEntity->offset = 0; + } + + done = (fileIteratorEntity->pos == fileIteratorEntity->fileInfoVec.size()); + nVal.AddProp("value", objFileInfoExporter); + nVal.AddProp("done", NVal::CreateBool(env, done).val_); + return ERR_OK; +} + +napi_value NapiFileIteratorExporter::Next(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto fileIteratorEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (fileIteratorEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of FileIteratorEntity"); + return nullptr; + } + + if ((fileIteratorEntity->fileInfo.mode & DOCUMENT_FLAG_REPRESENTS_DIR) != DOCUMENT_FLAG_REPRESENTS_DIR) { + HILOG_ERROR("current FileInfo is not dir."); + return NVal::CreateUndefined(env).val_; + } + + auto objFileInfoExporter = NClass::InstantiateClass(env, NapiFileInfoExporter::className_, {}); + if (objFileInfoExporter == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot instantiate class NapiFileInfoExporter"); + return nullptr; + } + + auto fileInfoEntity = NClass::GetEntityOf(env, objFileInfoExporter); + if (fileInfoEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get the entity of FileInfoEntity"); + return nullptr; + } + + if (fileIteratorEntity->fileAccessHelper == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "fileAccessHelper is null."); + return nullptr; + } + + auto retNVal = NVal::CreateObject(env); + int ret = MakeResult(objFileInfoExporter, fileIteratorEntity, fileInfoEntity, env, retNVal); + if (ret != ERR_OK) { + NError(ret).ThrowErr(env, "MakeResult fail."); + return nullptr; + } + + return retNVal.val_; +} + +std::string NapiFileIteratorExporter::GetClassName() +{ + return NapiFileIteratorExporter::className_; +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.h b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.h new file mode 100644 index 00000000..e1b51314 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.h @@ -0,0 +1,44 @@ +/* + * 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 NAPI_FILE_ITERATOR_EXPORTER_H +#define NAPI_FILE_ITERATOR_EXPORTER_H + +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace FileManagement::LibN; + +class NapiFileIteratorExporter final : public NExporter { +public: + inline static const std::string className_ = "NapiFileIteratorExporter"; + + NapiFileIteratorExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}; + ~NapiFileIteratorExporter() = default; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value Next(napi_env env, napi_callback_info info); + + bool Export() override; + std::string GetClassName() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_FILE_ITERATOR_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp index 15a28d2c..9fcb6410 100644 --- a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp +++ b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp @@ -20,14 +20,17 @@ #include "file_access_framework_errno.h" #include "file_access_helper.h" +#include "file_info_entity.h" #include "filemgmt_libn.h" #include "hilog_wrapper.h" #include "ifile_access_notify.h" #include "napi_base_context.h" #include "napi_common_fileaccess.h" #include "napi_error.h" +#include "napi_file_info_exporter.h" #include "napi_notify_callback.h" -#include "n_val.h" +#include "napi_root_iterator_exporter.h" +#include "root_iterator_entity.h" #include "securec.h" #include "uri.h" @@ -206,7 +209,6 @@ napi_value FileAccessHelperInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("delete", NAPI_Delete), DECLARE_NAPI_FUNCTION("move", NAPI_Move), DECLARE_NAPI_FUNCTION("rename", NAPI_Rename), - DECLARE_NAPI_FUNCTION("listFile", NAPI_ListFile), DECLARE_NAPI_FUNCTION("getRoots", NAPI_GetRoots), DECLARE_NAPI_FUNCTION("access", NAPI_Access), DECLARE_NAPI_FUNCTION("on", NAPI_On), @@ -587,56 +589,6 @@ napi_value NAPI_Rename(napi_env env, napi_callback_info info) return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; } -napi_value NAPI_ListFile(napi_env env, napi_callback_info info) -{ - NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { - NapiError(ERR_PARAM_NUMBER).ThrowErr(env); - return nullptr; - } - - bool succ = false; - std::unique_ptr uri; - std::tie(succ, uri, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); - if (!succ) { - NapiError(ERR_INVALID_PARAM).ThrowErr(env); - return nullptr; - } - - FileAccessHelper *fileAccessHelper = GetFileAccessHelper(env, funcArg.GetThisVar()); - if (fileAccessHelper == nullptr) { - return nullptr; - } - - auto result = std::make_shared>(); - string uriString(uri.get()); - auto cbExec = [uriString, result, fileAccessHelper]() -> NError { - OHOS::Uri uri(uriString); - int ret = fileAccessHelper->ListFile(uri, *result); - return NError(ret); - }; - auto cbComplete = [result](napi_env env, NError err) -> NVal { - if (err) { - return { env, err.GetNapiErr(env) }; - } - napi_value jsArray = WrapArrayFileInfoToJS(env, *result); - return {env, jsArray}; - }; - - const std::string procedureName = "listFile"; - NVal thisVar(env, funcArg.GetThisVar()); - if (funcArg.GetArgc() == NARG_CNT::ONE) { - return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; - } - - NVal cb(env, funcArg[NARG_POS::SECOND]); - if (!cb.TypeIs(napi_function)) { - NapiError(ERR_INVALID_PARAM).ThrowErr(env); - return nullptr; - } - return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; -} - napi_value NAPI_GetRoots(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -647,6 +599,7 @@ napi_value NAPI_GetRoots(napi_env env, napi_callback_info info) FileAccessHelper *fileAccessHelper = GetFileAccessHelper(env, funcArg.GetThisVar()); if (fileAccessHelper == nullptr) { + NapiError(ERR_NULL_POINTER).ThrowErr(env); return nullptr; } @@ -655,17 +608,36 @@ napi_value NAPI_GetRoots(napi_env env, napi_callback_info info) int ret = fileAccessHelper->GetRoots(*result); return NError(ret); }; - auto cbComplete = [result](napi_env env, NError err) -> NVal { + auto cbComplete = [fileAccessHelper, result](napi_env env, NError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } - napi_value jsArray = WrapArrayRootInfoToJS(env, *result); - return {env, jsArray}; + + auto objRootIterator = NClass::InstantiateClass(env, NapiRootIteratorExporter::className_, {}); + if (objRootIterator == nullptr) { + return { env, NError([]() -> std::tuple { + return { ERR_NULL_POINTER, "Cannot instantiate class NapiRootIteratorExporter" }; + }).GetNapiErr(env) }; + } + + auto rootIteratorEntity = NClass::GetEntityOf(env, objRootIterator); + if (rootIteratorEntity == nullptr) { + return { env, NError([]() -> std::tuple { + return { ERR_NULL_POINTER, "Cannot get the entity of RootIteratorEntity" }; + }).GetNapiErr(env) }; + } + + { + std::lock_guard lock(rootIteratorEntity->entityOperateMutex); + rootIteratorEntity->fileAccessHelper = fileAccessHelper; + rootIteratorEntity->devVec = std::move(*result); + rootIteratorEntity->pos = 0; + } + return { env, objRootIterator }; }; const std::string procedureName = "getRoots"; NVal thisVar(env, funcArg.GetThisVar()); - if (funcArg.GetArgc() == NARG_CNT::ZERO) { return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; } diff --git a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h index d0a4dbff..8c4f0fb6 100644 --- a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h +++ b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h @@ -30,11 +30,10 @@ namespace FileAccessFwk { napi_value NAPI_Delete(napi_env env, napi_callback_info info); napi_value NAPI_Move(napi_env env, napi_callback_info info); napi_value NAPI_Rename(napi_env env, napi_callback_info info); - napi_value NAPI_ListFile(napi_env env, napi_callback_info info); napi_value NAPI_GetRoots(napi_env env, napi_callback_info info); napi_value NAPI_Access(napi_env env, napi_callback_info info); napi_value NAPI_On(napi_env env, napi_callback_info info); napi_value NAPI_Off(napi_env env, napi_callback_info info); -} } // namespace FileAccessFwk +} // namespace OHOS #endif // NAPI_FILEACCESS_HELPER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/napi_notify_callback.h b/interfaces/kits/napi/file_access_module/napi_notify_callback.h index 5dec5b4f..2f89b006 100644 --- a/interfaces/kits/napi/file_access_module/napi_notify_callback.h +++ b/interfaces/kits/napi/file_access_module/napi_notify_callback.h @@ -44,6 +44,6 @@ private: napi_env env_; uv_loop_s *loop_ = nullptr; }; -} // FileAccessFwk -} // OHOS +} // namespace FileAccessFwk +} // namespace OHOS #endif // NAPI_NOTIFY_CALLBACK_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp b/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp index e094d85c..8ccb330d 100644 --- a/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp +++ b/interfaces/kits/napi/file_access_module/native_fileaccess_module.cpp @@ -13,14 +13,22 @@ * limitations under the License. */ +#include +#include + +#include "filemgmt_libn.h" #include "file_extension_info_napi.h" #include "hilog_wrapper.h" #include "napi_fileaccess_helper.h" -#include "napi/native_api.h" -#include "napi/native_node_api.h" +#include "napi_file_info_exporter.h" +#include "napi_file_iterator_exporter.h" +#include "napi_root_info_exporter.h" +#include "napi_root_iterator_exporter.h" namespace OHOS { namespace FileAccessFwk { +using namespace FileManagement::LibN; + EXTERN_C_START /* * The module initialization. @@ -34,6 +42,21 @@ static napi_value Init(napi_env env, napi_value exports) InitDeviceType(env, exports); InitFileInfo(env, exports); InitRootInfo(env, exports); + + std::vector> products; + products.emplace_back(std::make_unique(env, exports)); + products.emplace_back(std::make_unique(env, exports)); + products.emplace_back(std::make_unique(env, exports)); + products.emplace_back(std::make_unique(env, exports)); + for (auto &&product : products) { + if (!product->Export()) { + HILOG_ERROR("INNER BUG. Failed to export class %{public}s", product->GetClassName().c_str()); + return nullptr; + } else { + HILOG_ERROR("Class %{public}s has been exported", product->GetClassName().c_str()); + } + } + return exports; } EXTERN_C_END diff --git a/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.cpp b/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.cpp new file mode 100644 index 00000000..16571e5c --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.cpp @@ -0,0 +1,202 @@ +/* + * 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 NAPI_FILEACCESS_HELPER_H +#define NAPI_FILEACCESS_HELPER_H + +#include "napi_root_info_exporter.h" + +#include "file_access_framework_errno.h" +#include "file_iterator_entity.h" +#include "hilog_wrapper.h" +#include "napi_file_iterator_exporter.h" +#include "root_info_entity.h" + +namespace OHOS { +namespace FileAccessFwk { +bool NapiRootInfoExporter::Export() +{ + std::vector props = { + NVal::DeclareNapiFunction("listFile", ListFile), + NVal::DeclareNapiGetter("deviceType", GetDeviceType), + NVal::DeclareNapiGetter("uri", GetUri), + NVal::DeclareNapiGetter("displayName", GetDisplayName), + NVal::DeclareNapiGetter("deviceFlags", GetDeviceFlags) + }; + + std::string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + NapiRootInfoExporter::Constructor, std::move(props)); + if (!succ) { + NError(ERR_NULL_POINTER).ThrowErr(exports_.env_, "INNER BUG. Failed to define class NapiRootInfoExporter"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + NError(ERR_NULL_POINTER).ThrowErr(exports_.env_, "INNER BUG. Failed to save class NapiRootInfoExporter"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +napi_value NapiRootInfoExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = std::make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(rootInfoEntity))) { + NError(ERR_NULL_POINTER).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj RootInfoEntity"); + return nullptr; + } + + return funcArg.GetThisVar(); +} + +napi_value NapiRootInfoExporter::ListFile(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of FileInfoEntity"); + return nullptr; + } + + if (rootEntity->fileAccessHelper == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "fileAccessHelper is null."); + return nullptr; + } + + napi_value objFileIteratorExporter = NClass::InstantiateClass(env, NapiFileIteratorExporter::className_, {}); + if (objFileIteratorExporter == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot instantiate class NapiFileIteratorExporter"); + return nullptr; + } + + auto fileIteratorEntity = NClass::GetEntityOf(env, objFileIteratorExporter); + if (fileIteratorEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get the entity of FileIteratorEntity"); + return nullptr; + } + + FileInfo fileInfo; + fileInfo.uri = rootEntity->rootInfo.uri; + fileInfo.mode = DOCUMENT_FLAG_REPRESENTS_DIR | DOCUMENT_FLAG_SUPPORTS_READ | DOCUMENT_FLAG_SUPPORTS_WRITE; + { + std::lock_guard lock(fileIteratorEntity->entityOperateMutex); + fileIteratorEntity->fileAccessHelper = rootEntity->fileAccessHelper; + fileIteratorEntity->fileInfo = fileInfo; + fileIteratorEntity->fileInfoVec.clear(); + fileIteratorEntity->maxCount = MAX_COUNT; + fileIteratorEntity->offset = 0; + fileIteratorEntity->pos = 0; + auto ret = rootEntity->fileAccessHelper->ListFile(fileInfo, fileIteratorEntity->offset, + fileIteratorEntity->maxCount, fileIteratorEntity->fileInfoVec); + if (ret != ERR_OK) { + NError(ret).ThrowErr(env, "ListFile get result fail."); + return nullptr; + } + } + + return NVal(env, objFileIteratorExporter).val_; +} + +napi_value NapiRootInfoExporter::GetDeviceType(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateInt64(env, (int64_t)(rootInfoEntity->rootInfo.deviceType)).val_; +} + +napi_value NapiRootInfoExporter::GetUri(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateUTF8String(env, rootInfoEntity->rootInfo.uri).val_; +} + +napi_value NapiRootInfoExporter::GetDisplayName(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateUTF8String(env, rootInfoEntity->rootInfo.displayName).val_; +} + +napi_value NapiRootInfoExporter::GetDeviceFlags(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootInfoEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (rootInfoEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of RootInfoEntity"); + return nullptr; + } + + return NVal::CreateInt64(env, rootInfoEntity->rootInfo.deviceFlags).val_; +} + +std::string NapiRootInfoExporter::GetClassName() +{ + return NapiRootInfoExporter::className_; +} +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_FILEACCESS_HELPER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.h b/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.h new file mode 100644 index 00000000..720a7c40 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/napi_root_info_exporter.h @@ -0,0 +1,48 @@ +/* + * 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 NAPI_ROOT_INFO_EXPORTER_H +#define NAPI_ROOT_INFO_EXPORTER_H + +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace FileManagement::LibN; + +class NapiRootInfoExporter final : public NExporter { +public: + inline static const std::string className_ = "NapiRootInfoExporter"; + + NapiRootInfoExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}; + ~NapiRootInfoExporter() = default; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value ListFile(napi_env env, napi_callback_info info); + static napi_value GetDeviceType(napi_env env, napi_callback_info info); + static napi_value GetUri(napi_env env, napi_callback_info info); + static napi_value GetDisplayName(napi_env env, napi_callback_info info); + static napi_value GetDeviceFlags(napi_env env, napi_callback_info info); + + bool Export() override; + std::string GetClassName() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_ROOT_INFO_EXPORTER_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.cpp b/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.cpp new file mode 100644 index 00000000..fe90f865 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.cpp @@ -0,0 +1,123 @@ +/* + * 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 "napi_root_iterator_exporter.h" + +#include "hilog_wrapper.h" +#include "napi_root_info_exporter.h" +#include "root_info_entity.h" +#include "root_iterator_entity.h" + +namespace OHOS { +namespace FileAccessFwk { +bool NapiRootIteratorExporter::Export() +{ + std::vector props = { + NVal::DeclareNapiFunction("next", Next), + }; + + std::string className = GetClassName(); + bool succ = false; + napi_value classValue = nullptr; + std::tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, + NapiRootIteratorExporter::Constructor, std::move(props)); + if (!succ) { + NError(ERR_NULL_POINTER).ThrowErr(exports_.env_, + "INNER BUG. Failed to define class NapiRootIteratorExporter"); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + NError(ERR_NULL_POINTER).ThrowErr(exports_.env_, "INNER BUG. Failed to save class NapiRootIteratorExporter"); + return false; + } + + return exports_.AddProp(className, classValue); +} + +napi_value NapiRootIteratorExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + auto rootIteratorEntity = std::make_unique(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(rootIteratorEntity))) { + NError(ERR_NULL_POINTER).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj FileIteratorEntity"); + return nullptr; + } + + return funcArg.GetThisVar(); +} + +napi_value NapiRootIteratorExporter::Next(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + NError(ERR_PARAM_NUMBER).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + napi_value thisVar = funcArg.GetThisVar(); + auto iterEntity = NClass::GetEntityOf(env, thisVar); + if (iterEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get entity of RootIteratorEntity"); + return nullptr; + } + + napi_value objRootExporter = NClass::InstantiateClass(env, NapiRootInfoExporter::className_, {}); + if (objRootExporter == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot instantiate class NapiRootInfoExporter"); + return nullptr; + } + + auto rootEntity = NClass::GetEntityOf(env, objRootExporter); + if (rootEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "Cannot get the entity of RootInfoEntity"); + return nullptr; + } + + auto retNVal = NVal::CreateObject(env); + bool done = true; + { + std::lock_guard lock(iterEntity->entityOperateMutex); + auto len = (int64_t)iterEntity->devVec.size(); + rootEntity->fileAccessHelper = iterEntity->fileAccessHelper; + if (iterEntity->pos < len) { + rootEntity->rootInfo = iterEntity->devVec[iterEntity->pos]; + iterEntity->pos++; + done = (iterEntity->pos == len); + } else { + iterEntity->pos++; + rootEntity = nullptr; + objRootExporter = NVal::CreateUndefined(env).val_; + done = true; + } + retNVal.AddProp("value", objRootExporter); + retNVal.AddProp("done", NVal::CreateBool(env, done).val_); + } + + return retNVal.val_; +} + +std::string NapiRootIteratorExporter::GetClassName() +{ + return NapiRootIteratorExporter::className_; +} +} // namespace FileAccessFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.h b/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.h new file mode 100644 index 00000000..9902d7d1 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/napi_root_iterator_exporter.h @@ -0,0 +1,41 @@ +/* + * 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 NAPI_ROOT_ITERATOR_H +#define NAPI_ROOT_ITERATOR_H + +#include + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileAccessFwk { +using namespace FileManagement::LibN; +class NapiRootIteratorExporter final : public NExporter { +public: + inline static const std::string className_ = "NapiRootIteratorExporter"; + + NapiRootIteratorExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}; + ~NapiRootIteratorExporter() = default; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value Next(napi_env env, napi_callback_info info); + + bool Export() override; + std::string GetClassName() override; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // NAPI_ROOT_ITERATOR_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/root_info_entity.h b/interfaces/kits/napi/file_access_module/root_info/root_info_entity.h new file mode 100644 index 00000000..bfeef115 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/root_info_entity.h @@ -0,0 +1,30 @@ +/* + * 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 ROOT_INFO_ENTITY_H +#define ROOT_INFO_ENTITY_H + +#include "file_access_extension_info.h" +#include "file_access_helper.h" + +namespace OHOS { +namespace FileAccessFwk { +struct RootInfoEntity { + FileAccessHelper *fileAccessHelper { nullptr }; + RootInfo rootInfo {}; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // ROOT_INFO_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/napi/file_access_module/root_info/root_iterator_entity.h b/interfaces/kits/napi/file_access_module/root_info/root_iterator_entity.h new file mode 100644 index 00000000..8e746cf9 --- /dev/null +++ b/interfaces/kits/napi/file_access_module/root_info/root_iterator_entity.h @@ -0,0 +1,35 @@ +/* + * 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 ROOT_ITERATOR_ENTITY_H +#define ROOT_ITERATOR_ENTITY_H + +#include +#include + +#include "file_access_extension_info.h" +#include "file_access_helper.h" + +namespace OHOS { +namespace FileAccessFwk { +struct RootIteratorEntity { + FileAccessHelper *fileAccessHelper { nullptr }; + std::vector devVec {}; + std::mutex entityOperateMutex; + int64_t pos { 0 }; +}; +} // namespace FileAccessFwk +} // namespace OHOS +#endif // ROOT_ITERATOR_ENTITY_H \ No newline at end of file diff --git a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts index c4ee729b..5e5f732d 100644 --- a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts +++ b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts @@ -446,7 +446,7 @@ export default class FileExtAbility extends Extension { }; } - listFile(sourceFileUri) { + listFile(sourceFileUri, offset, count) { if (!this.checkUri(sourceFileUri)) { return { infos: [], @@ -458,6 +458,7 @@ export default class FileExtAbility extends Extension { let path = this.getPath(sourceFileUri); let dir = fileio.opendirSync(path); let hasNextFile = true; + let i = 0; while (hasNextFile) { try { let dirent = dir.readSync(); @@ -468,6 +469,12 @@ export default class FileExtAbility extends Extension { } else { mode |= DocumentFlag.REPRESENTS_FILE; } + + if (offset > i) { + i ++; + continue; + } + infos.push({ uri: this.genNewFileUri(sourceFileUri, dirent.name), fileName: dirent.name, @@ -476,6 +483,12 @@ export default class FileExtAbility extends Extension { mtime: stat.mtime, mimeType: '', }); + + i ++; + if (i == (offset + count)) { + hasNextFile = false; + break; + } } catch (e) { hasNextFile = false; } diff --git a/utils/hilog_wrapper.h b/utils/hilog_wrapper.h index 6df10f62..6425d5cc 100644 --- a/utils/hilog_wrapper.h +++ b/utils/hilog_wrapper.h @@ -53,22 +53,22 @@ #endif static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = {LOG_CORE, FAF_LOG_DOMAIN, FAF_LOG_TAG}; - +#define FAF_FILE_NAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) #define HILOG_FATAL(fmt, ...) \ (void)OHOS::HiviewDFX::HiLog::Fatal( \ - LOG_LABEL, "[(%{public}s:%{public}d)]" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) + LOG_LABEL, "[%{public}s(%{public}s:%{public}d)]" fmt, FAF_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) #define HILOG_ERROR(fmt, ...) \ (void)OHOS::HiviewDFX::HiLog::Error( \ - LOG_LABEL, "[(%{public}s:%{public}d)]" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) + LOG_LABEL, "[%{public}s(%{public}s:%{public}d)]" fmt, FAF_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) #define HILOG_WARN(fmt, ...) \ (void)OHOS::HiviewDFX::HiLog::Warn( \ - LOG_LABEL, "[(%{public}s:%{public}d)]" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) + LOG_LABEL, "[%{public}s(%{public}s:%{public}d)]" fmt, FAF_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) #define HILOG_INFO(fmt, ...) \ (void)OHOS::HiviewDFX::HiLog::Info( \ - LOG_LABEL, "[(%{public}s:%{public}d)]" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) + LOG_LABEL, "[%{public}s(%{public}s:%{public}d)]" fmt, FAF_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) #define HILOG_DEBUG(fmt, ...) \ (void)OHOS::HiviewDFX::HiLog::Debug( \ - LOG_LABEL, "[(%{public}s:%{public}d)]" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) + LOG_LABEL, "[%{public}s(%{public}s:%{public}d)]" fmt, FAF_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) #else #define HILOG_FATAL(...) -- Gitee From 6a6edd61344229b1581f981586fdd097a2b1bd64 Mon Sep 17 00:00:00 2001 From: linjun9528 Date: Fri, 2 Sep 2022 15:47:23 +0800 Subject: [PATCH 2/2] fix bug Signed-off-by: linjun9528 --- .../innerkits/file_access/src/file_access_ext_stub.cpp | 2 +- .../innerkits/file_access/src/file_access_ext_stub_impl.cpp | 6 ++++++ .../file_info/napi_file_iterator_exporter.cpp | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp index 117f5659..e7d58519 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp @@ -323,7 +323,7 @@ ErrCode FileAccessExtStub::CmdListFile(MessageParcel &data, MessageParcel &reply } int64_t maxCount = 0; - if (!data.ReadInt64()) { + if (!data.ReadInt64(maxCount)) { HILOG_ERROR("parameter ListFile maxCount is invalid"); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ERR_PARCEL_FAIL; diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp index 201f66e5..663e9aae 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp @@ -15,6 +15,8 @@ #include "file_access_ext_stub_impl.h" +#include + #include "file_access_framework_errno.h" #include "hilog_wrapper.h" #include "hitrace_meter.h" @@ -120,7 +122,11 @@ int FileAccessExtStubImpl::ListFile(const FileInfo &fileInfo, const int64_t offs return ERR_IPC_ERROR; } + HILOG_INFO("uri:%{public}s, offset:%{public}" PRId64 ", maxCount:%{public}" PRId64, fileInfo.uri.c_str(), offset, maxCount); int ret = extension_->ListFile(fileInfo, offset, maxCount, fileInfoVec); + for (auto info : fileInfoVec) { + HILOG_INFO("--fileInfo.uri:%{public}s, fileInfo.fileName:%{public}s, fileInfo.mode:%{public}d", info.uri.c_str(), info.fileName.c_str(), info.mode); + } FinishTrace(HITRACE_TAG_FILEMANAGEMENT); return ret; } diff --git a/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp index b1a47452..79e8febf 100644 --- a/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp +++ b/interfaces/kits/napi/file_access_module/file_info/napi_file_iterator_exporter.cpp @@ -58,6 +58,11 @@ napi_value NapiFileIteratorExporter::Constructor(napi_env env, napi_callback_inf } auto fileIteratorEntity = std::make_unique(); + if (fileIteratorEntity == nullptr) { + NError(ERR_NULL_POINTER).ThrowErr(env, "New obj FileIteratorEntity fail"); + return nullptr; + } + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(fileIteratorEntity))) { NError(ERR_NULL_POINTER).ThrowErr(env, "INNER BUG. Failed to wrap entity for obj FileIteratorEntity"); return nullptr; -- Gitee