243 lines
4.8 KiB
C++
243 lines
4.8 KiB
C++
#ifndef WC3RE_IFFFILE_HH__
|
|
#define WC3RE_IFFFILE_HH__
|
|
|
|
#include "Resource.hh"
|
|
|
|
class IffFile : public RefCounted {
|
|
public:
|
|
IffFile(Resource::Handle res);
|
|
|
|
~IffFile();
|
|
|
|
using Handle = ResourceHandle<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(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_;
|
|
}
|
|
|
|
void incRef() override {
|
|
parent_.incRef();
|
|
}
|
|
|
|
void decRef() override {
|
|
parent_.decRef();
|
|
}
|
|
|
|
unsigned getRef() const override {
|
|
return parent_.getRef();
|
|
}
|
|
|
|
operator std::string() const;
|
|
|
|
operator bool() const override {
|
|
return true;
|
|
}
|
|
|
|
protected:
|
|
Object(IffFile& parent, std::string type, uint8_t const* base, size_t length, size_t& footprint);
|
|
|
|
IffFile& parent_;
|
|
uint8_t const* base_;
|
|
size_t const length_;
|
|
std::string const type_;
|
|
|
|
friend class IffFile;
|
|
};
|
|
|
|
class Form final : public Object {
|
|
public:
|
|
~Form() override {
|
|
}
|
|
|
|
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());
|
|
}
|
|
|
|
Object& getObject(std::string const& spec) const;
|
|
private:
|
|
Form(IffFile& parent, std::string type, uint8_t const* base, size_t length, size_t& footprint);
|
|
|
|
std::vector<std::unique_ptr<Object> > children_;
|
|
std::string subtype_;
|
|
|
|
friend class IffFile;
|
|
};
|
|
|
|
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;
|
|
|
|
Object& getObject(std::string const& spec) const;
|
|
|
|
size_t size() const {
|
|
return res_->size();
|
|
}
|
|
|
|
uint8_t const* data() const {
|
|
return res_->data();
|
|
}
|
|
|
|
operator bool() const {
|
|
return *res_;
|
|
}
|
|
|
|
size_t footprint() const {
|
|
return footprint_;
|
|
}
|
|
|
|
private:
|
|
static std::unique_ptr<Object> parseObject(IffFile& parent, uint8_t const* base,
|
|
size_t length, size_t& footprint);
|
|
|
|
Resource::Handle res_;
|
|
std::vector<std::unique_ptr<Object> > roots_;
|
|
size_t footprint_;
|
|
};
|
|
|
|
#endif
|