9#ifdef STORM_HAVE_LIBARCHIVE
11 STORM_LOG_THROW(_archive, storm::exceptions::FileIoException,
"Failed to create archive reader.");
14 switch (compression) {
15 case CompressionMode::None:
17 case CompressionMode::Gzip:
18 archive_write_add_filter_gzip(_archive.get());
20 case CompressionMode::Xz:
21 case CompressionMode::Default:
22 archive_write_add_filter_xz(_archive.get());
25 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unsupported compression mode.");
27 checkResult(archive_write_set_format_pax_restricted(_archive.get()));
30 checkResult(archive_write_open_filename(_archive.get(), filename.c_str()));
33ArchiveWriter::ArchiveWriter(std::filesystem::path
const&,
CompressionMode const) {
34 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Writing archives is not supported. Storm is compiled without LibArchive.");
38void ArchiveWriter::addDirectory(std::filesystem::path
const& archivePath) {
39#ifdef STORM_HAVE_LIBARCHIVE
41 archive_entry* entry = archive_entry_new();
42 STORM_LOG_THROW(entry, storm::exceptions::FileIoException,
"Failed to create archive entry.");
45 archive_entry_set_pathname(entry, archivePath.c_str());
46 archive_entry_set_filetype(entry, AE_IFDIR);
47 archive_entry_set_perm(entry, 0777);
50 checkResult(archive_write_header(_archive.get(), entry), entry);
53 archive_entry_free(entry);
55 STORM_LOG_THROW(
false, storm::exceptions::MissingLibraryException,
"Writing archives is not supported. Storm is compiled without LibArchive.");
59void ArchiveWriter::addFile(std::filesystem::path
const& archivePath,
char const* data, std::size_t
const size) {
60 std::size_t startOfChunk = 0;
61 auto getNextChunk = [&]() {
62 auto const chunkSize = std::min<std::size_t>(size - startOfChunk, BufferSize);
63 auto const chunk = std::span<char const>(data + startOfChunk, chunkSize);
64 startOfChunk += chunkSize;
67 addFileFromChunks(archivePath, getNextChunk, size);
71 using BucketType =
decltype(std::declval<storm::storage::BitVector&>().getBucket({}));
72 static_assert(BufferSize %
sizeof(BucketType) == 0,
"Buffer size must be a multiple of sizeof(BucketType).");
73 std::array<BucketType, BufferSize /
sizeof(BucketType)> buffer;
76 uint64_t startOfChunk = 0;
77 auto getNextChunk = [&data, &buffer, &startOfChunk]() -> std::span<const char> {
78 auto const endOfChunk = std::min<uint64_t>(startOfChunk + buffer.size(), data.
bucketCount());
79 auto bufferIt = buffer.begin();
80 for (uint64_t i = startOfChunk; i < endOfChunk; ++i) {
82 bool constexpr NativeLittleEndian = std::endian::native == std::endian::little;
83 *bufferIt = storm::utility::reverseBits<BucketType, NativeLittleEndian>(data.
getBucket(i));
86 std::span<const char> chunk(
reinterpret_cast<const char*
>(buffer.data()), (endOfChunk - startOfChunk) *
sizeof(BucketType));
87 startOfChunk = endOfChunk;
90 uint64_t
const numBytes = data.
bucketCount() *
sizeof(BucketType);
91 addFileFromChunks(archivePath, getNextChunk, numBytes);
94void ArchiveWriter::addTextFile(std::filesystem::path
const& archivePath, std::string
const& data) {
95 addFile(archivePath, data.c_str(), data.size());
98#ifdef STORM_HAVE_LIBARCHIVE
99void ArchiveWriter::checkResult(
auto resultCode, archive_entry* entry)
const {
100 STORM_LOG_THROW(_archive, storm::exceptions::FileIoException,
"Unexpected result: Archive not loaded.");
102 STORM_LOG_WARN_COND(std::cmp_greater_equal(resultCode, ARCHIVE_OK),
"Unexpected result from archive: " << archive_error_string(_archive.get()) <<
".");
103 if (std::cmp_less(resultCode, ARCHIVE_WARN)) {
105 archive_entry_free(entry);
107 STORM_LOG_THROW(
false, storm::exceptions::FileIoException,
"Unexpected result from archive: " << archive_error_string(_archive.get()) <<
".");
111void ArchiveWriter::ArchiveDeleter::operator()(archive* arch)
const noexcept {
ArchiveWriter(std::filesystem::path const &filename, CompressionMode const compression)
Create a new archive and open it as a file on disk.
A bit vector that is internally represented as a vector of 64-bit values.
uint64_t getBucket(uint64_t bucketIndex) const
Gets the bits in the given bucket.
size_t bucketCount() const
Retrieves the number of buckets of the underlying storage.
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)