summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ArchiveEx/Archive.cpp29
-rw-r--r--ArchiveEx/Archive.h3
2 files changed, 32 insertions, 0 deletions
diff --git a/ArchiveEx/Archive.cpp b/ArchiveEx/Archive.cpp
index 4275502..e5f2c8f 100644
--- a/ArchiveEx/Archive.cpp
+++ b/ArchiveEx/Archive.cpp
@@ -26,6 +26,35 @@ static constexpr int UNUSED_BLOCK {-1};
static constexpr int DIRECTORY_BLOCK {-2};
+Archive
+CreateEmpty(const char* path)
+{
+ Header header = {VERSION, 0, {0, 0, 0}};
+ std::vector<Entry> entries;
+ entries.reserve(DIRECTORY_MARGIN);
+ const std::size_t uncompressed_size = DIRECTORY_MARGIN * sizeof(Entry);
+ uLongf compressed_size = uncompressed_size * 1.1 + 12;
+ auto compressed = std::make_unique<Bytef[]>(compressed_size);
+ int err = compress(
+ compressed.get(),
+ &compressed_size,
+ reinterpret_cast<Bytef*>(entries.data()),
+ uncompressed_size);
+ if (Z_OK != err)
+ throw "could not compress directory metadata";
+ header.directory.compressed_size = compressed_size;
+ UniqueFileHandle archive {std::fopen(path, "wb"), &std::fclose};
+ err = std::fwrite(&header, sizeof(Header), 1, archive.get());
+ if (1 != err)
+ throw "could not write header (write)";
+ err = std::fwrite(compressed.get(), 1, compressed_size, archive.get());
+ if (static_cast<int>(compressed_size) != err)
+ throw "could not write directory (write)";
+ archive.reset();
+ return Archive(path);
+}
+
+
Archive::Archive(const char* p) :
path {p},
header {},
diff --git a/ArchiveEx/Archive.h b/ArchiveEx/Archive.h
index ed042f6..64b73d5 100644
--- a/ArchiveEx/Archive.h
+++ b/ArchiveEx/Archive.h
@@ -55,4 +55,7 @@ private:
};
+Archive CreateEmpty(const char* path);
+
+
} // namespace Archive