разделение на разные модули кодека и сущностей
This commit is contained in:
13
vanilla-codec/src/main/java/mc/nbt/codec/vanilla/Codec.java
Normal file
13
vanilla-codec/src/main/java/mc/nbt/codec/vanilla/Codec.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.Tag;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Codec<T extends Tag> {
|
||||
|
||||
T decode(NbtInputStream in) throws IOException;
|
||||
void encode(T tag, NbtOutputStream out) throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import mc.nbt.TypeTag;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum CodecEnum {
|
||||
|
||||
END(TypeTag.END, new TagEndCodec()),
|
||||
BYTE(TypeTag.BYTE, new TagByteCodec()),
|
||||
SHORT(TypeTag.SHORT, new TagShortCodec()),
|
||||
INT(TypeTag.INT, new TagIntCodec()),
|
||||
LONG(TypeTag.LONG, new TagLongCodec()),
|
||||
FLOAT(TypeTag.FLOAT, new TagFloatCodec()),
|
||||
DOUBLE(TypeTag.DOUBLE, new TagDoubleCodec()),
|
||||
BYTE_ARRAY(TypeTag.BYTE_ARRAY, new TagByteArrayCodec()),
|
||||
STRING(TypeTag.STRING, new TagStringCodec()),
|
||||
LIST(TypeTag.LIST, new TagListCodec()),
|
||||
COMPOUND(TypeTag.COMPOUND, new TagCompoundCodec()),
|
||||
INT_ARRAY(TypeTag.INT_ARRAY, new TagIntArrayCodec()),
|
||||
LONG_ARRAY(TypeTag.LONG_ARRAY, new TagLongArrayCodec());
|
||||
|
||||
public static CodecEnum valueOfTypeTag(TypeTag typeTag) {
|
||||
return Stream.of(CodecEnum.values())
|
||||
.filter(codecEnum -> codecEnum.getTypeTag() == typeTag)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("Codec for " + typeTag.name() + " not found"));
|
||||
}
|
||||
|
||||
private final TypeTag typeTag;
|
||||
private final Codec codec;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagByteArray;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class TagByteArrayCodec implements Codec<TagByteArray> {
|
||||
|
||||
@Override
|
||||
public TagByteArray decode(NbtInputStream in) throws IOException {
|
||||
byte[] value = new byte[in.readInt()];
|
||||
in.read(value);
|
||||
return new TagByteArray(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagByteArray tag, NbtOutputStream out) throws IOException {
|
||||
out.writeInt(tag.getValue().length);
|
||||
out.write(tag.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagByte;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class TagByteCodec implements Codec<TagByte> {
|
||||
|
||||
@Override
|
||||
public TagByte decode(NbtInputStream in) throws IOException {
|
||||
return new TagByte(in.readByte());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagByte tag, NbtOutputStream out) throws IOException {
|
||||
out.writeByte(tag.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.TypeTag;
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.Tag;
|
||||
import mc.nbt.tag.TagCompound;
|
||||
import mc.nbt.tag.TagEnd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class TagCompoundCodec implements Codec<TagCompound> {
|
||||
|
||||
@Override
|
||||
public TagCompound decode(NbtInputStream in) throws IOException {
|
||||
List<Tag> tagList = new ArrayList<>();
|
||||
|
||||
while (true) {
|
||||
Tag tag = in.readTag();
|
||||
if (tag.getType() == TypeTag.END) {
|
||||
break;
|
||||
}
|
||||
|
||||
tagList.add(tag);
|
||||
}
|
||||
|
||||
TagCompound tagCompound = new TagCompound();
|
||||
tagCompound.setValue(tagList);
|
||||
return tagCompound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagCompound tag, NbtOutputStream out) throws IOException {
|
||||
for (Tag itemTag : tag.getValue()) {
|
||||
out.writeTag(itemTag);
|
||||
}
|
||||
|
||||
out.writeTag(TagEnd.INSTANCE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagDouble;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TagDoubleCodec implements Codec<TagDouble> {
|
||||
|
||||
@Override
|
||||
public TagDouble decode(NbtInputStream in) throws IOException {
|
||||
return new TagDouble(in.readDouble());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagDouble tag, NbtOutputStream out) throws IOException {
|
||||
out.writeDouble(tag.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagEnd;
|
||||
|
||||
class TagEndCodec implements Codec<TagEnd> {
|
||||
|
||||
@Override
|
||||
public TagEnd decode(NbtInputStream in) {
|
||||
return TagEnd.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagEnd tag, NbtOutputStream out) {
|
||||
//nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagFloat;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TagFloatCodec implements Codec<TagFloat> {
|
||||
|
||||
@Override
|
||||
public TagFloat decode(NbtInputStream in) throws IOException {
|
||||
return new TagFloat(in.readFloat());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagFloat tag, NbtOutputStream out) throws IOException {
|
||||
out.writeFloat(tag.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagIntArray;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TagIntArrayCodec implements Codec<TagIntArray> {
|
||||
|
||||
@Override
|
||||
public TagIntArray decode(NbtInputStream in) throws IOException {
|
||||
final int[] value = new int[in.readInt()];
|
||||
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
value[i] = in.readInt();
|
||||
}
|
||||
|
||||
return new TagIntArray(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagIntArray tag, NbtOutputStream out) throws IOException {
|
||||
out.writeInt(tag.getValue().length);
|
||||
for (int item : tag.getValue()) {
|
||||
out.writeInt(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagInt;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class TagIntCodec implements Codec<TagInt> {
|
||||
|
||||
@Override
|
||||
public TagInt decode(NbtInputStream in) throws IOException {
|
||||
return new TagInt(in.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagInt tag, NbtOutputStream out) throws IOException {
|
||||
out.writeInt(tag.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.TypeTag;
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.Tag;
|
||||
import mc.nbt.tag.TagList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class TagListCodec implements Codec<TagList> {
|
||||
|
||||
@Override
|
||||
public TagList decode(NbtInputStream in) throws IOException {
|
||||
final Codec typeCodec = CodecEnum.valueOfTypeTag(TypeTag.getTypeById(in.readByte())).getCodec();
|
||||
final int size = in.readInt();
|
||||
|
||||
List<Tag> tagList;
|
||||
if (size > 0) {
|
||||
tagList = new ArrayList<>(size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
tagList.add(typeCodec.decode(in));
|
||||
}
|
||||
} else {
|
||||
tagList = Collections.emptyList();
|
||||
}
|
||||
|
||||
return new TagList(tagList);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void encode(TagList tag, NbtOutputStream out) throws IOException {
|
||||
out.writeByte(tag.getTypeList().getId());
|
||||
out.writeInt(tag.getValue().size());
|
||||
|
||||
final Codec typeCodec = CodecEnum.valueOfTypeTag(tag.getTypeList()).getCodec();
|
||||
for (Tag item : tag.getValue()) {
|
||||
typeCodec.encode(item, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagLongArray;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TagLongArrayCodec implements Codec<TagLongArray> {
|
||||
|
||||
@Override
|
||||
public TagLongArray decode(NbtInputStream in) throws IOException {
|
||||
final long[] value = new long[in.readInt()];
|
||||
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
value[i] = in.readLong();
|
||||
}
|
||||
|
||||
return new TagLongArray(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagLongArray tag, NbtOutputStream out) throws IOException {
|
||||
out.writeInt(tag.getValue().length);
|
||||
for (long item : tag.getValue()) {
|
||||
out.writeLong(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagLong;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TagLongCodec implements Codec<TagLong> {
|
||||
|
||||
@Override
|
||||
public TagLong decode(NbtInputStream in) throws IOException {
|
||||
long value = in.readLong();
|
||||
return new TagLong(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagLong tag, NbtOutputStream out) throws IOException {
|
||||
out.writeLong(tag.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagShort;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class TagShortCodec implements Codec<TagShort> {
|
||||
|
||||
@Override
|
||||
public TagShort decode(NbtInputStream in) throws IOException {
|
||||
return new TagShort(in.readShort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagShort tag, NbtOutputStream out) throws IOException {
|
||||
out.writeShort(tag.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package mc.nbt.codec.vanilla;
|
||||
|
||||
import mc.nbt.codec.vanilla.io.NbtInputStream;
|
||||
import mc.nbt.codec.vanilla.io.NbtOutputStream;
|
||||
import mc.nbt.tag.TagString;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TagStringCodec implements Codec<TagString> {
|
||||
|
||||
@Override
|
||||
public TagString decode(NbtInputStream in) throws IOException {
|
||||
return new TagString(in.readString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(TagString tag, NbtOutputStream out) throws IOException {
|
||||
out.writeString(tag.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package mc.nbt.codec.vanilla.io;
|
||||
|
||||
import mc.nbt.TypeTag;
|
||||
import mc.nbt.codec.vanilla.Codec;
|
||||
import mc.nbt.codec.vanilla.CodecEnum;
|
||||
import mc.nbt.tag.Tag;
|
||||
import mc.nbt.tag.TagEnd;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class NbtInputStream extends InputStream {
|
||||
|
||||
private final DataInputStream dataInputStream;
|
||||
|
||||
public NbtInputStream(InputStream inputStream, boolean compressed) throws IOException {
|
||||
this.dataInputStream = new DataInputStream(
|
||||
compressed
|
||||
? new GZIPInputStream(inputStream)
|
||||
: inputStream);
|
||||
}
|
||||
|
||||
public NbtInputStream(InputStream inputStream) throws IOException {
|
||||
this(inputStream, false);
|
||||
}
|
||||
|
||||
public Tag readTag() throws IOException {
|
||||
final TypeTag typeTag = TypeTag.getTypeById(read());
|
||||
if (typeTag == TypeTag.END) {
|
||||
return TagEnd.INSTANCE;
|
||||
} else {
|
||||
final CodecEnum codecEnum = CodecEnum.valueOfTypeTag(typeTag);
|
||||
final Codec codec = codecEnum.getCodec();
|
||||
final String name = readString();
|
||||
final Tag tag = codec.decode(this);
|
||||
|
||||
tag.setName(name);
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
return dataInputStream.readByte();
|
||||
}
|
||||
|
||||
public short readShort() throws IOException {
|
||||
return dataInputStream.readShort();
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
return dataInputStream.readInt();
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
return dataInputStream.readLong();
|
||||
}
|
||||
|
||||
public String readString() throws IOException {
|
||||
int length = readShort();
|
||||
if (length > 0) {
|
||||
byte[] buff = new byte[length];
|
||||
if (read(buff, 0, length) < length) {
|
||||
throw new IOException("Unexpected end of stream");
|
||||
}
|
||||
|
||||
return new String(buff, StandardCharsets.UTF_8);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
return dataInputStream.readFloat();
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
return dataInputStream.readDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return dataInputStream.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.dataInputStream.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package mc.nbt.codec.vanilla.io;
|
||||
|
||||
import mc.nbt.TypeTag;
|
||||
import mc.nbt.codec.vanilla.Codec;
|
||||
import mc.nbt.codec.vanilla.CodecEnum;
|
||||
import mc.nbt.tag.Tag;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class NbtOutputStream extends OutputStream {
|
||||
|
||||
private final DataOutputStream dataOutputStream;
|
||||
|
||||
public NbtOutputStream(OutputStream outputStream, boolean compressed) throws IOException {
|
||||
this.dataOutputStream = new DataOutputStream(
|
||||
compressed
|
||||
? new GZIPOutputStream(outputStream)
|
||||
: outputStream);
|
||||
}
|
||||
|
||||
public NbtOutputStream(OutputStream outputStream) throws IOException {
|
||||
this(outputStream, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeTag(Tag tag) throws IOException {
|
||||
final TypeTag typeTag = tag.getType();
|
||||
final CodecEnum codecEnum = CodecEnum.valueOfTypeTag(typeTag);
|
||||
final Codec codec = codecEnum.getCodec();
|
||||
|
||||
writeByte(typeTag.getId());
|
||||
writeString(tag.getName());
|
||||
|
||||
codec.encode(tag, this);
|
||||
}
|
||||
|
||||
public void writeByte(int value) throws IOException {
|
||||
dataOutputStream.writeByte(value);
|
||||
}
|
||||
|
||||
public void writeShort(int value) throws IOException {
|
||||
dataOutputStream.writeShort(value);
|
||||
}
|
||||
|
||||
public void writeInt(int value) throws IOException {
|
||||
dataOutputStream.writeInt(value);
|
||||
}
|
||||
|
||||
public void writeLong(long value) throws IOException {
|
||||
dataOutputStream.writeLong(value);
|
||||
}
|
||||
|
||||
public void writeString(String value) throws IOException {
|
||||
if (value == null || value.isEmpty()) {
|
||||
writeShort(0);
|
||||
} else {
|
||||
writeShort(value.length());
|
||||
write(value.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeFloat(float value) throws IOException {
|
||||
dataOutputStream.writeFloat(value);
|
||||
}
|
||||
|
||||
public void writeDouble(double value) throws IOException {
|
||||
dataOutputStream.writeDouble(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
dataOutputStream.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.dataOutputStream.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package mc.nbt.codec.vanilla.io;
|
||||
|
||||
import mc.nbt.TypeTag;
|
||||
import mc.nbt.tag.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
//TODO необходимо добавить тесты для INT_ARRAY и LONG_ARRAY
|
||||
class NbtInputStreamTest {
|
||||
|
||||
@Test
|
||||
void testSimple() throws IOException {
|
||||
InputStream stream = NbtInputStreamTest.class.getResourceAsStream("/hello_world.nbt");
|
||||
assertNotNull(stream);
|
||||
|
||||
NbtInputStream nbtInputStream = new NbtInputStream(stream);
|
||||
Tag tag = nbtInputStream.readTag();
|
||||
assertNotNull(tag);
|
||||
assertEquals(TypeTag.COMPOUND, tag.getType());
|
||||
|
||||
TagCompound tagCompound = tag.asTagCompound();
|
||||
assertEquals("hello world", tagCompound.getName());
|
||||
assertEquals(1, tagCompound.getValue().size());
|
||||
|
||||
tag = tagCompound.getValue().get(0);
|
||||
assertEquals(TypeTag.STRING, tag.getType());
|
||||
|
||||
TagString tagString = tag.asTagString();
|
||||
assertEquals("name", tagString.getName());
|
||||
assertEquals("Bananrama", tagString.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGZipped() throws IOException {
|
||||
InputStream stream = NbtInputStreamTest.class.getResourceAsStream("/bigtest.nbt");
|
||||
assertNotNull(stream);
|
||||
|
||||
NbtInputStream nbtInputStream = new NbtInputStream(stream, true);
|
||||
Tag tag = nbtInputStream.readTag();
|
||||
assertNotNull(tag);
|
||||
assertEquals(TypeTag.COMPOUND, tag.getType());
|
||||
|
||||
TagCompound tagCompound = tag.asTagCompound();
|
||||
assertEquals("Level", tagCompound.getName());
|
||||
assertEquals(11, tagCompound.getValue().size());
|
||||
|
||||
tagCompound.getValue().forEach(tag1 -> {
|
||||
switch (tag1.getType()) {
|
||||
case BYTE: testTagByte(tag1.asTagByte()); break;
|
||||
case SHORT: testTagShort(tag1.asTagShort()); break;
|
||||
case INT: testTagInt(tag1.asTagInt()); break;
|
||||
case LONG: testTagLong(tag1.asTagLong()); break;
|
||||
case FLOAT: testTagFloat(tag1.asTagFloat()); break;
|
||||
case DOUBLE: testTagDouble(tag1.asTagDouble()); break;
|
||||
case BYTE_ARRAY: testTagByteArray(tag1.asTagByteArray()); break;
|
||||
case STRING: testTagString(tag1.asTagString()); break;
|
||||
case LIST: testTagList(tag1.asTagList()); break;
|
||||
case COMPOUND: testTagCompound(tag1.asTagCompound()); break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void testTagByte(TagByte tag) {
|
||||
assertEquals("byteTest", tag.getName());
|
||||
assertEquals(Byte.MAX_VALUE, tag.getValue());
|
||||
}
|
||||
|
||||
private void testTagShort(TagShort tag) {
|
||||
assertEquals("shortTest", tag.getName());
|
||||
assertEquals(Short.MAX_VALUE, tag.getValue());
|
||||
}
|
||||
|
||||
private void testTagInt(TagInt tag) {
|
||||
assertEquals("intTest", tag.getName());
|
||||
assertEquals(Integer.MAX_VALUE, tag.getValue());
|
||||
}
|
||||
|
||||
private void testTagLong(TagLong tag) {
|
||||
assertEquals("longTest", tag.getName());
|
||||
assertEquals(Long.MAX_VALUE, tag.getValue());
|
||||
}
|
||||
|
||||
private void testTagFloat(TagFloat tag) {
|
||||
assertEquals("floatTest", tag.getName());
|
||||
assertEquals(0.49823147058486938f, tag.getValue());
|
||||
}
|
||||
|
||||
private void testTagDouble(TagDouble tag) {
|
||||
assertEquals("doubleTest", tag.getName());
|
||||
assertEquals(0.49312871321823148d, tag.getValue());
|
||||
}
|
||||
|
||||
private void testTagByteArray(TagByteArray tag) {
|
||||
assertEquals("byteArrayTest " +
|
||||
"(the first 1000 values of (n*n*255+n*7)%100, " +
|
||||
"starting with n=0 (0, 62, 34, 16, 8, ...))", tag.getName());
|
||||
assertEquals(1000, tag.getValue().length);
|
||||
|
||||
for (int n = 0; n < tag.getValue().length; n++) {
|
||||
assertEquals((n * n * 255 + n * 7) % 100, tag.getValue()[n]);
|
||||
}
|
||||
}
|
||||
|
||||
private void testTagString(TagString tag) {
|
||||
assertEquals("stringTest", tag.getName());
|
||||
assertEquals("HELLO WORLD THIS IS A TEST STRING \305\304\326!", tag.getValue());
|
||||
}
|
||||
|
||||
private void testTagList(TagList tag) {
|
||||
if (tag.getName().equals("listTest (long)")) {
|
||||
testTagListLong(tag);
|
||||
} else if (tag.getName().equals("listTest (compound)")) {
|
||||
testTagListCompound(tag);
|
||||
} else {
|
||||
fail("Unknown TagList(name=" + tag.getName() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private void testTagListLong(TagList tag) {
|
||||
assertEquals(TypeTag.LONG, tag.getTypeList());
|
||||
assertEquals(5, tag.getValue().size());
|
||||
|
||||
Iterator<Tag> iterator = tag.getValue().iterator();
|
||||
for(int n = 11; n <= 15 && iterator.hasNext(); n++) {
|
||||
assertEquals(n, iterator.next().asTagLong().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void testTagListCompound(TagList tag) {
|
||||
assertEquals(TypeTag.COMPOUND, tag.getTypeList());
|
||||
assertEquals(2, tag.getValue().size());
|
||||
|
||||
{
|
||||
TagCompound tagCompound = tag.getValue().get(0).asTagCompound();
|
||||
assertNull(tagCompound.getName());
|
||||
assertEquals(2, tagCompound.getValue().size());
|
||||
|
||||
TagString tagString = tagCompound.getValue().get(0).asTagString();
|
||||
assertEquals("name", tagString.getName());
|
||||
assertEquals("Compound tag #0", tagString.getValue());
|
||||
|
||||
TagLong tagLong = tagCompound.getValue().get(1).asTagLong();
|
||||
assertEquals("created-on", tagLong.getName());
|
||||
assertEquals(1264099775885L, tagLong.getValue());
|
||||
}
|
||||
|
||||
{
|
||||
TagCompound tagCompound = tag.getValue().get(1).asTagCompound();
|
||||
assertNull(tagCompound.getName());
|
||||
assertEquals(2, tagCompound.getValue().size());
|
||||
|
||||
TagString tagString = tagCompound.getValue().get(0).asTagString();
|
||||
assertEquals("name", tagString.getName());
|
||||
assertEquals("Compound tag #1", tagString.getValue());
|
||||
|
||||
TagLong tagLong = tagCompound.getValue().get(1).asTagLong();
|
||||
assertEquals("created-on", tagLong.getName());
|
||||
assertEquals(1264099775885L, tagLong.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void testTagCompound(TagCompound tag) {
|
||||
assertEquals("nested compound test", tag.getName());
|
||||
assertEquals(2, tag.getValue().size());
|
||||
|
||||
{
|
||||
TagCompound tagCompound = tag.getValue().get(0).asTagCompound();
|
||||
assertEquals("ham", tagCompound.getName());
|
||||
assertEquals(2, tagCompound.getValue().size());
|
||||
|
||||
{
|
||||
TagString tagString = tagCompound.getValue().get(0).asTagString();
|
||||
assertEquals("name", tagString.getName());
|
||||
assertEquals("Hampus", tagString.getValue());
|
||||
|
||||
TagFloat tagFloat = tagCompound.getValue().get(1).asTagFloat();
|
||||
assertEquals("value", tagFloat.getName());
|
||||
assertEquals(0.75f, tagFloat.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
TagCompound tagCompound = tag.getValue().get(1).asTagCompound();
|
||||
assertEquals("egg", tagCompound.getName());
|
||||
assertEquals(2, tagCompound.getValue().size());
|
||||
|
||||
{
|
||||
TagString tagString = tagCompound.getValue().get(0).asTagString();
|
||||
assertEquals("name", tagString.getName());
|
||||
assertEquals("Eggbert", tagString.getValue());
|
||||
|
||||
TagFloat tagFloat = tagCompound.getValue().get(1).asTagFloat();
|
||||
assertEquals("value", tagFloat.getName());
|
||||
assertEquals(0.5f, tagFloat.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package mc.nbt.codec.vanilla.io;
|
||||
|
||||
import mc.nbt.TypeTag;
|
||||
import mc.nbt.tag.Tag;
|
||||
import mc.nbt.tag.TagLong;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class NbtOutputStreamCompressedTest {
|
||||
|
||||
@Test
|
||||
void testWriteCompressed() throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
NbtOutputStream nbtOutputStream = new NbtOutputStream(baos, true);
|
||||
|
||||
TagLong tagLong = new TagLong("Test compressed stream", RandomUtils.nextLong());
|
||||
nbtOutputStream.writeTag(tagLong);
|
||||
nbtOutputStream.close();
|
||||
|
||||
NbtInputStream nbtInputStream = new NbtInputStream(new ByteArrayInputStream(baos.toByteArray()), true);
|
||||
Tag tag = nbtInputStream.readTag();
|
||||
|
||||
assertEquals(TypeTag.LONG, tag.getType());
|
||||
assertEquals(tagLong.getName(), tag.getName());
|
||||
assertEquals(tagLong.getValue(), tag.asTagLong().getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
package mc.nbt.codec.vanilla.io;
|
||||
|
||||
import mc.nbt.TypeTag;
|
||||
import mc.nbt.tag.*;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class NbtOutputStreamTest {
|
||||
|
||||
private ByteArrayOutputStream baos;
|
||||
private NbtOutputStream nbtOutputStream;
|
||||
|
||||
@BeforeEach
|
||||
void before() throws IOException {
|
||||
baos = new ByteArrayOutputStream();
|
||||
nbtOutputStream = new NbtOutputStream(baos);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteTagEnd() throws IOException {
|
||||
nbtOutputStream.writeTag(TagEnd.INSTANCE);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.END, tag.getType());
|
||||
assertNull(tag.getName());
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagByte() {
|
||||
final byte value = RandomUtils.nextBytes(1)[0];
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagByte(value)),
|
||||
Arguments.of(new TagByte(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagByte")
|
||||
void testWriteTagByte(TagByte tagByte) throws IOException {
|
||||
nbtOutputStream.writeTag(tagByte);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.BYTE, tag.getType());
|
||||
assertEquals(tagByte.getValue(), tag.asTagByte().getValue());
|
||||
assertName(tagByte, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagShort() {
|
||||
final short value = (short) RandomUtils.nextInt(0, Short.MAX_VALUE);
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagShort(value)),
|
||||
Arguments.of(new TagShort(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagShort")
|
||||
void testWriteTagShort(TagShort tagShort) throws IOException {
|
||||
nbtOutputStream.writeTag(tagShort);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.SHORT, tag.getType());
|
||||
assertEquals(tagShort.getValue(), tag.asTagShort().getValue());
|
||||
assertName(tagShort, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagInt() {
|
||||
final int value = RandomUtils.nextInt();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagInt(value)),
|
||||
Arguments.of(new TagInt(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagInt")
|
||||
void testWriteTagInt(TagInt tagInt) throws IOException {
|
||||
nbtOutputStream.writeTag(tagInt);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.INT, tag.getType());
|
||||
assertEquals(tagInt.getValue(), tag.asTagInt().getValue());
|
||||
assertName(tagInt, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagLong() {
|
||||
final long value = RandomUtils.nextLong();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagLong(value)),
|
||||
Arguments.of(new TagLong(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagLong")
|
||||
void testWriteTagLong(TagLong tagLong) throws IOException {
|
||||
nbtOutputStream.writeTag(tagLong);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.LONG, tag.getType());
|
||||
assertEquals(tagLong.getValue(), tag.asTagLong().getValue());
|
||||
assertName(tagLong, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagFloat() {
|
||||
final float value = RandomUtils.nextFloat();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagFloat(value)),
|
||||
Arguments.of(new TagFloat(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagFloat")
|
||||
void testWriteTagFloat(TagFloat tagFloat) throws IOException {
|
||||
nbtOutputStream.writeTag(tagFloat);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.FLOAT, tag.getType());
|
||||
assertEquals(tagFloat.getValue(), tag.asTagFloat().getValue());
|
||||
assertName(tagFloat, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagDouble() {
|
||||
final double value = RandomUtils.nextDouble();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagDouble(value)),
|
||||
Arguments.of(new TagDouble(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagDouble")
|
||||
void testWriteTagDouble(TagDouble tagDouble) throws IOException {
|
||||
nbtOutputStream.writeTag(tagDouble);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.DOUBLE, tag.getType());
|
||||
assertEquals(tagDouble.getValue(), tag.asTagDouble().getValue());
|
||||
assertName(tagDouble, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagByteArray() {
|
||||
final byte[] value = RandomUtils.nextBytes(RandomUtils.nextInt(1, 1000));
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagByteArray(value)),
|
||||
Arguments.of(new TagByteArray(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagByteArray")
|
||||
void testWriteTagByteArray(TagByteArray tagByteArray) throws IOException {
|
||||
nbtOutputStream.writeTag(tagByteArray);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.BYTE_ARRAY, tag.getType());
|
||||
assertArrayEquals(tagByteArray.getValue(), tag.asTagByteArray().getValue());
|
||||
assertName(tagByteArray, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagString() {
|
||||
final String value = randomString();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagString(value)),
|
||||
Arguments.of(new TagString(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagString")
|
||||
void testWriteTagString(TagString tagString) throws IOException {
|
||||
nbtOutputStream.writeTag(tagString);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.STRING, tag.getType());
|
||||
assertEquals(tagString.getValue(), tag.asTagString().getValue());
|
||||
assertName(tagString, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagList() {
|
||||
final List<Tag> value = new ArrayList<>();
|
||||
// value.add(new TagLong("TestName", RandomUtils.nextLong()));
|
||||
// value.add(new TagLong(RandomUtils.nextLong()));
|
||||
// value.add(new TagLong(RandomUtils.nextLong()));
|
||||
// value.add(new TagLong(RandomUtils.nextLong()));
|
||||
value.add(new TagLong(1L));
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagList(value)),
|
||||
Arguments.of(new TagList(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagList")
|
||||
void testWriteTagList(TagList tagList) throws IOException {
|
||||
nbtOutputStream.writeTag(tagList);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.LIST, tag.getType());
|
||||
assertEquals(tagList.getValue().size(), tag.asTagList().getValue().size());
|
||||
assertEquals(tagList.getTypeList(), tag.asTagList().getTypeList());
|
||||
assertName(tagList, tag);
|
||||
|
||||
for (int i = 0; i < tagList.getValue().size(); i++) {
|
||||
TagLong tagLong1 = tagList.getValue().get(i).asTagLong();
|
||||
TagLong tagLong2 = tag.asTagList().getValue().get(i).asTagLong();
|
||||
|
||||
assertNull(tagLong2.getName());
|
||||
assertEquals(tagLong1.getValue(), tagLong2.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagCompound() {
|
||||
final List<Tag> value = new ArrayList<>();
|
||||
value.add(new TagLong("TestName1", RandomUtils.nextLong()));
|
||||
value.add(new TagLong(RandomUtils.nextLong()));
|
||||
value.add(new TagLong("TestName3",RandomUtils.nextLong()));
|
||||
value.add(new TagLong(RandomUtils.nextLong()));
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagCompound(value)),
|
||||
Arguments.of(new TagCompound(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagCompound")
|
||||
void testWriteTagCompound(TagCompound tagCompound) throws IOException {
|
||||
nbtOutputStream.writeTag(tagCompound);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.COMPOUND, tag.getType());
|
||||
assertEquals(tagCompound.getValue().size(), tag.asTagCompound().getValue().size());
|
||||
assertName(tagCompound, tag);
|
||||
|
||||
for (int i = 0; i < tagCompound.getValue().size(); i++) {
|
||||
TagLong tagLong1 = tagCompound.getValue().get(i).asTagLong();
|
||||
TagLong tagLong2 = tag.asTagCompound().getValue().get(i).asTagLong();
|
||||
|
||||
assertNotNull(tagLong2.getName());
|
||||
assertName(tagLong1, tagLong2);
|
||||
assertEquals(tagLong1.getValue(), tagLong2.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagIntArray() {
|
||||
final int[] value = new int[RandomUtils.nextInt(1, 1000)];
|
||||
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
value[i] = RandomUtils.nextInt();
|
||||
}
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagIntArray(value)),
|
||||
Arguments.of(new TagIntArray(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagIntArray")
|
||||
void testWriteTagIntArray(TagIntArray tagIntArray) throws IOException {
|
||||
nbtOutputStream.writeTag(tagIntArray);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.INT_ARRAY, tag.getType());
|
||||
assertArrayEquals(tagIntArray.getValue(), tag.asTagIntArray().getValue());
|
||||
assertName(tagIntArray, tag);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> streamOfTagLongArray() {
|
||||
final long[] value = new long[RandomUtils.nextInt(1, 1000)];
|
||||
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
value[i] = RandomUtils.nextLong();
|
||||
}
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(new TagLongArray(value)),
|
||||
Arguments.of(new TagLongArray(randomString(), value))
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfTagLongArray")
|
||||
void testWriteTagLongArray(TagLongArray tagLongArray) throws IOException {
|
||||
nbtOutputStream.writeTag(tagLongArray);
|
||||
|
||||
Tag tag = createNbtInputStream().readTag();
|
||||
assertEquals(TypeTag.LONG_ARRAY, tag.getType());
|
||||
assertArrayEquals(tagLongArray.getValue(), tag.asTagLongArray().getValue());
|
||||
assertName(tagLongArray, tag);
|
||||
}
|
||||
|
||||
private void assertName(Tag expectedTag, Tag actualTag) {
|
||||
if (expectedTag.getName() == null) {
|
||||
assertTrue(actualTag.getName().isEmpty());
|
||||
} else {
|
||||
assertEquals(expectedTag.getName(), actualTag.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static String randomString() {
|
||||
return RandomStringUtils.randomAscii(RandomUtils.nextInt(1, Short.MAX_VALUE));
|
||||
}
|
||||
|
||||
private NbtInputStream createNbtInputStream() throws IOException {
|
||||
return new NbtInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
}
|
||||
}
|
||||
BIN
vanilla-codec/src/test/resources/bigtest.nbt
Normal file
BIN
vanilla-codec/src/test/resources/bigtest.nbt
Normal file
Binary file not shown.
BIN
vanilla-codec/src/test/resources/hello_world.nbt
Normal file
BIN
vanilla-codec/src/test/resources/hello_world.nbt
Normal file
Binary file not shown.
Reference in New Issue
Block a user