#ifndef WC3RE_TREFILE_HH__ #define WC3RE_TREFILE_HH__ #include "Resource.hh" class TreFile : public RefCounted { public: TreFile(Resource::Handle base); ~TreFile(); using Handle = ResourceHandle; std::vector getNames() const; std::vector getCRCs() const; void dumpName(std::string path, std::string const& name) const; void dumpCRC(std::string path, uint32_t crc) const; void dumpAll(std::string path) const; void printStructure(); /* Calculate the XTRE "CRC" (in reality a cheap checksum) of 'path' */ static uint32_t calcCRC(std::string const& path); class Object : public Resource { public: Object() : data_(), base_(nullptr), length_(0), res_() { } Object(Object const& copy) : data_(copy.data_), base_(copy.base_), length_(copy.length_), res_(copy.res_) { } Object(Object && move) : data_(std::move(move.data_)), base_(move.base_), length_(move.length_), res_(std::move(move.res_)) { move.data_ = std::vector(); move.base_ = nullptr; move.length_ = 0; } Object& operator=(Object const& copy) { data_ = copy.data_; base_ = copy.base_; length_ = copy.length_; res_ = copy.res_; return *this; } Object& operator=(Object && move) { data_ = std::move(move.data_); base_ = move.base_; length_ = move.length_; res_ = std::move(move.res_); move.data_ = std::vector(); move.base_ = nullptr; move.length_ = 0; return *this; } ~Object() override { } uint8_t const* data() const override { if (!data_.empty()) return data_.data(); else return base_; } size_t size() const override { return length_; } operator bool() const override { return data_.empty() || base_; } size_t footprint() const override { if (res_) return sizeof(Object); return length_+sizeof(Object); } Object(uint8_t const* base, size_t length, Resource::Handle res) : data_(), base_(base), length_(length), res_(std::move(res)) { } Object(std::vector data) : data_(std::move(data)), base_(nullptr), length_(data_.size()), res_() { } private: // Object either owns data (when decompressed) (res_ is null in this case)... std::vector data_; // .. or points to area in underlying data (when not compressed) uint8_t const* base_; size_t length_; Resource::Handle res_; }; /* Open an object of the TRE file by name or by CRC */ std::unique_ptr openName(std::string const& name) const; std::unique_ptr openCRC(uint32_t crc) const; std::unique_ptr getObject(std::string const& spec) const; std::string normalizeName(std::string const& name) const; struct Stat { uint32_t size; uint32_t csize; uint8_t flags; }; Stat statName(std::string const& name) const; Stat statCRC(uint32_t crc) const; size_t footprint() const { return footprint_; } private: size_t findName_(std::string const& name) const; size_t findCRC_(uint32_t crc) const; void dumpIdx_(std::string const& name, size_t table3Idx) const; std::unique_ptr openIdx_(size_t table3Idx) const; Stat statIdx_(size_t table3Idx) const; std::map table1_; std::map table2_; // base, size, comp. size, flags std::vector > table3_; Resource::Handle res_; size_t footprint_; }; #endif