diff options
Diffstat (limited to 'ArchiveEx/Archive.cpp')
-rw-r--r-- | ArchiveEx/Archive.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/ArchiveEx/Archive.cpp b/ArchiveEx/Archive.cpp index 134404c..8ca7b71 100644 --- a/ArchiveEx/Archive.cpp +++ b/ArchiveEx/Archive.cpp @@ -23,6 +23,8 @@ static inline std::size_t ConvertPathSeparator(const char* src, char* dest); static constexpr std::uint32_t VERSION {0x0010}; static constexpr std::size_t BLOCK_SIZE {1024}; static constexpr std::size_t DIRECTORY_MARGIN {64}; +static constexpr int UNUSED_BLOCK {-1}; +static constexpr int DIRECTORY_BLOCK {-2}; Archive::Archive(const char* p) : @@ -56,6 +58,7 @@ Archive::Archive(const char* p) : header.directory.compressed_size); if (Z_OK != err) throw "could not uncompress directory"; + UpdateBlockMap(); } @@ -111,6 +114,29 @@ Archive::Find(const char* filepath) const void +Archive::UpdateBlockMap() +{ + const std::size_t last_directory_block = header.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; + if (last_block < block) + last_block = block; + } + blocks.clear(); + blocks.resize(last_block + 1, UNUSED_BLOCK); + for (std::size_t n = header.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; + const std::size_t exclusive_to = from + BytesToBlocks(entries[i].compressed_size); + for (std::size_t n = from; n < exclusive_to; ++n) + blocks[n] = i; + } +} + + +void Archive::PrintNamesOfEntries() const { for (const auto& entry : entries) @@ -118,6 +144,25 @@ Archive::PrintNamesOfEntries() const } +void +Archive::PrintBlocks() const +{ + for (std::size_t i = 0; i < blocks.size(); ++i) { + std::printf("%ld\t", i); + switch (blocks[i]) { + case UNUSED_BLOCK: + std::printf("(unused)\n"); + break; + case DIRECTORY_BLOCK: + std::printf("(dir)\n"); + break; + default: + std::printf("%s\n", entries[blocks[i]].name); + } + } +} + + std::size_t Archive::DirectoryBlocks() const { |