146 lines
3.5 KiB
C++
146 lines
3.5 KiB
C++
#ifndef WC3RE_TREFILE_HH__
|
|
#define WC3RE_TREFILE_HH__
|
|
|
|
#include "Resource.hh"
|
|
|
|
class TreFile : public RefCounted {
|
|
public:
|
|
TreFile(Resource::Handle base);
|
|
|
|
~TreFile();
|
|
|
|
using Handle = ResourceHandle<TreFile>;
|
|
|
|
std::vector<std::string> getNames() const;
|
|
std::vector<uint32_t> 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<uint8_t>();
|
|
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<uint8_t>();
|
|
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<uint8_t> 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<uint8_t> 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<Object> openName(std::string const& name) const;
|
|
std::unique_ptr<Object> openCRC(uint32_t crc) const;
|
|
|
|
std::unique_ptr<Object> 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<Object> openIdx_(size_t table3Idx) const;
|
|
Stat statIdx_(size_t table3Idx) const;
|
|
|
|
std::map<uint32_t, size_t> table1_;
|
|
std::map<std::string, size_t> table2_;
|
|
// base, size, comp. size, flags
|
|
std::vector<std::tuple<uint32_t, uint32_t, uint32_t, uint8_t> > table3_;
|
|
|
|
Resource::Handle res_;
|
|
size_t footprint_;
|
|
};
|
|
|
|
#endif
|