From ba475e6696883a8d7594af42e05aca9a94db08b9 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Sun, 9 Feb 2025 02:13:09 +0100 Subject: [PATCH] Expand archive reader --- openVulkanoCpp/IO/Archive/ArchiveReader.cpp | 53 +++++++++++++-------- openVulkanoCpp/IO/Archive/ArchiveReader.hpp | 16 +++++-- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp index 3240ad0..2eeec6a 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp +++ b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp @@ -66,6 +66,15 @@ namespace OpenVulkano m_open = true; } + bool ArchiveReader::Open(const std::filesystem::path& archiveFile) + { + PrepOpen(); + ChkErr(archive_read_open_filename(m_archive, archiveFile.c_str(), BUFFER_SIZE)); + ReadNextHeader(); + return HasNext(); + } + + bool ArchiveReader::Open(const char* archiveFile) { if (archiveFile[0] == '\0') @@ -176,20 +185,14 @@ namespace OpenVulkano ArchiveType::Type type = *m_archiveType; switch (type) { - case ArchiveType::ZIP: - return archive_read_support_format_zip; - case ArchiveType::SEVEN_ZIP: - return archive_read_support_format_7zip; - case ArchiveType::CPIO: - return archive_read_support_format_cpio; - case ArchiveType::ISO: - return archive_read_support_format_iso9660; - case ArchiveType::TAR: - return archive_read_support_format_tar; - case ArchiveType::WARC: - return archive_read_support_format_warc; - case ArchiveType::XAR: - return archive_read_support_format_xar; + case ArchiveType::SEVEN_ZIP: return archive_read_support_format_7zip; + case ArchiveType::ZIP: return archive_read_support_format_zip; + case ArchiveType::CPIO: return archive_read_support_format_cpio; + case ArchiveType::ISO: return archive_read_support_format_iso9660; + case ArchiveType::TAR: return archive_read_support_format_tar; + case ArchiveType::WARC: return archive_read_support_format_warc; + case ArchiveType::XAR: return archive_read_support_format_xar; + case ArchiveType::SHAR: break; // nothing to do } return archive_read_support_format_all; } @@ -203,6 +206,16 @@ namespace OpenVulkano } return count; } + + size_t ArchiveReader::ExtractRemaining(const std::filesystem::path &targetDir) + { + size_t count = 0; + while (ExtractNext(targetDir)) + { + count++; + } + return count; + } bool ArchiveReader::HasNext() const { @@ -246,19 +259,21 @@ namespace OpenVulkano return std::nullopt; } - std::optional ArchiveReader::ExtractNext(std::string_view targetDir) + std::optional ArchiveReader::ExtractNext(const std::filesystem::path& targetDir) { if (SkipTill(std::filesystem::file_type::regular)) { FileDescription fileDescription = GetNextDescription(); - std::string outputFileName; - outputFileName.reserve(targetDir.size() + 1 + fileDescription.path.size()); - outputFileName.append(targetDir).append("/").append(fileDescription.path); + std::filesystem::path outputFilePath; + if (m_filePathRewrite) + outputFilePath = targetDir / m_filePathRewrite(fileDescription.path); + else + outputFilePath = targetDir / fileDescription.path; std::unique_ptr a(archive_write_disk_new(), archive_write_free); std::unique_ptr entry(archive_entry_clone(m_archiveEntry), archive_entry_free); - archive_entry_set_pathname(entry.get(), outputFileName.c_str()); + archive_entry_set_pathname(entry.get(), outputFilePath.c_str()); ChkErr(archive_write_disk_set_options(a.get(), ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS)); diff --git a/openVulkanoCpp/IO/Archive/ArchiveReader.hpp b/openVulkanoCpp/IO/Archive/ArchiveReader.hpp index 09e1eaf..c66abb2 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveReader.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveReader.hpp @@ -12,7 +12,6 @@ #include #include #include -#include #include namespace OpenVulkano @@ -22,6 +21,7 @@ namespace OpenVulkano std::optional m_archiveType; std::queue m_archivesToRead; std::function m_passwordCallback; + std::function m_filePathRewrite; bool m_open = false; bool m_eof = false; @@ -38,6 +38,8 @@ namespace OpenVulkano void SetPasswordCallback(const decltype(m_passwordCallback)& callback); + bool Open(const std::filesystem::path& archiveFile); + bool Open(const char* archiveFile); bool Open(const std::string& archiveFile); @@ -50,7 +52,9 @@ namespace OpenVulkano [[nodiscard]] bool IsOpen() const { return m_open; } - size_t ExtractRemaining(std::string_view targetDir); + [[deprecated]] size_t ExtractRemaining(std::string_view targetDir); + + size_t ExtractRemaining(const std::filesystem::path& targetDir); // Element wise operations [[nodiscard]] bool HasNext() const; @@ -63,7 +67,9 @@ namespace OpenVulkano std::optional GetNextDirectory(); - std::optional ExtractNext(std::string_view targetDir); + [[deprecated]] std::optional ExtractNext(std::string_view targetDir) { return ExtractNext(std::filesystem::path(targetDir)); } + + std::optional ExtractNext(const std::filesystem::path& targetDir); std::optional>> GetNextFile(); @@ -76,6 +82,10 @@ namespace OpenVulkano bool GetNextFileAsStream(const std::function& streamReader); const decltype(m_passwordCallback)& GetPasswordCallback() const { return m_passwordCallback; } + + void SetPathRewriteFunction(const decltype(m_filePathRewrite)& rewriteFunc) { m_filePathRewrite = rewriteFunc; } + + const decltype(m_filePathRewrite)& GetPathRewriteFunction() const { return m_filePathRewrite; } private: void ReadNextHeader();