From 69a4ee53830121714927c37e4f0b9a357cd03957 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Wed, 7 Mar 2012 11:28:24 +0000 Subject: Added the Anvil level format (MCA) support, read-only for the time being. Now MCS can read your worlds from the official server :) git-svn-id: http://mc-server.googlecode.com/svn/trunk@380 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/NBT.h | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 source/NBT.h (limited to 'source/NBT.h') diff --git a/source/NBT.h b/source/NBT.h new file mode 100644 index 000000000..5bad0492c --- /dev/null +++ b/source/NBT.h @@ -0,0 +1,201 @@ + +// NBT.h + +// Interfaces to the classes used for NBT representation, parsing and serializing + + + + + +#pragma once + + + + + +typedef long long Int64; +typedef int Int32; +typedef short Int16; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Representation classes: + +class cNBTTag abstract // The base class for all NBT tags +{ +public: + enum eTagType + { + TAG_Min = 0, // The minimum value for a tag type + TAG_End = 0, + TAG_Byte = 1, + TAG_Short = 2, + TAG_Int = 3, + TAG_Long = 4, + TAG_Float = 5, + TAG_Double = 6, + TAG_ByteArray = 7, + TAG_String = 8, + TAG_List = 9, + TAG_Compound = 10, + TAG_IntArray = 11, + TAG_Max = 11, // The maximum value for a tag type + } ; + +protected: + cNBTTag * m_Parent; + eTagType m_Type; + AString m_Name; // tag name, in UTF-8 + +public: + cNBTTag(cNBTTag * a_Parent, eTagType a_Type) : m_Parent(a_Parent), m_Type(a_Type) {} + cNBTTag(cNBTTag * a_Parent, eTagType a_Type, const AString & a_Name) : m_Parent(a_Parent), m_Type(a_Type), m_Name(a_Name) {} + virtual ~cNBTTag() {} // Force a virtual destructor + + cNBTTag * GetParent(void) const {return m_Parent; } + eTagType GetType (void) const {return m_Type; } + const AString & GetName (void) const {return m_Name; } + void SetName (const AString & a_Name) {m_Name = a_Name; } + + static cNBTTag * CreateTag(cNBTTag * a_Parent, eTagType a_Type, const AString & a_Name); // Creates a new instance of a tag specified by iType, uses the correct class + + virtual cNBTTag * FindChildByName(const AString & a_Name) {return NULL; } + cNBTTag * FindChildByPath(const AString & a_Path); +} ; + +typedef cNBTTag cNBTTree; +typedef std::vector cNBTTags; + + + + + +#define DECLARE_SIMPLE_TAG(TAG,CTYPE) \ +class cNBT##TAG : \ + public cNBTTag \ +{ \ +public: \ + cNBT##TAG(cNBTTag * a_Parent) : cNBTTag(a_Parent, TAG_##TAG) {} \ + cNBT##TAG(cNBTTag * a_Parent, const AString & a_Name) : cNBTTag(a_Parent, TAG_##TAG, a_Name) {} \ + cNBT##TAG(cNBTTag * a_Parent, const AString & a_Name, const CTYPE & a_Value) : cNBTTag(a_Parent, TAG_##TAG, a_Name), m_Value(a_Value) {} \ + CTYPE m_Value; \ +} + + + + + +DECLARE_SIMPLE_TAG(Byte, char); +DECLARE_SIMPLE_TAG(Short, Int16); +DECLARE_SIMPLE_TAG(Int, Int32); +DECLARE_SIMPLE_TAG(Long, Int64); +DECLARE_SIMPLE_TAG(Float, float); +DECLARE_SIMPLE_TAG(Double, double); +DECLARE_SIMPLE_TAG(ByteArray, AString); // Represent the array as a string for easier manipulation +DECLARE_SIMPLE_TAG(String, AString); + + + + + + +class cNBTList : + public cNBTTag +{ + cNBTTags m_Children; + eTagType m_ChildrenType; + +public: + cNBTList(cNBTTag * a_Parent) : cNBTTag(a_Parent, TAG_List), m_ChildrenType(TAG_End) {} + cNBTList(cNBTTag * a_Parent, const AString & a_Name) : cNBTTag(a_Parent, TAG_List, a_Name), m_ChildrenType(TAG_End) {} + virtual ~cNBTList() {Clear(); } + + void Clear (void); + int Add (cNBTTag * a_Tag); + cNBTTag * GetChildByIdx (size_t a_Index); + const cNBTTags & GetChildren (void) const {return m_Children; } + size_t GetChildrenCount(void) const {return m_Children.size(); } + virtual cNBTTag * FindChildByName (const AString & a_Name) override; + + int SetChildrenType(eTagType a_Type); // Only valid when list empty + eTagType GetChildrenType(void) const {return m_ChildrenType; } +} ; + + + + + +class cNBTCompound : + public cNBTTag +{ + cNBTTags m_Children; +public: + cNBTCompound(cNBTTag * a_Parent) : cNBTTag(a_Parent, TAG_Compound) {} + cNBTCompound(cNBTTag * a_Parent, const AString & a_Name) : cNBTTag(a_Parent, TAG_Compound, a_Name) {} + virtual ~cNBTCompound() {Clear(); } + + void Clear (void); + int Add (cNBTTag * a_Tag); + cNBTTag * GetChildByIdx (size_t a_Index); + const cNBTTags & GetChildren (void) const {return m_Children; } + size_t GetChildrenCount(void) const {return m_Children.size(); } + virtual cNBTTag * FindChildByName (const AString & a_Name) override; +} ; + + + + + +class cNBTIntArray : + public cNBTTag +{ + typedef cNBTTag super; + + std::vector m_Values; + +public: + cNBTIntArray(cNBTTag * a_Parent) : super(a_Parent, TAG_IntArray) {} + cNBTIntArray(cNBTTag * a_Parent, const AString & a_Name) : super(a_Parent, TAG_IntArray, a_Name) {} + + void Clear(void) {m_Values.clear(); } + void Add (int a_Value) {m_Values.push_back(a_Value); } + int Get (int a_Index) const {return m_Values[a_Index]; } + int Size (void) const {return m_Values.size(); } + const std::vector & GetValues(void) const {return m_Values; } +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// The parser: + +class cNBTParser +{ + static int ReadTag (const char ** Data, int * Length, cNBTTag::eTagType iType, const AString & a_Name, cNBTTag * iParent, cNBTTag ** oTag); // Helper + + static int ReadByte (const char ** Data, int * Length, char & a_Value); + static int ReadInt16 (const char ** Data, int * Length, Int16 & a_Value); + static int ReadInt32 (const char ** Data, int * Length, Int32 & a_Value); + static int ReadInt64 (const char ** Data, int * Length, Int64 & a_Value); + static int ReadFloat (const char ** Data, int * Length, float & a_Value); + static int ReadDouble (const char ** Data, int * Length, double & a_Value); + static int ReadByteArray(const char ** Data, int * Length, AString & a_Value); + static int ReadString (const char ** Data, int * Length, AString & a_Value); + static int ReadList (const char ** Data, int * Length, cNBTList * a_List); + static int ReadCompound (const char ** Data, int * Length, cNBTCompound * a_Compound); + static int ReadIntArray (const char ** Data, int * Length, cNBTIntArray * a_Array); + +public: + + /// Returns the parsed tree, or NULL on failure + static cNBTTree * Parse(const char * a_Data, int a_Length); +} ; + + + + -- cgit v1.2.3