From e4bb06e7a22d766e7c0c689a9fa392346f5a3daa Mon Sep 17 00:00:00 2001 From: Aki Date: Sat, 20 Aug 2022 22:41:02 +0200 Subject: Merged on-demand Archive creation to constructor --- ArchiveEx/Archive.cpp | 50 ++++++++++++++++---------------------------------- ArchiveEx/Archive.h | 7 ++----- 2 files changed, 18 insertions(+), 39 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 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(compressed_size); - int err = compress( - compressed.get(), - &compressed_size, - reinterpret_cast(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(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)"; diff --git a/ArchiveEx/Archive.h b/ArchiveEx/Archive.h index 189cdbe..7ba32e4 100644 --- a/ArchiveEx/Archive.h +++ b/ArchiveEx/Archive.h @@ -24,12 +24,12 @@ struct Entry class Archive { public: - explicit Archive(const char* path); + explicit Archive(const char* path, bool create=false); int Extract(int index, std::uint8_t*& buffer, bool null_terminated=false) const; int Extract(const char* filepath, std::uint8_t*& buffer, bool null_terminated=false) const; int Find(const char* filepath) const; int Insert(const char* filepath); - void WriteMeta(); + void WriteMeta(bool create=false); void GenerateBlockMap(); std::size_t FindFreeSpot(std::size_t bytes) const; void PrintNamesOfEntries() const; @@ -43,7 +43,4 @@ private: }; -Archive CreateEmpty(const char* path); - - } // namespace ArchiveEx -- cgit v1.1