Terraria ModLoader  0.11.4
A framework for Terraria mods
TagCompound.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.IO;
5 
6 namespace Terraria.ModLoader.IO
7 {
8  //Tag compounds contained named values, serialisable as per the NBT spec http://minecraft.gamepedia.com/NBT_format
9  //All primitive data types are supported as well as byte[], int[] and Lists of other supported data types
10  //Lists of Lists are internally stored as IList<IList>
11  //Modification of lists stored in a TagCompound will only work if there were no type conversions involved and is not advised
12  //bool is supported using TagConverter, serialised as a byte. IList<bool> will serialise as IList<byte> (quite inefficient)
13  //Additional conversions can be added using TagConverter
14  public class TagCompound : IEnumerable<KeyValuePair<string, object>>, ICloneable
15  {
16  private Dictionary<string, object> dict = new Dictionary<string, object>();
17  public T Get<T>(string key) {
18  object tag = null;
19  dict.TryGetValue(key, out tag);
20  try {
21  return TagIO.Deserialize<T>(tag);
22  }
23  catch (Exception e) {
24  throw new IOException(
25  $"NBT Deserialization (type={typeof(T)}," +
26  $"entry={TagPrinter.Print(new KeyValuePair<string, object>(key, tag))})", e);
27  }
28  }
29 
30  // adding default param to Set overload is a breaking changefor now.
31  public void Set(string key, object value) => Set(key, value, false);
32 
33  //if value is null, calls RemoveTag, also performs type checking
34  public void Set(string key, object value, bool replace = false) {
35  if (value == null) {
36  Remove(key);
37  return;
38  }
39 
40  object serialized;
41  try {
42  serialized = TagIO.Serialize(value);
43  }
44  catch (IOException e) {
45  var valueInfo = "value=" + value;
46  if (value.GetType().ToString() != value.ToString())
47  valueInfo = "type=" + value.GetType() + "," + valueInfo;
48  throw new IOException($"NBT Serialization (key={key},{valueInfo})", e);
49  }
50  if (replace)
51  dict[key] = serialized;
52  else
53  dict.Add(key, serialized);
54  }
55 
56  public bool ContainsKey(string key) => dict.ContainsKey(key);
57  public bool Remove(string key) => dict.Remove(key);
58 
59  [Obsolete] public T GetTag<T>(string key) => Get<T>(key);
60  [Obsolete] public void SetTag(string key, object value) => Set(key, value);
61  [Obsolete] public bool HasTag(string key) => ContainsKey(key);
62  [Obsolete] public bool RemoveTag(string key) => Remove(key);
63 
64  //NBT spec getters
65  public byte GetByte(string key) => Get<byte>(key);
66  public short GetShort(string key) => Get<short>(key);
67  public int GetInt(string key) => Get<int>(key);
68  public long GetLong(string key) => Get<long>(key);
69  public float GetFloat(string key) => Get<float>(key);
70  public double GetDouble(string key) => Get<double>(key);
71  public byte[] GetByteArray(string key) => Get<byte[]>(key);
72  public int[] GetIntArray(string key) => Get<int[]>(key);
73  public string GetString(string key) => Get<string>(key);
74  public IList<T> GetList<T>(string key) => Get<List<T>>(key);
75  public TagCompound GetCompound(string key) => Get<TagCompound>(key);
76  public bool GetBool(string key) => Get<bool>(key);
77 
78  //type expansion helpers
79  public short GetAsShort(string key) {
80  var o = Get<object>(key);
81  return o as short? ?? o as byte? ?? 0;
82  }
83 
84  public int GetAsInt(string key) {
85  var o = Get<object>(key);
86  return o as int? ?? o as short? ?? o as byte? ?? 0;
87  }
88 
89  public long GetAsLong(string key) {
90  var o = Get<object>(key);
91  return o as long? ?? o as int? ?? o as short? ?? o as byte? ?? 0;
92  }
93 
94  public double GetAsDouble(string key) {
95  var o = Get<object>(key);
96  return o as double? ?? o as float? ?? 0;
97  }
98 
99  public object Clone() {
100  var copy = new TagCompound();
101  foreach (var entry in this)
102  copy.Set(entry.Key, TagIO.Clone(entry.Value));
103 
104  return copy;
105  }
106 
107  public override string ToString() {
108  return TagPrinter.Print(this);
109  }
110 
111  public object this[string key] {
112  get { return Get<object>(key); }
113  set { Set(key, value, true); }
114  }
115 
116  //collection initialiser
117  public void Add(string key, object value) => Set(key, value);
118  public void Add(KeyValuePair<string, object> entry) => Set(entry.Key, entry.Value);
119 
120  //delegate some collection implementations
121  public void Clear() { dict.Clear(); }
122  public int Count => dict.Count;
123  public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => dict.GetEnumerator();
124  IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
125  }
126 }
double GetAsDouble(string key)
Definition: TagCompound.cs:94
static string Print(TagCompound tag)
Definition: TagPrinter.cs:104
static object Deserialize(Type type, object tag)
Definition: TagIO.cs:213
static object Serialize(object value)
Definition: TagIO.cs:182
void Set(string key, object value, bool replace=false)
Definition: TagCompound.cs:34