| File: System\Xml\Dom\XmlNamedNodeMap.SmallXmlNodeList.cs | Web Access |
| Project: src\runtime\src\libraries\System.Private.Xml\src\System.Private.Xml.csproj (System.Private.Xml) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; using System.Collections.Generic; using System.Diagnostics; namespace System.Xml { public partial class XmlNamedNodeMap { // Optimized to minimize space in the zero or one element cases. internal struct SmallXmlNodeList { // If field is null, that represents an empty list. // If field is non-null, but not an List<object>, then the 'list' contains a single // object. // Otherwise, field is an List<object>. Once the field upgrades to an List<object>, it // never degrades back, even if all elements are removed. private object? _field; public int Count { get { if (_field == null) return 0; List<object>? list = _field as List<object>; if (list != null) return list.Count; return 1; } } public object this[int index] { get { if (_field == null) throw new ArgumentOutOfRangeException(nameof(index)); List<object>? list = _field as List<object>; if (list != null) return list[index]; ArgumentOutOfRangeException.ThrowIfNotEqual(index, 0); return _field; } } public void Add(object value) { if (_field == null) { if (value == null) { Debug.Fail("Null was added to the collection which didn't expect it"); // If a single null value needs to be stored, then // upgrade to an ArrayList List<object> temp = new List<object>(); temp.Add(null!); _field = temp; } else _field = value; return; } List<object>? list = _field as List<object>; if (list != null) { list.Add(value); } else { list = new List<object>(); list.Add(_field); list.Add(value); _field = list; } } public void RemoveAt(int index) { if (_field == null) throw new ArgumentOutOfRangeException(nameof(index)); List<object?>? list = _field as List<object?>; if (list != null) { list.RemoveAt(index); return; } ArgumentOutOfRangeException.ThrowIfNotEqual(index, 0); _field = null; } public void Insert(int index, object value) { if (_field == null) { ArgumentOutOfRangeException.ThrowIfNotEqual(index, 0); Add(value); return; } List<object>? list = _field as List<object>; if (list != null) { list.Insert(index, value); return; } if (index == 0) { list = new List<object>(); list.Add(value); list.Add(_field); _field = list; } else if (index == 1) { list = new List<object>(); list.Add(_field); list.Add(value); _field = list; } else { throw new ArgumentOutOfRangeException(nameof(index)); } } private sealed class SingleObjectEnumerator : IEnumerator { private readonly object _loneValue; private int _position = -1; public SingleObjectEnumerator(object value) { _loneValue = value; } public object Current { get { if (_position != 0) { throw new InvalidOperationException(); } return _loneValue; } } public bool MoveNext() { if (_position < 0) { _position = 0; return true; } _position = 1; return false; } public void Reset() { _position = -1; } } public IEnumerator GetEnumerator() { if (_field == null) { return XmlDocument.EmptyEnumerator; } List<object>? list = _field as List<object>; if (list != null) { return list.GetEnumerator(); } return new SingleObjectEnumerator(_field); } } } }