Exemple #1
0
        private void BoundsCheck(SequencePosition start, SequencePosition position)
        {
            int          startIndex = start.Index;
            int          endIndex   = position.Index;
            SequenceType type       = GetSequenceType();

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

            switch (type)
            {
            case SequenceType.OwnedMemory:
            case SequenceType.Array:
                if (endIndex > startIndex)
                {
                    ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
                }
                return;

            case SequenceType.MemoryList:
                IMemoryList <T> segment    = (IMemoryList <T>)position.Segment;
                IMemoryList <T> memoryList = (IMemoryList <T>)start.Segment;

                if (segment.RunningIndex - startIndex > memoryList.RunningIndex - endIndex)
                {
                    ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
                }
                return;

            default:
                ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType();
                return;
            }
        }
Exemple #2
0
        internal SequencePosition Seek(SequencePosition start, SequencePosition end, long count, bool checkEndReachable = true)
        {
            int          startIndex = start.Index;
            int          endIndex   = end.Index;
            SequenceType type       = GetSequenceType();

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

            switch (type)
            {
            case SequenceType.MemoryList:
                if (start.Segment == end.Segment && endIndex - startIndex >= count)
                {
                    // end.Index >= count + Index and end.Index is int
                    return(new SequencePosition(start.Segment, startIndex + (int)count));
                }
                return(SeekMultiSegment((IMemoryList <byte>)start.Segment, startIndex, (IMemoryList <byte>)end.Segment, endIndex, count, checkEndReachable));

            case SequenceType.OwnedMemory:
            case SequenceType.Array:
                if (endIndex - startIndex >= count)
                {
                    // end.Index >= count + Index and end.Index is int
                    return(new SequencePosition(start.Segment, startIndex + (int)count));
                }

                ThrowHelper.ThrowArgumentOutOfRangeException_CountOutOfRange();
                return(default);

            default:
                ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType();
                return(default);
            }
        }
Exemple #3
0
        internal SequencePosition Seek(SequencePosition start, SequencePosition end, int count, bool checkEndReachable = true)
        {
            int          startIndex = start.GetInteger();
            int          endIndex   = end.GetInteger();
            SequenceType type       = GetSequenceType();

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

            switch (type)
            {
            case SequenceType.MemoryList:
                if (start.GetObject() == end.GetObject() && endIndex - startIndex >= count)
                {
                    return(new SequencePosition(start.GetObject(), startIndex + count));
                }
                return(SeekMultiSegment((IMemoryList <byte>)start.GetObject(), startIndex, (IMemoryList <byte>)end.GetObject(), endIndex, count, checkEndReachable));

            case SequenceType.OwnedMemory:
            case SequenceType.Array:
                if (start.GetObject() != end.GetObject())
                {
                    ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached();
                }

                if (endIndex - startIndex >= count)
                {
                    return(new SequencePosition(start.GetObject(), startIndex + count));
                }

                ThrowHelper.ThrowArgumentOutOfRangeException_CountOutOfRange();
                return(default);

            default:
                ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType();
                return(default);
            }
        }
Exemple #4
0
        private long GetLength(SequencePosition start, SequencePosition end)
        {
            int          startIndex = start.Index;
            int          endIndex   = end.Index;
            SequenceType type       = GetSequenceType();

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

            switch (type)
            {
            case SequenceType.MemoryList:
                return(GetLength((IMemoryList <T>)start.Segment, startIndex, (IMemoryList <T>)end.Segment, endIndex));

            case SequenceType.OwnedMemory:
            case SequenceType.Array:
                return(endIndex - startIndex);

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

            int          startIndex = start.Index;
            int          endIndex   = end.Index;
            SequenceType type       = GetSequenceType();

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

            switch (type)
            {
            case SequenceType.MemoryList:
                var        segment             = (IMemoryList <T>)start.Segment;
                Memory <T> bufferSegmentMemory = segment.Memory;
                int        currentEndIndex     = bufferSegmentMemory.Length;

                if (segment == end.Segment)
                {
                    currentEndIndex = endIndex;
                    next            = default;
                }
                else
                {
                    IMemoryList <T> nextSegment = segment.Next;
                    if (nextSegment == null)
                    {
                        if (end.Segment != null)
                        {
                            ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached();
                        }

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

                data = bufferSegmentMemory.Slice(startIndex, currentEndIndex - startIndex);
                return(true);

            case SequenceType.OwnedMemory:
                var ownedMemory = (OwnedMemory <T>)start.Segment;
                if (ownedMemory != end.Segment)
                {
                    ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached();
                }

                data = ownedMemory.Memory.Slice(startIndex, endIndex - startIndex);
                next = default;
                return(true);

            case SequenceType.Array:
                var array = (T[])start.Segment;

                if (array != end.Segment)
                {
                    ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached();
                }

                data = new Memory <T>(array, startIndex, endIndex - startIndex);
                next = default;
                return(true);

            default:
                ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType();
                next = default;
                data = default;
                return(false);
            }
        }