FeatherMC/src/nbt/NBT.h

119 lines
2.7 KiB
C++

#pragma once
#include <stddef.h>
#include <iostream>
#include <vector>
#include <iterator>
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 <typename T>
class DataTag : public Tag
{
public:
DataTag<T>(nbt_node* node) : Tag(node) {}
T GetValue() const;
inline operator T() const { return GetValue(); }
};
template <typename T>
class ArrayTag : public DataTag<T*>
{
public:
ArrayTag<T>(nbt_node* node) : DataTag<T*>(node) {}
const T* GetValue() const;
const T* begin() { return GetValue(); }
const T* end() { return &(GetValue()[this->GetLength()]); }
};
using StringTag = ArrayTag<char>;
template <typename T>
class ListTag : public Tag
{
public:
ListTag<T>(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 <typename T>
const ListTag<T> GetList(const char* name) const;
template <typename T>
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 <typename T>
T ListTag<T>::Get(int32_t index) const
{
nbt_node* result = Internal::ListItem(m_node, index);
return DataTag<T>(result);
}
//==================================================
template <typename T>
const ListTag<T> 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<T>(result);
}
}