diff options
author | Aki <please@ignore.pl> | 2022-08-17 22:40:59 +0200 |
---|---|---|
committer | Aki <please@ignore.pl> | 2022-08-17 22:40:59 +0200 |
commit | 5708303f6ae772cf2ca8da30249262c772d3021d (patch) | |
tree | 72e724f754a555bd154c8badc8614fa41ee078d7 | |
parent | e7b0d4dc387f732e9f146fdaef5e531448510366 (diff) | |
download | starshatter-5708303f6ae772cf2ca8da30249262c772d3021d.zip starshatter-5708303f6ae772cf2ca8da30249262c772d3021d.tar.gz starshatter-5708303f6ae772cf2ca8da30249262c772d3021d.tar.bz2 |
Hid Header definition from public archive header
-rw-r--r-- | ArchiveEx/Archive.cpp | 35 | ||||
-rw-r--r-- | ArchiveEx/Archive.h | 14 |
2 files changed, 27 insertions, 22 deletions
diff --git a/ArchiveEx/Archive.cpp b/ArchiveEx/Archive.cpp index e5f2c8f..766949b 100644 --- a/ArchiveEx/Archive.cpp +++ b/ArchiveEx/Archive.cpp @@ -12,6 +12,18 @@ namespace Archive { +struct Header +{ + std::uint32_t version; + std::uint32_t total_entries; + struct { + std::uint32_t total_blocks; + std::uint32_t compressed_size; + std::uint32_t offset; + } directory; +}; + + using UniqueFileHandle = std::unique_ptr<std::FILE, decltype(&std::fclose)>; @@ -57,12 +69,14 @@ CreateEmpty(const char* path) Archive::Archive(const char* p) : path {p}, - header {}, - entries {} + directory_offset {0}, + entries {}, + blocks {} { UniqueFileHandle file {std::fopen(path, "rb"), &std::fclose}; if (!file) throw "could not open archive"; + Header header {}; std::size_t length = std::fread(&header, sizeof(Header), 1, file.get()); if (1 != length) throw "could not read"; @@ -86,6 +100,7 @@ Archive::Archive(const char* p) : header.directory.compressed_size); if (Z_OK != err) throw "could not uncompress directory"; + directory_offset = header.directory.offset; GenerateBlockMap(); } @@ -93,7 +108,7 @@ Archive::Archive(const char* p) : int Archive::Extract(const int index, std::uint8_t*& buffer, const bool null_terminated) const { - if (0 > index && static_cast<int>(header.total_entries) <= index) + if (0 > index && entries.size() <= static_cast<decltype(entries)::size_type>(index)) return -1; // Can be replaced by error-checked access to std::vector holding entries. UniqueFileHandle file {std::fopen(path, "rb"), &std::fclose}; if (!file) @@ -228,11 +243,13 @@ Archive::WriteMeta() blocks.resize(destination_block + total_blocks, UNUSED_BLOCK); for (std::size_t i = destination_block; i < destination_block + total_blocks; ++i) blocks[i] = DIRECTORY_BLOCK; - const std::size_t offset = destination_block * BLOCK_SIZE; + directory_offset = destination_block * BLOCK_SIZE; + Header header {}; + header.version = VERSION; header.total_entries = total_entries; header.directory.total_blocks = total_blocks; // Unused header.directory.compressed_size = compressed_size; - header.directory.offset = offset; + header.directory.offset = directory_offset; UniqueFileHandle archive {std::fopen(path, "rb+"), &std::fclose}; err = std::fseek(archive.get(), 0, SEEK_SET); if (-1 == err) @@ -240,7 +257,7 @@ Archive::WriteMeta() err = std::fwrite(&header, sizeof(Header), 1, archive.get()); if (1 != err) throw "could not write header (write)"; - err = std::fseek(archive.get(), sizeof(Header) + offset, SEEK_SET); + err = std::fseek(archive.get(), sizeof(Header) + directory_offset, SEEK_SET); if (-1 == err) throw "could not write directory (seek)"; err = std::fwrite(compressed.get(), 1, compressed_size, archive.get()); @@ -252,7 +269,7 @@ Archive::WriteMeta() void Archive::GenerateBlockMap() { - const std::size_t last_directory_block = header.directory.offset / BLOCK_SIZE + DirectoryBlocks() - 1; + const std::size_t last_directory_block = directory_offset / BLOCK_SIZE + DirectoryBlocks() - 1; std::size_t last_block = last_directory_block; for (const auto& entry : entries) { const std::size_t block = entry.offset / BLOCK_SIZE + BytesToBlocks(entry.compressed_size) - 1; @@ -261,7 +278,7 @@ Archive::GenerateBlockMap() } blocks.clear(); blocks.resize(last_block + 1, UNUSED_BLOCK); - for (std::size_t n = header.directory.offset / BLOCK_SIZE; n <= last_directory_block; ++n) + for (std::size_t n = directory_offset / BLOCK_SIZE; n <= last_directory_block; ++n) blocks[n] = DIRECTORY_BLOCK; for (std::size_t i = 0; i < entries.size(); ++i) { const std::size_t from = entries[i].offset / BLOCK_SIZE; @@ -322,7 +339,7 @@ Archive::PrintBlocks() const std::size_t Archive::DirectoryBlocks() const { - const std::size_t blocks = BytesToBlocks(header.total_entries * sizeof(Entry)); + const std::size_t blocks = BytesToBlocks(entries.size() * sizeof(Entry)); return blocks == 0 ? 1 : blocks; } diff --git a/ArchiveEx/Archive.h b/ArchiveEx/Archive.h index 64b73d5..2bef8fe 100644 --- a/ArchiveEx/Archive.h +++ b/ArchiveEx/Archive.h @@ -12,18 +12,6 @@ namespace Archive static constexpr std::size_t NAMELEN {64}; -struct Header -{ - std::uint32_t version; - std::uint32_t total_entries; - struct { - std::uint32_t total_blocks; - std::uint32_t compressed_size; - std::uint32_t offset; - } directory; -}; - - struct Entry { char name[NAMELEN]; @@ -49,7 +37,7 @@ public: std::size_t DirectoryBlocks() const; private: const char* path; - Header header; + std::size_t directory_offset; std::vector<Entry> entries; std::vector<int> blocks; }; |