< Summary

Information
Class: System.Net.Http.Headers.ObjectCollection<T>
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\ObjectCollection.cs
Line coverage
45%
Covered lines: 56
Uncovered lines: 66
Coverable lines: 122
Total lines: 214
Line coverage: 45.9%
Branch coverage
27%
Covered branches: 10
Total branches: 36
Branch coverage: 27.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%11100%
Add(...)100%66100%
Clear()100%110%
Contains(...)0%660%
CopyTo(...)0%10100%
Remove(...)0%10100%
GetEnumerator()100%11100%
System.Collections.Generic.IEnumerable<T>.GetEnumerator()100%110%
System.Collections.IEnumerable.GetEnumerator()100%110%
.ctor(...)100%11100%
Dispose()100%11100%
MoveNext()100%44100%
System.Collections.IEnumerator.Reset()100%110%
.ctor(...)100%110%

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)
 13        {
 14            ArgumentNullException.ThrowIfNull(item);
 15        }
 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
 38056530        public ObjectCollection() { }
 31
 19971732        public int Count => _size;
 33
 034        public bool IsReadOnly => false;
 35
 36        public abstract void Validate(T item);
 37
 38        public void Add(T item)
 51677839        {
 51677840            Validate(item);
 51677841            Debug.Assert(item != null);
 42
 51677843            if (_items is null)
 12657544            {
 45                // The collection is empty. Just store the new item directly.
 12657546                _items = item;
 12657547                _size = 1;
 12657548            }
 39020349            else if (_items is T existingItem)
 6364750            {
 51                // The collection has a single item stored directly.  Upgrade to
 52                // an array, and store both the existing and new items.
 6364753                Debug.Assert(_size == 1);
 6364754                T[] items = new T[DefaultSize];
 6364755                items[0] = existingItem;
 6364756                items[1] = item;
 6364757                _items = items;
 6364758                _size = 2;
 6364759            }
 60            else
 32655661            {
 32655662                T[] array = (T[])_items;
 32655663                int size = _size;
 32655664                if ((uint)size < (uint)array.Length)
 31080365                {
 66                    // There's room in the existing array.  Add the item.
 31080367                    array[size] = item;
 31080368                }
 69                else
 1575370                {
 71                    // We need to grow the array.  Do so, and store the new item.
 1575372                    Debug.Assert(_size > 0);
 1575373                    Debug.Assert(_size == array.Length);
 74
 1575375                    var newItems = new T[array.Length * 2];
 1575376                    Array.Copy(array, newItems, size);
 1575377                    _items = newItems;
 1575378                    newItems[size] = item;
 1575379                }
 32655680                _size = size + 1;
 32655681            }
 51677882        }
 83
 84        public void Clear()
 085        {
 086            _items = null;
 087            _size = 0;
 088        }
 89
 90        public bool Contains(T item) =>
 091            _size <= 0 ? false :
 092            _items is T o ? o.Equals(item) :
 093            _items is T[] items && Array.IndexOf(items, item, 0, _size) >= 0;
 94
 95        public void CopyTo(T[] array, int arrayIndex)
 096        {
 097            if (_items is T[] items)
 098            {
 099                Array.Copy(items, 0, array, arrayIndex, _size);
 0100            }
 101            else
 0102            {
 0103                Debug.Assert(_size == 0 || _size == 1);
 0104                if (array is null || _size > array.Length - arrayIndex)
 0105                {
 106                    // Use Array.CopyTo to throw the right exceptions.
 0107                    new T[] { (T)_items! }.CopyTo(array!, arrayIndex);
 0108                }
 0109                else if (_size == 1)
 0110                {
 0111                    array[arrayIndex] = (T)_items!;
 0112                }
 0113            }
 0114        }
 115
 116        public bool Remove(T item)
 0117        {
 0118            if (_items is T o)
 0119            {
 0120                if (o.Equals(item))
 0121                {
 0122                    _items = null;
 0123                    _size = 0;
 0124                    return true;
 125                }
 0126            }
 0127            else if (_items is T[] items)
 0128            {
 0129                int index = Array.IndexOf(items, item, 0, _size);
 0130                if (index >= 0)
 0131                {
 0132                    _size--;
 0133                    if (index < _size)
 0134                    {
 0135                        Array.Copy(items, index + 1, items, index, _size - index);
 0136                    }
 0137                    items[_size] = null!;
 138
 0139                    return true;
 140                }
 0141            }
 142
 0143            return false;
 0144        }
 145
 199222146        public Enumerator GetEnumerator() => new Enumerator(this);
 0147        IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
 0148        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)
 199222157            {
 199222158                _list = list;
 199222159                _index = 0;
 199222160                _current = default!;
 199222161            }
 162
 398444163            public void Dispose() { }
 164
 165            public bool MoveNext()
 1019706166            {
 1019706167                ObjectCollection<T> list = _list;
 168
 1019706169                if ((uint)_index < (uint)list._size)
 820484170                {
 820484171                    _current = list._items is T[] items ? items[_index] : (T)list._items!;
 820484172                    _index++;
 820484173                    return true;
 174                }
 175
 199222176                _index = _list._size + 1;
 199222177                _current = default!;
 199222178                return false;
 1019706179            }
 180
 820484181            public T Current => _current!;
 182
 0183            object? IEnumerator.Current => _current;
 184
 185            void IEnumerator.Reset()
 0186            {
 0187                _index = 0;
 0188                _current = default!;
 0189            }
 190        }
 191
 192        internal sealed class DebugView
 193        {
 194            private readonly ObjectCollection<T> _collection;
 195
 0196            public DebugView(ObjectCollection<T> collection)
 0197            {
 0198                ArgumentNullException.ThrowIfNull(collection);
 0199                _collection = collection;
 0200            }
 201
 202            [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
 203            public T[] Items
 204            {
 205                get
 0206                {
 0207                    T[] items = new T[_collection.Count];
 0208                    _collection.CopyTo(items, 0);
 0209                    return items;
 0210                }
 211            }
 212        }
 213    }
 214}