#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 = std::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(stream_); info = std::make_shared(stream_); root_entry->offset = 0; entries.push_back(root_entry); entry_p next_entry = std::make_shared(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(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 *)×tamp, 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); } } } }