Files
wc3re/TreFile.hh

152 lines
3.6 KiB
C++

#ifndef WC3RE_TREFILE_HH__
#define WC3RE_TREFILE_HH__
#include <map>
#include <string>
#include <cstdio>
#include <vector>
#include <tuple>
#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