diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/MinedMap.cpp | 6 | ||||
-rw-r--r-- | src/NBT/CompoundTag.hpp | 22 | ||||
-rw-r--r-- | src/NBT/ListTag.hpp | 2 | ||||
-rw-r--r-- | src/NBT/StringTag.hpp | 4 | ||||
-rw-r--r-- | src/NBT/Tag.cpp | 61 | ||||
-rw-r--r-- | src/NBT/Tag.hpp | 7 | ||||
-rw-r--r-- | src/World/Chunk.cpp | 12 | ||||
-rw-r--r-- | src/World/Chunk.hpp | 8 |
8 files changed, 103 insertions, 19 deletions
diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index 306837d..97074b2 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -40,5 +40,11 @@ int main(int argc, char *argv[]) { World::Region region(argv[1]); + const World::Chunk &chunk = *region(0, 0); + + for (auto &entry : std::dynamic_pointer_cast<const NBT::CompoundTag>(chunk->get("Level"))->getValues()) { + std::cout << entry.first << " " << entry.second->getType() << std::endl; + } + return 0; } diff --git a/src/NBT/CompoundTag.hpp b/src/NBT/CompoundTag.hpp index 99bbd94..18de1c6 100644 --- a/src/NBT/CompoundTag.hpp +++ b/src/NBT/CompoundTag.hpp @@ -39,15 +39,15 @@ class CompoundTag : public Tag { private: friend class Tag; - std::unordered_map<std::string, std::shared_ptr<Tag>> value; + std::unordered_map<std::string, std::shared_ptr<const Tag>> values; CompoundTag(Buffer *buffer) { while (true) { - std::pair<std::string, std::shared_ptr<Tag>> v = Tag::readNamedTag(buffer); + std::pair<std::string, std::shared_ptr<const Tag>> v = Tag::readNamedTag(buffer); if (v.second->getType() == Type::End) break; - value.insert(std::move(v)); + values.insert(std::move(v)); } } @@ -55,6 +55,22 @@ public: virtual Type getType() const { 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... 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)); + if (!tag) + return std::shared_ptr<Tag>(nullptr); + + tag->get(args...); + } }; } diff --git a/src/NBT/ListTag.hpp b/src/NBT/ListTag.hpp index 6404065..67ba619 100644 --- a/src/NBT/ListTag.hpp +++ b/src/NBT/ListTag.hpp @@ -38,7 +38,7 @@ class ListTag : public Tag { private: friend class Tag; - std::vector<std::shared_ptr<Tag>> value; + std::vector<std::shared_ptr<const Tag>> value; ListTag(Buffer *buffer) { diff --git a/src/NBT/StringTag.hpp b/src/NBT/StringTag.hpp index a120183..0144081 100644 --- a/src/NBT/StringTag.hpp +++ b/src/NBT/StringTag.hpp @@ -49,6 +49,10 @@ public: virtual Type getType() const { return Type::String; } + + const std::string & getValue() const { + return value; + } }; } diff --git a/src/NBT/Tag.cpp b/src/NBT/Tag.cpp index fddfc4e..a2d57e3 100644 --- a/src/NBT/Tag.cpp +++ b/src/NBT/Tag.cpp @@ -46,7 +46,7 @@ namespace MinedMap { namespace NBT { -std::shared_ptr<Tag> Tag::readTag(Type type, Buffer *buffer) { +std::shared_ptr<const Tag> Tag::readTag(Type type, Buffer *buffer) { switch (type) { case Type::End: return std::shared_ptr<EndTag>(new EndTag()); @@ -89,7 +89,7 @@ std::shared_ptr<Tag> Tag::readTag(Type type, Buffer *buffer) { } } -std::pair<std::string, std::shared_ptr<Tag>> Tag::readNamedTag(Buffer *buffer) { +std::pair<std::string, std::shared_ptr<const Tag>> Tag::readNamedTag(Buffer *buffer) { Type type = static_cast<Type>(buffer->get()); if (type == Type::End) return std::make_pair("", std::shared_ptr<EndTag>(new EndTag())); @@ -101,5 +101,62 @@ std::pair<std::string, std::shared_ptr<Tag>> Tag::readNamedTag(Buffer *buffer) { return std::make_pair(name, readTag(type, buffer)); } +std::ostream& operator<<(std::ostream& os, Tag::Type type) { + switch (type) { + case Tag::Type::End: + os << "End"; + break; + + case Tag::Type::Byte: + os << "Byte"; + break; + + case Tag::Type::Short: + os << "Short"; + break; + + case Tag::Type::Int: + os << "Int"; + break; + + case Tag::Type::Long: + os << "Long"; + break; + + case Tag::Type::Float: + os << "Float"; + break; + + case Tag::Type::Double: + os << "Double"; + break; + + case Tag::Type::ByteArray: + os << "ByteArray"; + break; + + case Tag::Type::String: + os << "String"; + break; + + case Tag::Type::List: + os << "List"; + break; + + case Tag::Type::Compound: + os << "Compound"; + break; + + case Tag::Type::IntArray: + os << "IntArray"; + break; + + default: + os.setstate(std::ios_base::failbit); + } + + return os; +} + } } diff --git a/src/NBT/Tag.hpp b/src/NBT/Tag.hpp index 0d25299..077c508 100644 --- a/src/NBT/Tag.hpp +++ b/src/NBT/Tag.hpp @@ -28,6 +28,7 @@ #include <cstdint> #include <memory> +#include <ostream> #include "../Buffer.hpp" @@ -52,14 +53,16 @@ public: IntArray = 11, }; - static std::shared_ptr<Tag> readTag(Type type, Buffer *buffer); + static std::shared_ptr<const Tag> readTag(Type type, Buffer *buffer); - static std::pair<std::string, std::shared_ptr<Tag>> readNamedTag(Buffer *buffer); + static std::pair<std::string, std::shared_ptr<const Tag>> readNamedTag(Buffer *buffer); virtual Type getType() const = 0; virtual ~Tag() {} }; +std::ostream& operator<<(std::ostream& os, Tag::Type type); + } } diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index ccd0d87..f3a140d 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -36,7 +36,7 @@ namespace MinedMap { namespace World { -std::tuple<UniqueCPtr<uint8_t[]>, size_t> Chunk::inflateChunk(uint8_t *data, size_t len) { +std::pair<UniqueCPtr<uint8_t[]>, size_t> Chunk::inflateChunk(uint8_t *data, size_t len) { size_t outlen = 0; uint8_t *output = nullptr; @@ -67,7 +67,7 @@ std::tuple<UniqueCPtr<uint8_t[]>, size_t> Chunk::inflateChunk(uint8_t *data, siz inflateEnd(&stream); - return std::make_tuple(UniqueCPtr<uint8_t[]>(output), stream.total_out); + return std::make_pair(UniqueCPtr<uint8_t[]>(output), stream.total_out); } Chunk::Chunk(uint8_t *buffer, size_t buflen) { @@ -89,12 +89,12 @@ Chunk::Chunk(uint8_t *buffer, size_t buflen) { std::cerr << "Chunk has size " << size << " (" << len << " inflated)" << std::endl; Buffer nbt(data.get(), len); + std::pair<std::string, std::shared_ptr<const NBT::Tag>> tag = NBT::Tag::readNamedTag(&nbt); - std::pair<std::string, std::shared_ptr<NBT::Tag>> tag = NBT::Tag::readNamedTag(&nbt); - if (tag.first != "") - throw std::invalid_argument("non-empty root tag"); + std::shared_ptr<const NBT::CompoundTag>::operator=(std::dynamic_pointer_cast<const NBT::CompoundTag>(tag.second)); - content = std::move(tag.second); + if (!(*this) || tag.first != "") + throw std::invalid_argument("invalid root tag"); } } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index eba4626..7c485eb 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -28,7 +28,7 @@ #include "../UniqueCPtr.hpp" -#include "../NBT/Tag.hpp" +#include "../NBT/CompoundTag.hpp" #include <cstdint> #include <tuple> @@ -37,14 +37,12 @@ namespace MinedMap { namespace World { -class Chunk { +class Chunk : public std::shared_ptr<const NBT::CompoundTag> { public: static const size_t SIZE = 16; private: - static std::tuple<UniqueCPtr<uint8_t[]>, size_t> inflateChunk(uint8_t *data, size_t len); - - std::shared_ptr<NBT::Tag> content; + static std::pair<UniqueCPtr<uint8_t[]>, size_t> inflateChunk(uint8_t *data, size_t len); public: Chunk(uint8_t *buffer, size_t buflen); |