public async Task WritesToArrayPoolByDefault() { var pipe = new Pipe(); pipe.Writer.WriteEmpty(10); await pipe.Writer.FlushAsync(); pipe.Writer.Complete(); ReadResult result = await pipe.Reader.ReadAsync(); Assert.Equal(10, result.Buffer.Length); SequenceMarshal.TryGetReadOnlySequenceSegment( result.Buffer, out ReadOnlySequenceSegment <byte> start, out int startIndex, out ReadOnlySequenceSegment <byte> end, out int endIndex); var startSegment = (BufferSegment)start; var endSegment = (BufferSegment)end; Assert.Same(startSegment, endSegment); Assert.IsType <byte[]>(startSegment.MemoryOwner); pipe.Reader.AdvanceTo(result.Buffer.End); pipe.Reader.Complete(); }
public void Ctor_Memory_String() { var text = "Hello"; var memory = text.AsMemory(); var buffer = new ReadOnlySequence <char>(memory.Slice(2, 3)); Assert.True(SequenceMarshal.TryGetReadOnlyMemory(buffer, out ReadOnlyMemory <char> newMemory)); Assert.Equal(text.Substring(2, 3).ToCharArray(), newMemory.ToArray()); Assert.False(SequenceMarshal.TryGetReadOnlySequenceSegment(buffer, out ReadOnlySequenceSegment <char> startSegment, out int startIndex, out ReadOnlySequenceSegment <char> endSegment, out int endIndex)); Assert.False(SequenceMarshal.TryGetArray(buffer, out _)); }
public void Ctor_Array_Offset() { var buffer = new ReadOnlySequence <byte>(new byte[] { 1, 2, 3, 4, 5 }, 2, 3); Assert.True(SequenceMarshal.TryGetArray(buffer, out ArraySegment <byte> array)); Assert.Equal(2, array.Offset); Assert.Equal(3, array.Count); Assert.False(SequenceMarshal.TryGetReadOnlySequenceSegment(buffer, out _, out _, out _, out _)); // Array can be retrieved with TryGetReadOnlyMemory Assert.True(SequenceMarshal.TryGetReadOnlyMemory(buffer, out ReadOnlyMemory <byte> newMemory)); Assert.Equal(new byte[] { 3, 4, 5 }, newMemory.ToArray()); }
public void Ctor_Memory() { var memory = new ReadOnlyMemory <byte>(new byte[] { 1, 2, 3, 4, 5 }); var buffer = new ReadOnlySequence <byte>(memory.Slice(2, 3)); Assert.True(SequenceMarshal.TryGetReadOnlyMemory(buffer, out ReadOnlyMemory <byte> newMemory)); Assert.Equal(new byte[] { 3, 4, 5 }, newMemory.ToArray()); Assert.False(SequenceMarshal.TryGetReadOnlySequenceSegment(buffer, out ReadOnlySequenceSegment <byte> startSegment, out int startIndex, out ReadOnlySequenceSegment <byte> endSegment, out int endIndex)); // Memory is internally decomposed to its container so it would be accessible via TryGetArray Assert.True(SequenceMarshal.TryGetArray(buffer, out ArraySegment <byte> array)); Assert.Equal(2, array.Offset); Assert.Equal(3, array.Count); }
public void Ctor_OwnedMemory_Offset() { var ownedMemory = new CustomMemoryForTest <byte>(new byte[] { 1, 2, 3, 4, 5 }, 0, 5); var buffer = new ReadOnlySequence <byte>(ownedMemory, 2, 3); Assert.True(SequenceMarshal.TryGetOwnedMemory(buffer, out OwnedMemory <byte> newOwnedMemory, out int start, out int length)); Assert.Equal(ownedMemory, newOwnedMemory); Assert.Equal(2, start); Assert.Equal(3, length); Assert.False(SequenceMarshal.TryGetReadOnlySequenceSegment(buffer, out _, out _, out _, out _)); Assert.False(SequenceMarshal.TryGetArray(buffer, out _)); // OwnedMemory can be retrieved with TryGetReadOnlyMemory Assert.True(SequenceMarshal.TryGetReadOnlyMemory(buffer, out ReadOnlyMemory <byte> newMemory)); Assert.Equal(new byte[] { 3, 4, 5 }, newMemory.ToArray()); }
private static List <ReadOnlySequenceSegment <byte> > GetSegments(ReadResult result) { SequenceMarshal.TryGetReadOnlySequenceSegment( result.Buffer, out ReadOnlySequenceSegment <byte> start, out int startIndex, out ReadOnlySequenceSegment <byte> end, out int endIndex); var segments = new List <ReadOnlySequenceSegment <byte> >(); while (start != end.Next) { segments.Add(start); start = start.Next; } return(segments); }
public void Ctor_IMemoryList_MultiBlock() { var memoryListSegment1 = new BufferSegment <byte>(new byte[] { 1, 2, 3 }); var memoryListSegment2 = memoryListSegment1.Append(new byte[] { 4, 5 }); var buffer = new ReadOnlySequence <byte>(memoryListSegment1, 2, memoryListSegment2, 1); Assert.True(SequenceMarshal.TryGetReadOnlySequenceSegment(buffer, out ReadOnlySequenceSegment <byte> startSegment, out int startIndex, out ReadOnlySequenceSegment <byte> endSegment, out int endIndex)); Assert.Equal(startSegment, memoryListSegment1); Assert.Equal(endSegment, memoryListSegment2); Assert.Equal(2, startIndex); Assert.Equal(1, endIndex); Assert.False(SequenceMarshal.TryGetArray(buffer, out _)); // Multi-block can't be retrieved with TryGetReadOnlyMemory Assert.False(SequenceMarshal.TryGetReadOnlyMemory(buffer, out _)); }
public void Ctor_IMemoryList_SingleBlock() { var memoryListSegment = new BufferSegment <byte>(new byte[] { 1, 2, 3, 4, 5 }); var buffer = new ReadOnlySequence <byte>(memoryListSegment, 2, memoryListSegment, 5); Assert.True(SequenceMarshal.TryGetReadOnlySequenceSegment(buffer, out ReadOnlySequenceSegment <byte> startSegment, out int startIndex, out ReadOnlySequenceSegment <byte> endSegment, out int endIndex)); Assert.Equal(startSegment, memoryListSegment); Assert.Equal(endSegment, memoryListSegment); Assert.Equal(2, startIndex); Assert.Equal(5, endIndex); Assert.False(SequenceMarshal.TryGetArray(buffer, out _)); // Single block can be retrieved with TryGetReadOnlyMemory Assert.True(SequenceMarshal.TryGetReadOnlyMemory(buffer, out ReadOnlyMemory <byte> newMemory)); Assert.Equal(new byte[] { 3, 4, 5 }, newMemory.ToArray()); }
public async Task GetMemoryOverMaxPoolSizeAllocatesArray() { using (var pool = new DisposeTrackingBufferPool()) { var pipe = new Pipe(new PipeOptions(pool: pool)); // Allocate 5 KB pipe.Writer.WriteEmpty(5 * 1024); await pipe.Writer.FlushAsync(); pipe.Writer.Complete(); Assert.Equal(0, pool.CurrentlyRentedBlocks); ReadResult result = await pipe.Reader.ReadAsync(); Assert.Equal(5 * 1024, result.Buffer.Length); SequenceMarshal.TryGetReadOnlySequenceSegment( result.Buffer, out ReadOnlySequenceSegment <byte> start, out int startIndex, out ReadOnlySequenceSegment <byte> end, out int endIndex); var startSegment = (BufferSegment)start; var endSegment = (BufferSegment)end; Assert.Same(startSegment, endSegment); // Check owner is array rather than a different type Assert.IsType <byte[]>(startSegment.MemoryOwner); pipe.Reader.AdvanceTo(result.Buffer.End); pipe.Reader.Complete(); Assert.Equal(0, pool.CurrentlyRentedBlocks); Assert.Equal(0, pool.DisposedBlocks); } }
public async Task GetMemoryAtMaxPoolSizeAllocatesFromPool() { using (var pool = new DisposeTrackingBufferPool()) { var pipe = new Pipe(new PipeOptions(pool: pool)); pipe.Writer.WriteEmpty(pool.MaxBufferSize); await pipe.Writer.FlushAsync(); pipe.Writer.Complete(); Assert.Equal(1, pool.CurrentlyRentedBlocks); ReadResult result = await pipe.Reader.ReadAsync(); Assert.Equal(pool.MaxBufferSize, result.Buffer.Length); SequenceMarshal.TryGetReadOnlySequenceSegment( result.Buffer, out ReadOnlySequenceSegment <byte> start, out int startIndex, out ReadOnlySequenceSegment <byte> end, out int endIndex); var startSegment = (BufferSegment)start; var endSegment = (BufferSegment)end; Assert.Same(startSegment, endSegment); // Null owner implies that the buffer is allocated and wasn't rented from the pool Assert.NotNull(startSegment.MemoryOwner); pipe.Reader.AdvanceTo(result.Buffer.End); pipe.Reader.Complete(); Assert.Equal(0, pool.CurrentlyRentedBlocks); Assert.Equal(1, pool.DisposedBlocks); } }
public async Task ArrayPoolUsedByDefault() { WriteByteArray(20); var reader = new StreamPipeReader(Stream); var result = await reader.ReadAsync(); SequenceMarshal.TryGetReadOnlySequenceSegment( result.Buffer, out var startSegment, out var startIndex, out var endSegment, out var endIndex); var start = (BufferSegment)startSegment; var end = (BufferSegment)endSegment; Assert.Same(start, end); Assert.IsType <byte[]>(start.MemoryOwner); reader.AdvanceTo(result.Buffer.End); reader.Complete(); }
public async Task ResetAfterCompleteReaderAndWriterWithoutAdvancingClearsEverything() { _pipe.Writer.WriteEmpty(4094); _pipe.Writer.WriteEmpty(4094); await _pipe.Writer.FlushAsync(); ReadResult result = await _pipe.Reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; SequenceMarshal.TryGetReadOnlySequenceSegment( buffer, out ReadOnlySequenceSegment <byte> start, out int startIndex, out ReadOnlySequenceSegment <byte> end, out int endIndex); var startSegment = (BufferSegment)start; var endSegment = (BufferSegment)end; Assert.NotNull(startSegment.OwnedMemory); Assert.NotNull(endSegment.OwnedMemory); _pipe.Reader.Complete(); // Nothing cleaned up Assert.NotNull(startSegment.OwnedMemory); Assert.NotNull(endSegment.OwnedMemory); _pipe.Writer.Complete(); // Should be cleaned up now Assert.Null(startSegment.OwnedMemory); Assert.Null(endSegment.OwnedMemory); _pipe.Reset(); }