Example #1
0
        private void BoundsCheck(SequencePosition start, SequencePosition newCursor)
        {
            var startIndex = start.Index;
            var endIndex   = newCursor.Index;
            var type       = GetBufferType();

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

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

            case BufferType.MemoryList:
                var segment    = (IMemoryList <T>)newCursor.Segment;
                var memoryList = (IMemoryList <T>)start.Segment;

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

            default:
                ThrowHelper.ThrowCursorOutOfBoundsException();
                return;
            }
        }
        internal SequencePosition Seek(SequencePosition start, SequencePosition end, long bytes, bool checkEndReachable = true)
        {
            var startIndex = start.Index;
            var endIndex   = end.Index;
            var type       = GetBufferType();

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

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


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

                ThrowHelper.ThrowCursorOutOfBoundsException();
                return(default);
            }

            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
            return(default);
Example #3
0
        private static SequencePosition SeekMultiSegment(IMemoryList <byte> start, int startIndex, IMemoryList <byte> end, int endPosition, long bytes, bool checkEndReachable)
        {
            SequencePosition result = default(SequencePosition);
            var foundResult         = false;
            var current             = start;
            var currentIndex        = startIndex;

            while (current != null)
            {
                // We need to loop up until the end to make sure start and end are connected
                // if end is not trusted
                if (!foundResult)
                {
                    var memory     = current.Memory;
                    var currentEnd = current == end ? endPosition : memory.Length;

                    memory = memory.Slice(0, currentEnd - currentIndex);
                    // We would prefer to put cursor in the beginning of next segment
                    // then past the end of previous one, but only if we are not leaving current buffer
                    if (memory.Length > bytes ||
                        (memory.Length == bytes && current == end))
                    {
                        result      = new SequencePosition(current, currentIndex + (int)bytes);
                        foundResult = true;
                        if (!checkEndReachable)
                        {
                            break;
                        }
                    }

                    bytes -= memory.Length;
                }

                if (current.Next == null && current != end)
                {
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.EndCursorNotReached);
                }

                current      = current.Next;
                currentIndex = 0;
            }

            if (!foundResult)
            {
                ThrowHelper.ThrowCursorOutOfBoundsException();
            }

            return(result);
        }
Example #4
0
        private static Position SeekMultiSegment(Position begin, Position end, long bytes, bool checkEndReachable)
        {
            Position result      = default;
            var      foundResult = false;
            var      current     = begin;

            while (TryGetBuffer(begin, end, out var memory, out begin))
            {
                // We need to loop up until the end to make sure start and end are connected
                // if end is not trusted
                if (!foundResult)
                {
                    // We would prefer to put cursor in the beginning of next segment
                    // then past the end of previous one, but only if next exists

                    if (memory.Length > bytes ||
                        (memory.Length == bytes && begin.Segment == null))
                    {
                        result      = new Position(current.Segment, current.Index + (int)bytes);
                        foundResult = true;
                        if (!checkEndReachable)
                        {
                            break;
                        }
                    }

                    bytes -= memory.Length;
                }
                current = begin;
            }

            if (!foundResult)
            {
                ThrowHelper.ThrowCursorOutOfBoundsException();
            }

            return(result);
        }