using System.Collections; using System.Collections.Generic; using System.Text; using JetBrains.Annotations; using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute; namespace SharpNBT { /// /// Base class for tags that contain a collection of values and can be enumerated. /// /// The type of the item the tag contains. [PublicAPI] public abstract class EnumerableTag : Tag, IList { /// /// Internal list implementation. /// private readonly List list; /// /// Initializes a new instance of the . /// /// A constant describing the NBT type for this tag. /// The name of the tag, or if tag has no name. protected EnumerableTag(TagType type, [CanBeNull] string name) : base(type, name) { list = new List(); } /// /// Initializes a new instance of the with the specified . /// /// A constant describing the NBT type for this tag. /// The name of the tag, or if tag has no name. /// A collection of values to include in this tag. protected EnumerableTag(TagType type, [CanBeNull] string name, [NotNull] IEnumerable values) : base(type, name) { list = new List(values); } /// Returns an enumerator that iterates through the collection. /// An enumerator that can be used to iterate through the collection. /// public IEnumerator GetEnumerator() => list.GetEnumerator(); /// Returns an enumerator that iterates through a collection. /// An object that can be used to iterate through the collection. /// IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)list).GetEnumerator(); /// Adds an item to the . /// The object to add to the . /// The is read-only. /// [SuppressMessage("ReSharper", "AnnotationConflictInHierarchy")] public void Add([NotNull] T item) { if (item is Tag child) child.Parent = this; list.Add(item); } /// /// Adds the elements of the specified collection to the . /// /// A collection containing the items to add. public void AddRange([NotNull] [ItemNotNull] IEnumerable items) { foreach (var item in items) Add(item); } /// Inserts an item to the at the specified index. /// The zero-based index at which should be inserted. /// The object to insert into the . /// /// is not a valid index in the . /// The is read-only. /// [SuppressMessage("ReSharper", "AnnotationConflictInHierarchy")] public void Insert(int index, [NotNull] T item) { if (item is Tag child) child.Parent = this; list.Insert(index, item); } /// Gets or sets the element at the specified index. /// The zero-based index of the element to get or set. /// /// is not a valid index in the . /// The property is set and the is read-only. /// The element at the specified index. /// [NotNull] public T this[int index] { get => list[index]; set { if (value is Tag child) child.Parent = this; list[index] = value; } } /// Removes all items from the . /// The is read-only. /// public void Clear() { foreach (var item in list) { if (item is Tag child) child.Parent = null; } list.Clear(); } /// Determines whether the contains a specific value. /// The object to locate in the . /// /// if is found in the ; otherwise, . /// public bool Contains(T item) => list.Contains(item); /// Copies the elements of the to an , starting at a particular index. /// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. /// The zero-based index in at which copying begins. /// /// is . /// /// is less than 0. /// The number of elements in the source is greater than the available space from to the end of the destination . /// public void CopyTo(T[] array, int arrayIndex) => list.CopyTo(array, arrayIndex); /// Removes the first occurrence of a specific object from the . /// The object to remove from the . /// The is read-only. /// /// if was successfully removed from the ; otherwise, . This method also returns if is not found in the original . /// public bool Remove(T item) { if (list.Remove(item)) { if (item is Tag child) child.Parent = null; return true; } return false; } /// Gets the number of elements contained in the . /// The number of elements contained in the . /// public int Count => list.Count; /// Gets a value indicating whether the is read-only. /// /// if the is read-only; otherwise, . /// public bool IsReadOnly => false; /// Determines the index of a specific item in the . /// The object to locate in the . /// The index of if found in the list; otherwise, -1. /// public int IndexOf(T item) => list.IndexOf(item); /// Removes the item at the specified index. /// The zero-based index of the item to remove. /// /// is not a valid index in the . /// The is read-only. /// public void RemoveAt(int index) { if (list[index] is Tag child) child.Parent = null; list.RemoveAt(index); } protected internal override void PrettyPrinted(StringBuilder buffer, int level, string indent) { for (var i = 0; i < level; i++) buffer.Append(indent); buffer.AppendLine(ToString()); } } }