NBT iterator for CompoundTag + fix warnings

This commit is contained in:
DankParrot 2020-08-13 18:38:43 -07:00
parent 5d1257456f
commit 83ecf57e76
2 changed files with 61 additions and 5 deletions

View File

@ -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.
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<double>::GetValue() const { return m_node->payload.tag_double; }
// String
template <> const char* DataTag<const char*>::GetValue() const { return m_node->payload.tag_string; }
//==================================================
// Byte Array

View File

@ -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<std::input_iterator_tag, T, int32_t, const T*, const T&>
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<T>& 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<CompoundTag>(name); }
const Tag operator[](const char* name) const;
iterator begin() { return iterator(*this); }
iterator end() { return iterator(*this, Tag::GetLength()); }
};
//==================================================