119 lines
2.7 KiB
C++
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);
|
|
}
|
|
} |