package net.minecraft.nbt;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.google.common.collect.Lists;
public class NBTTagList extends NBTBase
{
private static final Logger LOGGER = LogManager.getLogger();
/** The array list containing the tags encapsulated in this list. */
List<NBTBase> tagList = new ArrayList<>();
/**
* The type byte for the tags in the list - they must all be of the same type.
*/
private byte tagType = 0;
private static final String __OBFID = "CL_00001224";
/**
* Write the actual data contents of the tag, implemented in NBT extension classes
*/
@Override
void write(final DataOutput output) throws IOException
{
if (!this.tagList.isEmpty())
this.tagType = this.tagList.get(0).getId();
else
this.tagType = 0;
output.writeByte(this.tagType);
output.writeInt(this.tagList.size());
for (int var2 = 0; var2 < this.tagList.size(); ++var2)
this.tagList.get(var2).write(output);
}
@Override
void read(final DataInput input, final int depth, final NBTSizeTracker sizeTracker) throws IOException
{
if (depth > 512)
throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
else
{
sizeTracker.read(8L);
this.tagType = input.readByte();
final int var4 = input.readInt();
this.tagList = Lists.newArrayList();
for (int var5 = 0; var5 < var4; ++var5)
{
final NBTBase var6 = NBTBase.createNewByType(this.tagType);
var6.read(input, depth + 1, sizeTracker);
this.tagList.add(var6);
}
}
}
/**
* Gets the type byte for the tag.
*/
@Override
public byte getId()
{
return (byte) 9;
}
@Override
public String toString()
{
String var1 = "[";
int var2 = 0;
for (final Iterator var3 = this.tagList.iterator(); var3.hasNext(); ++var2)
{
final NBTBase var4 = (NBTBase) var3.next();
var1 = var1 + "" + var4 + ','; // var1 + "" + var2 + ':' + var4 + ','; (removed the 'index:' part in order to make the output parsable (the original parser simply ignores it...))
}
return var1 + "]";
}
/**
* Adds the provided tag to the end of the list. There is no check to verify this tag is of the same type as any previous tag.
*/
public void appendTag(final NBTBase nbt)
{
if (this.tagType == 0)
this.tagType = nbt.getId();
else if (this.tagType != nbt.getId())
{
LOGGER.warn("Adding mismatching tag types to tag list");
return;
}
this.tagList.add(nbt);
}
/**
* Set the given index to the given tag
*/
public void set(final int idx, final NBTBase nbt)
{
if (idx >= 0 && idx < this.tagList.size())
{
if (this.tagType == 0)
this.tagType = nbt.getId();
else if (this.tagType != nbt.getId())
{
LOGGER.warn("Adding mismatching tag types to tag list");
return;
}
this.tagList.set(idx, nbt);
}
else
LOGGER.warn("index out of bounds to set tag in tag list");
}
/**
* Removes a tag at the given index.
*/
public NBTBase removeTag(final int i)
{
return this.tagList.remove(i);
}
/**
* Return whether this compound has no tags.
*/
@Override
public boolean hasNoTags()
{
return this.tagList.isEmpty();
}
/**
* Retrieves the NBTTagCompound at the specified index in the list
*/
public NBTTagCompound getCompoundTagAt(final int i)
{
if (i >= 0 && i < this.tagList.size())
{
final NBTBase var2 = this.tagList.get(i);
return var2.getId() == 10 ? (NBTTagCompound) var2 : new NBTTagCompound();
}
else
return new NBTTagCompound();
}
public int[] getIntArray(final int i)
{
if (i >= 0 && i < this.tagList.size())
{
final NBTBase var2 = this.tagList.get(i);
return var2.getId() == 11 ? ((NBTTagIntArray) var2).getIntArray() : new int[0];
}
else
return new int[0];
}
public double getDouble(final int i)
{
if (i >= 0 && i < this.tagList.size())
{
final NBTBase var2 = this.tagList.get(i);
return var2.getId() == 6 ? ((NBTTagDouble) var2).getDouble() : 0.0D;
}
else
return 0.0D;
}
public float getFloat(final int i)
{
if (i >= 0 && i < this.tagList.size())
{
final NBTBase var2 = this.tagList.get(i);
return var2.getId() == 5 ? ((NBTTagFloat) var2).getFloat() : 0.0F;
}
else
return 0.0F;
}
/**
* Retrieves the tag String value at the specified index in the list
*/
public String getStringTagAt(final int i)
{
if (i >= 0 && i < this.tagList.size())
{
final NBTBase var2 = this.tagList.get(i);
return var2.getId() == 8 ? var2.getString() : var2.toString();
}
else
return "";
}
/**
* Get the tag at the given position
*/
public NBTBase get(final int idx)
{
return idx >= 0 && idx < this.tagList.size() ? (NBTBase) this.tagList.get(idx) : new NBTTagEnd();
}
/**
* Returns the number of tags in the list.
*/
public int tagCount()
{
return this.tagList.size();
}
/**
* Creates a clone of the tag.
*/
@Override
public NBTBase copy()
{
final NBTTagList var1 = new NBTTagList();
var1.tagType = this.tagType;
final Iterator var2 = this.tagList.iterator();
while (var2.hasNext())
{
final NBTBase var3 = (NBTBase) var2.next();
final NBTBase var4 = var3.copy();
var1.tagList.add(var4);
}
return var1;
}
@Override
public boolean equals(final Object p_equals_1_)
{
if (super.equals(p_equals_1_))
{
final NBTTagList var2 = (NBTTagList) p_equals_1_;
if (this.tagType == var2.tagType)
return this.tagList.equals(var2.tagList);
}
return false;
}
@Override
public int hashCode()
{
return super.hashCode() ^ this.tagList.hashCode();
}
public int getTagType()
{
return this.tagType;
}
public static class CopyOnWrite extends NBTTagList
{
boolean copied = false;
public CopyOnWrite(final NBTTagList tag)
{
this.tagList = tag.tagList;
}
private void shallowCopy()
{
if (!this.copied)
{
this.copied = true;
final List<NBTBase> oldList = this.tagList;
this.tagList = new ArrayList<>();
this.tagList.addAll(oldList);
}
}
@Override
public NBTTagCompound getCompoundTagAt(final int i)
{
return new NBTTagCompound.CopyOnWrite(super.getCompoundTagAt(i));
}
@Override
public NBTBase get(final int idx)
{
final NBTBase tag = super.get(idx);
if (tag.getId() == 9)
return new CopyOnWrite((NBTTagList) tag);
else if (tag.getId() == 10)
return new NBTTagCompound.CopyOnWrite((NBTTagCompound) tag);
else
return tag.copy();
}
@Override
public void appendTag(final NBTBase nbt)
{
this.shallowCopy();
super.appendTag(nbt);
}
@Override
public NBTBase removeTag(final int i)
{
this.shallowCopy();
return super.removeTag(i);
}
@Override
public void set(final int idx, final NBTBase nbt)
{
this.shallowCopy();
super.set(idx, nbt);
}
}
}