< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 24
Coverable lines: 24
Total lines: 92
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 10
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%110%
GetEnumerator()100%110%
MoveNext()0%10100%
System.Collections.IEnumerator.Reset()100%110%
System.IDisposable.Dispose()100%110%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Private.CoreLib/src/System/Text/SpanLineEnumerator.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;
 6
 7namespace System.Text
 8{
 9    /// <summary>
 10    /// Enumerates the lines of a <see cref="ReadOnlySpan{Char}"/>.
 11    /// </summary>
 12    /// <remarks>
 13    /// To get an instance of this type, use <see cref="MemoryExtensions.EnumerateLines(ReadOnlySpan{char})"/>.
 14    /// </remarks>
 15    public ref struct SpanLineEnumerator : IEnumerator<ReadOnlySpan<char>>
 16    {
 17        private ReadOnlySpan<char> _remaining;
 18        private ReadOnlySpan<char> _current;
 19        private bool _isEnumeratorActive;
 20
 21        internal SpanLineEnumerator(ReadOnlySpan<char> buffer)
 22        {
 023            _remaining = buffer;
 024            _current = default;
 025            _isEnumeratorActive = true;
 026        }
 27
 28        /// <summary>
 29        /// Gets the line at the current position of the enumerator.
 30        /// </summary>
 031        public ReadOnlySpan<char> Current => _current;
 32
 33        /// <summary>
 34        /// Returns this instance as an enumerator.
 35        /// </summary>
 036        public SpanLineEnumerator GetEnumerator() => this;
 37
 38        /// <summary>
 39        /// Advances the enumerator to the next line of the span.
 40        /// </summary>
 41        /// <returns>
 42        /// True if the enumerator successfully advanced to the next line; false if
 43        /// the enumerator has advanced past the end of the span.
 44        /// </returns>
 45        public bool MoveNext()
 46        {
 047            if (!_isEnumeratorActive)
 48            {
 049                _current = default;
 050                return false; // EOF previously reached or enumerator was never initialized
 51            }
 52
 053            ReadOnlySpan<char> remaining = _remaining;
 54
 055            int idx = remaining.IndexOfAny(string.SearchValuesStorage.NewLineChars);
 56
 057            if ((uint)idx < (uint)remaining.Length)
 58            {
 059                int stride = 1;
 60
 061                if (remaining[idx] == '\r' && (uint)(idx + 1) < (uint)remaining.Length && remaining[idx + 1] == '\n')
 62                {
 063                    stride = 2;
 64                }
 65
 066                _current = remaining.Slice(0, idx);
 067                _remaining = remaining.Slice(idx + stride);
 68            }
 69            else
 70            {
 71                // We've reached EOF, but we still need to return 'true' for this final
 72                // iteration so that the caller can query the Current property once more.
 73
 074                _current = remaining;
 075                _remaining = default;
 076                _isEnumeratorActive = false;
 77            }
 78
 079            return true;
 80        }
 81
 82        /// <inheritdoc />
 083        object IEnumerator.Current => throw new NotSupportedException();
 84
 85        /// <inheritdoc />
 086        void IEnumerator.Reset() => throw new NotSupportedException();
 87
 88        /// <inheritdoc />
 089        void IDisposable.Dispose() { }
 90    }
 91}
 92