1 module nbtd.INBTItem;
2 
3 import nbtd;
4 
5 import std.conv;
6 
7 /// Enum for all NBT Types.
8 enum NBTType : ubyte
9 {
10 	End = cast(ubyte)0, ///
11 	Byte, ///
12 	Short, ///
13 	Int, ///
14 	Long, ///
15 	Float, ///
16 	Double, ///
17 	ByteArray, ///
18 	String, ///
19 	List, ///
20 	Compound, ///
21 	IntArray, ///
22 }
23 
24 /// Interface for all NBT TAGs containing convertion functions and virtual functions for type, size, name, value, encoding, decoding and reading from a stream.
25 interface INBTItem
26 {
27 	/// Returns: the type of the NBT Item.
28 	@property NBTType type();
29 	/// Returns: the size in bytes of the NBT Item without name.length, name or TAG ID.
30 	@property int size();
31 
32 	/// Returns: the name of the Item as UTF-8 string.
33 	@property string name();
34 	/// Sets the name of the Item as UTF-8 string.
35 	@property void name(string name);
36 
37 	/// Returns: the current value as specified in the child classes.
38 	@property T value(T)();
39 	/// Sets the current value and possible checks the input in the child classes.
40 	@property void value(T)(T value);
41 
42 	/// Encodes the item to a ubyte[] that can be compressed and/or written without name and TAG ID.
43 	/// Params:
44 	/// 	compressed = When true, the resulting ubyte[] will be GZip compressed.
45 	/// 	hasName    = When false, name and TAG ID will be omitted.
46 	ubyte[] encode(bool compressed = true, bool hasName = true);
47 
48 	/// Decodes the item from a ubyte[] that can be compressed and/or read without name and TAG ID and stores the results in `this`.
49 	/// Params:
50 	/// 	compressed = When true, the ubyte[] will get uncompressed for decoding.
51 	/// 	hasName    = When false, reading won't try to read a name and `this.name` will be set to `""`.
52 	void decode(ubyte[] data, bool compressed = true, bool hasName = true);
53 
54 	/// Decodes the item from a ubyte[] stream that can be read without name and TAG ID and stores the results in `this` and advances the stream.
55 	/// Params:
56 	/// 	hasName    = When false, reading won't try to read a name and `this.name` will be set to `""`.
57 	void read(ref ubyte[] stream, bool hasName = true);
58 
59 	/// Duplicates the Item.
60 	@property INBTItem dup();
61 
62 	final NBTByte asByte() { assert(type == NBTType.Byte, "Expected Byte, got " ~ to!string(type)); return cast(NBTByte)this; } /// Will check if the type is `NBTType.Byte` and return `this` as `NBTByte`
63 	final NBTShort asShort() { assert(type == NBTType.Short, "Expected Short, got " ~ to!string(type)); return cast(NBTShort)this; } /// Will check if the type is `NBTType.Short` and return `this` as `NBTShort`
64 	final NBTInt asInt() { assert(type == NBTType.Int, "Expected Int, got " ~ to!string(type)); return cast(NBTInt)this; } /// Will check if the type is `NBTType.Int` and return `this` as `NBTInt`
65 	final NBTLong asLong() { assert(type == NBTType.Long, "Expected Long, got " ~ to!string(type)); return cast(NBTLong)this; } /// Will check if the type is `NBTType.Long` and return `this` as `NBTLong`
66 	final NBTFloat asFloat() { assert(type == NBTType.Float, "Expected Float, got " ~ to!string(type)); return cast(NBTFloat)this; } /// Will check if the type is `NBTType.Float` and return `this` as `NBTFloat`
67 	final NBTDouble asDouble() { assert(type == NBTType.Double, "Expected Double, got " ~ to!string(type)); return cast(NBTDouble)this; } /// Will check if the type is `NBTType.Double` and return `this` as `NBTDouble`
68 	final NBTByteArray asByteArray() { assert(type == NBTType.ByteArray, "Expected ByteArray, got " ~ to!string(type)); return cast(NBTByteArray)this; } /// Will check if the type is `NBTType.ByteArray` and return `this` as `NBTByteArray`
69 	final NBTString asString() { assert(type == NBTType.String, "Expected String, got " ~ to!string(type)); return cast(NBTString)this; } /// Will check if the type is `NBTType.String` and return `this` as `NBTString`
70 	final NBTList asList() { assert(type == NBTType.List, "Expected List, got " ~ to!string(type)); return cast(NBTList)this; } /// Will check if the type is `NBTType.List` and return `this` as `NBTList`
71 	final NBTCompound asCompound() { assert(type == NBTType.Compound, "Expected Compound, got " ~ to!string(type)); return cast(NBTCompound)this; } /// Will check if the type is `NBTType.Compound` and return `this` as `NBTCompound`
72 	final NBTIntArray asIntArray() { assert(type == NBTType.IntArray, "Expected IntArray, got " ~ to!string(type)); return cast(NBTIntArray)this; } /// Will check if the type is `NBTType.IntArray` and return `this` as `NBTIntArray`
73 }