/* Starshatter: The Open Source Project Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors Copyright (c) 1997-2006, Destroyer Studios LLC. AUTHOR: John DiCamillo */ #ifndef Archive_h #define Archive_h #include // +------------------------------------------------------------------+ namespace Archive { static constexpr std::uint32_t VERSION {0x0010}; static constexpr std::size_t BLOCK_SIZE {1024}; static constexpr std::size_t NAMELEN {64}; } // +------------------------------------------------------------------+ struct DataHeader { static const char* TYPENAME() { return "DataHeader"; } std::uint32_t version; std::uint32_t nfiles; std::uint32_t dir_blocks; std::uint32_t dir_size_comp; std::uint32_t dir_offset; }; struct DataEntry { static const char* TYPENAME() { return "DataEntry"; } char name[Archive::NAMELEN]; std::uint32_t size_orig; std::uint32_t size_comp; std::uint32_t offset; }; class DataArchive { public: static const char* TYPENAME() { return "DataArchive"; } // ctor: DataArchive(const char* name = 0); ~DataArchive(); // operations: void LoadDatafile(const char* name); void Insert(const char* name); void Extract(const char* name); void Remove(const char* name); void List(); void WriteEntry(int index, std::uint8_t* buf); int FindEntry(const char* req_name); int ExpandEntry(int index, std::uint8_t*& buf, bool null_terminate=false); std::uint8_t* CompressEntry(int index); int InsertEntry(const char* name); void RemoveEntry(int index); std::uint32_t Blocks(std::uint32_t raw_size); std::uint32_t DirBlocks(); std::uint32_t FileBlocks(int index); int FindDataBlocks(int blocks_needed); void CreateBlockMap(); std::uint32_t NumFiles() { return header.nfiles; } DataEntry* GetFile(int i) { if (i>=0 && i<(int)header.nfiles) return &directory[i]; return 0; } const char* Name() const { return datafile; } private: // persistent data members: DataHeader header; DataEntry* directory; std::uint8_t* dirbuf; // transient members: char datafile[Archive::NAMELEN]; std::uint32_t* block_map; std::uint32_t nblocks; }; #endif // Archive_h