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