ACE3/extensions/common/pbo/archive.cpp

92 lines
3.0 KiB
C++

#pragma once
#include "archive.hpp"
#include "p3d/read_helpers.hpp"
namespace ace {
namespace pbo {
bool archive::get_file(std::istream &, const std::string & file, file_p output) {
return false;
}
bool archive::get_file(std::istream & stream_, const entry_p entry, file_p output) {
uint32_t file_offset, bytes_read, use_size;
std::streampos _save = stream_.tellg();
file_offset = begin_data_offset + entry->offset;
use_size = max(entry->size, entry->storage_size);
output->data = new uint8_t[use_size];
bytes_read = 0;
stream_.seekg(file_offset, stream_.beg);
while (bytes_read < use_size) {
if (!stream_.read((char *)output->data + bytes_read, use_size - bytes_read)) {
delete[] output->data;
output->data = nullptr;
return false;
}
bytes_read += stream_.gcount();
}
output->size = use_size;
output->entry = entry;
stream_.seekg(_save, stream_.beg);
return true;
}
archive::archive() { }
archive::archive(std::istream &stream_) {
// Read the first entry, then info, then next entry
uint32_t offset = 0;
entry_p root_entry = std::make_shared<entry>(stream_);
info = std::make_shared<ext_entry>(stream_);
root_entry->offset = 0;
entries.push_back(root_entry);
entry_p next_entry = std::make_shared<entry>(stream_);
while (next_entry->filename != "") { // off by 1006 ?!
next_entry->offset = offset;
entries.push_back(next_entry);
offset += next_entry->storage_size;
next_entry = std::make_shared<entry>(stream_);
}
begin_data_offset = stream_.tellg();
}
archive::~archive() {}
entry::entry() {}
entry::entry(std::istream &stream_) {
READ_STRING(filename);
std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower);
stream_.read((char *)&compression, sizeof(uint32_t));
stream_.read((char *)&size, sizeof(uint32_t));
stream_.read((char *)&reserved, sizeof(uint32_t));
stream_.read((char *)&timestamp, sizeof(uint32_t));
stream_.read((char *)&storage_size, sizeof(uint32_t));
}
ext_entry::ext_entry() {}
ext_entry::ext_entry(std::istream &stream_) {
READ_STRING(name);
READ_STRING(data);
READ_STRING(version);
std::string temp;
temp = version;
while (temp != "") {
extras.push_back(temp);
READ_STRING(temp);
}
}
}
}