#include "NBT.h" #include "cNBT/nbt.h" #include "cNBT/list.h" #include #include #include 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(node); case TAG_SHORT: return DataTag(node); case TAG_INT: return DataTag(node); case TAG_LONG: return DataTag(node); case TAG_FLOAT: return DataTag(node); case TAG_DOUBLE: return DataTag(node); case TAG_BYTE_ARRAY: return ArrayTag(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(node); case TAG_LONG_ARRAY: return ArrayTag(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(node); case TAG_SHORT: return ListTag(node); case TAG_INT: return ListTag(node); case TAG_LONG: return ListTag(node); case TAG_FLOAT: return ListTag(node); case TAG_DOUBLE: return ListTag(node); case TAG_BYTE_ARRAY: return ListTag>(node); case TAG_STRING: return ListTag(node); case TAG_LIST: return CreateListTag(node); case TAG_COMPOUND: return ListTag(node); case TAG_INT_ARRAY: return ListTag>(node); case TAG_LONG_ARRAY: return ListTag>(node); case TAG_INVALID: default: return NULL; } } const char *Tag::GetName() const { return m_node->name ? m_node->name : ""; } 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::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 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::GetValue() const { return m_node->payload.tag_byte; } // Short template <> int16_t DataTag::GetValue() const { return m_node->payload.tag_short; } // Int template <> int32_t DataTag::GetValue() const { return m_node->payload.tag_int; } // Long template <> int64_t DataTag::GetValue() const { return m_node->payload.tag_long; } // Float template <> float DataTag::GetValue() const { return m_node->payload.tag_float; } // Double template <> double DataTag::GetValue() const { return m_node->payload.tag_double; } // String template <> const char* DataTag::GetValue() const { return m_node->payload.tag_string; } //================================================== // Byte Array template <> const int8_t* ArrayTag::GetValue() const { return (const int8_t*)(m_node->payload.tag_byte_array.data); } // Int Array template <> const int32_t* ArrayTag::GetValue() const { return m_node->payload.tag_int_array.data; } // Long Array template <> const int64_t* ArrayTag::GetValue() const { return m_node->payload.tag_long_array.data; } // String template <> const char* StringTag::GetValue() const { return m_node->payload.tag_string; } }