diff --git a/openVulkanoCpp/IO/Archive/ArchiveConfiguration.hpp b/openVulkanoCpp/IO/Archive/ArchiveConfiguration.hpp index 38215d7..fdb43fb 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveConfiguration.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveConfiguration.hpp @@ -32,8 +32,6 @@ namespace OpenVulkano [[nodiscard]] int GetLibArchiveArchiveType() const; [[nodiscard]] int GetLibArchiveCompressionType() const; - - [[nodiscard]] constexpr bool AllowsUnknownFileSize() const { return type == ArchiveType::ZIP; } }; namespace ArchiveConfig diff --git a/openVulkanoCpp/IO/Archive/ArchiveType.hpp b/openVulkanoCpp/IO/Archive/ArchiveType.hpp index fc7a9e2..739ba1f 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveType.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveType.hpp @@ -33,6 +33,7 @@ namespace OpenVulkano [[nodiscard]] constexpr bool operator!=(ArchiveType rhs) const { return m_type != rhs.m_type; } [[nodiscard]] constexpr explicit operator int() const { return m_type; } + [[nodiscard]] constexpr operator Type() const { return m_type; } [[nodiscard]] static constexpr std::optional FromExtension(std::string_view fName) { diff --git a/openVulkanoCpp/IO/Archive/ArchiveWriter.cpp b/openVulkanoCpp/IO/Archive/ArchiveWriter.cpp index af3dcf2..b9299d5 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveWriter.cpp +++ b/openVulkanoCpp/IO/Archive/ArchiveWriter.cpp @@ -7,6 +7,7 @@ #include "ArchiveWriter.hpp" #include "LibArchiveHelper.hpp" #include "ArchiveStreamBufferWriter.hpp" +#include "SimpleFileTypeShouldCompressChecker.hpp" #include #include #include @@ -16,6 +17,7 @@ namespace OpenVulkano ArchiveWriter::ArchiveWriter(const char* fileName, ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger) : ArchiveBase(archive_write_new(), archive_entry_new(), logger) , m_archiveConfig(archiveConfiguration) + , m_shouldCompress(&SimpleFileTypeShouldCompressChecker) { //TODO error handling ChkErr(archive_write_set_format(m_archive, archiveConfiguration.GetLibArchiveArchiveType())); if (archiveConfiguration.type == ArchiveType::TAR) @@ -87,6 +89,11 @@ namespace OpenVulkano void ArchiveWriter::WriteHeader(const FileDescription& fileDescription) { if (m_asBuffer) { m_asBuffer->Close(); m_asBuffer = nullptr; } + if (m_archiveConfig.type.AllowsMixedCompressionLevels()) + { + if (m_shouldCompress(fileDescription)) SetCompressed(); + else SetUncompressed(); + } archive_entry_clear(m_archiveEntry); archive_entry_set_pathname_utf8(m_archiveEntry, fileDescription.path.c_str()); if (fileDescription.size != FileDescription::UNKNOWN_SIZE) @@ -95,7 +102,7 @@ namespace OpenVulkano } else { - if (!m_archiveConfig.AllowsUnknownFileSize()) + if (!m_archiveConfig.type.AllowsUnknownFileSize()) throw std::invalid_argument("Only ZIP files allow files of unknown size"); archive_entry_unset_size(m_archiveEntry); } @@ -106,4 +113,26 @@ namespace OpenVulkano ChkErr(archive_write_header(m_archive, m_archiveEntry)); m_bytesWritten += fileDescription.size; } + + void ArchiveWriter::SetUncompressed() + { + if (!m_lastCompressed) return; + m_lastCompressed = false; + switch (m_archiveConfig.type) + { + case ArchiveType::ZIP: ChkErr(archive_write_zip_set_compression_store(m_archive)); + default: ; + } + } + + void ArchiveWriter::SetCompressed() + { + if (m_lastCompressed) return; + m_lastCompressed = true; + switch (m_archiveConfig.type) + { + case ArchiveType::ZIP: ChkErr(archive_write_zip_set_compression_deflate(m_archive)); + default: ; + } + } } diff --git a/openVulkanoCpp/IO/Archive/ArchiveWriter.hpp b/openVulkanoCpp/IO/Archive/ArchiveWriter.hpp index cb18d31..f1540bc 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveWriter.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveWriter.hpp @@ -22,6 +22,8 @@ namespace OpenVulkano ArchiveConfiguration m_archiveConfig; size_t m_bytesWritten = 0; ArchiveOStream::ASBufferPtr m_asBuffer = nullptr; + bool m_lastCompressed = true; + std::function m_shouldCompress; public: ArchiveWriter(const char* fileName, const std::shared_ptr& logger = nullptr) @@ -39,7 +41,13 @@ namespace OpenVulkano bool AddFile(const char* fileName, const char* inArchiveName) override; [[nodiscard]] ArchiveOStream AddFileStream(const FileDescription& description) override; + void SetShouldCompressFunction(const std::function& shouldComp) override { m_shouldCompress = shouldComp; } + private: void WriteHeader(const FileDescription& fileDescription); + + void SetUncompressed(); + + void SetCompressed(); }; } \ No newline at end of file diff --git a/openVulkanoCpp/IO/Archive/IArchiveWriter.hpp b/openVulkanoCpp/IO/Archive/IArchiveWriter.hpp index a96b6d6..7c6a775 100644 --- a/openVulkanoCpp/IO/Archive/IArchiveWriter.hpp +++ b/openVulkanoCpp/IO/Archive/IArchiveWriter.hpp @@ -8,6 +8,7 @@ #include "ArchiveOStream.hpp" #include "IO/FileDescription.hpp" +#include #include namespace OpenVulkano @@ -20,6 +21,8 @@ namespace OpenVulkano public: virtual ~IArchiveWriter() = default; + virtual void SetShouldCompressFunction(const std::function& shouldComp) = 0; + virtual bool AddFile(const FileDescription& description, const void* buffer) = 0; virtual bool AddFile(const FileDescription& description, const std::vector>& buffers) = 0; virtual bool AddFile(const char* fileName, const char* inArchiveName) = 0; diff --git a/openVulkanoCpp/IO/Archive/MultiPartArchiveWriter.cpp b/openVulkanoCpp/IO/Archive/MultiPartArchiveWriter.cpp index a08b0ac..5049c97 100644 --- a/openVulkanoCpp/IO/Archive/MultiPartArchiveWriter.cpp +++ b/openVulkanoCpp/IO/Archive/MultiPartArchiveWriter.cpp @@ -41,6 +41,7 @@ namespace OpenVulkano #else m_writer = std::make_unique(m_archives.back().c_str(), m_archiveConfig, m_logger); #endif + if (m_shouldCompress) m_writer->SetShouldCompressFunction(m_shouldCompress); } void MultiPartArchiveWriter::CheckSize(size_t size) @@ -114,4 +115,10 @@ namespace OpenVulkano if (!m_writer || !m_writer->GetTotalWrittenBytes()) return; // Nothing has been written yet, no need to split file m_writer = nullptr; } + + void MultiPartArchiveWriter::SetShouldCompressFunction(const std::function& shouldComp) + { + if (m_writer) m_writer->SetShouldCompressFunction(shouldComp); + m_shouldCompress = shouldComp; + } } diff --git a/openVulkanoCpp/IO/Archive/MultiPartArchiveWriter.hpp b/openVulkanoCpp/IO/Archive/MultiPartArchiveWriter.hpp index 3e08ad6..823ade1 100644 --- a/openVulkanoCpp/IO/Archive/MultiPartArchiveWriter.hpp +++ b/openVulkanoCpp/IO/Archive/MultiPartArchiveWriter.hpp @@ -22,6 +22,7 @@ namespace OpenVulkano std::unique_ptr m_writer; std::shared_ptr m_logger; std::vector m_archives; + std::function m_shouldCompress; bool m_lazyCreation; void StartNewFile(); @@ -39,6 +40,8 @@ namespace OpenVulkano using IArchiveWriter::AddFile; [[nodiscard]] virtual ArchiveOStream AddFileStream(const FileDescription& description) override; + void SetShouldCompressFunction(const std::function& shouldComp) override; + void SetLogger(const std::shared_ptr& logger) { m_logger = logger; } [[nodiscard]] std::shared_ptr GetLogger() const { return m_logger; } diff --git a/openVulkanoCpp/IO/Archive/SimpleFileTypeShouldCompressChecker.cpp b/openVulkanoCpp/IO/Archive/SimpleFileTypeShouldCompressChecker.cpp new file mode 100644 index 0000000..8e8e605 --- /dev/null +++ b/openVulkanoCpp/IO/Archive/SimpleFileTypeShouldCompressChecker.cpp @@ -0,0 +1,32 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "SimpleFileTypeShouldCompressChecker.hpp" +#include "Base/Utils.hpp" +#include + +namespace OpenVulkano +{ + namespace + { + const std::set INCOMPRESSIBLE_TYPES = { + // Image formats + "jpg", "jpeg", "png", + // Video formats + "mp4", + // Audio formats + "mp3", "aac", "ac3", + // Other + }; + } + + bool SimpleFileTypeShouldCompressChecker(const FileDescription& fileDescription) + { + auto [fName, fType] = Utils::SplitAtLastOccurrence(fileDescription.path, '.'); + std::transform(fType.begin(), fType.end(), fType.begin(), ::tolower); // fType to lowercase + return !INCOMPRESSIBLE_TYPES.count(fType); + } +} \ No newline at end of file diff --git a/openVulkanoCpp/IO/Archive/SimpleFileTypeShouldCompressChecker.hpp b/openVulkanoCpp/IO/Archive/SimpleFileTypeShouldCompressChecker.hpp new file mode 100644 index 0000000..e45ea88 --- /dev/null +++ b/openVulkanoCpp/IO/Archive/SimpleFileTypeShouldCompressChecker.hpp @@ -0,0 +1,14 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "IO/FileDescription.hpp" + +namespace OpenVulkano +{ + bool SimpleFileTypeShouldCompressChecker(const FileDescription& fileDescription); +}