/// <summary>
/// Writes contents of <paramref name="value"/> to <paramref name="writer"/>
/// </summary>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the <paramref name="writer"/> is shorter than the <paramref name="value"/>.
+ /// </exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Write<T>(this IBufferWriter<T> writer, ReadOnlySpan<T> value)
{
if (input.Length > 0)
{
destination = writer.GetSpan();
+
+ if (destination.IsEmpty)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.writer);
+ }
+
continue;
}
Assert.Equal("Hello World!", bufferWriter.ToString());
}
+ [Fact]
+ public void WritingEmptyBufferToSingleSegmentEmptyBufferWriterDoesNothing()
+ {
+ IBufferWriter<byte> bufferWriter = new MultiSegmentArrayBufferWriter<byte>(
+ new byte[][] { Array.Empty<byte>() }
+ );
+
+ bufferWriter.Write(Array.Empty<byte>()); // This is equivalent to: Span<byte>.Empty.CopyTo(Span<byte>.Empty);
+ }
+
+ [Fact]
+ public void WritingEmptyBufferToMultipleSegmentEmptyBufferWriterDoesNothing()
+ {
+ IBufferWriter<byte> bufferWriter = new MultiSegmentArrayBufferWriter<byte>(
+ new byte[][] { Array.Empty<byte>(), Array.Empty<byte>() }
+ );
+
+ bufferWriter.Write(Array.Empty<byte>());
+ }
+
+ [Theory]
+ [InlineData(1, 0)]
+ [InlineData(10, 9)]
+ public void WritingToTooSmallSingleSegmentBufferFailsWithException(int inputSize, int destinationSize)
+ {
+ IBufferWriter<byte> bufferWriter = new MultiSegmentArrayBufferWriter<byte>(
+ new byte[][] { new byte[destinationSize] }
+ );
+
+ Assert.Throws<ArgumentOutOfRangeException>(paramName: "writer", testCode: () => bufferWriter.Write(new byte[inputSize]));
+ }
+
+ [Theory]
+ [InlineData(10, 2, 2)]
+ [InlineData(10, 9, 0)]
+ public void WritingToTooSmallMultiSegmentBufferFailsWithException(int inputSize, int firstSegmentSize, int secondSegmentSize)
+ {
+ IBufferWriter<byte> bufferWriter = new MultiSegmentArrayBufferWriter<byte>(
+ new byte[][] {
+ new byte[firstSegmentSize],
+ new byte[secondSegmentSize]
+ }
+ );
+
+ Assert.Throws<ArgumentOutOfRangeException>(
+ paramName: "writer",
+ testCode: () => bufferWriter.Write(new byte[inputSize]));
+ }
+
+ private class MultiSegmentArrayBufferWriter<T> : IBufferWriter<T>
+ {
+ private readonly T[][] _segments;
+ private int _segmentIndex;
+
+ public MultiSegmentArrayBufferWriter(T[][] segments) => _segments = segments;
+
+ public void Advance(int size)
+ {
+ if (size != _segments[_segmentIndex].Length)
+ throw new NotSupportedException("By design");
+
+ _segmentIndex++;
+ }
+
+ public Memory<T> GetMemory(int sizeHint = 0) => _segmentIndex < _segments.Length ? _segments[_segmentIndex] : Memory<T>.Empty;
+
+ public Span<T> GetSpan(int sizeHint = 0) => _segmentIndex < _segments.Length ? _segments[_segmentIndex] : Span<T>.Empty;
+ }
+
private class TestBufferWriterSingleSegment : IBufferWriter<byte>
{
private byte[] _buffer = new byte[1000];