Files
wc3re/TreFile.hh
2015-04-29 15:13:17 +02:00

120 lines
2.9 KiB
C++

#ifndef WC3RE_TREFILE_HH__
#define WC3RE_TREFILE_HH__
#include <map>
#include <string>
#include <cstdio>
#include <vector>
#include <tuple>
#include <experimental/optional>
class TreFile {
public:
TreFile(char const* base, size_t length);
~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();
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<std::vector<uint8_t> > 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<uint8_t> 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;
uint32_t csize;
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<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_;
char const* base_;
size_t length_;
};
#endif