001package net.minecraft.nbt;
002
003import java.io.DataInput;
004import java.io.DataOutput;
005import java.io.IOException;
006import net.minecraft.crash.CrashReport;
007import net.minecraft.crash.CrashReportCategory;
008import net.minecraft.util.ReportedException;
009
010public abstract class NBTBase
011{
012    public static final String[] NBTTypes = new String[] {"END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]"};
013
014    /** The UTF string key used to lookup values. */
015    private String name;
016
017    /**
018     * Write the actual data contents of the tag, implemented in NBT extension classes
019     */
020    abstract void write(DataOutput var1) throws IOException;
021
022    /**
023     * Read the actual data contents of the tag, implemented in NBT extension classes
024     */
025    abstract void load(DataInput var1) throws IOException;
026
027    /**
028     * Gets the type byte for the tag.
029     */
030    public abstract byte getId();
031
032    protected NBTBase(String par1Str)
033    {
034        if (par1Str == null)
035        {
036            this.name = "";
037        }
038        else
039        {
040            this.name = par1Str;
041        }
042    }
043
044    /**
045     * Sets the name for this tag and returns this for convenience.
046     */
047    public NBTBase setName(String par1Str)
048    {
049        if (par1Str == null)
050        {
051            this.name = "";
052        }
053        else
054        {
055            this.name = par1Str;
056        }
057
058        return this;
059    }
060
061    /**
062     * Gets the name corresponding to the tag, or an empty string if none set.
063     */
064    public String getName()
065    {
066        return this.name == null ? "" : this.name;
067    }
068
069    /**
070     * Reads and returns a tag from the given DataInput, or the End tag if no tag could be read.
071     */
072    public static NBTBase readNamedTag(DataInput par0DataInput) throws IOException
073    {
074        byte var1 = par0DataInput.readByte();
075
076        if (var1 == 0)
077        {
078            return new NBTTagEnd();
079        }
080        else
081        {
082            String var2 = par0DataInput.readUTF();
083            NBTBase var3 = newTag(var1, var2);
084
085            try
086            {
087                var3.load(par0DataInput);
088                return var3;
089            }
090            catch (IOException var7)
091            {
092                CrashReport var5 = CrashReport.makeCrashReport(var7, "Loading NBT data");
093                CrashReportCategory var6 = var5.makeCategory("NBT Tag");
094                var6.addCrashSection("Tag name", var2);
095                var6.addCrashSection("Tag type", Byte.valueOf(var1));
096                throw new ReportedException(var5);
097            }
098        }
099    }
100
101    /**
102     * Writes the specified tag to the given DataOutput, writing the type byte, the UTF string key and then calling the
103     * tag to write its data.
104     */
105    public static void writeNamedTag(NBTBase par0NBTBase, DataOutput par1DataOutput) throws IOException
106    {
107        par1DataOutput.writeByte(par0NBTBase.getId());
108
109        if (par0NBTBase.getId() != 0)
110        {
111            par1DataOutput.writeUTF(par0NBTBase.getName());
112            par0NBTBase.write(par1DataOutput);
113        }
114    }
115
116    /**
117     * Creates and returns a new tag of the specified type, or null if invalid.
118     */
119    public static NBTBase newTag(byte par0, String par1Str)
120    {
121        switch (par0)
122        {
123            case 0:
124                return new NBTTagEnd();
125            case 1:
126                return new NBTTagByte(par1Str);
127            case 2:
128                return new NBTTagShort(par1Str);
129            case 3:
130                return new NBTTagInt(par1Str);
131            case 4:
132                return new NBTTagLong(par1Str);
133            case 5:
134                return new NBTTagFloat(par1Str);
135            case 6:
136                return new NBTTagDouble(par1Str);
137            case 7:
138                return new NBTTagByteArray(par1Str);
139            case 8:
140                return new NBTTagString(par1Str);
141            case 9:
142                return new NBTTagList(par1Str);
143            case 10:
144                return new NBTTagCompound(par1Str);
145            case 11:
146                return new NBTTagIntArray(par1Str);
147            default:
148                return null;
149        }
150    }
151
152    /**
153     * Returns the string name of a tag with the specified type, or 'UNKNOWN' if invalid.
154     */
155    public static String getTagName(byte par0)
156    {
157        switch (par0)
158        {
159            case 0:
160                return "TAG_End";
161            case 1:
162                return "TAG_Byte";
163            case 2:
164                return "TAG_Short";
165            case 3:
166                return "TAG_Int";
167            case 4:
168                return "TAG_Long";
169            case 5:
170                return "TAG_Float";
171            case 6:
172                return "TAG_Double";
173            case 7:
174                return "TAG_Byte_Array";
175            case 8:
176                return "TAG_String";
177            case 9:
178                return "TAG_List";
179            case 10:
180                return "TAG_Compound";
181            case 11:
182                return "TAG_Int_Array";
183            default:
184                return "UNKNOWN";
185        }
186    }
187
188    /**
189     * Creates a clone of the tag.
190     */
191    public abstract NBTBase copy();
192
193    public boolean equals(Object par1Obj)
194    {
195        if (!(par1Obj instanceof NBTBase))
196        {
197            return false;
198        }
199        else
200        {
201            NBTBase var2 = (NBTBase)par1Obj;
202            return this.getId() != var2.getId() ? false : ((this.name != null || var2.name == null) && (this.name == null || var2.name != null) ? this.name == null || this.name.equals(var2.name) : false);
203        }
204    }
205
206    public int hashCode()
207    {
208        return this.name.hashCode() ^ this.getId();
209    }
210}