Пример #1
0
        public void CursorIsCorrectWithEmptyLastBlock()
        {
            var last = new BufferSegment();

            last.SetMemory(new OwnedArray <byte>(new byte[4]), 0, 4);

            var first = new BufferSegment();

            first.SetMemory(new OwnedArray <byte>(new byte[2] {
                1, 2
            }), 0, 2);
            first.SetNext(last);

            var start = new ReadCursor(first);
            var end   = new ReadCursor(last);

            var reader = new ReadableBufferReader(start, end);

            reader.Take();
            reader.Take();
            reader.Take();
            Assert.Same(last, reader.Cursor.Segment);
            Assert.Equal(0, reader.Cursor.Index);
            Assert.True(reader.End);
        }
Пример #2
0
        private void AdvanceTo(BufferSegment consumedSegment, int consumedIndex, BufferSegment examinedSegment, int examinedIndex)
        {
            if (consumedSegment == null)
            {
                return;
            }

            var returnStart = _readHead;
            var returnEnd   = consumedSegment;

            var consumedBytes = new ReadOnlySequence <byte>(returnStart, _readIndex, consumedSegment, consumedIndex).Length;

            _bufferedBytes -= consumedBytes;

            Debug.Assert(_bufferedBytes >= 0);

            _examinedEverything = false;

            if (examinedSegment == _readTail)
            {
                // If we examined everything, we force ReadAsync to actually read from the underlying stream
                // instead of returning a ReadResult from TryRead.
                _examinedEverything = examinedIndex == _readTail.End - _readTail.Start;
            }

            // Three cases here:
            // 1. All data is consumed. If so, we reset _readHead and _readTail to _readTail's original memory owner
            //  SetMemory on a IMemoryOwner will reset the internal Memory<byte> to be an empty segment
            // 2. A segment is entirely consumed but there is still more data in nextSegments
            //  We are allowed to remove an extra segment. by setting returnEnd to be the next block.
            // 3. We are in the middle of a segment.
            //  Move _readHead and _readIndex to consumedSegment and index
            if (_bufferedBytes == 0)
            {
                _readTail.SetMemory(_readTail.MemoryOwner);
                _readHead  = _readTail;
                returnEnd  = _readTail;
                _readIndex = 0;
            }
            else if (consumedIndex == returnEnd.Length)
            {
                var nextBlock = returnEnd.NextSegment;
                _readHead  = nextBlock;
                _readIndex = 0;
                returnEnd  = nextBlock;
            }
            else
            {
                _readHead  = consumedSegment;
                _readIndex = consumedIndex;
            }

            // Remove all blocks that are freed (except the last one)
            while (returnStart != returnEnd)
            {
                returnStart.ResetMemory();
                returnStart = returnStart.NextSegment;
            }
        }
Пример #3
0
 private void AllocateReadTail()
 {
     if (_readHead == null)
     {
         Debug.Assert(_readTail == null);
         _readHead = CreateBufferSegment();
         _readHead.SetMemory(_pool.Rent(GetSegmentSize()));
         _readTail = _readHead;
     }
     else if (_readTail.WritableBytes < _minimumReadThreshold)
     {
         CreateNewTailSegment();
     }
 }
Пример #4
0
        public void MovePrefersNextSegment()
        {
            var bufferSegment1 = new BufferSegment();

            bufferSegment1.SetMemory(new OwnedArray <byte>(new byte[100]), 49, 99);

            var bufferSegment2 = new BufferSegment();

            bufferSegment2.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 0);
            bufferSegment1.SetNext(bufferSegment2);

            var readableBuffer = new ReadOnlyBuffer <byte>(bufferSegment1, 0, bufferSegment2, 0);

            var c1 = readableBuffer.GetPosition(readableBuffer.Start, 50);

            Assert.Equal(0, c1.Index);
            Assert.Equal(bufferSegment2, c1.Segment);
        }
Пример #5
0
        public void GetPositionPrefersNextSegment()
        {
            var bufferSegment1 = new BufferSegment();

            bufferSegment1.SetMemory(new OwnedArray <byte>(new byte[100]), 49, 99);

            var bufferSegment2 = new BufferSegment();

            bufferSegment2.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 0);
            bufferSegment1.SetNext(bufferSegment2);

            var readableBuffer = new ReadOnlySequence <byte>(bufferSegment1, 0, bufferSegment2, 0);

            var c1 = readableBuffer.GetPosition(50);

            Assert.Equal(0, c1.GetInteger());
            Assert.Equal(bufferSegment2, c1.GetObject());
        }
        public void CursorIsCorrectWithEmptyLastBlock()
        {
            var last = new BufferSegment();

            last.SetMemory(new OwnedArray <byte>(new byte[4]), 0, 4);

            var first = new BufferSegment();

            first.SetMemory(new OwnedArray <byte>(new byte[] { 1, 2 }), 0, 2);
            first.SetNext(last);

            var reader = BufferReader.Create(new ReadOnlyBuffer <byte>(first, first.Start, last, last.Start));

            reader.Take();
            reader.Take();
            reader.Take();
            Assert.Same(last, reader.Position.Segment);
            Assert.Equal(0, reader.Position.Index);
            Assert.True(reader.End);
        }
Пример #7
0
        public void CursorIsCorrectWithEmptyLastBlock()
        {
            var last = new BufferSegment();

            last.SetMemory(new OwnedArray <byte>(new byte[4]), 0, 4);

            var first = new BufferSegment();

            first.SetMemory(new OwnedArray <byte>(new byte[] { 1, 2 }), 0, 2);
            first.SetNext(last);

            var reader = new BufferReader(new ReadOnlySequence <byte>(first, first.Start, last, last.Start));

            reader.Read();
            reader.Read();
            reader.Read();
            Assert.Same(last, reader.Position.GetObject());
            Assert.Equal(0, reader.Position.GetInteger());
            Assert.True(reader.End);
        }
Пример #8
0
        public void SegmentStartIsConsideredInBoundsCheck()
        {
            // 0               50           100    0             50             100
            // [                ##############] -> [##############                ]
            //                         ^c1            ^c2
            var bufferSegment1 = new BufferSegment();

            bufferSegment1.SetMemory(new OwnedArray <byte>(new byte[100]), 50, 99);

            var bufferSegment2 = new BufferSegment();

            bufferSegment2.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 50);
            bufferSegment1.SetNext(bufferSegment2);

            var readableBuffer = new ReadOnlyBuffer <byte>(bufferSegment1, 0, bufferSegment2, 50);

            var c1 = readableBuffer.GetPosition(readableBuffer.Start, 25); // segment 1 index 75
            var c2 = readableBuffer.GetPosition(readableBuffer.Start, 55); // segment 2 index 5

            var sliced = readableBuffer.Slice(c1, c2);

            Assert.Equal(30, sliced.Length);
        }
Пример #9
0
        public void GetPositionDoesNotCrossOutsideBuffer()
        {
            var bufferSegment1 = new BufferSegment();

            bufferSegment1.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 100);

            var bufferSegment2 = new BufferSegment();

            bufferSegment2.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 100);

            var bufferSegment3 = new BufferSegment();

            bufferSegment3.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 0);

            bufferSegment1.SetNext(bufferSegment2);
            bufferSegment2.SetNext(bufferSegment3);

            var readableBuffer = new ReadOnlySequence <byte>(bufferSegment1, 0, bufferSegment2, 100);

            var c1 = readableBuffer.GetPosition(200);

            Assert.Equal(100, c1.GetInteger());
            Assert.Equal(bufferSegment2, c1.GetObject());
        }
Пример #10
0
        public void GetPositionDoesNotCrossOutsideBuffer()
        {
            var bufferSegment1 = new BufferSegment();

            bufferSegment1.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 100);

            var bufferSegment2 = new BufferSegment();

            bufferSegment2.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 100);

            var bufferSegment3 = new BufferSegment();

            bufferSegment3.SetMemory(new OwnedArray <byte>(new byte[100]), 0, 0);

            bufferSegment1.SetNext(bufferSegment2);
            bufferSegment2.SetNext(bufferSegment3);

            var readableBuffer = new ReadOnlyBuffer <byte>(bufferSegment1, 0, bufferSegment2, 100);

            var c1 = readableBuffer.GetPosition(readableBuffer.Start, 200);

            Assert.Equal(100, c1.Index);
            Assert.Equal(bufferSegment2, c1.Segment);
        }