Attempted NBT library with templates

This was a bad idea lol
This commit is contained in:
DankParrot 2020-08-02 21:29:05 -07:00
parent fb0738b37e
commit 4b6646d8a0
3 changed files with 305 additions and 0 deletions

View File

@ -5,6 +5,8 @@ feather_src = [
'logging/Logger.cpp',
'nbt/NBT.cpp',
'network/NetworkManager.cpp',
'network/TCPListener.cpp',
'network/TCPClient.cpp',

184
src/nbt/NBT.cpp Normal file
View File

@ -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; }
}

119
src/nbt/NBT.h Normal file
View File

@ -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);
}
}