Example #1
0
        internal static bool TryGetBuffer(Position begin, Position end, out ReadOnlyMemory <T> data, out Position next)
        {
            var segment = begin.Segment;

            switch (segment)
            {
            case null:
                data = default;
                next = default;
                return(false);

            case IMemoryList <T> bufferSegment:
                var startIndex = begin.Index;
                var endIndex   = bufferSegment.Memory.Length;

                if (segment == end.Segment)
                {
                    endIndex = end.Index;
                    next     = default;
                }
                else
                {
                    var nextSegment = bufferSegment.Next;
                    if (nextSegment == null)
                    {
                        if (end.Segment != null)
                        {
                            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                        }

                        next = default;
                    }
                    else
                    {
                        next = new Position(nextSegment, 0);
                    }
                }

                data = bufferSegment.Memory.Slice(startIndex, endIndex - startIndex);

                return(true);


            case OwnedMemory <T> ownedMemory:
                data = ownedMemory.Memory.Slice(begin.Index, end.Index - begin.Index);

                if (segment != end.Segment)
                {
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                }

                next = default;
                return(true);

            case T[] array:
                data = new Memory <T>(array, begin.Index, end.Index - begin.Index);

                if (segment != end.Segment)
                {
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                }
                next = default;
                return(true);
            }

            ThrowHelper.ThrowNotSupportedException();
            next = default;
            return(false);
        }
        internal bool TryGetBuffer(SequencePosition start, SequencePosition end, out ReadOnlyMemory <T> data, out SequencePosition next)
        {
            if (start.Segment == null)
            {
                data = default;
                next = default;
                return(false);
            }

            var startIndex = start.Index;
            var endIndex   = end.Index;
            var type       = GetBufferType();

            startIndex = GetIndex(startIndex);
            endIndex   = GetIndex(endIndex);

            switch (type)
            {
            case BufferType.MemoryList:
                var bufferSegment   = (IMemoryList <T>)start.Segment;
                var currentEndIndex = bufferSegment.Memory.Length;

                if (bufferSegment == end.Segment)
                {
                    currentEndIndex = endIndex;
                    next            = default;
                }
                else
                {
                    var nextSegment = bufferSegment.Next;
                    if (nextSegment == null)
                    {
                        if (end.Segment != null)
                        {
                            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                        }

                        next = default;
                    }
                    else
                    {
                        next = new SequencePosition(nextSegment, 0);
                    }
                }

                data = bufferSegment.Memory.Slice(startIndex, currentEndIndex - startIndex);

                return(true);


            case BufferType.OwnedMemory:
                var ownedMemory = (OwnedMemory <T>)start.Segment;
                data = ownedMemory.Memory.Slice(startIndex, endIndex - startIndex);

                if (ownedMemory != end.Segment)
                {
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                }

                next = default;
                return(true);

            case BufferType.Array:
                var array = (T[])start.Segment;
                data = new Memory <T>(array, startIndex, endIndex - startIndex);

                if (array != end.Segment)
                {
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                }

                next = default;
                return(true);
            }

            ThrowHelper.ThrowNotSupportedException();
            next = default;
            return(false);
        }