    001    package net.minecraft.nbt;
    002
    003    import java.io.DataInput;
    004    import java.io.DataOutput;
    005    import java.io.IOException;
    006    import net.minecraft.crash.CrashReport;
    007    import net.minecraft.crash.CrashReportCategory;
    008    import net.minecraft.util.ReportedException;
    009
    010    public 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    }