summaryrefslogtreecommitdiffhomepage
path: root/ArchiveEx/Archive.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ArchiveEx/Archive.cpp')
-rw-r--r--ArchiveEx/Archive.cpp50
1 files changed, 16 insertions, 34 deletions
diff --git a/ArchiveEx/Archive.cpp b/ArchiveEx/Archive.cpp
index 0313eda..808b6fc 100644
--- a/ArchiveEx/Archive.cpp
+++ b/ArchiveEx/Archive.cpp
@@ -38,44 +38,19 @@ 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) :
+Archive::Archive(const char* p, bool create) :
path {p},
directory_offset {0},
entries {},
- blocks {}
+ blocks {DIRECTORY_BLOCK}
{
UniqueFileHandle file {std::fopen(path, "rb"), &std::fclose};
- if (!file)
- throw "could not open archive";
+ if (!file) {
+ if (!create)
+ throw "could not open archive";
+ WriteMeta(true);
+ return;
+ }
Header header {};
std::size_t length = std::fread(&header, sizeof(Header), 1, file.get());
if (1 != length)
@@ -218,7 +193,7 @@ Archive::Insert(const char* filepath)
void
-Archive::WriteMeta()
+Archive::WriteMeta(bool create)
{
const std::size_t total_entries = entries.size();
const std::size_t dirsize = total_entries + DIRECTORY_MARGIN;
@@ -251,6 +226,13 @@ Archive::WriteMeta()
header.directory.compressed_size = compressed_size;
header.directory.offset = directory_offset;
UniqueFileHandle archive {std::fopen(path, "rb+"), &std::fclose};
+ if (!archive) {
+ if (!create)
+ throw "could not open archive file";
+ archive.reset(std::fopen(path, "wb"));
+ if (!archive)
+ throw "could not create archive file";
+ }
err = std::fseek(archive.get(), 0, SEEK_SET);
if (-1 == err)
throw "could not write header (seek)";