Handle multipart tar archives when reading archive
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ArchiveReader.hpp"
|
#include "ArchiveReader.hpp"
|
||||||
|
#include "ArchiveConfiguration.hpp"
|
||||||
#include "LibArchiveHelper.hpp"
|
#include "LibArchiveHelper.hpp"
|
||||||
#include "Base/Utils.hpp"
|
#include "Base/Utils.hpp"
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
@@ -43,7 +44,12 @@ namespace openVulkanoCpp
|
|||||||
|
|
||||||
void ArchiveReader::PrepOpen()
|
void ArchiveReader::PrepOpen()
|
||||||
{
|
{
|
||||||
if (m_open) ChkErr(archive_read_close(m_archive));
|
if (m_open)
|
||||||
|
{
|
||||||
|
ChkErr(archive_read_close(m_archive));
|
||||||
|
ChkErr(archive_free(m_archive));
|
||||||
|
m_archive = archive_read_new();
|
||||||
|
}
|
||||||
ChkErr(archive_read_support_filter_all(m_archive));
|
ChkErr(archive_read_support_filter_all(m_archive));
|
||||||
ChkErr(archive_read_support_format_all(m_archive));
|
ChkErr(archive_read_support_format_all(m_archive));
|
||||||
m_open = true;
|
m_open = true;
|
||||||
@@ -72,6 +78,20 @@ namespace openVulkanoCpp
|
|||||||
|
|
||||||
bool ArchiveReader::Open(const std::vector<std::string>& archiveFiles)
|
bool ArchiveReader::Open(const std::vector<std::string>& archiveFiles)
|
||||||
{
|
{
|
||||||
|
if (archiveFiles.empty()) return false;
|
||||||
|
ArchiveConfiguration ac = ArchiveConfiguration::FromFileName(archiveFiles.front().c_str());
|
||||||
|
if (ac.type == ArchiveType::TAR) // TODO handle all archive types correctly
|
||||||
|
{ // Queue based approach for all archive types that do not natively support split archives
|
||||||
|
for(const std::string& file : archiveFiles)
|
||||||
|
{
|
||||||
|
m_archivesToRead.push(file);
|
||||||
|
}
|
||||||
|
bool state = Open(m_archivesToRead.front());
|
||||||
|
m_archivesToRead.pop();
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // This might only be used for archive types that support split archives (like zip, rar, 7zip, ...)
|
||||||
auto files = Utils::toCString(archiveFiles);
|
auto files = Utils::toCString(archiveFiles);
|
||||||
files.push_back(nullptr);
|
files.push_back(nullptr);
|
||||||
PrepOpen();
|
PrepOpen();
|
||||||
@@ -79,6 +99,7 @@ namespace openVulkanoCpp
|
|||||||
ReadNextHeader();
|
ReadNextHeader();
|
||||||
return HasNext();
|
return HasNext();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ArchiveReader::Open(const std::filesystem::path& dir, const std::string& fileNamePattern)
|
bool ArchiveReader::Open(const std::filesystem::path& dir, const std::string& fileNamePattern)
|
||||||
{
|
{
|
||||||
@@ -113,7 +134,12 @@ namespace openVulkanoCpp
|
|||||||
if (result == ARCHIVE_EOF)
|
if (result == ARCHIVE_EOF)
|
||||||
{
|
{
|
||||||
m_archiveEntry = nullptr;
|
m_archiveEntry = nullptr;
|
||||||
m_eof = true;
|
if (!m_archivesToRead.empty())
|
||||||
|
{
|
||||||
|
Open(m_archivesToRead.front());
|
||||||
|
m_archivesToRead.pop();
|
||||||
|
}
|
||||||
|
else m_eof = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
namespace openVulkanoCpp
|
namespace openVulkanoCpp
|
||||||
{
|
{
|
||||||
@@ -20,6 +21,8 @@ namespace openVulkanoCpp
|
|||||||
bool m_open = false;
|
bool m_open = false;
|
||||||
bool m_eof = false;
|
bool m_eof = false;
|
||||||
|
|
||||||
|
std::queue<std::string> m_archivesToRead;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ArchiveReader(const std::shared_ptr<spdlog::logger>& logger = nullptr);
|
explicit ArchiveReader(const std::shared_ptr<spdlog::logger>& logger = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace openVulkanoCpp
|
|||||||
if (archiveResult <= ARCHIVE_FATAL) lvl = spdlog::level::level_enum::critical;
|
if (archiveResult <= ARCHIVE_FATAL) lvl = spdlog::level::level_enum::critical;
|
||||||
else if (archiveResult <= ARCHIVE_FAILED) lvl = spdlog::level::level_enum::err;
|
else if (archiveResult <= ARCHIVE_FAILED) lvl = spdlog::level::level_enum::err;
|
||||||
const char* errorString = archive_error_string(arch);
|
const char* errorString = archive_error_string(arch);
|
||||||
if (logger) logger->log(lvl, errorString);
|
if (logger) logger->log(lvl, errorString ? errorString : "Unknown error while handling archive");
|
||||||
if (archiveResult == ARCHIVE_FAILED) throw std::runtime_error(errorString);
|
if (archiveResult == ARCHIVE_FAILED) throw std::runtime_error(errorString);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user