#ifndef WC3RE_TREFILE_HH__ #define WC3RE_TREFILE_HH__ #include #include #include #include #include #include class TreFile { public: TreFile(char const* base, size_t length); ~TreFile(); 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(); class Object { public: Object() : base_(nullptr), length_(0) { } Object(Object const& copy) = delete; Object(Object && move) : data_(std::move(move.data_)), base_(move.base_), length_(move.length_) { move.data_ = std::experimental::nullopt; move.base_ = nullptr; move.length_ = 0; } Object& operator=(Object const& copy) = delete; Object& operator=(Object && move) { data_ = std::move(move.data_); base_ = move.base_; length_ = move.length_; move.data_ = std::experimental::nullopt; move.base_ = nullptr; move.length_ = 0; return *this; } char const* data() const { if (data_) return (char const*)(data_->data()); else return base_; } size_t size() const { return length_; } operator bool() const { return data_ || base_; } private: // Object either owns data (when decompressed) ... std::experimental::optional > data_; // .. or points to area in underlying data (when not compressed) char const* base_; size_t length_; Object(char const* base, size_t length) : data_(), base_(base), length_(length) { } Object(std::vector data) : data_(std::move(data)), base_(nullptr), length_(data_->size()) { } friend class TreFile; }; /* Open an object of the TRE file by name or by CRC * The returned object should be destroyed when no longer needed as it may * hold a memory allocation for its data. But it must not be used after the * TreFile object is destroyed. */ Object openName(std::string const& name) const; Object openCRC(uint32_t crc) const; struct Stat { uint32_t size; uint8_t flags; }; Stat statName(std::string const& name) const; Stat statCRC(uint32_t crc) const; private: void construct_(); 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; Object openIdx_(size_t table3Idx) const; Stat statIdx_(size_t table3Idx) const; std::map table1_; std::map table2_; std::vector > table3_; char const* base_; size_t length_; }; #endif