mirror of https://github.com/ViaVersion/ViaNBT.git
4.4.0: Add generic type to ListTag
This commit is contained in:
parent
9f71f9b978
commit
45506291a3
2
pom.xml
2
pom.xml
|
@ -5,7 +5,7 @@
|
|||
|
||||
<groupId>com.viaversion</groupId>
|
||||
<artifactId>nbt</artifactId>
|
||||
<version>4.3.0</version>
|
||||
<version>4.4.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>ViaNBT</name>
|
||||
|
|
|
@ -76,7 +76,7 @@ final class TagStringReader {
|
|||
throw this.buffer.makeError("Unterminated compound tag!");
|
||||
}
|
||||
|
||||
public ListTag list() throws StringifiedTagParseException {
|
||||
public ListTag<?> list() throws StringifiedTagParseException {
|
||||
final ListTag listTag = new ListTag();
|
||||
this.buffer.expect(Tokens.ARRAY_BEGIN);
|
||||
final boolean prefixedIndex = this.acceptLegacy && this.buffer.peek() == '0' && this.buffer.peek(1) == ':';
|
||||
|
|
|
@ -102,7 +102,7 @@ final class TagStringWriter {
|
|||
return this;
|
||||
}
|
||||
|
||||
private TagStringWriter writeList(final ListTag tag) {
|
||||
private TagStringWriter writeList(final ListTag<?> tag) {
|
||||
this.beginList();
|
||||
for (final Tag el : tag) {
|
||||
this.printAndResetSeparator();
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Arrays;
|
|||
/**
|
||||
* A tag containing a byte array.
|
||||
*/
|
||||
public class ByteArrayTag extends NumberArrayTag {
|
||||
public final class ByteArrayTag extends NumberArrayTag {
|
||||
public static final int ID = 7;
|
||||
private static final byte[] EMPTY_ARRAY = new byte[0];
|
||||
private byte[] value;
|
||||
|
@ -90,8 +90,8 @@ public class ByteArrayTag extends NumberArrayTag {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ListTag toListTag() {
|
||||
final ListTag list = new ListTag(ByteTag.class);
|
||||
public ListTag<ByteTag> toListTag() {
|
||||
final ListTag<ByteTag> list = new ListTag<>(ByteTag.class);
|
||||
for (final byte b : this.value) {
|
||||
list.add(new ByteTag(b));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
|||
/**
|
||||
* A tag containing a byte.
|
||||
*/
|
||||
public class ByteTag extends NumberTag {
|
||||
public final class ByteTag extends NumberTag {
|
||||
public static final int ID = 1;
|
||||
private byte value;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
/**
|
||||
* A compound tag containing other tags.
|
||||
*/
|
||||
public class CompoundTag extends Tag implements Iterable<Entry<String, Tag>> {
|
||||
public final class CompoundTag extends Tag implements Iterable<Entry<String, Tag>> {
|
||||
public static final int ID = 10;
|
||||
private Map<String, Tag> value;
|
||||
|
||||
|
@ -152,9 +152,31 @@ public class CompoundTag extends Tag implements Iterable<Entry<String, Tag>> {
|
|||
return tag instanceof CompoundTag ? (CompoundTag) tag : null;
|
||||
}
|
||||
|
||||
public @Nullable ListTag getListTag(String tagName) {
|
||||
public @Nullable ListTag<?> getListTag(String tagName) {
|
||||
final Tag tag = this.value.get(tagName);
|
||||
return tag instanceof ListTag ? (ListTag) tag : null;
|
||||
return tag instanceof ListTag<?> ? (ListTag<?>) tag : null;
|
||||
}
|
||||
|
||||
public <T extends Tag> @Nullable ListTag<T> getListTag(String tagName, Class<T> type) {
|
||||
final Tag tag = this.value.get(tagName);
|
||||
if (!(tag instanceof ListTag<?>)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Class<? extends Tag> elementType = ((ListTag<?>) tag).getElementType();
|
||||
//noinspection unchecked
|
||||
return elementType == type || elementType == null ? (ListTag<T>) tag : null;
|
||||
}
|
||||
|
||||
public @Nullable ListTag<? extends NumberTag> getNumberListTag(String tagName) {
|
||||
final Tag tag = this.value.get(tagName);
|
||||
if (!(tag instanceof ListTag<?>)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Class<? extends Tag> elementType = ((ListTag<?>) tag).getElementType();
|
||||
//noinspection unchecked
|
||||
return elementType == null || NumberTag.class.isAssignableFrom(elementType) ? (ListTag<? extends NumberTag>) tag : null;
|
||||
}
|
||||
|
||||
public @Nullable NumberTag getNumberTag(String tagName) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
|||
/**
|
||||
* A tag containing a double.
|
||||
*/
|
||||
public class DoubleTag extends NumberTag {
|
||||
public final class DoubleTag extends NumberTag {
|
||||
public static final int ID = 6;
|
||||
private double value;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
|||
/**
|
||||
* A tag containing a float.
|
||||
*/
|
||||
public class FloatTag extends NumberTag {
|
||||
public final class FloatTag extends NumberTag {
|
||||
public static final int ID = 5;
|
||||
private float value;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Arrays;
|
|||
/**
|
||||
* A tag containing an integer array.
|
||||
*/
|
||||
public class IntArrayTag extends NumberArrayTag {
|
||||
public final class IntArrayTag extends NumberArrayTag {
|
||||
public static final int ID = 11;
|
||||
private static final int[] EMPTY_ARRAY = new int[0];
|
||||
private int[] value;
|
||||
|
@ -91,8 +91,8 @@ public class IntArrayTag extends NumberArrayTag {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ListTag toListTag() {
|
||||
final ListTag list = new ListTag();
|
||||
public ListTag<IntTag> toListTag() {
|
||||
final ListTag<IntTag> list = new ListTag<>(IntTag.class);
|
||||
for (final int i : this.value) {
|
||||
list.add(new IntTag(i));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
|||
/**
|
||||
* A tag containing an integer.
|
||||
*/
|
||||
public class IntTag extends NumberTag {
|
||||
public final class IntTag extends NumberTag {
|
||||
public static final int ID = 3;
|
||||
private int value;
|
||||
|
||||
|
|
|
@ -14,14 +14,15 @@ import org.jetbrains.annotations.Nullable;
|
|||
/**
|
||||
* A tag containing a list of tags.
|
||||
*/
|
||||
public class ListTag extends Tag implements Iterable<Tag> {
|
||||
public final class ListTag<T extends Tag> extends Tag implements Iterable<T> {
|
||||
public static final int ID = 9;
|
||||
private List<Tag> value;
|
||||
private Class<? extends Tag> type;
|
||||
private Class<T> type;
|
||||
private List<T> value;
|
||||
|
||||
/**
|
||||
* Creates an empty list tag and no defined type.
|
||||
*/
|
||||
@Deprecated
|
||||
public ListTag() {
|
||||
this.value = new ArrayList<>();
|
||||
}
|
||||
|
@ -31,7 +32,7 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
*
|
||||
* @param type Tag type of the list.
|
||||
*/
|
||||
public ListTag(@Nullable Class<? extends Tag> type) {
|
||||
public ListTag(Class<T> type) {
|
||||
this.type = type;
|
||||
this.value = new ArrayList<>();
|
||||
}
|
||||
|
@ -43,11 +44,11 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
* @param value The value of the tag.
|
||||
* @throws IllegalArgumentException If all tags in the list are not of the same type.
|
||||
*/
|
||||
public ListTag(List<Tag> value) throws IllegalArgumentException {
|
||||
public ListTag(List<T> value) {
|
||||
this.setValue(value);
|
||||
}
|
||||
|
||||
public static ListTag read(DataInput in, TagLimiter tagLimiter, int nestingLevel) throws IOException {
|
||||
public static ListTag<?> read(DataInput in, TagLimiter tagLimiter, int nestingLevel) throws IOException {
|
||||
tagLimiter.checkLevel(nestingLevel);
|
||||
tagLimiter.countBytes(Byte.BYTES + Integer.BYTES);
|
||||
|
||||
|
@ -59,14 +60,18 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
throw new IOException("Unknown tag ID in ListTag: " + id);
|
||||
}
|
||||
}
|
||||
return read(in, id, type, tagLimiter, nestingLevel);
|
||||
}
|
||||
|
||||
ListTag listTag = new ListTag(type);
|
||||
private static <T extends Tag> ListTag<T> read(DataInput in, int id, Class<T> type, TagLimiter tagLimiter, int nestingLevel) throws IOException {
|
||||
ListTag<T> listTag = new ListTag<>(type);
|
||||
int count = in.readInt();
|
||||
int newNestingLevel = nestingLevel + 1;
|
||||
for (int index = 0; index < count; index++) {
|
||||
Tag tag;
|
||||
T tag;
|
||||
try {
|
||||
tag = TagRegistry.read(id, in, tagLimiter, newNestingLevel);
|
||||
//noinspection unchecked
|
||||
tag = (T) TagRegistry.read(id, in, tagLimiter, newNestingLevel);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IOException("Failed to create tag.", e);
|
||||
}
|
||||
|
@ -76,7 +81,7 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Tag> getValue() {
|
||||
public List<T> getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
|
@ -92,15 +97,15 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
* @param value New value of this tag.
|
||||
* @throws IllegalArgumentException If all tags in the list are not of the same type.
|
||||
*/
|
||||
public void setValue(List<Tag> value) throws IllegalArgumentException {
|
||||
public void setValue(List<T> value) {
|
||||
this.value = new ArrayList<>(value);
|
||||
if (!value.isEmpty()) {
|
||||
this.type = value.get(0).getClass();
|
||||
for (int i = 1; i < value.size(); i++) {
|
||||
this.checkType(value.get(i));
|
||||
if (this.type == null) {
|
||||
this.type = (Class<T>) value.get(0).getClass();
|
||||
}
|
||||
for (T t : value) {
|
||||
this.checkType(t);
|
||||
}
|
||||
} else {
|
||||
this.type = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,18 +126,20 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
* @return If the list was changed as a result.
|
||||
* @throws IllegalArgumentException If the tag's type differs from the list tag's type.
|
||||
*/
|
||||
public boolean add(Tag tag) throws IllegalArgumentException {
|
||||
// If currently empty, use this as the tag type
|
||||
if (this.type == null) {
|
||||
this.type = tag.getClass();
|
||||
} else if (tag.getClass() != this.type) {
|
||||
this.checkType(tag);
|
||||
}
|
||||
|
||||
public boolean add(T tag) throws IllegalArgumentException {
|
||||
this.checkAddedTag(tag);
|
||||
return this.value.add(tag);
|
||||
}
|
||||
|
||||
private void checkType(Tag tag) throws IllegalArgumentException {
|
||||
private void checkAddedTag(T tag) {
|
||||
if (this.type == null) {
|
||||
this.type = (Class<T>) tag.getClass();
|
||||
} else {
|
||||
this.checkType(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkType(Tag tag) {
|
||||
if (tag.getClass() != this.type) {
|
||||
throw new IllegalArgumentException("Tag type " + tag.getClass().getSimpleName() + " differs from list type " + this.type.getSimpleName());
|
||||
}
|
||||
|
@ -144,19 +151,40 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
* @param tag Tag to remove.
|
||||
* @return If the list contained the tag.
|
||||
*/
|
||||
public boolean remove(Tag tag) {
|
||||
public boolean remove(T tag) {
|
||||
return this.value.remove(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag at the given index of this list tag.
|
||||
*
|
||||
* @param <T> Type of tag to get
|
||||
* @param index Index of the tag.
|
||||
* @return The tag at the given index.
|
||||
*/
|
||||
public <T extends Tag> T get(int index) {
|
||||
return (T) this.value.get(index);
|
||||
public T get(int index) {
|
||||
return this.value.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tag at the given index of this list tag.
|
||||
*
|
||||
* @param index Index of the tag.
|
||||
* @param tag New tag to set.
|
||||
* @return The old tag at the given index.
|
||||
*/
|
||||
public T set(int index, T tag) {
|
||||
this.checkAddedTag(tag);
|
||||
return this.value.set(index, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the tag at the given index of this list tag.
|
||||
*
|
||||
* @param index Index of the tag.
|
||||
* @return The removed tag at the given index.
|
||||
*/
|
||||
public T remove(int index) {
|
||||
return this.value.remove(index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,13 +201,13 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Tag> iterator() {
|
||||
public Iterator<T> iterator() {
|
||||
return this.value.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput out) throws IOException {
|
||||
if (this.type == null) {
|
||||
if (this.value.isEmpty()) {
|
||||
out.writeByte(TagRegistry.END);
|
||||
} else {
|
||||
int id = TagRegistry.getIdFor(this.type);
|
||||
|
@ -197,20 +225,20 @@ public class ListTag extends Tag implements Iterable<Tag> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ListTag copy() {
|
||||
List<Tag> newList = new ArrayList<>();
|
||||
for (Tag value : this.value) {
|
||||
newList.add(value.copy());
|
||||
public ListTag<T> copy() {
|
||||
ListTag<T> copy = new ListTag<>(this.type);
|
||||
copy.value = new ArrayList<>(this.value.size());
|
||||
for (T value : this.value) {
|
||||
copy.add((T) value.copy());
|
||||
}
|
||||
|
||||
return new ListTag(newList);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ListTag tags = (ListTag) o;
|
||||
ListTag<?> tags = (ListTag<?>) o;
|
||||
if (!Objects.equals(this.type, tags.type)) return false;
|
||||
return this.value.equals(tags.value);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Arrays;
|
|||
/**
|
||||
* A tag containing a long array.
|
||||
*/
|
||||
public class LongArrayTag extends NumberArrayTag {
|
||||
public final class LongArrayTag extends NumberArrayTag {
|
||||
public static final int ID = 12;
|
||||
private static final long[] EMPTY_ARRAY = new long[0];
|
||||
private long[] value;
|
||||
|
@ -91,8 +91,8 @@ public class LongArrayTag extends NumberArrayTag {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ListTag toListTag() {
|
||||
final ListTag list = new ListTag(LongTag.class);
|
||||
public ListTag<LongTag> toListTag() {
|
||||
final ListTag<LongTag> list = new ListTag<>(LongTag.class);
|
||||
for (final long l : this.value) {
|
||||
list.add(new LongTag(l));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
|||
/**
|
||||
* A tag containing a long.
|
||||
*/
|
||||
public class LongTag extends NumberTag {
|
||||
public final class LongTag extends NumberTag {
|
||||
public static final int ID = 4;
|
||||
private long value;
|
||||
|
||||
|
|
|
@ -14,5 +14,5 @@ public abstract class NumberArrayTag extends Tag {
|
|||
*
|
||||
* @return a new list tag
|
||||
*/
|
||||
public abstract ListTag toListTag();
|
||||
public abstract ListTag<? extends NumberTag> toListTag();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
|||
/**
|
||||
* A tag containing a short.
|
||||
*/
|
||||
public class ShortTag extends NumberTag {
|
||||
public final class ShortTag extends NumberTag {
|
||||
public static final int ID = 2;
|
||||
private short value;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
|||
/**
|
||||
* A tag containing a string.
|
||||
*/
|
||||
public class StringTag extends Tag {
|
||||
public final class StringTag extends Tag {
|
||||
public static final int ID = 8;
|
||||
private String value;
|
||||
|
||||
|
|
Loading…
Reference in New Issue