diff --git a/src/nbt/NBT.cpp b/src/nbt/NBT.cpp index 40b7102..4d162f1 100644 --- a/src/nbt/NBT.cpp +++ b/src/nbt/NBT.cpp @@ -23,7 +23,15 @@ namespace NBT { // The first node in nbt_list is the sentinel node, // so the first node is the one right after it. - return GetNextItem(&(list->payload.tag_list->entry)); + switch (list->type) + { + case TAG_LIST: + return GetNextItem(&(list->payload.tag_list->entry)); + case TAG_COMPOUND: + return GetNextItem(&(list->payload.tag_compound->entry)); + default: + return nullptr; + } } list_head* Internal::GetNextItem(list_head* item) @@ -133,6 +141,21 @@ namespace NBT return result; } + const char* Tag::GetValueString() const + { + // TODO: stringification for all other types + switch (m_node->type) + { + case TAG_STRING: + return ((StringTag*)this)->GetValue(); + + case TAG_INVALID: + default: + return ToString(); + + } + } + const char *Tag::ToString() const { return nbt_dump_ascii(m_node); @@ -203,9 +226,6 @@ namespace NBT // Double template <> double DataTag::GetValue() const { return m_node->payload.tag_double; } - // String - template <> const char* DataTag::GetValue() const { return m_node->payload.tag_string; } - //================================================== // Byte Array diff --git a/src/nbt/NBT.h b/src/nbt/NBT.h index 334b27c..e3c4c67 100644 --- a/src/nbt/NBT.h +++ b/src/nbt/NBT.h @@ -44,6 +44,8 @@ namespace NBT // Get uncompressed NBT binary data const DataBuffer GetData() const; + virtual const char* GetValueString() const; + const char* ToString() const; operator bool() const; @@ -104,10 +106,16 @@ namespace NBT { // Iterator for use in range-based for loops. // TODO: this might not need to be a nested class - class iterator : public std::iterator + class iterator { list_head* m_pos; public: + using iterator_category = std::input_iterator_tag; + using value_type = T; + using difference_type = int32_t; + using pointer = const T*; + using reference = const T&; + // TODO: could inline some of this explicit iterator(ListTag& tag, int32_t offset = 0) : m_pos(Internal::GetFirstItem(tag.m_node)) @@ -135,6 +143,31 @@ namespace NBT // A Compound Tag is an unordered list of named tags class CompoundTag : public Tag { + // TODO: see ListTag::iterator + class iterator + { + list_head* m_pos; + public: + using iterator_category = std::input_iterator_tag; + using value_type = Tag; + using difference_type = int32_t; + using pointer = const Tag*; + using reference = const Tag&; + + // TODO: could inline some of this + + explicit iterator(CompoundTag& tag, int32_t offset = 0) : m_pos(Internal::GetFirstItem(tag.m_node)) + { + // If we have an offset, call operator++ that number of times + for (int i = 0; i < offset; i++) { ++(*this); } + } + iterator& operator++() { m_pos = Internal::GetNextItem(m_pos); return *this; } + bool operator==(iterator other) const { return m_pos == other.m_pos; } + bool operator!=(iterator other) const { return !(*this == other); } + Tag operator*() const { return Tag::CreateTag(Internal::GetListEntry(m_pos)); } + }; + + // only true if the tree was allocated by constructor const bool m_isRoot; @@ -159,6 +192,9 @@ namespace NBT inline const CompoundTag GetCompound(const char* name) const { return Get(name); } const Tag operator[](const char* name) const; + + iterator begin() { return iterator(*this); } + iterator end() { return iterator(*this, Tag::GetLength()); } }; //==================================================