summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/MinedMap.cpp6
-rw-r--r--src/NBT/CompoundTag.hpp22
-rw-r--r--src/NBT/ListTag.hpp2
-rw-r--r--src/NBT/StringTag.hpp4
-rw-r--r--src/NBT/Tag.cpp61
-rw-r--r--src/NBT/Tag.hpp7
-rw-r--r--src/World/Chunk.cpp12
-rw-r--r--src/World/Chunk.hpp8
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);