using System; using System.Collections.Generic; namespace Substrate.Nbt { /// <summary> /// A concrete <see cref="SchemaNode"/> representing a <see cref="TagNodeCompound"/>. /// </summary> public sealed class SchemaNodeCompound : SchemaNode, ICollection<SchemaNode> { private List<SchemaNode> _subnodes; #region ICollection<NBTSchemaNode> Members /// <summary> /// Adds a <see cref="SchemaNode"/> as a child of this node. /// </summary> /// <param name="item">The <see cref="SchemaNode"/> to add.</param> public void Add (SchemaNode item) { _subnodes.Add(item); } /// <summary> /// Removes all <see cref="SchemaNode"/> objects from the node. /// </summary> public void Clear () { _subnodes.Clear(); } /// <summary> /// Checks if a <see cref="SchemaNode"/> is a child of this node. /// </summary> /// <param name="item">The <see cref="SchemaNode"/> to check for existance.</param> /// <returns>Status indicating if the <see cref="SchemaNode"/> exists as a child of this node.</returns> public bool Contains (SchemaNode item) { return _subnodes.Contains(item); } /// <summary> /// Copies all child <see cref="SchemaNode"/> objects of this node to a compatible one-dimensional array, starting at the specified index of the target array. /// </summary> /// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the subnodes copied. The Array must have zero-based indexing.</param> /// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param> public void CopyTo (SchemaNode[] array, int arrayIndex) { _subnodes.CopyTo(array, arrayIndex); } /// <summary> /// Gets the number of child <see cref="SchemaNode"/> objects in this node. /// </summary> public int Count { get { return _subnodes.Count; } } /// <summary> /// Gets a value indicating whether the node is readonly. /// </summary> public bool IsReadOnly { get { return false; } } /// <summary> /// Removes the first occurance of a <see cref="SchemaNode"/> from this node. /// </summary> /// <param name="item">The <see cref="SchemaNode"/> to remove.</param> /// <returns>Status indicating whether a <see cref="SchemaNode"/> was removed.</returns> public bool Remove (SchemaNode item) { return _subnodes.Remove(item); } #endregion #region IEnumerable<SchemaNode> Members /// <summary> /// Iterates through all of the <see cref="SchemaNode"/> objects in this <see cref="SchemaNodeCompound"/>. /// </summary> /// <returns>An enumerator for this node.</returns> public IEnumerator<SchemaNode> GetEnumerator () { return _subnodes.GetEnumerator(); } #endregion #region IEnumerable Members /// <summary> /// Iterates through all of the <see cref="SchemaNode"/> objects in this <see cref="SchemaNodeCompound"/>. /// </summary> /// <returns>An enumerator for this node.</returns> System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () { return _subnodes.GetEnumerator(); } #endregion /// <summary> /// Constructs a new <see cref="SchemaNodeCompound"/> representing a root <see cref="TagNodeCompound"/>. /// </summary> public SchemaNodeCompound () : base("") { _subnodes = new List<SchemaNode>(); } /// <summary> /// Constructs a new <see cref="SchemaNodeCompound"/> with additional options. /// </summary> /// <param name="options">One or more option flags modifying the processing of this node.</param> public SchemaNodeCompound (SchemaOptions options) : base("", options) { _subnodes = new List<SchemaNode>(); } /// <summary> /// Constructs a new <see cref="SchemaNodeCompound"/> representing a <see cref="TagNodeCompound"/> named <paramref name="name"/>. /// </summary> /// <param name="name">The name of the corresponding <see cref="TagNodeCompound"/>.</param> public SchemaNodeCompound (string name) : base(name) { _subnodes = new List<SchemaNode>(); } /// <summary> /// Constructs a new <see cref="SchemaNodeCompound"/> with additional options. /// </summary> /// <param name="name">The name of the corresponding <see cref="TagNodeCompound"/>.</param> /// <param name="options">One or more option flags modifying the processing of this node.</param> public SchemaNodeCompound (string name, SchemaOptions options) : base(name, options) { _subnodes = new List<SchemaNode>(); } /// <summary> /// Constructs a new <see cref="SchemaNodeCompound"/> representing a <see cref="TagNodeCompound"/> named <paramref name="name"/> matching the given schema. /// </summary> /// <param name="name">The name of the corresponding <see cref="TagNodeCompound"/>.</param> /// <param name="subschema">A <see cref="SchemaNodeCompound"/> representing a schema to verify against the corresponding <see cref="TagNodeCompound"/>.</param> public SchemaNodeCompound (string name, SchemaNode subschema) : base(name) { _subnodes = new List<SchemaNode>(); SchemaNodeCompound schema = subschema as SchemaNodeCompound; if (schema == null) { return; } foreach (SchemaNode node in schema._subnodes) { _subnodes.Add(node); } } /// <summary> /// Constructs a new <see cref="SchemaNodeCompound"/> with additional options. /// </summary> /// <param name="name">The name of the corresponding <see cref="TagNodeCompound"/>.</param> /// <param name="subschema">A <see cref="SchemaNodeCompound"/> representing a schema to verify against the corresponding <see cref="TagNodeCompound"/>.</param> /// <param name="options">One or more option flags modifying the processing of this node.</param> public SchemaNodeCompound (string name, SchemaNode subschema, SchemaOptions options) : base(name, options) { _subnodes = new List<SchemaNode>(); SchemaNodeCompound schema = subschema as SchemaNodeCompound; if (schema == null) { return; } foreach (SchemaNode node in schema._subnodes) { _subnodes.Add(node); } } /// <summary> /// Copies all the elements of this <see cref="SchemaNodeCompound"/> into <paramref name="tree"/>. /// </summary> /// <param name="tree">The destination <see cref="SchemaNodeCompound"/> to copy <see cref="SchemaNode"/> elements into.</param> /// <returns>A reference to <paramref name="tree"/>.</returns> public SchemaNodeCompound MergeInto (SchemaNodeCompound tree) { foreach (SchemaNode node in _subnodes) { SchemaNode f = tree._subnodes.Find(n => n.Name == node.Name); if (f != null) { continue; } tree.Add(node); } return tree; } /// <summary> /// Constructs a default <see cref="TagNodeCompound"/> satisfying the constraints of this node. /// </summary> /// <returns>A <see cref="TagNodeCompound"/> with a sensible default value. A default child <see cref="TagNode"/> is created for every <see cref="SchemaNode"/> contained in this <see cref="SchemaNodeCompound"/>.</returns> public override TagNode BuildDefaultTree () { TagNodeCompound list = new TagNodeCompound(); foreach (SchemaNode node in _subnodes) { list[node.Name] = node.BuildDefaultTree(); } return list; } } }