Summary

Class:System.Buffers.BuffersExtensions
Assembly:System.Memory
File(s):C:\GitHub\corefx\src\System.Memory\src\System\Buffers\BuffersExtensions.cs
Covered lines:57
Uncovered lines:25
Coverable lines:82
Total lines:141
Line coverage:69.5%
Branch coverage:72.7%

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
PositionOf(...)34100100
PositionOfMultiSegement(...)4810085.71
CopyTo(...)34100100
CopyToMultiSegement(...)3410080
ToArray(...)10100100
Write(...)2200
WriteMultiSegment(...)2200

File(s)

C:\GitHub\corefx\src\System.Memory\src\System\Buffers\BuffersExtensions.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// See the LICENSE file in the project root for more information.
 4
 5namespace System.Buffers
 6{
 7    /// <summary>
 8    /// Extension methods for <see cref="ReadOnlySequence{T}"/>
 9    /// </summary>
 10    public static class BuffersExtensions
 11    {
 12        /// <summary>
 13        /// Returns position of first occurrence of item in the <see cref="ReadOnlySequence{T}"/>
 14        /// </summary>
 15        public static SequencePosition? PositionOf<T>(in this ReadOnlySequence<T> sequence, T value) where T : IEquatabl
 116        {
 117            if (sequence.IsSingleSegment)
 118            {
 119                int index = sequence.First.Span.IndexOf(value);
 120                if (index != -1)
 121                {
 122                    return sequence.GetPosition(index);
 23                }
 24
 125                return null;
 26            }
 27            else
 128            {
 129                return PositionOfMultiSegement(sequence, value);
 30            }
 131        }
 32
 33        private static SequencePosition? PositionOfMultiSegement<T>(in ReadOnlySequence<T> sequence, T value) where T : 
 134        {
 135            SequencePosition position = sequence.Start;
 136            SequencePosition result = position;
 137            while (sequence.TryGet(ref position, out ReadOnlyMemory<T> memory))
 138            {
 139                int index = memory.Span.IndexOf(value);
 140                if (index != -1)
 141                {
 142                    return sequence.GetPosition(index, result);
 43                }
 144                else if (position.GetObject() == null)
 145                {
 146                    break;
 47                }
 48
 149                result = position;
 150            }
 51
 152            return null;
 153        }
 54
 55        /// <summary>
 56        /// Copy the <see cref="ReadOnlySequence{T}"/> to the specified <see cref="Span{Byte}"/>.
 57        /// </summary>
 58        /// <param name="sequence">The source <see cref="ReadOnlySequence{T}"/>.</param>
 59        /// <param name="destination">The destination <see cref="Span{Byte}"/>.</param>
 60        public static void CopyTo<T>(in this ReadOnlySequence<T> sequence, Span<T> destination)
 161        {
 162            if (sequence.Length > destination.Length)
 163                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.destination);
 64
 165            if (sequence.IsSingleSegment)
 166            {
 167                sequence.First.Span.CopyTo(destination);
 168            }
 69            else
 170            {
 171                CopyToMultiSegement(sequence, destination);
 172            }
 173        }
 74
 75        private static void CopyToMultiSegement<T>(in ReadOnlySequence<T> sequence, Span<T> destination)
 176        {
 177            SequencePosition position = sequence.Start;
 178            while (sequence.TryGet(ref position, out ReadOnlyMemory<T> memory))
 179            {
 180                ReadOnlySpan<T> span = memory.Span;
 181                span.CopyTo(destination);
 182                if (position.GetObject() != null)
 183                {
 184                    destination = destination.Slice(span.Length);
 185                }
 86                else
 187                {
 188                    break;
 89                }
 190            }
 191        }
 92
 93        /// <summary>
 94        /// Converts the <see cref="ReadOnlySequence{T}"/> to an array
 95        /// </summary>
 96        public static T[] ToArray<T>(in this ReadOnlySequence<T> sequence)
 197        {
 198            var array = new T[sequence.Length];
 199            sequence.CopyTo(array);
 1100            return array;
 1101        }
 102
 103        /// <summary>
 104        /// Writes contents of <paramref name="source"/> to <paramref name="bufferWriter"/>
 105        /// </summary>
 106        public static void Write<T>(this IBufferWriter<T> bufferWriter, ReadOnlySpan<T> source)
 0107        {
 0108            Span<T> destination = bufferWriter.GetSpan();
 109
 110            // Fast path, try copying to the available memory directly
 0111            if (source.Length <= destination.Length)
 0112            {
 0113                source.CopyTo(destination);
 0114                bufferWriter.Advance(source.Length);
 0115            }
 116            else
 0117            {
 0118                WriteMultiSegment(bufferWriter, source, destination);
 0119            }
 0120        }
 121
 122        private static void WriteMultiSegment<T>(IBufferWriter<T> bufferWriter, in ReadOnlySpan<T> source, Span<T> desti
 0123        {
 0124            ReadOnlySpan<T> input = source;
 0125            while (true)
 0126            {
 0127                int writeSize = Math.Min(destination.Length, input.Length);
 0128                input.Slice(0, writeSize).CopyTo(destination);
 0129                bufferWriter.Advance(writeSize);
 0130                input = input.Slice(writeSize);
 0131                if (input.Length > 0)
 0132                {
 0133                    destination = bufferWriter.GetSpan(input.Length);
 0134                    continue;
 135                }
 136
 0137                return;
 138            }
 0139        }
 140    }
 141}