mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-07-02 05:49:06 +02:00
Use template argument for list subtype, extract further information from chunks
This commit is contained in:
parent
a6a2a62812
commit
fc1fc8fbbc
9 changed files with 108 additions and 32 deletions
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
template<typename T>
|
||||
std::shared_ptr<const T> get(const std::string &key) const {
|
||||
return std::dynamic_pointer_cast<const T>(at(key));
|
||||
}
|
||||
|
||||
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));
|
||||
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...);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -34,30 +34,39 @@
|
|||
namespace MinedMap {
|
||||
namespace NBT {
|
||||
|
||||
class ListTag : public Tag {
|
||||
|
||||
class ListTagBase : public Tag {
|
||||
public:
|
||||
virtual Type getType() const {
|
||||
return Type::List;
|
||||
}
|
||||
|
||||
virtual Type getSubtype() const = 0;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class ListTag : public ListTagBase, public std::vector<std::shared_ptr<const T>> {
|
||||
private:
|
||||
friend class Tag;
|
||||
|
||||
std::vector<std::shared_ptr<const Tag>> value;
|
||||
|
||||
|
||||
ListTag(Buffer *buffer) {
|
||||
Type type = static_cast<Type>(buffer->get());
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue