Files
wc3re/IffFile.hh

206 lines
4.1 KiB
C++

#ifndef WC3RE_IFFFILE_HH__
#define WC3RE_IFFFILE_HH__
#include <cstddef>
#include <string>
#include <vector>
#include <memory>
#include <typeinfo>
#include "Resource.hh"
class IffFile {
public:
IffFile(Resource const& res);
~IffFile();
class Object;
class Form;
class ObjectIterator : public std::iterator<std::random_access_iterator_tag, const Object> {
public:
Object const& operator*() const {
return **implIt_;
}
ObjectIterator& operator++() {
++implIt_;
return *this;
}
ObjectIterator& operator--() {
--implIt_;
return *this;
}
bool operator!=(ObjectIterator const& other) const {
return (implIt_ != other.implIt_);
}
bool operator>(ObjectIterator const& other) const {
return (implIt_ > other.implIt_);
}
bool operator>=(ObjectIterator const& other) const {
return (implIt_ >= other.implIt_);
}
bool operator<(ObjectIterator const& other) const {
return (implIt_ < other.implIt_);
}
bool operator<=(ObjectIterator const& other) const {
return (implIt_ <= other.implIt_);
}
Object const* operator->() const {
return implIt_->get();
}
ObjectIterator operator++(int) {
ObjectIterator ret = *this;
++implIt_;
return ret;
}
ObjectIterator operator--(int) {
ObjectIterator ret = *this;
--implIt_;
return ret;
}
ObjectIterator& operator+=(ptrdiff_t n) {
implIt_ += n;
return *this;
}
ObjectIterator operator+(ptrdiff_t n) const {
ObjectIterator ret = *this;
ret += n;
return ret;
}
ObjectIterator& operator-=(ptrdiff_t n) {
implIt_ -= n;
return *this;
}
ObjectIterator operator-(ptrdiff_t n) const {
ObjectIterator ret = *this;
ret -= n;
return ret;
}
ptrdiff_t operator-(ObjectIterator const& other) const {
return implIt_ - other.implIt_;
}
Object const& operator[](ptrdiff_t n) const {
return *(implIt_[n]);
}
private:
ObjectIterator(std::vector<std::unique_ptr<Object> >::const_iterator implIt)
: implIt_(std::move(implIt)) {
}
friend class Form;
friend class IffFile;
std::vector<std::unique_ptr<Object> >::const_iterator implIt_;
};
class Object : public Resource {
public:
Object(std::string type, uint8_t const* base, size_t length);
Object(Object const& copy) = delete;
~Object() override {
}
std::string const& getType() const {
return type_;
}
bool isForm() const {
return (typeid(*this) == typeid(Form));
}
size_t size() const override {
return length_;
}
uint8_t const* data() const override {
return base_;
}
uint8_t const* begin() const {
return base_;
}
uint8_t const* end() const {
return base_+length_;
}
operator std::string() const;
operator bool() const override {
return true;
}
protected:
uint8_t const* base_;
const size_t length_;
std::string const type_;
};
class Form final : public Object {
public:
Form(std::string type, uint8_t const* base, size_t length);
~Form() {}
std::string const& getSubtype() const {
return subtype_;
}
size_t getChildCount() const {
return children_.size();
}
ObjectIterator childrenBegin() const {
return ObjectIterator(children_.cbegin());
}
ObjectIterator childrenEnd() const {
return ObjectIterator(children_.cend());
}
private:
std::vector<std::unique_ptr<Object> > children_;
std::string subtype_;
};
Object const& getRoot() const {
return *roots_[0];
}
ObjectIterator begin() const {
return ObjectIterator(roots_.cbegin());
}
ObjectIterator end() const {
return ObjectIterator(roots_.cend());
}
void printStructure(unsigned level = 0) const;
private:
static std::unique_ptr<Object> parseObject(uint8_t const* base, size_t length);
Resource const& res_;
std::vector<std::unique_ptr<Object> > roots_;
};
#endif