< Summary

Information
Class: System.Net.Http.Headers.UnvalidatedObjectCollection<T>
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\ObjectCollection.cs
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 214
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
Validate(...)100%11100%

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\ObjectCollection.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections;
 5using System.Collections.Generic;
 6using System.Diagnostics;
 7
 8namespace System.Net.Http.Headers
 9{
 10    internal sealed class UnvalidatedObjectCollection<T> : ObjectCollection<T> where T : class
 11    {
 12        public override void Validate(T item)
 51677813        {
 51677814            ArgumentNullException.ThrowIfNull(item);
 51677815        }
 16    }
 17
 18    /// <summary>An <see cref="ICollection{T}"/> list that prohibits null elements and that is optimized for a small num
 19    [DebuggerDisplay("Count = {Count}")]
 20    [DebuggerTypeProxy(typeof(ObjectCollection<>.DebugView))]
 21    internal abstract class ObjectCollection<T> : ICollection<T> where T : class
 22    {
 23        private const int DefaultSize = 4;
 24
 25        /// <summary>null, a T, or a T[].</summary>
 26        internal object? _items;
 27        /// <summary>Number of elements stored in the collection.</summary>
 28        internal int _size;
 29
 30        public ObjectCollection() { }
 31
 32        public int Count => _size;
 33
 34        public bool IsReadOnly => false;
 35
 36        public abstract void Validate(T item);
 37
 38        public void Add(T item)
 39        {
 40            Validate(item);
 41            Debug.Assert(item != null);
 42
 43            if (_items is null)
 44            {
 45                // The collection is empty. Just store the new item directly.
 46                _items = item;
 47                _size = 1;
 48            }
 49            else if (_items is T existingItem)
 50            {
 51                // The collection has a single item stored directly.  Upgrade to
 52                // an array, and store both the existing and new items.
 53                Debug.Assert(_size == 1);
 54                T[] items = new T[DefaultSize];
 55                items[0] = existingItem;
 56                items[1] = item;
 57                _items = items;
 58                _size = 2;
 59            }
 60            else
 61            {
 62                T[] array = (T[])_items;
 63                int size = _size;
 64                if ((uint)size < (uint)array.Length)
 65                {
 66                    // There's room in the existing array.  Add the item.
 67                    array[size] = item;
 68                }
 69                else
 70                {
 71                    // We need to grow the array.  Do so, and store the new item.
 72                    Debug.Assert(_size > 0);
 73                    Debug.Assert(_size == array.Length);
 74
 75                    var newItems = new T[array.Length * 2];
 76                    Array.Copy(array, newItems, size);
 77                    _items = newItems;
 78                    newItems[size] = item;
 79                }
 80                _size = size + 1;
 81            }
 82        }
 83
 84        public void Clear()
 85        {
 86            _items = null;
 87            _size = 0;
 88        }
 89
 90        public bool Contains(T item) =>
 91            _size <= 0 ? false :
 92            _items is T o ? o.Equals(item) :
 93            _items is T[] items && Array.IndexOf(items, item, 0, _size) >= 0;
 94
 95        public void CopyTo(T[] array, int arrayIndex)
 96        {
 97            if (_items is T[] items)
 98            {
 99                Array.Copy(items, 0, array, arrayIndex, _size);
 100            }
 101            else
 102            {
 103                Debug.Assert(_size == 0 || _size == 1);
 104                if (array is null || _size > array.Length - arrayIndex)
 105                {
 106                    // Use Array.CopyTo to throw the right exceptions.
 107                    new T[] { (T)_items! }.CopyTo(array!, arrayIndex);
 108                }
 109                else if (_size == 1)
 110                {
 111                    array[arrayIndex] = (T)_items!;
 112                }
 113            }
 114        }
 115
 116        public bool Remove(T item)
 117        {
 118            if (_items is T o)
 119            {
 120                if (o.Equals(item))
 121                {
 122                    _items = null;
 123                    _size = 0;
 124                    return true;
 125                }
 126            }
 127            else if (_items is T[] items)
 128            {
 129                int index = Array.IndexOf(items, item, 0, _size);
 130                if (index >= 0)
 131                {
 132                    _size--;
 133                    if (index < _size)
 134                    {
 135                        Array.Copy(items, index + 1, items, index, _size - index);
 136                    }
 137                    items[_size] = null!;
 138
 139                    return true;
 140                }
 141            }
 142
 143            return false;
 144        }
 145
 146        public Enumerator GetEnumerator() => new Enumerator(this);
 147        IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
 148        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 149
 150        public struct Enumerator : IEnumerator<T>
 151        {
 152            private readonly ObjectCollection<T> _list;
 153            private int _index;
 154            private T _current;
 155
 156            internal Enumerator(ObjectCollection<T> list)
 157            {
 158                _list = list;
 159                _index = 0;
 160                _current = default!;
 161            }
 162
 163            public void Dispose() { }
 164
 165            public bool MoveNext()
 166            {
 167                ObjectCollection<T> list = _list;
 168
 169                if ((uint)_index < (uint)list._size)
 170                {
 171                    _current = list._items is T[] items ? items[_index] : (T)list._items!;
 172                    _index++;
 173                    return true;
 174                }
 175
 176                _index = _list._size + 1;
 177                _current = default!;
 178                return false;
 179            }
 180
 181            public T Current => _current!;
 182
 183            object? IEnumerator.Current => _current;
 184
 185            void IEnumerator.Reset()
 186            {
 187                _index = 0;
 188                _current = default!;
 189            }
 190        }
 191
 192        internal sealed class DebugView
 193        {
 194            private readonly ObjectCollection<T> _collection;
 195
 196            public DebugView(ObjectCollection<T> collection)
 197            {
 198                ArgumentNullException.ThrowIfNull(collection);
 199                _collection = collection;
 200            }
 201
 202            [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
 203            public T[] Items
 204            {
 205                get
 206                {
 207                    T[] items = new T[_collection.Count];
 208                    _collection.CopyTo(items, 0);
 209                    return items;
 210                }
 211            }
 212        }
 213    }
 214}

Methods/Properties

Validate(T)