summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2022-08-17 22:40:59 +0200
committerAki <please@ignore.pl>2022-08-17 22:40:59 +0200
commit5708303f6ae772cf2ca8da30249262c772d3021d (patch)
tree72e724f754a555bd154c8badc8614fa41ee078d7
parente7b0d4dc387f732e9f146fdaef5e531448510366 (diff)
downloadstarshatter-5708303f6ae772cf2ca8da30249262c772d3021d.zip
starshatter-5708303f6ae772cf2ca8da30249262c772d3021d.tar.gz
starshatter-5708303f6ae772cf2ca8da30249262c772d3021d.tar.bz2
Hid Header definition from public archive header
-rw-r--r--ArchiveEx/Archive.cpp35
-rw-r--r--ArchiveEx/Archive.h14
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;
};