From 8dfe9882eeeb1bde9016af3dc3f5a5588523c339 Mon Sep 17 00:00:00 2001 From: Igor Cotruta Date: Tue, 16 Apr 2024 11:12:31 +0100 Subject: [PATCH] disable pip[elien --- .../workflows/MainDistributionPipeline.yml | 1 + CMakeLists.txt | 11 +- src/abf/AbfParser.cpp | 174 ++++++++++--- src/abf/AbfParser.h | 15 +- src/abf/FileHandleStream.cpp | 54 ---- src/abf/FileHandleStream.h | 38 --- src/abf/pbix.cpp | 236 ----------------- src/abf/pbix.h | 240 ------------------ 8 files changed, 156 insertions(+), 613 deletions(-) delete mode 100644 src/abf/FileHandleStream.cpp delete mode 100644 src/abf/FileHandleStream.h delete mode 100644 src/abf/pbix.cpp delete mode 100644 src/abf/pbix.h diff --git a/.github/workflows/MainDistributionPipeline.yml b/.github/workflows/MainDistributionPipeline.yml index 73db8fb..ad2c954 100644 --- a/.github/workflows/MainDistributionPipeline.yml +++ b/.github/workflows/MainDistributionPipeline.yml @@ -6,6 +6,7 @@ on: push: pull_request: workflow_dispatch: + if: false concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref || '' }}-${{ github.base_ref || '' }}-${{ github.ref != 'refs/heads/main' || github.sha }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 6161e72..29df1f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,11 @@ set(TARGET_NAME pbix) set(EXTENSION_NAME ${TARGET_NAME}_extension) set(LOADABLE_EXTENSION_NAME ${TARGET_NAME}_loadable_extension) -set(STRING_ENCODING_TYPE "ICONV" CACHE STRING "Set the way strings have to be encoded (ICONV|WIN32API|NONE|...)") -add_definitions(-DKS_STR_ENCODING_ICONV) + project(${TARGET_NAME}) include_directories(src/include) include_directories(src/abf) -include_directories(third_party/kaitai) include_directories(third_party/miniz) include_directories(third_party/sqlite) include_directories(third_party/tinyxml2) @@ -36,9 +34,6 @@ set(XPRESS9_SOURCES third_party/xpress9/Xpress9Misc.c third_party/xpress9/Xpress9Wrapper.cpp) -set(KAITAI_SOURCES - third_party/kaitai/kaitaistream.cpp) - SET(ABF_SOURCES src/abf/AbfParser.cpp src/abf/BackupFile.cpp @@ -51,8 +46,7 @@ SET(ABF_SOURCES src/abf/FileList.cpp src/abf/Languages.cpp src/abf/LogBackupFile.cpp - src/abf/VirtualDirectory.cpp - src/abf/pbix.cpp) + src/abf/VirtualDirectory.cpp) set(EXTENSION_SOURCES src/pbix_extension.cpp @@ -64,7 +58,6 @@ set(EXTENSION_SOURCES ${SQLITE_SOURCES} ${TINYXML2_SOURCES} ${XPRESS9_SOURCES} - ${KAITAI_SOURCES} ${ABF_SOURCES}) # build_static_extension(${TARGET_NAME} ${EXTENSION_SOURCES}) diff --git a/src/abf/AbfParser.cpp b/src/abf/AbfParser.cpp index 3864912..f54d1be 100644 --- a/src/abf/AbfParser.cpp +++ b/src/abf/AbfParser.cpp @@ -1,7 +1,9 @@ #include "AbfParser.h" +// #include "duckdb/common/file_system.hpp" using namespace tinyxml2; +using namespace duckdb; std::vector AbfParser::read_buffer_bytes(const std::vector &buffer, uint64_t offset, int size) { @@ -110,28 +112,49 @@ std::pair AbfParser::initialize_zip_and_locate_datamodel(con return {file_stat.m_local_header_ofs, file_stat.m_comp_size}; } -std::pair AbfParser::locate_datamodel(duckdb::ClientContext &context,const std::string &path) { - auto &fs = duckdb::FileSystem::GetFileSystem(context); - auto file_handle = fs.OpenFile(path, FILE_READ); - duckdb::FileHandleStream file_stream(file_handle.get()); - kaitai::kstream ks(&file_stream); +std::pair AbfParser::locate_datamodel(duckdb::FileHandle &file_handle_p, const std::string &path) { + constexpr auto DataModelFileName = "DataModel"; + mz_zip_archive zip_archive; + memset(&zip_archive, 0, sizeof(zip_archive)); - pbix_t pbix(&ks); - for(auto §ion : *pbix.sections()) { - if (section->section_type() == 513) { //Central Directory - auto central_directory = static_cast(section->body()); - //check if the file is DataModel - if(central_directory->file_name() == "DataModel") { - return {central_directory->ofs_local_header(), central_directory->len_body_compressed()}; - } - } + // Setup the custom IO operations + zip_archive.m_pIO_opaque = &file_handle_p; + zip_archive.m_pRead = [](void *opaque, mz_uint64 file_offset, void *buffer, size_t n) { + auto handle = static_cast(opaque); + handle->Seek(file_offset); + return static_cast(handle->Read(buffer, n)); + }; + + // Initialize the zip archive for reading using the custom IO + if (!mz_zip_reader_init(&zip_archive, file_handle_p.GetFileSize(), MZ_ZIP_FLAG_COMPRESSED_DATA)) { // Note: MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY might be needed depending on use case + throw std::runtime_error("Could not initialize zip reader"); } - throw std::runtime_error("DataModel not found in the zip file."); + // Locate the DataModel file within the zip + int file_index = mz_zip_reader_locate_file(&zip_archive, DataModelFileName, nullptr, 0); + if (file_index < 0) { + mz_zip_reader_end(&zip_archive); // Clean up before throwing + throw std::runtime_error("DataModel not found in the zip file."); + } + + // Retrieve information about the DataModel file + mz_zip_archive_file_stat file_stat; + if (!mz_zip_reader_file_stat(&zip_archive, file_index, &file_stat)) { + mz_zip_reader_end(&zip_archive); // Clean up before throwing + throw std::runtime_error("Could not retrieve information about DataModel."); + } + + // // Clean up the zip reader as it's no longer needed after getting the info + mz_zip_reader_end(&zip_archive); + // file_handle = file_handle_p.release(); + + // Return the offset and compressed size of the DataModel file + return {file_stat.m_local_header_ofs, file_stat.m_comp_size}; } + void AbfParser::read_compressed_datamodel_header(std::ifstream &entryStream, uint64_t &datamodel_ofs) { // Read compressed DataModel header to adjust offset entryStream.seekg(datamodel_ofs+ZIP_LOCAL_FILE_HEADER_FIXED); @@ -145,7 +168,7 @@ void AbfParser::read_compressed_datamodel_header(std::ifstream &entryStream, uin std::vector AbfParser::decompress_initial_block(std::ifstream &entryStream, uint64_t datamodel_ofs, XPress9Wrapper &xpress9_wrapper) { // Seek to the start of the DataModel compressed data - entryStream.seekg(datamodel_ofs + ABF_XPRESS9_SIGNATRUE, std::ios::beg); + entryStream.seekg(datamodel_ofs + ABF_XPRESS9_SIGNATURE, std::ios::beg); uint32_t uncompressed_size; uint32_t compressed_size; @@ -167,10 +190,39 @@ std::vector AbfParser::decompress_initial_block(std::ifstream &entryStr } return decompressed_buffer; } +std::vector AbfParser::decompress_initial_block(duckdb::FileHandle &file_handle_p, uint64_t &bytes_read,XPress9Wrapper &xpress9_wrapper) { + // Seek to the start of the DataModel compressed data + std::vector signature(ABF_XPRESS9_SIGNATURE); + file_handle_p.Read(reinterpret_cast(signature.data()),ABF_XPRESS9_SIGNATURE); + + bytes_read += ABF_XPRESS9_SIGNATURE; + + uint32_t uncompressed_size; + uint32_t compressed_size; + // Read the compressed and uncompressed sizes before the offset + file_handle_p.Read(reinterpret_cast(&uncompressed_size), sizeof(uint32_t)); + file_handle_p.Read(reinterpret_cast(&compressed_size), sizeof(uint32_t)); + bytes_read += sizeof(uint32_t) + sizeof(uint32_t); + + // Allocate buffers for compressed and decompressed data + std::vector decompressed_buffer(uncompressed_size); + std::vector compressed_buffer(compressed_size); + + file_handle_p.Read(reinterpret_cast(compressed_buffer.data()), compressed_size); + bytes_read += compressed_size; + + // Decompress the entire data + uint32_t decompressed_size = xpress9_wrapper.Decompress(compressed_buffer.data(), compressed_size, decompressed_buffer.data(), decompressed_buffer.size()); + // Verify that the total decompressed size matches the expected size + if (decompressed_size != uncompressed_size) { + throw std::runtime_error("Mismatch in decompressed block size in first block."); + } + // file_handle = file_handle_p.release(); + return decompressed_buffer; +} std::vector AbfParser::iterate_and_decompress_blocks(std::ifstream &entryStream, uint64_t datamodel_ofs, uint64_t datamodel_size, XPress9Wrapper &xpress9_wrapper, uint64_t virtual_directory_offset, int virtual_directory_size, const int trailing_blocks, uint64_t &skip_offset) { // Calculate the total number of blocks - constexpr uint32_t BLOCK_SIZE = 0x200000; auto total_blocks = (virtual_directory_size + virtual_directory_offset) / BLOCK_SIZE; std::vector all_decompressed_data; @@ -218,6 +270,61 @@ std::vector AbfParser::iterate_and_decompress_blocks(std::ifstream &ent return all_decompressed_data; } +std::vector AbfParser::iterate_and_decompress_blocks(duckdb::FileHandle &file_handle_p, uint64_t &bytes_read, uint64_t datamodel_ofs,uint64_t datamodel_size, XPress9Wrapper &xpress9_wrapper, uint64_t virtual_directory_offset, int virtual_directory_size, const int trailing_blocks, uint64_t &skip_offset) { + // Calculate the total number of blocks + + auto total_blocks = (virtual_directory_size + virtual_directory_offset) / BLOCK_SIZE; + + std::vector all_decompressed_data; + uint32_t block_index = 0; + uint32_t block_index_iterator = 0; + + // Iterate through each block in the DataModel + while (bytes_read < datamodel_size) { + block_index++; + // Read the compressed and uncompressed sizes + uint32_t uncompressed_size = 0; + uint32_t compressed_size = 0; + file_handle_p.Read(reinterpret_cast(&uncompressed_size), sizeof(uncompressed_size)); + file_handle_p.Read(reinterpret_cast(&compressed_size), sizeof(compressed_size)); + bytes_read += sizeof(uncompressed_size) + sizeof(compressed_size); + + // Skip blocks if not within the last `trailing_blocks` (based on your logic) + if (total_blocks > trailing_blocks && block_index < (total_blocks - trailing_blocks)) { + skip_offset += uncompressed_size; + bytes_read += compressed_size; + file_handle_p.Seek(datamodel_ofs+bytes_read); // Skip this block + continue; + } + + // Allocate buffers for the compressed and decompressed data + std::vector compressed_buffer(compressed_size); + std::vector decompressed_buffer(uncompressed_size); + + // Read the compressed block + file_handle_p.Read(reinterpret_cast(compressed_buffer.data()), compressed_size); + bytes_read += compressed_size; + + // call to a new function process header_buffer which we'll use to modify compressed_buffer + patch_header_of_compressed_buffer(compressed_buffer, block_index_iterator); + + // Decompress the block + uint32_t decompressed_size = xpress9_wrapper.Decompress(compressed_buffer.data(), compressed_size, decompressed_buffer.data(), decompressed_buffer.size()); + + // Verify decompression success + if (decompressed_size != uncompressed_size) { + throw std::runtime_error("Decompression failed or resulted in unexpected size."); + } + + // Add decompressed data to the overall buffer + all_decompressed_data.insert(all_decompressed_data.end(), decompressed_buffer.begin(), decompressed_buffer.end()); + } + + // file_handle = file_handle_p.release(); + + return all_decompressed_data; +} + std::vector AbfParser::get_sqlite(const std::string &path, const int trailing_blocks=15) { // Initialize zip and locate DataModel @@ -260,18 +367,27 @@ std::vector AbfParser::get_sqlite(const std::string &path, const int tr } std::vector AbfParser::get_sqlite_v2(duckdb::ClientContext &context, const std::string &path, const int trailing_blocks=15) { - // Initialize zip and locate DataModel - auto [datamodel_ofs, datamodel_size] = locate_datamodel(context,path); - - // Open file stream - std::ifstream entryStream(path, std::ios::binary); - if (!entryStream.is_open()) { - throw std::runtime_error("Could not open pbix file for reading compressed DataModel header."); + auto &fs = duckdb::FileSystem::GetFileSystem(context); + // Open the file using FileSystem + auto file_handle = fs.OpenFile(path, FILE_READ); + if (!file_handle) { + throw std::runtime_error("Could not open zip file"); } - // Read compressed DataModel header to adjust offset - read_compressed_datamodel_header(entryStream, datamodel_ofs); - + auto [datamodel_ofs, datamodel_size] = locate_datamodel(*file_handle, path); + uint64_t bytes_read = 0; + uint16_t zip_pointer = 0; + + // Read compressed DataModel header to adjust offset + file_handle->Seek(datamodel_ofs+ZIP_LOCAL_FILE_HEADER_FIXED); + uint16_t filename_len = 0; + uint16_t extra_len = 0; + file_handle->Read(reinterpret_cast(&filename_len), sizeof(filename_len)); + file_handle->Read(reinterpret_cast(&extra_len), sizeof(extra_len)); + datamodel_ofs += ZIP_LOCAL_FILE_HEADER + filename_len + extra_len; + + file_handle->Seek(datamodel_ofs); + XPress9Wrapper xpress9_wrapper; if (!xpress9_wrapper.Initialize()) { @@ -279,14 +395,14 @@ std::vector AbfParser::get_sqlite_v2(duckdb::ClientContext &context, co } // Decompress initial block to get the virtual directory info - auto initial_decompressed_buffer = decompress_initial_block(entryStream, datamodel_ofs, xpress9_wrapper); + auto initial_decompressed_buffer = decompress_initial_block(*file_handle, bytes_read,xpress9_wrapper); // Process backup log header to get virtual directory offset and size auto [virtual_directory_offset, virtual_directory_size] = process_backup_log_header(initial_decompressed_buffer); uint64_t skip_offset = 0; //optimization for skipping blocks // Iterate through the remaining blocks and decompress them - auto all_decompressed_buffer = iterate_and_decompress_blocks(entryStream, datamodel_ofs, datamodel_size, xpress9_wrapper, virtual_directory_offset, virtual_directory_size, trailing_blocks, skip_offset); + auto all_decompressed_buffer = iterate_and_decompress_blocks(*file_handle, bytes_read, datamodel_ofs, datamodel_size, xpress9_wrapper, virtual_directory_offset, virtual_directory_size, trailing_blocks, skip_offset); // Prefix all_decompressed_buffer with initial_decompressed_buffer in case we have only one block all_decompressed_buffer.insert(all_decompressed_buffer.begin(), initial_decompressed_buffer.begin(), initial_decompressed_buffer.end()); diff --git a/src/abf/AbfParser.h b/src/abf/AbfParser.h index 7893762..2910b48 100644 --- a/src/abf/AbfParser.h +++ b/src/abf/AbfParser.h @@ -18,18 +18,15 @@ #include "Xpress9Wrapper.h" #include "Crc32.h" #include "duckdb.hpp" -#include "duckdb/common/file_open_flags.hpp" -#include "pbix.h" -#include "FileHandleStream.h" -#include -#include "kaitai/kaitaistream.h" + // Constants related to ZIP file parsing constexpr unsigned char ZIP_LOCAL_FILE_HEADER_FIXED = 26; constexpr unsigned char ZIP_LOCAL_FILE_HEADER = 30; -constexpr unsigned char ABF_XPRESS9_SIGNATRUE = 102; +constexpr unsigned char ABF_XPRESS9_SIGNATURE = 102; constexpr unsigned char ABF_BACKUP_LOG_HEADER_OFFSET = 72; +constexpr uint32_t BLOCK_SIZE = 0x200000; constexpr unsigned short ABF_BACKUP_LOG_HEADER_SIZE = 0x1000 - ABF_BACKUP_LOG_HEADER_OFFSET; static constexpr idx_t FILE_READ = idx_t(1 << 0); @@ -38,16 +35,20 @@ class AbfParser { static std::vector get_sqlite(const std::string &path, const int trailing_chunks); static std::vector get_sqlite_v2(duckdb::ClientContext &context,const std::string &path, const int trailing_chunks); private: + // duckdb::FileHandle *file_handle; + // mz_zip_archive zip_archive; static void patch_header_of_compressed_buffer(std::vector &compressed_buffer, uint32_t& block_index_iterator); static std::vector read_buffer_bytes(const std::vector& buffer, uint64_t offset, int size); static std::vector trim_buffer(const std::vector& buffer); static std::tuple process_backup_log_header(const std::vector &buffer); static std::vector extract_sqlite_buffer(const std::vector &buffer, uint64_t skip_offset, uint64_t virtual_directory_offset, int virtual_directory_size); static std::pair initialize_zip_and_locate_datamodel(const std::string &path); - static std::pair locate_datamodel(duckdb::ClientContext &context, const std::string &path); + static std::pair locate_datamodel(duckdb::FileHandle &file_handle, const std::string &path); static void read_compressed_datamodel_header(std::ifstream &entryStream, uint64_t &datamodel_ofs); static std::vector decompress_initial_block(std::ifstream &entryStream, uint64_t datamodel_ofs, XPress9Wrapper &xpress9_wrapper); + static std::vector decompress_initial_block(duckdb::FileHandle &file_handle, uint64_t &bytes_read, XPress9Wrapper &xpress9_wrapper); static std::vector iterate_and_decompress_blocks(std::ifstream &entryStream, uint64_t datamodel_ofs, uint64_t datamodel_size, XPress9Wrapper &xpress9_wrapper, uint64_t virtual_directory_offset, int virtual_directory_size, const int trailing_blocks, uint64_t &skip_offset); + static std::vector iterate_and_decompress_blocks(duckdb::FileHandle &file_handle, uint64_t &bytes_read, uint64_t datamodel_ofs, uint64_t datamodel_size, XPress9Wrapper &xpress9_wrapper, uint64_t virtual_directory_offset, int virtual_directory_size, const int trailing_blocks, uint64_t &skip_offset); }; class Header { diff --git a/src/abf/FileHandleStream.cpp b/src/abf/FileHandleStream.cpp deleted file mode 100644 index b9d2a0f..0000000 --- a/src/abf/FileHandleStream.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include "duckdb/common/file_system.hpp" - -class FileHandleStreamBuf : public std::streambuf { -public: - FileHandleStreamBuf(duckdb::FileHandle* handle) : handle(handle) {} - -protected: - // Override underflow() to handle reading from the custom file system - int underflow() override { - if (gptr() < egptr()) { - return traits_type::to_int_type(*gptr()); - } - char* base = &buffer[0]; - setg(base, base, base); - std::size_t n = handle->Read(base, buffer.size()); - if (n == 0) return traits_type::eof(); - setg(base, base, base + n); - return traits_type::to_int_type(*gptr()); - } - - // Override overflow() if you need write capability - int overflow(int c = traits_type::eof()) override { - return traits_type::eof(); // Indicate always full buffer (no writing) - } - - // Override seekoff to handle seeking - std::streampos seekoff(std::streamoff off, std::ios_base::seekdir dir, - std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override { - if (dir == std::ios_base::cur) { - off += handle->SeekPosition(); - } else if (dir == std::ios_base::end) { - off += handle->GetFileSize(); - } - handle->Seek(off); - return handle->SeekPosition(); - } - -private: - duckdb::FileHandle* handle; - std::vector buffer = std::vector(1024); -}; - -class FileHandleStream : public std::istream { -public: - FileHandleStream(duckdb::FileHandle* handle) - : std::istream(nullptr), buf(handle) { - rdbuf(&buf); - } - -private: - FileHandleStreamBuf buf; -}; diff --git a/src/abf/FileHandleStream.h b/src/abf/FileHandleStream.h deleted file mode 100644 index 633070a..0000000 --- a/src/abf/FileHandleStream.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include -#include -#include "duckdb/common/file_system.hpp" - -namespace duckdb { - -class FileHandleStreamBuf : public std::streambuf { -public: - explicit FileHandleStreamBuf(FileHandle* handle); - -protected: - // Override underflow() to handle reading from the custom file system - int underflow() override; - - // Override overflow() if you need write capability - int overflow(int c = traits_type::eof()) override; - - // Override seekoff to handle seeking - std::streampos seekoff(std::streamoff off, std::ios_base::seekdir dir, - std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; - -private: - FileHandle* handle; - std::vector buffer; -}; - -class FileHandleStream : public std::istream { -public: - explicit FileHandleStream(FileHandle* handle); - -private: - FileHandleStreamBuf buf; -}; - -} // namespace duckdb diff --git a/src/abf/pbix.cpp b/src/abf/pbix.cpp deleted file mode 100644 index 85ff8cf..0000000 --- a/src/abf/pbix.cpp +++ /dev/null @@ -1,236 +0,0 @@ -// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild - -#include "pbix.h" -#include "kaitai/exceptions.h" - -pbix_t::pbix_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, pbix_t* p__root) : kaitai::kstruct(p__io) { - m__parent = p__parent; - m__root = this; - m_sections = 0; - - try { - _read(); - } catch(...) { - _clean_up(); - throw; - } -} - -void pbix_t::_read() { - m_sections = new std::vector(); - { - int i = 0; - while (!m__io->is_eof()) { - m_sections->push_back(new pk_section_t(m__io, this, m__root)); - i++; - } - } -} - -pbix_t::~pbix_t() { - _clean_up(); -} - -void pbix_t::_clean_up() { - if (m_sections) { - for (std::vector::iterator it = m_sections->begin(); it != m_sections->end(); ++it) { - delete *it; - } - delete m_sections; m_sections = 0; - } -} - -pbix_t::local_file_t::local_file_t(kaitai::kstream* p__io, pbix_t::pk_section_t* p__parent, pbix_t* p__root) : kaitai::kstruct(p__io) { - m__parent = p__parent; - m__root = p__root; - m_header = 0; - - try { - _read(); - } catch(...) { - _clean_up(); - throw; - } -} - -void pbix_t::local_file_t::_read() { - m_header = new local_file_header_t(m__io, this, m__root); - m_body = m__io->read_bytes(header()->len_body_compressed()); -} - -pbix_t::local_file_t::~local_file_t() { - _clean_up(); -} - -void pbix_t::local_file_t::_clean_up() { - if (m_header) { - delete m_header; m_header = 0; - } -} - -pbix_t::data_descriptor_t::data_descriptor_t(kaitai::kstream* p__io, pbix_t::pk_section_t* p__parent, pbix_t* p__root) : kaitai::kstruct(p__io) { - m__parent = p__parent; - m__root = p__root; - - try { - _read(); - } catch(...) { - _clean_up(); - throw; - } -} - -void pbix_t::data_descriptor_t::_read() { - m_data_descriptor_obs = m__io->read_bytes(12); -} - -pbix_t::data_descriptor_t::~data_descriptor_t() { - _clean_up(); -} - -void pbix_t::data_descriptor_t::_clean_up() { -} - -pbix_t::central_dir_entry_t::central_dir_entry_t(kaitai::kstream* p__io, pbix_t::pk_section_t* p__parent, pbix_t* p__root) : kaitai::kstruct(p__io) { - m__parent = p__parent; - m__root = p__root; - - try { - _read(); - } catch(...) { - _clean_up(); - throw; - } -} - -void pbix_t::central_dir_entry_t::_read() { - m_header_obs = m__io->read_bytes(12); - m_crc32 = m__io->read_u4le(); - m_len_body_compressed = m__io->read_u4le(); - m_len_body_uncompressed = m__io->read_u4le(); - m_len_file_name = m__io->read_u2le(); - m_len_extra = m__io->read_u2le(); - m_len_comment = m__io->read_u2le(); - m_disk_number_start = m__io->read_u2le(); - m_int_file_attr = m__io->read_u2le(); - m_ext_file_attr = m__io->read_u4le(); - m_ofs_local_header = m__io->read_s4le(); - m_file_name = kaitai::kstream::bytes_to_str(m__io->read_bytes(len_file_name()), "UTF-8"); - m_extra = m__io->read_bytes((len_extra() + len_comment())); -} - -pbix_t::central_dir_entry_t::~central_dir_entry_t() { - _clean_up(); -} - -void pbix_t::central_dir_entry_t::_clean_up() { -} - -pbix_t::pk_section_t::pk_section_t(kaitai::kstream* p__io, pbix_t* p__parent, pbix_t* p__root) : kaitai::kstruct(p__io) { - m__parent = p__parent; - m__root = p__root; - - try { - _read(); - } catch(...) { - _clean_up(); - throw; - } -} - -void pbix_t::pk_section_t::_read() { - m_magic = m__io->read_bytes(2); - if (!(magic() == std::string("\x50\x4B", 2))) { - throw kaitai::validation_not_equal_error(std::string("\x50\x4B", 2), magic(), _io(), std::string("/types/pk_section/seq/0")); - } - m_section_type = m__io->read_u2le(); - n_body = true; - switch (section_type()) { - case 513: { - n_body = false; - m_body = new central_dir_entry_t(m__io, this, m__root); - break; - } - case 1027: { - n_body = false; - m_body = new local_file_t(m__io, this, m__root); - break; - } - case 1541: { - n_body = false; - m_body = new end_of_central_dir_t(m__io, this, m__root); - break; - } - case 2055: { - n_body = false; - m_body = new data_descriptor_t(m__io, this, m__root); - break; - } - } -} - -pbix_t::pk_section_t::~pk_section_t() { - _clean_up(); -} - -void pbix_t::pk_section_t::_clean_up() { - if (!n_body) { - if (m_body) { - delete m_body; m_body = 0; - } - } -} - -pbix_t::local_file_header_t::local_file_header_t(kaitai::kstream* p__io, pbix_t::local_file_t* p__parent, pbix_t* p__root) : kaitai::kstruct(p__io) { - m__parent = p__parent; - m__root = p__root; - - try { - _read(); - } catch(...) { - _clean_up(); - throw; - } -} - -void pbix_t::local_file_header_t::_read() { - m_header_trimmed = m__io->read_bytes(14); - m_len_body_compressed = m__io->read_u4le(); - m_len_body_uncompressed = m__io->read_u4le(); - m_len_file_name = m__io->read_u2le(); - m_len_extra = m__io->read_u2le(); - m_file_name = m__io->read_bytes(len_file_name()); - m_extra = m__io->read_bytes(len_extra()); -} - -pbix_t::local_file_header_t::~local_file_header_t() { - _clean_up(); -} - -void pbix_t::local_file_header_t::_clean_up() { -} - -pbix_t::end_of_central_dir_t::end_of_central_dir_t(kaitai::kstream* p__io, pbix_t::pk_section_t* p__parent, pbix_t* p__root) : kaitai::kstruct(p__io) { - m__parent = p__parent; - m__root = p__root; - - try { - _read(); - } catch(...) { - _clean_up(); - throw; - } -} - -void pbix_t::end_of_central_dir_t::_read() { - m_header_obs = m__io->read_bytes(16); - m_len_comment = m__io->read_u2le(); - m_comment = m__io->read_bytes(len_comment()); -} - -pbix_t::end_of_central_dir_t::~end_of_central_dir_t() { - _clean_up(); -} - -void pbix_t::end_of_central_dir_t::_clean_up() { -} diff --git a/src/abf/pbix.h b/src/abf/pbix.h deleted file mode 100644 index f03647f..0000000 --- a/src/abf/pbix.h +++ /dev/null @@ -1,240 +0,0 @@ -#ifndef PBIX_H_ -#define PBIX_H_ - -// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild - -#include "kaitai/kaitaistruct.h" -#include -#include - -#if KAITAI_STRUCT_VERSION < 9000L -#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required" -#endif - -class pbix_t : public kaitai::kstruct { - -public: - class local_file_t; - class data_descriptor_t; - class central_dir_entry_t; - class pk_section_t; - class local_file_header_t; - class end_of_central_dir_t; - - pbix_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, pbix_t* p__root = 0); - -private: - void _read(); - void _clean_up(); - -public: - ~pbix_t(); - - class local_file_t : public kaitai::kstruct { - - public: - - local_file_t(kaitai::kstream* p__io, pbix_t::pk_section_t* p__parent = 0, pbix_t* p__root = 0); - - private: - void _read(); - void _clean_up(); - - public: - ~local_file_t(); - - private: - local_file_header_t* m_header; - std::string m_body; - pbix_t* m__root; - pbix_t::pk_section_t* m__parent; - - public: - local_file_header_t* header() const { return m_header; } - std::string body() const { return m_body; } - pbix_t* _root() const { return m__root; } - pbix_t::pk_section_t* _parent() const { return m__parent; } - }; - - class data_descriptor_t : public kaitai::kstruct { - - public: - - data_descriptor_t(kaitai::kstream* p__io, pbix_t::pk_section_t* p__parent = 0, pbix_t* p__root = 0); - - private: - void _read(); - void _clean_up(); - - public: - ~data_descriptor_t(); - - private: - std::string m_data_descriptor_obs; - pbix_t* m__root; - pbix_t::pk_section_t* m__parent; - - public: - std::string data_descriptor_obs() const { return m_data_descriptor_obs; } - pbix_t* _root() const { return m__root; } - pbix_t::pk_section_t* _parent() const { return m__parent; } - }; - - class central_dir_entry_t : public kaitai::kstruct { - - public: - - central_dir_entry_t(kaitai::kstream* p__io, pbix_t::pk_section_t* p__parent = 0, pbix_t* p__root = 0); - - private: - void _read(); - void _clean_up(); - - public: - ~central_dir_entry_t(); - - private: - std::string m_header_obs; - uint32_t m_crc32; - uint32_t m_len_body_compressed; - uint32_t m_len_body_uncompressed; - uint16_t m_len_file_name; - uint16_t m_len_extra; - uint16_t m_len_comment; - uint16_t m_disk_number_start; - uint16_t m_int_file_attr; - uint32_t m_ext_file_attr; - int32_t m_ofs_local_header; - std::string m_file_name; - std::string m_extra; - pbix_t* m__root; - pbix_t::pk_section_t* m__parent; - - public: - std::string header_obs() const { return m_header_obs; } - uint32_t crc32() const { return m_crc32; } - uint32_t len_body_compressed() const { return m_len_body_compressed; } - uint32_t len_body_uncompressed() const { return m_len_body_uncompressed; } - uint16_t len_file_name() const { return m_len_file_name; } - uint16_t len_extra() const { return m_len_extra; } - uint16_t len_comment() const { return m_len_comment; } - uint16_t disk_number_start() const { return m_disk_number_start; } - uint16_t int_file_attr() const { return m_int_file_attr; } - uint32_t ext_file_attr() const { return m_ext_file_attr; } - int32_t ofs_local_header() const { return m_ofs_local_header; } - std::string file_name() const { return m_file_name; } - std::string extra() const { return m_extra; } - pbix_t* _root() const { return m__root; } - pbix_t::pk_section_t* _parent() const { return m__parent; } - }; - - class pk_section_t : public kaitai::kstruct { - - public: - - pk_section_t(kaitai::kstream* p__io, pbix_t* p__parent = 0, pbix_t* p__root = 0); - - private: - void _read(); - void _clean_up(); - - public: - ~pk_section_t(); - - private: - std::string m_magic; - uint16_t m_section_type; - kaitai::kstruct* m_body; - bool n_body; - - public: - bool _is_null_body() { body(); return n_body; }; - - private: - pbix_t* m__root; - pbix_t* m__parent; - - public: - std::string magic() const { return m_magic; } - uint16_t section_type() const { return m_section_type; } - kaitai::kstruct* body() const { return m_body; } - pbix_t* _root() const { return m__root; } - pbix_t* _parent() const { return m__parent; } - }; - - class local_file_header_t : public kaitai::kstruct { - - public: - - local_file_header_t(kaitai::kstream* p__io, pbix_t::local_file_t* p__parent = 0, pbix_t* p__root = 0); - - private: - void _read(); - void _clean_up(); - - public: - ~local_file_header_t(); - - private: - std::string m_header_trimmed; - uint32_t m_len_body_compressed; - uint32_t m_len_body_uncompressed; - uint16_t m_len_file_name; - uint16_t m_len_extra; - std::string m_file_name; - std::string m_extra; - pbix_t* m__root; - pbix_t::local_file_t* m__parent; - - public: - std::string header_trimmed() const { return m_header_trimmed; } - uint32_t len_body_compressed() const { return m_len_body_compressed; } - uint32_t len_body_uncompressed() const { return m_len_body_uncompressed; } - uint16_t len_file_name() const { return m_len_file_name; } - uint16_t len_extra() const { return m_len_extra; } - std::string file_name() const { return m_file_name; } - std::string extra() const { return m_extra; } - pbix_t* _root() const { return m__root; } - pbix_t::local_file_t* _parent() const { return m__parent; } - }; - - class end_of_central_dir_t : public kaitai::kstruct { - - public: - - end_of_central_dir_t(kaitai::kstream* p__io, pbix_t::pk_section_t* p__parent = 0, pbix_t* p__root = 0); - - private: - void _read(); - void _clean_up(); - - public: - ~end_of_central_dir_t(); - - private: - std::string m_header_obs; - uint16_t m_len_comment; - std::string m_comment; - pbix_t* m__root; - pbix_t::pk_section_t* m__parent; - - public: - std::string header_obs() const { return m_header_obs; } - uint16_t len_comment() const { return m_len_comment; } - std::string comment() const { return m_comment; } - pbix_t* _root() const { return m__root; } - pbix_t::pk_section_t* _parent() const { return m__parent; } - }; - -private: - std::vector* m_sections; - pbix_t* m__root; - kaitai::kstruct* m__parent; - -public: - std::vector* sections() const { return m_sections; } - pbix_t* _root() const { return m__root; } - kaitai::kstruct* _parent() const { return m__parent; } -}; - -#endif // PBIX_H_