summaryrefslogtreecommitdiffstats
path: root/source/NBT.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/NBT.h')
-rw-r--r--source/NBT.h201
1 files changed, 201 insertions, 0 deletions
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<cNBTTag *> 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<int> 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<int> & 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);
+} ;
+
+
+
+