forked from cybertiger/Bukkit-LibNBT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TagType.java
303 lines (250 loc) · 9.05 KB
/
TagType.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
package org.cyberiantiger.minecraft.nbt;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.Map;
public enum TagType {
END(null, null) {
public Tag read(TagInputStream in) throws IOException {
return EndTag.VALUE;
}
public void write(Tag tag, TagOutputStream out) throws IOException {
// NOOP
}
@Override
public String readName(TagInputStream in) throws IOException {
return null;
}
@Override
public void writeName(String name, TagOutputStream out) throws IOException {
// NOOP
}
@Override
public EndTag[] newArray(int size) {
throw new IllegalStateException("Cannot construct arrays of end tags");
}
},
BYTE(ByteTag.class, Byte.class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
out.writeByte(((ByteTag) tag).getRawValue());
}
public ByteTag read(TagInputStream in) throws IOException {
return new ByteTag(in.readByte());
}
@Override
public ByteTag[] newArray(int size) {
return new ByteTag[size];
}
},
SHORT(ShortTag.class, Short.class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
out.writeShort(((ShortTag) tag).getRawValue());
}
public ShortTag read(TagInputStream in) throws IOException {
return new ShortTag(in.readShort());
}
@Override
public ShortTag[] newArray(int size) {
return new ShortTag[size];
}
},
INT(IntTag.class, Integer.class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
out.writeInt(((IntTag) tag).getRawValue());
}
public IntTag read(TagInputStream in) throws IOException {
return new IntTag(in.readInt());
}
@Override
public IntTag[] newArray(int size) {
return new IntTag[size];
}
},
LONG(LongTag.class, Long.class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
out.writeLong(((LongTag) tag).getRawValue());
}
public LongTag read(TagInputStream in) throws IOException {
return new LongTag(in.readLong());
}
@Override
public LongTag[] newArray(int size) {
return new LongTag[size];
}
},
FLOAT(FloatTag.class, Float.class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
out.writeFloat(((FloatTag) tag).getRawValue());
}
public FloatTag read(TagInputStream in) throws IOException {
return new FloatTag(in.readFloat());
}
@Override
public FloatTag[] newArray(int size) {
return new FloatTag[size];
}
},
DOUBLE(DoubleTag.class, Double.class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
out.writeDouble(((DoubleTag) tag).getRawValue());
}
public DoubleTag read(TagInputStream in) throws IOException {
return new DoubleTag(in.readDouble());
}
@Override
public DoubleTag[] newArray(int size) {
return new DoubleTag[size];
}
},
BYTE_ARRAY(ByteArrayTag.class, byte[].class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
byte[] data = ((ByteArrayTag) tag).getValue();
out.writeInt(data.length);
out.write(data);
}
public ByteArrayTag read(TagInputStream in) throws IOException {
int length = in.readInt();
byte[] value = new byte[length];
in.readFully(value);
return new ByteArrayTag(value);
}
@Override
public ByteArrayTag[] newArray(int size) {
return new ByteArrayTag[size];
}
},
STRING(StringTag.class, String.class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
out.writeMCString(((StringTag) tag).getValue());
}
public StringTag read(TagInputStream in) throws IOException {
return new StringTag(in.readMCString());
}
@Override
public StringTag[] newArray(int size) {
return new StringTag[size];
}
},
LIST(ListTag.class, Tag[].class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
TagType type = ((ListTag) tag).getListType();
Tag[] values = ((ListTag) tag).getValue();
out.writeByte(type.ordinal());
if (values == null) {
out.writeInt(0);
} else {
out.writeInt(values.length);
for (int i = 0; i < values.length; i++) {
type.write(values[i], out);
}
}
}
public ListTag read(TagInputStream in) throws IOException {
TagType type = TagType.values()[in.readByte()];
int length = in.readInt();
if (type == TagType.END) {
if (length == 0 ) {
return new ListTag(type, null);
} else {
throw new IOException("Illegal list tag, had type of 0 and non-zero length");
}
} else {
Tag[] value = (Tag[]) Array.newInstance(type.getTagClass(), length);
for (int i = 0; i < length; i++) {
value[i] = type.read(in);
}
return new ListTag(type, value);
}
}
@Override
public ListTag[] newArray(int size) {
return new ListTag[size];
}
},
COMPOUND(CompoundTag.class, Map.class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
for (Map.Entry<String, Tag> e : ((CompoundTag)tag).getValue().entrySet()) {
out.writeTag(e);
}
out.writeTag(EndTag.TUPLE);
}
public CompoundTag read(TagInputStream in) throws IOException {
Map<String, Tag> values = new HashMap<>();
while (true) {
TagTuple<? extends Tag> tag = in.readTag();
if (tag.getValue().getType() == TagType.END) {
break;
}
values.put(tag.getKey(), tag.getValue());
}
return new CompoundTag(values);
}
@Override
public CompoundTag[] newArray(int size) {
return new CompoundTag[size];
}
},
INT_ARRAY(IntArrayTag.class, int[].class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
int[] value = ((IntArrayTag)tag).getValue();
out.writeInt(value.length);
for (int i = 0; i < value.length; i++) {
out.writeInt(value[i]);
}
}
public IntArrayTag read(TagInputStream in) throws IOException {
int length = in.readInt();
int[] value = new int[length];
for (int i = 0; i < length; i++) {
value[i] = in.readInt();
}
return new IntArrayTag(value);
}
@Override
public IntArrayTag[] newArray(int size) {
return new IntArrayTag[size];
}
},
LONG_ARRAY(LongArrayTag.class, long[].class) {
public void write(Tag tag, TagOutputStream out) throws IOException {
long[] value = ((LongArrayTag) tag).getValue();
out.writeInt(value.length);
for (int i = 0; i < value.length; i++) {
out.writeLong(value[i]);
}
}
public LongArrayTag read(TagInputStream in) throws IOException {
int length = in.readInt();
long[] value = new long[length];
for (int i = 0; i < length; i++) {
value[i] = in.readLong();
}
return new LongArrayTag(value);
}
@Override
public LongArrayTag[] newArray(int size) {
return new LongArrayTag[size];
}
};
private final Class<? extends Tag> tagClass;
private final Class<?> valueClass;
private TagType(Class<? extends Tag> tagClass, Class<?> valueClass) {
this.tagClass = tagClass;
this.valueClass = valueClass;
}
public Class<? extends Tag> getTagClass() {
return tagClass;
}
public Class<?> getValueClass() {
return valueClass;
}
public abstract <T extends Tag> T read(TagInputStream in) throws IOException;
public String readName(TagInputStream in) throws IOException {
return in.readMCString();
}
public abstract <T extends Tag> void write(T tag, TagOutputStream out) throws IOException;
public void writeName(String name, TagOutputStream out) throws IOException {
out.writeMCString(name);
}
public abstract <T extends Tag> T[] newArray(int size);
}