#ifndef WC3RE_IFFFILE_HH__ #define WC3RE_IFFFILE_HH__ #include "Resource.hh" class IffFile : public RefCounted { public: IffFile(Resource::Handle res); ~IffFile(); using Handle = ResourceHandle; class Object; class Form; class ObjectIterator : public std::iterator { 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 >::const_iterator implIt) : implIt_(std::move(implIt)) { } friend class Form; friend class IffFile; std::vector >::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 > 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 parseObject(IffFile& parent, uint8_t const* base, size_t length, size_t& footprint); Resource::Handle res_; std::vector > roots_; size_t footprint_; }; #endif