diff --git a/src/main/java/mc/nbt/TypeTag.java b/src/main/java/mc/nbt/TypeTag.java index 71f27cc..4806fca 100644 --- a/src/main/java/mc/nbt/TypeTag.java +++ b/src/main/java/mc/nbt/TypeTag.java @@ -2,10 +2,8 @@ package mc.nbt; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import mc.nbt.tag.*; -@Slf4j @RequiredArgsConstructor @Getter public enum TypeTag { @@ -24,18 +22,22 @@ public enum TypeTag { LONG_ARRAY(12, TagLongArray.class); public static Tag getTagById(int id) { + TypeTag type = getTypeById(id); + try { + return type.classTag.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); //FIXME + } + } + + public static TypeTag getTypeById(int id) { for (TypeTag type : TypeTag.values()) { if (type.id == id) { - try { - return type.classTag.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - log.error("{}", e.getMessage(), e); - break; - } + return type; } } - return null; + throw new RuntimeException("Unknown tag id: " + id); //FIXME } private final int id; diff --git a/src/main/java/mc/nbt/io/NbtInputStream.java b/src/main/java/mc/nbt/io/NbtInputStream.java new file mode 100644 index 0000000..6a5b70c --- /dev/null +++ b/src/main/java/mc/nbt/io/NbtInputStream.java @@ -0,0 +1,87 @@ +package mc.nbt.io; + +import mc.nbt.TypeTag; +import mc.nbt.tag.Tag; + +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() { + Tag tag = null; + + try { + tag = TypeTag.getTagById(read()); + if (tag.getType() != TypeTag.END) { + tag.setName(readString()); + } + + tag.readSelf(this); + + } catch (IOException e) { + e.printStackTrace(); //FIXME + } + + 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(); + } +} diff --git a/src/main/java/mc/nbt/tag/Tag.java b/src/main/java/mc/nbt/tag/Tag.java index 1993c7e..00da3b5 100644 --- a/src/main/java/mc/nbt/tag/Tag.java +++ b/src/main/java/mc/nbt/tag/Tag.java @@ -3,6 +3,9 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; + +import java.io.IOException; public abstract class Tag { @@ -12,4 +15,21 @@ public abstract class Tag { public abstract TypeTag getType(); + public abstract void readSelf(NbtInputStream nbtInputStream) throws IOException; + + public TagCompound asTagCompound() { + return (TagCompound) this; + } + + public TagList asTagList() { + return (TagList) this; + } + + public String toString() { + if (name != null && !name.isEmpty()) { + return "Tag(name=" + this.name + ")"; + } else { + return "Tag"; + } + } } diff --git a/src/main/java/mc/nbt/tag/TagByte.java b/src/main/java/mc/nbt/tag/TagByte.java index 5601402..2eaae4b 100644 --- a/src/main/java/mc/nbt/tag/TagByte.java +++ b/src/main/java/mc/nbt/tag/TagByte.java @@ -2,8 +2,13 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; + +@ToString(callSuper = true) public class TagByte extends Tag { @Getter @@ -14,4 +19,9 @@ public class TagByte extends Tag { public TypeTag getType() { return TypeTag.BYTE; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + value = nbtInputStream.readByte(); + } } diff --git a/src/main/java/mc/nbt/tag/TagByteArray.java b/src/main/java/mc/nbt/tag/TagByteArray.java index f97503e..9b26849 100644 --- a/src/main/java/mc/nbt/tag/TagByteArray.java +++ b/src/main/java/mc/nbt/tag/TagByteArray.java @@ -2,8 +2,13 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; + +@ToString(callSuper = true) public class TagByteArray extends Tag { @Getter @@ -14,4 +19,10 @@ public class TagByteArray extends Tag { public TypeTag getType() { return TypeTag.BYTE_ARRAY; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + value = new byte[nbtInputStream.readInt()]; + nbtInputStream.read(value); //FIXME + } } diff --git a/src/main/java/mc/nbt/tag/TagCompound.java b/src/main/java/mc/nbt/tag/TagCompound.java index 465a24e..d2dad5e 100644 --- a/src/main/java/mc/nbt/tag/TagCompound.java +++ b/src/main/java/mc/nbt/tag/TagCompound.java @@ -2,11 +2,16 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -public class TagCompound extends Tag { +@ToString(callSuper = true) +public class TagCompound extends Tag implements Iterable { @Getter @Setter @@ -16,4 +21,23 @@ public class TagCompound extends Tag { public TypeTag getType() { return TypeTag.COMPOUND; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) { + value = new ArrayList<>(); + + while (true) { + Tag tag = nbtInputStream.readTag(); + if (tag.getType() == TypeTag.END) { + break; + } + + value.add(tag); + } + } + + @Override + public Iterator iterator() { + return value.iterator(); + } } diff --git a/src/main/java/mc/nbt/tag/TagDouble.java b/src/main/java/mc/nbt/tag/TagDouble.java index b464d0a..dc99d48 100644 --- a/src/main/java/mc/nbt/tag/TagDouble.java +++ b/src/main/java/mc/nbt/tag/TagDouble.java @@ -2,8 +2,13 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; + +@ToString(callSuper = true) public class TagDouble extends Tag { @Getter @@ -14,4 +19,9 @@ public class TagDouble extends Tag { public TypeTag getType() { return TypeTag.DOUBLE; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + value = nbtInputStream.readDouble(); + } } diff --git a/src/main/java/mc/nbt/tag/TagEnd.java b/src/main/java/mc/nbt/tag/TagEnd.java index b36c885..0eec5b1 100644 --- a/src/main/java/mc/nbt/tag/TagEnd.java +++ b/src/main/java/mc/nbt/tag/TagEnd.java @@ -1,6 +1,9 @@ package mc.nbt.tag; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; + +import java.io.IOException; public class TagEnd extends Tag { @@ -18,4 +21,8 @@ public class TagEnd extends Tag { public TypeTag getType() { return TypeTag.END; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + } } diff --git a/src/main/java/mc/nbt/tag/TagFloat.java b/src/main/java/mc/nbt/tag/TagFloat.java index 9822e1b..8f2d06b 100644 --- a/src/main/java/mc/nbt/tag/TagFloat.java +++ b/src/main/java/mc/nbt/tag/TagFloat.java @@ -2,8 +2,13 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; + +@ToString(callSuper = true) public class TagFloat extends Tag { @Getter @@ -14,4 +19,9 @@ public class TagFloat extends Tag { public TypeTag getType() { return TypeTag.FLOAT; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + value = nbtInputStream.readFloat(); + } } diff --git a/src/main/java/mc/nbt/tag/TagInt.java b/src/main/java/mc/nbt/tag/TagInt.java index 65b278b..5abd6bc 100644 --- a/src/main/java/mc/nbt/tag/TagInt.java +++ b/src/main/java/mc/nbt/tag/TagInt.java @@ -2,8 +2,13 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; + +@ToString(callSuper = true) public class TagInt extends Tag { @Getter @@ -14,4 +19,9 @@ public class TagInt extends Tag { public TypeTag getType() { return TypeTag.INT; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + value = nbtInputStream.readInt(); + } } diff --git a/src/main/java/mc/nbt/tag/TagIntArray.java b/src/main/java/mc/nbt/tag/TagIntArray.java index aa47505..7ce6827 100644 --- a/src/main/java/mc/nbt/tag/TagIntArray.java +++ b/src/main/java/mc/nbt/tag/TagIntArray.java @@ -3,6 +3,9 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; + +import java.io.IOException; public class TagIntArray extends Tag { @@ -14,4 +17,14 @@ public class TagIntArray extends Tag { public TypeTag getType() { return TypeTag.INT_ARRAY; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + int count = nbtInputStream.readInt(); + value = new int[count]; + + for (int i = 0; i < count; i++) { + value[i] = nbtInputStream.readInt(); + } + } } diff --git a/src/main/java/mc/nbt/tag/TagList.java b/src/main/java/mc/nbt/tag/TagList.java index d8a7826..0069558 100644 --- a/src/main/java/mc/nbt/tag/TagList.java +++ b/src/main/java/mc/nbt/tag/TagList.java @@ -2,18 +2,47 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -@Getter -@Setter -public class TagList extends Tag { +@ToString(callSuper = true) +public class TagList extends Tag implements Iterable { + @Getter + @Setter private List value; //FIXME + private TypeTag typeList; + @Override public TypeTag getType() { return TypeTag.LIST; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + typeList = TypeTag.getTypeById(nbtInputStream.readByte()); + + int size = nbtInputStream.readInt(); + if (size > 0) { + value = new ArrayList<>(size); + + for (int i = 0; i < size; i++) { + Tag tag = TypeTag.getTagById(typeList.getId()); + tag.readSelf(nbtInputStream); + value.add(tag); + } + } + } + + @Override + public Iterator iterator() { + return value.iterator(); + } } diff --git a/src/main/java/mc/nbt/tag/TagLong.java b/src/main/java/mc/nbt/tag/TagLong.java index e83bd33..a63d15b 100644 --- a/src/main/java/mc/nbt/tag/TagLong.java +++ b/src/main/java/mc/nbt/tag/TagLong.java @@ -2,8 +2,13 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; + +@ToString(callSuper = true) public class TagLong extends Tag { @Getter @@ -14,4 +19,9 @@ public class TagLong extends Tag { public TypeTag getType() { return TypeTag.LONG; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + value = nbtInputStream.readLong(); + } } diff --git a/src/main/java/mc/nbt/tag/TagLongArray.java b/src/main/java/mc/nbt/tag/TagLongArray.java index fa51d6c..dab7c46 100644 --- a/src/main/java/mc/nbt/tag/TagLongArray.java +++ b/src/main/java/mc/nbt/tag/TagLongArray.java @@ -3,6 +3,9 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; + +import java.io.IOException; public class TagLongArray extends Tag { @@ -14,4 +17,14 @@ public class TagLongArray extends Tag { public TypeTag getType() { return TypeTag.LONG_ARRAY; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + int count = nbtInputStream.readInt(); + value = new long[count]; + + for (int i = 0; i < count; i++) { + value[i] = nbtInputStream.readInt(); + } + } } diff --git a/src/main/java/mc/nbt/tag/TagShort.java b/src/main/java/mc/nbt/tag/TagShort.java index b0c1fd6..238a12d 100644 --- a/src/main/java/mc/nbt/tag/TagShort.java +++ b/src/main/java/mc/nbt/tag/TagShort.java @@ -2,8 +2,13 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; + +@ToString(callSuper = true) public class TagShort extends Tag { @Getter @@ -14,4 +19,9 @@ public class TagShort extends Tag { public TypeTag getType() { return TypeTag.SHORT; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + value = nbtInputStream.readShort(); + } } diff --git a/src/main/java/mc/nbt/tag/TagString.java b/src/main/java/mc/nbt/tag/TagString.java index 590afdf..7bf7d41 100644 --- a/src/main/java/mc/nbt/tag/TagString.java +++ b/src/main/java/mc/nbt/tag/TagString.java @@ -2,8 +2,13 @@ package mc.nbt.tag; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import mc.nbt.TypeTag; +import mc.nbt.io.NbtInputStream; +import java.io.IOException; + +@ToString(callSuper = true) public class TagString extends Tag { @Getter @@ -14,4 +19,9 @@ public class TagString extends Tag { public TypeTag getType() { return TypeTag.STRING; } + + @Override + public void readSelf(NbtInputStream nbtInputStream) throws IOException { + value = nbtInputStream.readString(); + } }