#pragma once #include #include #include #include struct nbt_node; struct list_head; namespace NBT { class Tag { protected: nbt_node* m_node; Tag(nbt_node *node) : m_node(node) {} static Tag CreateTag(nbt_node* node); static Tag CreateListTag(nbt_node* node); public: const char* GetName() const; // Get the number of iterable immediate children size_t GetLength() const; const char* ToString() const; }; // Operator overload for ostream std::ostream& operator<<(std::ostream& stream, const Tag& tag); template class DataTag : public Tag { public: DataTag(nbt_node* node) : Tag(node) {} T GetValue() const; inline operator T() const { return GetValue(); } }; template class ArrayTag : public DataTag { public: ArrayTag(nbt_node* node) : DataTag(node) {} const T* GetValue() const; const T* begin() { return GetValue(); } const T* end() { return &(GetValue()[this->GetLength()]); } }; using StringTag = ArrayTag; template class ListTag : public Tag { public: ListTag(nbt_node *node) : Tag(node) {} T Get(int32_t index) const; inline const T operator[](int32_t index) const { return Get(index); } }; // A Compound Tag is an unordered list of named tags class CompoundTag : public Tag { public: CompoundTag(nbt_node* node) : Tag(node) {} CompoundTag(const char *filename); ~CompoundTag(); template const ListTag GetList(const char* name) const; template const T Get(const char* name) const; const Tag operator[](const char* name) const; }; //================================================== namespace Internal { nbt_node* FindByName(nbt_node* tree, const char* name); nbt_node* ListItem(nbt_node* list, int32_t index); } //================================================== template T ListTag::Get(int32_t index) const { nbt_node* result = Internal::ListItem(m_node, index); return DataTag(result); } //================================================== template const ListTag CompoundTag::GetList(const char *name) const { nbt_node *result = Internal::FindByName(m_node, name); if (result == NULL) return NULL; //if (result->type != TAG_LIST) // return NULL; return ListTag(result); } }