Attempted NBT library with templates
This was a bad idea lol
This commit is contained in:
parent
fb0738b37e
commit
4b6646d8a0
|
@ -5,6 +5,8 @@ feather_src = [
|
|||
|
||||
'logging/Logger.cpp',
|
||||
|
||||
'nbt/NBT.cpp',
|
||||
|
||||
'network/NetworkManager.cpp',
|
||||
'network/TCPListener.cpp',
|
||||
'network/TCPClient.cpp',
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
#include "NBT.h"
|
||||
|
||||
#include "cNBT/nbt.h"
|
||||
#include "cNBT/list.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
|
||||
namespace NBT
|
||||
{
|
||||
nbt_node* Internal::FindByName(nbt_node* tree, const char* name)
|
||||
{
|
||||
return nbt_find_by_name(tree, name);
|
||||
}
|
||||
|
||||
nbt_node* Internal::ListItem(nbt_node* list, int32_t index)
|
||||
{
|
||||
return nbt_list_item(list, index);
|
||||
}
|
||||
|
||||
Tag Tag::CreateTag(nbt_node *node)
|
||||
{
|
||||
switch (node->type)
|
||||
{
|
||||
case TAG_BYTE: return DataTag<int8_t>(node);
|
||||
case TAG_SHORT: return DataTag<int16_t>(node);
|
||||
case TAG_INT: return DataTag<int32_t>(node);
|
||||
case TAG_LONG: return DataTag<int64_t>(node);
|
||||
case TAG_FLOAT: return DataTag<float>(node);
|
||||
case TAG_DOUBLE: return DataTag<double>(node);
|
||||
case TAG_BYTE_ARRAY: return ArrayTag<int8_t>(node);
|
||||
case TAG_STRING: return StringTag(node);
|
||||
case TAG_LIST: return CreateListTag(node);
|
||||
case TAG_COMPOUND: return CompoundTag(node);
|
||||
case TAG_INT_ARRAY: return ArrayTag<int32_t>(node);
|
||||
case TAG_LONG_ARRAY: return ArrayTag<int64_t>(node);
|
||||
|
||||
case TAG_INVALID:
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Tag Tag::CreateListTag(nbt_node* node)
|
||||
{
|
||||
nbt_type type = node->payload.tag_list->data->type;
|
||||
switch (type)
|
||||
{
|
||||
case TAG_BYTE: return ListTag<int8_t>(node);
|
||||
case TAG_SHORT: return ListTag<int16_t>(node);
|
||||
case TAG_INT: return ListTag<int32_t>(node);
|
||||
case TAG_LONG: return ListTag<int64_t>(node);
|
||||
case TAG_FLOAT: return ListTag<float>(node);
|
||||
case TAG_DOUBLE: return ListTag<double>(node);
|
||||
case TAG_BYTE_ARRAY: return ListTag<ArrayTag<int8_t>>(node);
|
||||
case TAG_STRING: return ListTag<StringTag>(node);
|
||||
case TAG_LIST: return CreateListTag(node);
|
||||
case TAG_COMPOUND: return ListTag<CompoundTag>(node);
|
||||
case TAG_INT_ARRAY: return ListTag<ArrayTag<int32_t>>(node);
|
||||
case TAG_LONG_ARRAY: return ListTag<ArrayTag<int64_t>>(node);
|
||||
|
||||
case TAG_INVALID:
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *Tag::GetName() const
|
||||
{
|
||||
return m_node->name ? m_node->name : "<null>";
|
||||
}
|
||||
|
||||
size_t Tag::GetLength() const
|
||||
{
|
||||
switch (m_node->type)
|
||||
{
|
||||
case TAG_BYTE_ARRAY:
|
||||
return m_node->payload.tag_byte_array.length;
|
||||
case TAG_INT_ARRAY:
|
||||
return m_node->payload.tag_int_array.length;
|
||||
case TAG_LONG_ARRAY:
|
||||
return m_node->payload.tag_long_array.length;
|
||||
|
||||
case TAG_LIST:
|
||||
return list_length(&(m_node->payload.tag_list->entry));
|
||||
case TAG_COMPOUND:
|
||||
return list_length(&(m_node->payload.tag_compound->entry));
|
||||
|
||||
// nbt_size(node) is only used for non-list types because
|
||||
// it gets the total number of nodes, rather than immediate children
|
||||
// and it treats arrays as consisting of one node
|
||||
default:
|
||||
// will return 1 for most types and 0 for invalid
|
||||
return nbt_size(m_node);
|
||||
}
|
||||
}
|
||||
|
||||
const char *Tag::ToString() const
|
||||
{
|
||||
return nbt_dump_ascii(m_node);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const Tag& tag)
|
||||
{
|
||||
return stream << tag.ToString();
|
||||
}
|
||||
|
||||
//==================================================
|
||||
|
||||
|
||||
|
||||
//==================================================
|
||||
|
||||
template <>
|
||||
Tag ListTag<Tag>::Get(int32_t index) const
|
||||
{
|
||||
nbt_node* result = nbt_list_item(m_node, index);
|
||||
return Tag::CreateTag(result);
|
||||
}
|
||||
|
||||
//==================================================
|
||||
|
||||
CompoundTag::CompoundTag(const char *filename)
|
||||
: CompoundTag(nbt_parse_path(filename))
|
||||
{
|
||||
}
|
||||
|
||||
CompoundTag::~CompoundTag()
|
||||
{
|
||||
nbt_free(m_node);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T CompoundTag::Get(const char *name) const
|
||||
{
|
||||
nbt_node *result = nbt_find_by_name(m_node, name);
|
||||
return T(result);
|
||||
}
|
||||
|
||||
const Tag CompoundTag::operator[](const char *name) const
|
||||
{
|
||||
nbt_node *result = nbt_find_by_name(m_node, name);
|
||||
|
||||
return Tag::CreateTag(result);
|
||||
}
|
||||
|
||||
//==================================================
|
||||
|
||||
// Byte
|
||||
template <> int8_t DataTag<int8_t>::GetValue() const { return m_node->payload.tag_byte; }
|
||||
|
||||
// Short
|
||||
template <> int16_t DataTag<int16_t>::GetValue() const { return m_node->payload.tag_short; }
|
||||
|
||||
// Int
|
||||
template <> int32_t DataTag<int32_t>::GetValue() const { return m_node->payload.tag_int; }
|
||||
|
||||
// Long
|
||||
template <> int64_t DataTag<int64_t>::GetValue() const { return m_node->payload.tag_long; }
|
||||
|
||||
// Float
|
||||
template <> float DataTag<float>::GetValue() const { return m_node->payload.tag_float; }
|
||||
|
||||
// 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
|
||||
template <> const int8_t* ArrayTag<int8_t>::GetValue() const { return (const int8_t*)(m_node->payload.tag_byte_array.data); }
|
||||
|
||||
// Int Array
|
||||
template <> const int32_t* ArrayTag<int32_t>::GetValue() const { return m_node->payload.tag_int_array.data; }
|
||||
|
||||
// Long Array
|
||||
template <> const int64_t* ArrayTag<int64_t>::GetValue() const { return m_node->payload.tag_long_array.data; }
|
||||
|
||||
// String
|
||||
template <> const char* StringTag::GetValue() const { return m_node->payload.tag_string; }
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
#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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue