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); }
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; } }
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(); } }
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); }
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); }
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); }
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); }
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()); }
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); }