diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-02-01 03:21:57 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-02-01 03:21:57 +0100 |
commit | fc1fc8fbbc9dd9534f40de348210ea66b6defe42 (patch) | |
tree | 3cfa5fae12050f49df5cc6bc0482d4e5a45711d1 /src/NBT | |
parent | a6a2a6281218688de7a74a9cd2a426aad3fe2da2 (diff) | |
download | MinedMap-fc1fc8fbbc9dd9534f40de348210ea66b6defe42.tar MinedMap-fc1fc8fbbc9dd9534f40de348210ea66b6defe42.zip |
Use template argument for list subtype, extract further information from chunks
Diffstat (limited to 'src/NBT')
-rw-r--r-- | src/NBT/ByteArrayTag.hpp | 4 | ||||
-rw-r--r-- | src/NBT/CompoundTag.hpp | 24 | ||||
-rw-r--r-- | src/NBT/ListTag.hpp | 29 | ||||
-rw-r--r-- | src/NBT/Tag.cpp | 49 | ||||
-rw-r--r-- | src/NBT/Tag.hpp | 4 |
5 files changed, 80 insertions, 30 deletions
diff --git a/src/NBT/ByteArrayTag.hpp b/src/NBT/ByteArrayTag.hpp index d5a6333..ee0d7d1 100644 --- a/src/NBT/ByteArrayTag.hpp +++ b/src/NBT/ByteArrayTag.hpp @@ -47,9 +47,7 @@ private: len |= uint32_t(buffer->get()); value.resize(len); - - for (uint32_t i = 0; i < len; i++) - value[i] = buffer->get(); + buffer->getData(value.data(), len); } public: diff --git a/src/NBT/CompoundTag.hpp b/src/NBT/CompoundTag.hpp index 18de1c6..28efc41 100644 --- a/src/NBT/CompoundTag.hpp +++ b/src/NBT/CompoundTag.hpp @@ -35,19 +35,17 @@ namespace MinedMap { namespace NBT { -class CompoundTag : public Tag { +class CompoundTag : public Tag, public std::unordered_map<std::string, std::shared_ptr<const Tag>> { private: friend class Tag; - std::unordered_map<std::string, std::shared_ptr<const Tag>> values; - CompoundTag(Buffer *buffer) { while (true) { std::pair<std::string, std::shared_ptr<const Tag>> v = Tag::readNamedTag(buffer); if (v.second->getType() == Type::End) break; - values.insert(std::move(v)); + insert(std::move(v)); } } @@ -56,20 +54,18 @@ public: return Type::Compound; } - const std::unordered_map<std::string, std::shared_ptr<const Tag>> & getValues() const { - return values; - } - - const std::shared_ptr<const Tag> & get(const std::string &key) const { - return values.at(key); + template<typename T> + std::shared_ptr<const T> get(const std::string &key) const { + return std::dynamic_pointer_cast<const T>(at(key)); } - template<typename... Args> const std::shared_ptr<const Tag> & get(const std::string &key, const Args &...args) const { - std::shared_ptr<const CompoundTag> tag = std::dynamic_pointer_cast<const CompoundTag>(get(key)); + template<typename T, typename... Args> + std::shared_ptr<const T> get(const std::string &key, const Args &...args) const { + std::shared_ptr<const CompoundTag> tag = get<CompoundTag>(key); if (!tag) - return std::shared_ptr<Tag>(nullptr); + return std::shared_ptr<const T>(); - tag->get(args...); + return tag->get<T>(args...); } }; diff --git a/src/NBT/ListTag.hpp b/src/NBT/ListTag.hpp index 67ba619..1a48062 100644 --- a/src/NBT/ListTag.hpp +++ b/src/NBT/ListTag.hpp @@ -34,30 +34,39 @@ namespace MinedMap { namespace NBT { -class ListTag : public Tag { -private: - friend class Tag; - std::vector<std::shared_ptr<const Tag>> value; +class ListTagBase : public Tag { +public: + virtual Type getType() const { + return Type::List; + } + virtual Type getSubtype() const = 0; +}; - ListTag(Buffer *buffer) { - Type type = static_cast<Type>(buffer->get()); +template<typename T> +class ListTag : public ListTagBase, public std::vector<std::shared_ptr<const T>> { +private: + friend class Tag; + + Type type; + + ListTag(Type type0, Buffer *buffer) : type(type0) { uint32_t len = uint32_t(buffer->get()) << 24; len |= uint32_t(buffer->get()) << 16; len |= uint32_t(buffer->get()) << 8; len |= uint32_t(buffer->get()); - value.resize(len); + this->resize(len); for (uint32_t i = 0; i < len; i++) - value[i] = Tag::readTag(type, buffer); + (*this)[i] = std::static_pointer_cast<const T>(Tag::readTag(type, buffer)); } public: - virtual Type getType() const { - return Type::List; + virtual Type getSubtype() const { + return type; } }; diff --git a/src/NBT/Tag.cpp b/src/NBT/Tag.cpp index a2d57e3..1829dc5 100644 --- a/src/NBT/Tag.cpp +++ b/src/NBT/Tag.cpp @@ -76,7 +76,7 @@ std::shared_ptr<const Tag> Tag::readTag(Type type, Buffer *buffer) { return std::shared_ptr<StringTag>(new StringTag(buffer)); case Type::List: - return std::shared_ptr<ListTag>(new ListTag(buffer)); + return readList(buffer); case Type::Compound: return std::shared_ptr<CompoundTag>(new CompoundTag(buffer)); @@ -85,7 +85,52 @@ std::shared_ptr<const Tag> Tag::readTag(Type type, Buffer *buffer) { return std::shared_ptr<IntArrayTag>(new IntArrayTag(buffer)); default: - throw std::runtime_error("Tag::read: unknown tag type"); + throw std::runtime_error("Tag::readTag: unknown tag type"); + } +} + +std::shared_ptr<const Tag> Tag::readList(Buffer *buffer) { + Type type = static_cast<Type>(buffer->get()); + + switch (type) { + case Type::End: + return std::shared_ptr<Tag>(new ListTag<EndTag>(type, buffer)); + + case Type::Byte: + return std::shared_ptr<Tag>(new ListTag<ByteTag>(type, buffer)); + + case Type::Short: + return std::shared_ptr<Tag>(new ListTag<ShortTag>(type, buffer)); + + case Type::Int: + return std::shared_ptr<Tag>(new ListTag<IntTag>(type, buffer)); + + case Type::Long: + return std::shared_ptr<Tag>(new ListTag<LongTag>(type, buffer)); + + case Type::Float: + return std::shared_ptr<Tag>(new ListTag<FloatTag>(type, buffer)); + + case Type::Double: + return std::shared_ptr<Tag>(new ListTag<DoubleTag>(type, buffer)); + + case Type::ByteArray: + return std::shared_ptr<Tag>(new ListTag<ByteArrayTag>(type, buffer)); + + case Type::String: + return std::shared_ptr<Tag>(new ListTag<StringTag>(type, buffer)); + + case Type::List: + return std::shared_ptr<Tag>(new ListTag<ListTagBase>(type, buffer)); + + case Type::Compound: + return std::shared_ptr<Tag>(new ListTag<CompoundTag>(type, buffer)); + + case Type::IntArray: + return std::shared_ptr<Tag>(new ListTag<IntArrayTag>(type, buffer)); + + default: + throw std::runtime_error("Tag::readList: unknown tag type"); } } diff --git a/src/NBT/Tag.hpp b/src/NBT/Tag.hpp index 077c508..a3c0c76 100644 --- a/src/NBT/Tag.hpp +++ b/src/NBT/Tag.hpp @@ -37,6 +37,9 @@ namespace MinedMap { namespace NBT { class Tag { +private: + static std::shared_ptr<const Tag> readList(Buffer *buffer); + public: enum class Type { End = 0, @@ -54,7 +57,6 @@ public: }; static std::shared_ptr<const Tag> readTag(Type type, Buffer *buffer); - static std::pair<std::string, std::shared_ptr<const Tag>> readNamedTag(Buffer *buffer); virtual Type getType() const = 0; |