283 lines
7.2 KiB
C#
283 lines
7.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using LibAC.NBT.API;
|
|
|
|
namespace LibAC.NBT
|
|
{
|
|
public class CompoundTag : Tag, IDictionary<string, Tag>
|
|
{
|
|
private readonly Dictionary<string, Tag> _value = new Dictionary<string, Tag>();
|
|
|
|
public CompoundTag() { }
|
|
|
|
public override void ReadValue(ByteLayer data)
|
|
{
|
|
_value.Clear();
|
|
|
|
while (true)
|
|
{
|
|
Tag tag = Tag.ReadNamedTag(data);
|
|
if (tag.GetType() == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
tag.SetParentTagType(TagType.Compound);
|
|
this[tag.GetKey()] = tag;
|
|
}
|
|
}
|
|
|
|
public override void WriteValue(ByteLayer data)
|
|
{
|
|
foreach (var tag in _value.Values)
|
|
{
|
|
Tag.WriteNamedTag(tag, data);
|
|
}
|
|
|
|
data.WriteByte((byte)TagType.End);
|
|
}
|
|
|
|
public void Put(string name, Tag tag)
|
|
{
|
|
_value[name] = tag;
|
|
tag.SetKey(name);
|
|
tag.UpdateParent(this);
|
|
}
|
|
|
|
public Tag? Get(string name)
|
|
{
|
|
return ContainsKey(name) ? _value[name] : null;
|
|
}
|
|
|
|
public override TagType GetTagType()
|
|
{
|
|
return TagType.Compound;
|
|
}
|
|
|
|
public override object GetValue()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public override void SetValue(object val) { }
|
|
|
|
public override void PrettyPrint(int indent, bool recurse)
|
|
{
|
|
Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: [{_value.Count} entries]");
|
|
Console.WriteLine($"{new string('\t', indent)}");
|
|
if (recurse)
|
|
{
|
|
foreach (var tag in _value.Values)
|
|
{
|
|
tag.PrettyPrint(indent + 1, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void EndPrettyPrint(int indent)
|
|
{
|
|
Console.WriteLine($"{new string('\t', indent)}");
|
|
}
|
|
|
|
public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
|
|
{
|
|
builder.Append($"{(isList ? new string('\t', indent - 1) : "")}{{\n");
|
|
|
|
bool firstEntry = true;
|
|
foreach (var tag in _value.Values)
|
|
{
|
|
if (!firstEntry)
|
|
{
|
|
builder.Append(",\n");
|
|
}
|
|
firstEntry = false;
|
|
Tag.WriteStringifiedNamedTag(tag, builder, indent);
|
|
}
|
|
|
|
builder.Append($"\n{new string('\t', indent - 1)}}}");
|
|
}
|
|
|
|
public bool TryGetValue(string key, out Tag value)
|
|
{
|
|
return _value.TryGetValue(key, out value);
|
|
}
|
|
|
|
public Tag? this[string key]
|
|
{
|
|
get => _value.ContainsKey(key) ? _value[key] : null;
|
|
set
|
|
{
|
|
if (value != null)
|
|
{
|
|
_value[key] = value;
|
|
value.UpdateParent(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Add(string key, Tag value)
|
|
{
|
|
_value.Add(key, value);
|
|
value.UpdateParent(this);
|
|
}
|
|
|
|
public void Add(KeyValuePair<string, Tag> item)
|
|
{
|
|
_value.Add(item.Key, item.Value);
|
|
item.Value.UpdateParent(this);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
UnsetParent();
|
|
_value.Clear();
|
|
}
|
|
|
|
public bool Contains(KeyValuePair<string, Tag> item)
|
|
{
|
|
return _value.ContainsKey(item.Key);
|
|
}
|
|
|
|
public void CopyTo(KeyValuePair<string, Tag>[] array, int arrayIndex)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public bool Remove(KeyValuePair<string, Tag> item)
|
|
{
|
|
return _value.Remove(item.Key);
|
|
}
|
|
|
|
public void UnsetParent()
|
|
{
|
|
foreach (var entry in _value)
|
|
{
|
|
entry.Value.SetParentTagType(TagType.End);
|
|
entry.Value.UpdateParent(null);
|
|
}
|
|
}
|
|
|
|
public bool ContainsKey(string key)
|
|
{
|
|
return _value.ContainsKey(key);
|
|
}
|
|
|
|
public bool ContainsValue(Tag value)
|
|
{
|
|
return _value.ContainsValue(value);
|
|
}
|
|
|
|
public void ForEach(Action<string, Tag> action)
|
|
{
|
|
foreach (var entry in _value)
|
|
{
|
|
action(entry.Key, entry.Value);
|
|
}
|
|
}
|
|
|
|
public int Count => _value.Count;
|
|
public bool IsReadOnly { get; }
|
|
|
|
public bool IsEmpty => _value.Count == 0;
|
|
|
|
public bool IsNotEmpty => _value.Count > 0;
|
|
|
|
public ICollection<string> Keys => _value.Keys;
|
|
|
|
public ICollection<Tag> Values => _value.Values;
|
|
|
|
public override void ReadStringifiedValue(StringReader reader)
|
|
{
|
|
reader.Expect('{');
|
|
|
|
while (reader.Peek() != '}')
|
|
{
|
|
Tag tag = Tag.ReadStringifiedNamedTag(reader);
|
|
Put(tag.GetKey(), tag);
|
|
|
|
if (reader.Peek() == ',') reader.Next();
|
|
}
|
|
|
|
reader.Expect('}');
|
|
}
|
|
|
|
public void AddAll(IDictionary<string, Tag> other)
|
|
{
|
|
foreach (var entry in other)
|
|
{
|
|
_value[entry.Key] = entry.Value;
|
|
entry.Value.UpdateParent(this);
|
|
}
|
|
}
|
|
|
|
public bool Remove(string key)
|
|
{
|
|
if (_value.ContainsKey(key))
|
|
{
|
|
_value[key].UpdateParent(null);
|
|
return _value.Remove(key);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void RemoveWhere(Predicate<KeyValuePair<string, Tag>> predicate)
|
|
{
|
|
var toRemove = new List<string>();
|
|
foreach (var entry in _value)
|
|
{
|
|
if (predicate(entry))
|
|
{
|
|
toRemove.Add(entry.Key);
|
|
}
|
|
}
|
|
|
|
foreach (var key in toRemove)
|
|
{
|
|
_value[key].UpdateParent(null);
|
|
_value.Remove(key);
|
|
}
|
|
}
|
|
|
|
public void UpdateAll(Action<string, Tag> update)
|
|
{
|
|
foreach (var entry in _value)
|
|
{
|
|
update(entry.Key, entry.Value);
|
|
}
|
|
}
|
|
|
|
public Tag PutIfAbsent(string key, Func<Tag> ifAbsent)
|
|
{
|
|
if (!_value.ContainsKey(key))
|
|
{
|
|
var tag = ifAbsent();
|
|
tag.UpdateParent(this);
|
|
_value[key] = tag;
|
|
return tag;
|
|
}
|
|
|
|
return _value[key];
|
|
}
|
|
|
|
public void AddEntries(IEnumerable<KeyValuePair<string, Tag>> newEntries)
|
|
{
|
|
foreach (var entry in newEntries)
|
|
{
|
|
_value.Add(entry.Key, entry.Value);
|
|
entry.Value.UpdateParent(this);
|
|
}
|
|
}
|
|
|
|
public IEnumerator<KeyValuePair<string, Tag>> GetEnumerator()
|
|
{
|
|
return _value.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return _value.GetEnumerator();
|
|
}
|
|
}
|
|
}
|