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    }