Add support for streaming archive writing and unknown filesizes in zip files

This commit is contained in:
2023-11-14 23:42:23 +01:00
parent 6356075227
commit 966db4b452
13 changed files with 154 additions and 12 deletions

View File

@@ -6,18 +6,16 @@
#include "ArchiveWriter.hpp"
#include "LibArchiveHelper.hpp"
#include "ArchiveStreamBufferWriter.hpp"
#include <archive.h>
#include <archive_entry.h>
#include <iostream>
namespace OpenVulkano
{
ArchiveWriter::ArchiveWriter(const char* fileName, const std::shared_ptr<spdlog::logger>& logger)
: ArchiveWriter(fileName, ArchiveConfiguration::FromFileName(fileName), logger)
{}
ArchiveWriter::ArchiveWriter(const char* fileName, ArchiveConfiguration archiveConfiguration, const std::shared_ptr<spdlog::logger>& logger)
: ArchiveBase(archive_write_new(), archive_entry_new(), logger)
, m_archiveConfig(archiveConfiguration)
{ //TODO error handling
ChkErr(archive_write_set_format(m_archive, archiveConfiguration.GetLibArchiveArchiveType()));
if (archiveConfiguration.type == ArchiveType::TAR)
@@ -35,6 +33,7 @@ namespace OpenVulkano
ArchiveWriter::~ArchiveWriter()
{
if (m_asBuffer) { m_asBuffer->Close(); m_asBuffer = nullptr; }
archive_write_close(m_archive);
archive_entry_free(m_archiveEntry);
}
@@ -48,7 +47,7 @@ namespace OpenVulkano
//archive_read_disk_entry_from_file(archiveDisk, m_archiveEntry, -1, nullptr);
archive_entry_set_pathname(m_archiveEntry, inArchiveName);
ChkErr(archive_write_header(m_archive, m_archiveEntry));
int result = LibArchiveHelper::CopyArchiveData(archiveDisk.get(), m_archive);
long result = LibArchiveHelper::CopyArchiveData(archiveDisk.get(), m_archive);
ChkErr(result);
LibArchiveHelper::CheckError(result, archiveDisk.get(), m_logger);
ChkErr(archive_write_finish_entry(m_archive));
@@ -79,11 +78,27 @@ namespace OpenVulkano
return true;
}
ArchiveOStream ArchiveWriter::AddFileStream(const FileDescription& description)
{
WriteHeader(description);
return ArchiveOStream(m_asBuffer = std::make_shared<ArchiveStreamBufferWriter>(this, description.size));
}
void ArchiveWriter::WriteHeader(const FileDescription& fileDescription)
{
if (m_asBuffer) { m_asBuffer->Close(); m_asBuffer = nullptr; }
archive_entry_clear(m_archiveEntry);
archive_entry_set_pathname_utf8(m_archiveEntry, fileDescription.path.c_str());
archive_entry_set_size(m_archiveEntry, fileDescription.size);
if (fileDescription.size != FileDescription::UNKNOWN_SIZE)
{
archive_entry_set_size(m_archiveEntry, fileDescription.size);
}
else
{
if (!m_archiveConfig.AllowsUnknownFileSize())
throw std::invalid_argument("Only ZIP files allow files of unknown size");
archive_entry_unset_size(m_archiveEntry);
}
archive_entry_set_filetype(m_archiveEntry, LibArchiveHelper::GetFileType(fileDescription.type));
archive_entry_set_perm(m_archiveEntry, static_cast<mode_t>(fileDescription.permissions));
archive_entry_set_ctime(m_archiveEntry, fileDescription.createTime, 0);