1 module nbtd;
2 
3 public
4 {
5 	import nbtd.INBTItem;
6 	import nbtd.NBTCommon;
7 	import nbtd.NBTEnd;
8 	import nbtd.NBTList;
9 	import nbtd.NBTCompound;
10 
11 	/// Helper function for uncompressing a full GZip byte array
12 	ubyte[] uncompressGZip(ubyte[] data)
13 	{
14 		import std.zlib;
15 
16 		UnCompress uncompressor = new UnCompress(HeaderFormat.gzip);
17 		ubyte[] result;
18 		while(data.length > 1024)
19 		{
20 			result ~= cast(ubyte[])uncompressor.uncompress(data[0 .. 1024]);
21 			data = data[1024 .. $];
22 		}
23 		result ~= cast(ubyte[])uncompressor.uncompress(data);
24 		result ~= cast(ubyte[])uncompressor.flush();
25 		return result;
26 	}
27 
28 	/// Helper function for GZiping a full byte array
29 	ubyte[] compressGZip(ubyte[] data)
30 	{
31 		import std.zlib;
32 
33 		Compress compressor = new Compress(HeaderFormat.gzip);
34 		ubyte[] result;
35 		while(data.length > 1024)
36 		{
37 			result ~= cast(ubyte[])compressor.compress(data[0 .. 1024]);
38 			data = data[1024 .. $];
39 		}
40 		result ~= cast(ubyte[])compressor.compress(data);
41 		result ~= cast(ubyte[])compressor.flush();
42 		return result;
43 	}
44 
45 	/// Function to read a element from a stream and advance the stream
46 	INBTItem parseElement(ref ubyte[] stream, bool hasName = true)
47 	{
48 		import std.conv;
49 
50 		switch(stream[0])
51 		{
52 		case 0:
53 			if(hasName)
54 				stream = stream[1 .. $];
55 			return new NBTEnd();
56 		case 1:
57 		{
58 			auto value = new NBTByte();
59 			value.read(stream, hasName);
60 			return value;
61 		}
62 		case 2:
63 		{
64 			auto value = new NBTShort();
65 			value.read(stream, hasName);
66 			return value;
67 		}
68 		case 3:
69 		{
70 			auto value = new NBTInt();
71 			value.read(stream, hasName);
72 			return value;
73 		}
74 		case 4:
75 		{
76 			auto value = new NBTLong();
77 			value.read(stream, hasName);
78 			return value;
79 		}
80 		case 5:
81 		{
82 			auto value = new NBTFloat();
83 			value.read(stream, hasName);
84 			return value;
85 		}
86 		case 6:
87 		{
88 			auto value = new NBTDouble();
89 			value.read(stream, hasName);
90 			return value;
91 		}
92 		case 7:
93 		{
94 			auto value = new NBTByteArray();
95 			value.read(stream, hasName);
96 			return value;
97 		}
98 		case 8:
99 		{
100 			auto value = new NBTString();
101 			value.read(stream, hasName);
102 			return value;
103 		}
104 		case 9:
105 		{
106 			auto value = new NBTList();
107 			value.read(stream, hasName);
108 			return value;
109 		}
110 		case 10:
111 		{
112 			auto value = new NBTCompound();
113 			value.read(stream, hasName);
114 			return value;
115 		}
116 		case 11:
117 		{
118 			auto value = new NBTIntArray();
119 			value.read(stream, hasName);
120 			return value;
121 		}
122 		default:
123 			throw new Exception("Invalid NBT-TAG(" ~ to!string(stream[0]) ~ ")!");
124 		}
125 	}
126 
127 	/// Function to read a specified element from a stream and advance the stream
128 	INBTItem parseElement(NBTType type, ref ubyte[] stream, bool hasName = true)
129 	{
130 		import std.conv;
131 
132 		switch(type)
133 		{
134 		case 0:
135 			if(hasName)
136 				stream = stream[1 .. $];
137 			return new NBTEnd();
138 		case 1:
139 		{
140 			auto value = new NBTByte();
141 			value.read(stream, hasName);
142 			return value;
143 		}
144 		case 2:
145 		{
146 			auto value = new NBTShort();
147 			value.read(stream, hasName);
148 			return value;
149 		}
150 		case 3:
151 		{
152 			auto value = new NBTInt();
153 			value.read(stream, hasName);
154 			return value;
155 		}
156 		case 4:
157 		{
158 			auto value = new NBTLong();
159 			value.read(stream, hasName);
160 			return value;
161 		}
162 		case 5:
163 		{
164 			auto value = new NBTFloat();
165 			value.read(stream, hasName);
166 			return value;
167 		}
168 		case 6:
169 		{
170 			auto value = new NBTDouble();
171 			value.read(stream, hasName);
172 			return value;
173 		}
174 		case 7:
175 		{
176 			auto value = new NBTByteArray();
177 			value.read(stream, hasName);
178 			return value;
179 		}
180 		case 8:
181 		{
182 			auto value = new NBTString();
183 			value.read(stream, hasName);
184 			return value;
185 		}
186 		case 9:
187 		{
188 			auto value = new NBTList();
189 			value.read(stream, hasName);
190 			return value;
191 		}
192 		case 10:
193 		{
194 			auto value = new NBTCompound();
195 			value.read(stream, hasName);
196 			return value;
197 		}
198 		case 11:
199 		{
200 			auto value = new NBTIntArray();
201 			value.read(stream, hasName);
202 			return value;
203 		}
204 		default:
205 			throw new Exception("Invalid NBT-TAG(" ~ to!string(type) ~ ")!");
206 		}
207 	}
208 }