001package net.minecraft.nbt;
002
003import java.io.DataInput;
004import java.io.DataOutput;
005import java.io.IOException;
006import java.util.Collection;
007import java.util.HashMap;
008import java.util.Iterator;
009import java.util.Map;
010import net.minecraft.crash.CrashReport;
011import net.minecraft.crash.CrashReportCategory;
012import net.minecraft.util.ReportedException;
013
014public class NBTTagCompound extends NBTBase
015{
016    /**
017     * The key-value pairs for the tag. Each key is a UTF string, each value is a tag.
018     */
019    private Map tagMap = new HashMap();
020
021    public NBTTagCompound()
022    {
023        super("");
024    }
025
026    public NBTTagCompound(String par1Str)
027    {
028        super(par1Str);
029    }
030
031    /**
032     * Write the actual data contents of the tag, implemented in NBT extension classes
033     */
034    void write(DataOutput par1DataOutput) throws IOException
035    {
036        Iterator var2 = this.tagMap.values().iterator();
037
038        while (var2.hasNext())
039        {
040            NBTBase var3 = (NBTBase)var2.next();
041            NBTBase.writeNamedTag(var3, par1DataOutput);
042        }
043
044        par1DataOutput.writeByte(0);
045    }
046
047    /**
048     * Read the actual data contents of the tag, implemented in NBT extension classes
049     */
050    void load(DataInput par1DataInput) throws IOException
051    {
052        this.tagMap.clear();
053        NBTBase var2;
054
055        while ((var2 = NBTBase.readNamedTag(par1DataInput)).getId() != 0)
056        {
057            this.tagMap.put(var2.getName(), var2);
058        }
059    }
060
061    /**
062     * Returns all the values in the tagMap HashMap.
063     */
064    public Collection getTags()
065    {
066        return this.tagMap.values();
067    }
068
069    /**
070     * Gets the type byte for the tag.
071     */
072    public byte getId()
073    {
074        return (byte)10;
075    }
076
077    /**
078     * Stores the given tag into the map with the given string key. This is mostly used to store tag lists.
079     */
080    public void setTag(String par1Str, NBTBase par2NBTBase)
081    {
082        this.tagMap.put(par1Str, par2NBTBase.setName(par1Str));
083    }
084
085    /**
086     * Stores a new NBTTagByte with the given byte value into the map with the given string key.
087     */
088    public void setByte(String par1Str, byte par2)
089    {
090        this.tagMap.put(par1Str, new NBTTagByte(par1Str, par2));
091    }
092
093    /**
094     * Stores a new NBTTagShort with the given short value into the map with the given string key.
095     */
096    public void setShort(String par1Str, short par2)
097    {
098        this.tagMap.put(par1Str, new NBTTagShort(par1Str, par2));
099    }
100
101    /**
102     * Stores a new NBTTagInt with the given integer value into the map with the given string key.
103     */
104    public void setInteger(String par1Str, int par2)
105    {
106        this.tagMap.put(par1Str, new NBTTagInt(par1Str, par2));
107    }
108
109    /**
110     * Stores a new NBTTagLong with the given long value into the map with the given string key.
111     */
112    public void setLong(String par1Str, long par2)
113    {
114        this.tagMap.put(par1Str, new NBTTagLong(par1Str, par2));
115    }
116
117    /**
118     * Stores a new NBTTagFloat with the given float value into the map with the given string key.
119     */
120    public void setFloat(String par1Str, float par2)
121    {
122        this.tagMap.put(par1Str, new NBTTagFloat(par1Str, par2));
123    }
124
125    /**
126     * Stores a new NBTTagDouble with the given double value into the map with the given string key.
127     */
128    public void setDouble(String par1Str, double par2)
129    {
130        this.tagMap.put(par1Str, new NBTTagDouble(par1Str, par2));
131    }
132
133    /**
134     * Stores a new NBTTagString with the given string value into the map with the given string key.
135     */
136    public void setString(String par1Str, String par2Str)
137    {
138        this.tagMap.put(par1Str, new NBTTagString(par1Str, par2Str));
139    }
140
141    /**
142     * Stores a new NBTTagByteArray with the given array as data into the map with the given string key.
143     */
144    public void setByteArray(String par1Str, byte[] par2ArrayOfByte)
145    {
146        this.tagMap.put(par1Str, new NBTTagByteArray(par1Str, par2ArrayOfByte));
147    }
148
149    /**
150     * Stores a new NBTTagIntArray with the given array as data into the map with the given string key.
151     */
152    public void setIntArray(String par1Str, int[] par2ArrayOfInteger)
153    {
154        this.tagMap.put(par1Str, new NBTTagIntArray(par1Str, par2ArrayOfInteger));
155    }
156
157    /**
158     * Stores the given NBTTagCompound into the map with the given string key.
159     */
160    public void setCompoundTag(String par1Str, NBTTagCompound par2NBTTagCompound)
161    {
162        this.tagMap.put(par1Str, par2NBTTagCompound.setName(par1Str));
163    }
164
165    /**
166     * Stores the given boolean value as a NBTTagByte, storing 1 for true and 0 for false, using the given string key.
167     */
168    public void setBoolean(String par1Str, boolean par2)
169    {
170        this.setByte(par1Str, (byte)(par2 ? 1 : 0));
171    }
172
173    /**
174     * gets a generic tag with the specified name
175     */
176    public NBTBase getTag(String par1Str)
177    {
178        return (NBTBase)this.tagMap.get(par1Str);
179    }
180
181    /**
182     * Returns whether the given string has been previously stored as a key in the map.
183     */
184    public boolean hasKey(String par1Str)
185    {
186        return this.tagMap.containsKey(par1Str);
187    }
188
189    /**
190     * Retrieves a byte value using the specified key, or 0 if no such key was stored.
191     */
192    public byte getByte(String par1Str)
193    {
194        try
195        {
196            return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagByte)this.tagMap.get(par1Str)).data;
197        }
198        catch (ClassCastException var3)
199        {
200            throw new ReportedException(this.createCrashReport(par1Str, 1, var3));
201        }
202    }
203
204    /**
205     * Retrieves a short value using the specified key, or 0 if no such key was stored.
206     */
207    public short getShort(String par1Str)
208    {
209        try
210        {
211            return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagShort)this.tagMap.get(par1Str)).data;
212        }
213        catch (ClassCastException var3)
214        {
215            throw new ReportedException(this.createCrashReport(par1Str, 2, var3));
216        }
217    }
218
219    /**
220     * Retrieves an integer value using the specified key, or 0 if no such key was stored.
221     */
222    public int getInteger(String par1Str)
223    {
224        try
225        {
226            return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagInt)this.tagMap.get(par1Str)).data;
227        }
228        catch (ClassCastException var3)
229        {
230            throw new ReportedException(this.createCrashReport(par1Str, 3, var3));
231        }
232    }
233
234    /**
235     * Retrieves a long value using the specified key, or 0 if no such key was stored.
236     */
237    public long getLong(String par1Str)
238    {
239        try
240        {
241            return !this.tagMap.containsKey(par1Str) ? 0L : ((NBTTagLong)this.tagMap.get(par1Str)).data;
242        }
243        catch (ClassCastException var3)
244        {
245            throw new ReportedException(this.createCrashReport(par1Str, 4, var3));
246        }
247    }
248
249    /**
250     * Retrieves a float value using the specified key, or 0 if no such key was stored.
251     */
252    public float getFloat(String par1Str)
253    {
254        try
255        {
256            return !this.tagMap.containsKey(par1Str) ? 0.0F : ((NBTTagFloat)this.tagMap.get(par1Str)).data;
257        }
258        catch (ClassCastException var3)
259        {
260            throw new ReportedException(this.createCrashReport(par1Str, 5, var3));
261        }
262    }
263
264    /**
265     * Retrieves a double value using the specified key, or 0 if no such key was stored.
266     */
267    public double getDouble(String par1Str)
268    {
269        try
270        {
271            return !this.tagMap.containsKey(par1Str) ? 0.0D : ((NBTTagDouble)this.tagMap.get(par1Str)).data;
272        }
273        catch (ClassCastException var3)
274        {
275            throw new ReportedException(this.createCrashReport(par1Str, 6, var3));
276        }
277    }
278
279    /**
280     * Retrieves a string value using the specified key, or an empty string if no such key was stored.
281     */
282    public String getString(String par1Str)
283    {
284        try
285        {
286            return !this.tagMap.containsKey(par1Str) ? "" : ((NBTTagString)this.tagMap.get(par1Str)).data;
287        }
288        catch (ClassCastException var3)
289        {
290            throw new ReportedException(this.createCrashReport(par1Str, 8, var3));
291        }
292    }
293
294    /**
295     * Retrieves a byte array using the specified key, or a zero-length array if no such key was stored.
296     */
297    public byte[] getByteArray(String par1Str)
298    {
299        try
300        {
301            return !this.tagMap.containsKey(par1Str) ? new byte[0] : ((NBTTagByteArray)this.tagMap.get(par1Str)).byteArray;
302        }
303        catch (ClassCastException var3)
304        {
305            throw new ReportedException(this.createCrashReport(par1Str, 7, var3));
306        }
307    }
308
309    /**
310     * Retrieves an int array using the specified key, or a zero-length array if no such key was stored.
311     */
312    public int[] getIntArray(String par1Str)
313    {
314        try
315        {
316            return !this.tagMap.containsKey(par1Str) ? new int[0] : ((NBTTagIntArray)this.tagMap.get(par1Str)).intArray;
317        }
318        catch (ClassCastException var3)
319        {
320            throw new ReportedException(this.createCrashReport(par1Str, 11, var3));
321        }
322    }
323
324    /**
325     * Retrieves a NBTTagCompound subtag matching the specified key, or a new empty NBTTagCompound if no such key was
326     * stored.
327     */
328    public NBTTagCompound getCompoundTag(String par1Str)
329    {
330        try
331        {
332            return !this.tagMap.containsKey(par1Str) ? new NBTTagCompound(par1Str) : (NBTTagCompound)this.tagMap.get(par1Str);
333        }
334        catch (ClassCastException var3)
335        {
336            throw new ReportedException(this.createCrashReport(par1Str, 10, var3));
337        }
338    }
339
340    /**
341     * Retrieves a NBTTagList subtag matching the specified key, or a new empty NBTTagList if no such key was stored.
342     */
343    public NBTTagList getTagList(String par1Str)
344    {
345        try
346        {
347            return !this.tagMap.containsKey(par1Str) ? new NBTTagList(par1Str) : (NBTTagList)this.tagMap.get(par1Str);
348        }
349        catch (ClassCastException var3)
350        {
351            throw new ReportedException(this.createCrashReport(par1Str, 9, var3));
352        }
353    }
354
355    /**
356     * Retrieves a boolean value using the specified key, or false if no such key was stored. This uses the getByte
357     * method.
358     */
359    public boolean getBoolean(String par1Str)
360    {
361        return this.getByte(par1Str) != 0;
362    }
363
364    /**
365     * Remove the specified tag.
366     */
367    public void removeTag(String par1Str)
368    {
369        this.tagMap.remove(par1Str);
370    }
371
372    public String toString()
373    {
374        return "" + this.tagMap.size() + " entries";
375    }
376
377    /**
378     * Return whether this compound has no tags.
379     */
380    public boolean hasNoTags()
381    {
382        return this.tagMap.isEmpty();
383    }
384
385    /**
386     * Create a crash report which indicates a NBT read error.
387     */
388    private CrashReport createCrashReport(String par1Str, int par2, ClassCastException par3ClassCastException)
389    {
390        CrashReport var4 = CrashReport.makeCrashReport(par3ClassCastException, "Reading NBT data");
391        CrashReportCategory var5 = var4.makeCategoryDepth("Corrupt NBT tag", 1);
392        var5.addCrashSectionCallable("Tag type found", new CallableTagCompound1(this, par1Str));
393        var5.addCrashSectionCallable("Tag type expected", new CallableTagCompound2(this, par2));
394        var5.addCrashSection("Tag name", par1Str);
395
396        if (this.getName() != null && this.getName().length() > 0)
397        {
398            var5.addCrashSection("Tag parent", this.getName());
399        }
400
401        return var4;
402    }
403
404    /**
405     * Creates a clone of the tag.
406     */
407    public NBTBase copy()
408    {
409        NBTTagCompound var1 = new NBTTagCompound(this.getName());
410        Iterator var2 = this.tagMap.keySet().iterator();
411
412        while (var2.hasNext())
413        {
414            String var3 = (String)var2.next();
415            var1.setTag(var3, ((NBTBase)this.tagMap.get(var3)).copy());
416        }
417
418        return var1;
419    }
420
421    public boolean equals(Object par1Obj)
422    {
423        if (super.equals(par1Obj))
424        {
425            NBTTagCompound var2 = (NBTTagCompound)par1Obj;
426            return this.tagMap.entrySet().equals(var2.tagMap.entrySet());
427        }
428        else
429        {
430            return false;
431        }
432    }
433
434    public int hashCode()
435    {
436        return super.hashCode() ^ this.tagMap.hashCode();
437    }
438
439    /**
440     * Return the tag map for this compound.
441     */
442    static Map getTagMap(NBTTagCompound par0NBTTagCompound)
443    {
444        return par0NBTTagCompound.tagMap;
445    }
446}