diff --git a/openVulkanoCpp/IO/Archive/ArchiveWriter.cpp b/openVulkanoCpp/IO/Archive/ArchiveWriter.cpp index 7f083b8..9d6bc4c 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveWriter.cpp +++ b/openVulkanoCpp/IO/Archive/ArchiveWriter.cpp @@ -15,47 +15,75 @@ namespace OpenVulkano { - ArchiveWriter::ArchiveWriter(const char* fileName, ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger, const char* password) + ArchiveWriter::ArchiveWriter(ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger, const char* password) : ArchiveBase(archive_write_new(), archive_entry_new(), logger) , m_archiveConfig(archiveConfiguration) , m_shouldCompress(&SimpleFileTypeShouldCompressChecker) - { //TODO error handling + { //TODO better error handling ChkErr(archive_write_set_format(m_archive, archiveConfiguration.GetLibArchiveArchiveType())); if (archiveConfiguration.type == ArchiveType::TAR) { ChkErr(archive_write_add_filter(m_archive, archiveConfiguration.GetLibArchiveCompressionType())); } if (archiveConfiguration.compression != CompressionType::NONE && - archiveConfiguration.compressionLevel > 0) + archiveConfiguration.compressionLevel > 0) { std::string level = "compression-level=" + std::to_string(archiveConfiguration.compressionLevel); ChkErr(archive_write_set_options(m_archive, level.c_str())); } if (password) ChkErr(archive_write_set_passphrase(m_archive, password)); + } + + ArchiveWriter::ArchiveWriter(const char* fileName, ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger, const char* password) + : ArchiveWriter(archiveConfiguration, logger, password) + { ChkErr(archive_write_open_filename(m_archive, fileName)); } ArchiveWriter::ArchiveWriter(const std::filesystem::path& fileName, ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger, const char* password) - : 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) - { - ChkErr(archive_write_add_filter(m_archive, archiveConfiguration.GetLibArchiveCompressionType())); - } - if (archiveConfiguration.compression != CompressionType::NONE && - archiveConfiguration.compressionLevel > 0) - { - std::string level = "compression-level=" + std::to_string(archiveConfiguration.compressionLevel); - ChkErr(archive_write_set_options(m_archive, level.c_str())); - } - if (password) ChkErr(archive_write_set_passphrase(m_archive, password)); + : ArchiveWriter(archiveConfiguration, logger, password) + { +#pragma clang diagnostic push +#pragma ide diagnostic ignored "UnreachableCode" if constexpr (std::is_same_v) ChkErr(archive_write_open_filename(m_archive, (const char*)fileName.c_str())); else ChkErr(archive_write_open_filename_w(m_archive, (const wchar_t*)fileName.c_str())); +#pragma clang diagnostic pop + } + + namespace + { + static int LibArchiveFileOpen(struct archive* a, void* clientData) + { + (void)clientData; /* UNUSED */ + archive_write_set_bytes_in_last_block(a, 1); + return (ARCHIVE_OK); + } + + static ssize_t LibArchiveFileWrite(struct archive* a, void* clientData, const void* buff, size_t length) + { + FILE* file = (FILE*)clientData; + size_t bytesWritten; + + while (true) + { + bytesWritten = fwrite(buff, 1, length, file); + if (bytesWritten <= 0) + { + if (errno == EINTR) continue; + archive_set_error(a, errno, "Write error"); + return (-1); + } + return (bytesWritten); + } + } + } + + ArchiveWriter::ArchiveWriter(FILE* file, ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger, const char* password) + : ArchiveWriter(archiveConfiguration, logger, password) + { + ChkErr(archive_write_open2(m_archive, file, LibArchiveFileOpen, LibArchiveFileWrite, NULL, NULL)); } ArchiveWriter::~ArchiveWriter() diff --git a/openVulkanoCpp/IO/Archive/ArchiveWriter.hpp b/openVulkanoCpp/IO/Archive/ArchiveWriter.hpp index a327ac8..7b201c4 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveWriter.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveWriter.hpp @@ -26,6 +26,8 @@ namespace OpenVulkano bool m_lastCompressed = true; std::function m_shouldCompress; + ArchiveWriter(ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger, const char* password); + public: ArchiveWriter(const char* fileName, const std::shared_ptr& logger = nullptr, const char* password = nullptr) : ArchiveWriter(fileName, ArchiveConfiguration::FromFileName(fileName), logger, password) @@ -38,6 +40,8 @@ namespace OpenVulkano {} ArchiveWriter(const std::filesystem::path& fileName, ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger = nullptr, const char* password = nullptr); + + ArchiveWriter(FILE* file, ArchiveConfiguration archiveConfiguration, const std::shared_ptr& logger = nullptr, const char* password = nullptr); ~ArchiveWriter() override;