Files
wc3re/IffFile.hh
Matthias Blankertz c87836468d iffexplore: Put IFF parsing logic in own class
Created an IffFile class which contains the IFF parsing logic, changed
iffexplore to use this class.
2015-04-22 17:18:43 +02:00

201 lines
4.0 KiB
C++

#ifndef WC3RE_IFFFILE_HH__
#define WC3RE_IFFFILE_HH__
#include <cstddef>
#include <string>
#include <vector>
#include <memory>
#include <typeinfo>
class IffFile {
public:
IffFile(char const* base, size_t length);
~IffFile();
class Object {
public:
Object(std::string type, char const* base, size_t length);
Object(Object const& copy)
: base_(copy.base_), length_(copy.length_), type_(copy.type_) {
}
virtual ~Object() {
}
virtual Object* copy() const {
return new Object(*this);
}
std::string const& getType() const {
return type_;
}
bool isForm() const {
return (typeid(*this) == typeid(Form));
}
size_t getSize() const {
return length_;
}
char const* begin() const {
return base_;
}
char const* end() const {
return base_+length_;
}
operator std::string() const;
protected:
char const* base_;
const size_t length_;
std::string const type_;
};
class Form final : public Object {
public:
Form(std::string type, char const* base, size_t length);
Form(Form const& copy)
: Object(copy), subtype_(copy.subtype_) {
for(auto& ent : copy.children_) {
children_.push_back(std::unique_ptr<Object>(ent->copy()));
}
}
Form* copy() const override {
return new Form(*this);
}
~Form() {}
std::string const& getSubtype() const {
return subtype_;
}
size_t getChildCount() const {
return children_.size();
}
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;
std::vector<std::unique_ptr<Object> >::const_iterator implIt_;
};
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() {
return *root_;
}
void printStructure(unsigned level = 0);
private:
static std::unique_ptr<Object> parseObject(char const* base, size_t length);
char const* base_;
const size_t length_;
std::unique_ptr<Object> root_;
};
#endif