Combine BufferWriter and CountingBufferWriter
This commit is contained in:
parent
128eefdef3
commit
f179339a79
|
|
@ -78,7 +78,7 @@ namespace PlatformBenchmarks
|
||||||
}
|
}
|
||||||
private static void PlainText(PipeWriter pipeWriter)
|
private static void PlainText(PipeWriter pipeWriter)
|
||||||
{
|
{
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(pipeWriter);
|
var writer = new BufferWriter<PipeWriter>(pipeWriter);
|
||||||
// HTTP 1.1 OK
|
// HTTP 1.1 OK
|
||||||
writer.Write(_http11OK);
|
writer.Write(_http11OK);
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ namespace PlatformBenchmarks
|
||||||
|
|
||||||
private static void Json(PipeWriter pipeWriter)
|
private static void Json(PipeWriter pipeWriter)
|
||||||
{
|
{
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(pipeWriter);
|
var writer = new BufferWriter<PipeWriter>(pipeWriter);
|
||||||
|
|
||||||
// HTTP 1.1 OK
|
// HTTP 1.1 OK
|
||||||
writer.Write(_http11OK);
|
writer.Write(_http11OK);
|
||||||
|
|
@ -134,7 +134,7 @@ namespace PlatformBenchmarks
|
||||||
|
|
||||||
private static void Default(PipeWriter pipeWriter)
|
private static void Default(PipeWriter pipeWriter)
|
||||||
{
|
{
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(pipeWriter);
|
var writer = new BufferWriter<PipeWriter>(pipeWriter);
|
||||||
|
|
||||||
// HTTP 1.1 OK
|
// HTTP 1.1 OK
|
||||||
writer.Write(_http11OK);
|
writer.Write(_http11OK);
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,27 @@
|
||||||
// Licensed to the .NET Foundation under one or more agreements.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
// See the LICENSE file in the project root for more information.
|
|
||||||
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace System.Buffers
|
namespace System.Buffers
|
||||||
{
|
{
|
||||||
internal ref struct BufferWriter<T> where T: IBufferWriter<byte>
|
internal ref struct BufferWriter<T> where T : IBufferWriter<byte>
|
||||||
{
|
{
|
||||||
private T _output;
|
private T _output;
|
||||||
private Span<byte> _span;
|
private Span<byte> _span;
|
||||||
private int _buffered;
|
private int _buffered;
|
||||||
|
private long _bytesCommitted;
|
||||||
|
|
||||||
public BufferWriter(T output)
|
public BufferWriter(T output)
|
||||||
{
|
{
|
||||||
_buffered = 0;
|
_buffered = 0;
|
||||||
|
_bytesCommitted = 0;
|
||||||
_output = output;
|
_output = output;
|
||||||
_span = output.GetSpan();
|
_span = output.GetSpan();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Span<byte> Span => _span;
|
public Span<byte> Span => _span;
|
||||||
|
public long BytesCommitted => _bytesCommitted;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Commit()
|
public void Commit()
|
||||||
|
|
@ -27,6 +29,7 @@ namespace System.Buffers
|
||||||
var buffered = _buffered;
|
var buffered = _buffered;
|
||||||
if (buffered > 0)
|
if (buffered > 0)
|
||||||
{
|
{
|
||||||
|
_bytesCommitted += buffered;
|
||||||
_buffered = 0;
|
_buffered = 0;
|
||||||
_output.Advance(buffered);
|
_output.Advance(buffered);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
return new ArraySegment<byte>(bytes, offset, 10 - offset);
|
return new ArraySegment<byte>(bytes, offset, 10 - offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int WriteBeginChunkBytes(ref CountingBufferWriter<PipeWriter> start, int dataCount)
|
internal static int WriteBeginChunkBytes(ref BufferWriter<PipeWriter> start, int dataCount)
|
||||||
{
|
{
|
||||||
var chunkSegment = BeginChunkBytes(dataCount);
|
var chunkSegment = BeginChunkBytes(dataCount);
|
||||||
start.Write(new ReadOnlySpan<byte>(chunkSegment.Array, chunkSegment.Offset, chunkSegment.Count));
|
start.Write(new ReadOnlySpan<byte>(chunkSegment.Array, chunkSegment.Offset, chunkSegment.Count));
|
||||||
return chunkSegment.Count;
|
return chunkSegment.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WriteEndChunkBytes(ref CountingBufferWriter<PipeWriter> start)
|
internal static void WriteEndChunkBytes(ref BufferWriter<PipeWriter> start)
|
||||||
{
|
{
|
||||||
start.Write(new ReadOnlySpan<byte>(_endChunkBytes.Array, _endChunkBytes.Offset, _endChunkBytes.Count));
|
start.Write(new ReadOnlySpan<byte>(_endChunkBytes.Array, _endChunkBytes.Offset, _endChunkBytes.Count));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
|
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace System.Buffers
|
|
||||||
{
|
|
||||||
// TODO: Once this is public, update the actual CountingBufferWriter in the Common repo,
|
|
||||||
// and go back to using that.
|
|
||||||
internal ref struct CountingBufferWriter<T> where T: IBufferWriter<byte>
|
|
||||||
{
|
|
||||||
private T _output;
|
|
||||||
private Span<byte> _span;
|
|
||||||
private int _buffered;
|
|
||||||
private long _bytesCommitted;
|
|
||||||
|
|
||||||
public CountingBufferWriter(T output)
|
|
||||||
{
|
|
||||||
_buffered = 0;
|
|
||||||
_bytesCommitted = 0;
|
|
||||||
_output = output;
|
|
||||||
_span = output.GetSpan();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Span<byte> Span => _span;
|
|
||||||
public long BytesCommitted => _bytesCommitted;
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Commit()
|
|
||||||
{
|
|
||||||
var buffered = _buffered;
|
|
||||||
if (buffered > 0)
|
|
||||||
{
|
|
||||||
_bytesCommitted += buffered;
|
|
||||||
_buffered = 0;
|
|
||||||
_output.Advance(buffered);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Advance(int count)
|
|
||||||
{
|
|
||||||
_buffered += count;
|
|
||||||
_span = _span.Slice(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Write(ReadOnlySpan<byte> source)
|
|
||||||
{
|
|
||||||
if (_span.Length >= source.Length)
|
|
||||||
{
|
|
||||||
source.CopyTo(_span);
|
|
||||||
Advance(source.Length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteMultiBuffer(source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Ensure(int count = 1)
|
|
||||||
{
|
|
||||||
if (_span.Length < count)
|
|
||||||
{
|
|
||||||
EnsureMore(count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
||||||
private void EnsureMore(int count = 0)
|
|
||||||
{
|
|
||||||
if (_buffered > 0)
|
|
||||||
{
|
|
||||||
Commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
_output.GetMemory(count);
|
|
||||||
_span = _output.GetSpan();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteMultiBuffer(ReadOnlySpan<byte> source)
|
|
||||||
{
|
|
||||||
while (source.Length > 0)
|
|
||||||
{
|
|
||||||
if (_span.Length == 0)
|
|
||||||
{
|
|
||||||
EnsureMore();
|
|
||||||
}
|
|
||||||
|
|
||||||
var writable = Math.Min(source.Length, _span.Length);
|
|
||||||
source.Slice(0, writable).CopyTo(_span);
|
|
||||||
source = source.Slice(writable);
|
|
||||||
Advance(writable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer = _pipeWriter;
|
var buffer = _pipeWriter;
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(buffer);
|
var writer = new BufferWriter<PipeWriter>(buffer);
|
||||||
|
|
||||||
writer.Write(_bytesHttpVersion11);
|
writer.Write(_bytesHttpVersion11);
|
||||||
var statusBytes = ReasonPhrases.ToStatusBytes(statusCode, reasonPhrase);
|
var statusBytes = ReasonPhrases.ToStatusBytes(statusCode, reasonPhrase);
|
||||||
|
|
@ -210,7 +210,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
writableBuffer = _pipeWriter;
|
writableBuffer = _pipeWriter;
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(writableBuffer);
|
var writer = new BufferWriter<PipeWriter>(writableBuffer);
|
||||||
if (buffer.Length > 0)
|
if (buffer.Length > 0)
|
||||||
{
|
{
|
||||||
writer.Write(buffer);
|
writer.Write(buffer);
|
||||||
|
|
|
||||||
|
|
@ -7765,7 +7765,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void CopyToFast(ref CountingBufferWriter<PipeWriter> output)
|
internal void CopyToFast(ref BufferWriter<PipeWriter> output)
|
||||||
{
|
{
|
||||||
var tempBits = _bits | (_contentLength.HasValue ? -9223372036854775808L : 0);
|
var tempBits = _bits | (_contentLength.HasValue ? -9223372036854775808L : 0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -936,7 +936,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
var bytesWritten = 0L;
|
var bytesWritten = 0L;
|
||||||
if (buffer.Length > 0)
|
if (buffer.Length > 0)
|
||||||
{
|
{
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(writableBuffer);
|
var writer = new BufferWriter<PipeWriter>(writableBuffer);
|
||||||
|
|
||||||
ChunkWriter.WriteBeginChunkBytes(ref writer, buffer.Length);
|
ChunkWriter.WriteBeginChunkBytes(ref writer, buffer.Length);
|
||||||
writer.Write(buffer.Span);
|
writer.Write(buffer.Span);
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
return GetEnumerator();
|
return GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void CopyTo(ref CountingBufferWriter<PipeWriter> buffer)
|
internal void CopyTo(ref BufferWriter<PipeWriter> buffer)
|
||||||
{
|
{
|
||||||
CopyToFast(ref buffer);
|
CopyToFast(ref buffer);
|
||||||
if (MaybeUnknown != null)
|
if (MaybeUnknown != null)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static unsafe void WriteAsciiNoValidation(ref this CountingBufferWriter<PipeWriter> buffer, string data)
|
internal static unsafe void WriteAsciiNoValidation(ref this BufferWriter<PipeWriter> buffer, string data)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(data))
|
if (string.IsNullOrEmpty(data))
|
||||||
{
|
{
|
||||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void WriteNumeric(ref this CountingBufferWriter<PipeWriter> buffer, ulong number)
|
internal static unsafe void WriteNumeric(ref this BufferWriter<PipeWriter> buffer, ulong number)
|
||||||
{
|
{
|
||||||
const byte AsciiDigitStart = (byte)'0';
|
const byte AsciiDigitStart = (byte)'0';
|
||||||
|
|
||||||
|
|
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
private static void WriteNumericMultiWrite(ref this CountingBufferWriter<PipeWriter> buffer, ulong number)
|
private static void WriteNumericMultiWrite(ref this BufferWriter<PipeWriter> buffer, ulong number)
|
||||||
{
|
{
|
||||||
const byte AsciiDigitStart = (byte)'0';
|
const byte AsciiDigitStart = (byte)'0';
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
private unsafe static void WriteAsciiMultiWrite(ref this CountingBufferWriter<PipeWriter> buffer, string data)
|
private unsafe static void WriteAsciiMultiWrite(ref this BufferWriter<PipeWriter> buffer, string data)
|
||||||
{
|
{
|
||||||
var remaining = data.Length;
|
var remaining = data.Length;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace System.IO.Pipelines.Tests
|
namespace System.IO.Pipelines.Tests
|
||||||
|
|
@ -73,15 +72,20 @@ namespace System.IO.Pipelines.Tests
|
||||||
[InlineData(1, 2)]
|
[InlineData(1, 2)]
|
||||||
[InlineData(2, 1)]
|
[InlineData(2, 1)]
|
||||||
[InlineData(1, 1)]
|
[InlineData(1, 1)]
|
||||||
public void CanWriteWithOffsetAndLenght(int offset, int length)
|
public void CanWriteWithOffsetAndLength(int offset, int length)
|
||||||
{
|
{
|
||||||
BufferWriter<PipeWriter> writer = new BufferWriter<PipeWriter>(Pipe.Writer);
|
BufferWriter<PipeWriter> writer = new BufferWriter<PipeWriter>(Pipe.Writer);
|
||||||
var array = new byte[] { 1, 2, 3 };
|
var array = new byte[] { 1, 2, 3 };
|
||||||
|
|
||||||
writer.Write(new Span<byte>(array, offset, length));
|
writer.Write(new Span<byte>(array, offset, length));
|
||||||
|
|
||||||
|
Assert.Equal(0, writer.BytesCommitted);
|
||||||
|
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
|
|
||||||
|
Assert.Equal(length, writer.BytesCommitted);
|
||||||
Assert.Equal(array.Skip(offset).Take(length).ToArray(), Read());
|
Assert.Equal(array.Skip(offset).Take(length).ToArray(), Read());
|
||||||
|
Assert.Equal(length, writer.BytesCommitted);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -94,6 +98,7 @@ namespace System.IO.Pipelines.Tests
|
||||||
writer.Write(new Span<byte>(array, 0, array.Length));
|
writer.Write(new Span<byte>(array, 0, array.Length));
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
|
|
||||||
|
Assert.Equal(0, writer.BytesCommitted);
|
||||||
Assert.Equal(array, Read());
|
Assert.Equal(array, Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,6 +110,7 @@ namespace System.IO.Pipelines.Tests
|
||||||
writer.Write(new byte[] { 1, 2, 3 });
|
writer.Write(new byte[] { 1, 2, 3 });
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
|
|
||||||
|
Assert.Equal(3, writer.BytesCommitted);
|
||||||
Assert.Equal(new byte[] { 1, 2, 3 }, Read());
|
Assert.Equal(new byte[] { 1, 2, 3 }, Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,6 +124,7 @@ namespace System.IO.Pipelines.Tests
|
||||||
writer.Write(new byte[] { 3 });
|
writer.Write(new byte[] { 3 });
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
|
|
||||||
|
Assert.Equal(3, writer.BytesCommitted);
|
||||||
Assert.Equal(new byte[] { 1, 2, 3 }, Read());
|
Assert.Equal(new byte[] { 1, 2, 3 }, Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,6 +140,7 @@ namespace System.IO.Pipelines.Tests
|
||||||
writer.Write(expectedBytes);
|
writer.Write(expectedBytes);
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
|
|
||||||
|
Assert.Equal(expectedBytes.LongLength, writer.BytesCommitted);
|
||||||
Assert.Equal(expectedBytes, Read());
|
Assert.Equal(expectedBytes, Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,6 +150,7 @@ namespace System.IO.Pipelines.Tests
|
||||||
BufferWriter<PipeWriter> writer = new BufferWriter<PipeWriter>(Pipe.Writer);
|
BufferWriter<PipeWriter> writer = new BufferWriter<PipeWriter>(Pipe.Writer);
|
||||||
writer.Ensure(10);
|
writer.Ensure(10);
|
||||||
Assert.True(writer.Span.Length > 10);
|
Assert.True(writer.Span.Length > 10);
|
||||||
|
Assert.Equal(0, writer.BytesCommitted);
|
||||||
Assert.Equal(new byte[] { }, Read());
|
Assert.Equal(new byte[] { }, Read());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,6 +173,7 @@ namespace System.IO.Pipelines.Tests
|
||||||
writer.Write(new byte[] { 1, 2, 3 });
|
writer.Write(new byte[] { 1, 2, 3 });
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
|
|
||||||
|
Assert.Equal(3, writer.BytesCommitted);
|
||||||
Assert.Equal(initialLength - 3, writer.Span.Length);
|
Assert.Equal(initialLength - 3, writer.Span.Length);
|
||||||
Assert.Equal(Pipe.Writer.GetMemory().Length, writer.Span.Length);
|
Assert.Equal(Pipe.Writer.GetMemory().Length, writer.Span.Length);
|
||||||
Assert.Equal(new byte[] { 1, 2, 3 }, Read());
|
Assert.Equal(new byte[] { 1, 2, 3 }, Read());
|
||||||
|
|
@ -175,49 +185,17 @@ namespace System.IO.Pipelines.Tests
|
||||||
[InlineData(500)]
|
[InlineData(500)]
|
||||||
[InlineData(5000)]
|
[InlineData(5000)]
|
||||||
[InlineData(50000)]
|
[InlineData(50000)]
|
||||||
public async Task WriteLargeDataBinary(int length)
|
public void WriteLargeDataBinary(int length)
|
||||||
{
|
{
|
||||||
var data = new byte[length];
|
var data = new byte[length];
|
||||||
new Random(length).NextBytes(data);
|
new Random(length).NextBytes(data);
|
||||||
PipeWriter output = Pipe.Writer;
|
|
||||||
output.Write(data);
|
|
||||||
await output.FlushAsync();
|
|
||||||
|
|
||||||
ReadResult result = await Pipe.Reader.ReadAsync();
|
BufferWriter<PipeWriter> writer = new BufferWriter<PipeWriter>(Pipe.Writer);
|
||||||
ReadOnlySequence<byte> input = result.Buffer;
|
writer.Write(data);
|
||||||
Assert.Equal(data, input.ToArray());
|
writer.Commit();
|
||||||
Pipe.Reader.AdvanceTo(input.End);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
Assert.Equal(length, writer.BytesCommitted);
|
||||||
public async Task CanWriteNothingToBuffer()
|
Assert.Equal(data, Read());
|
||||||
{
|
|
||||||
PipeWriter buffer = Pipe.Writer;
|
|
||||||
buffer.GetMemory(0);
|
|
||||||
buffer.Advance(0); // doing nothing, the hard way
|
|
||||||
await buffer.FlushAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void EmptyWriteDoesNotThrow()
|
|
||||||
{
|
|
||||||
Pipe.Writer.Write(new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ThrowsOnAdvanceOverMemorySize()
|
|
||||||
{
|
|
||||||
Memory<byte> buffer = Pipe.Writer.GetMemory(1);
|
|
||||||
var exception = Assert.Throws<InvalidOperationException>(() => Pipe.Writer.Advance(buffer.Length + 1));
|
|
||||||
Assert.Equal("Can't advance past buffer size.", exception.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ThrowsOnAdvanceWithNoMemory()
|
|
||||||
{
|
|
||||||
PipeWriter buffer = Pipe.Writer;
|
|
||||||
var exception = Assert.Throws<InvalidOperationException>(() => buffer.Advance(1));
|
|
||||||
Assert.Equal("No writing operation. Make sure GetMemory() was called.", exception.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
public void WritesNumericToAscii(ulong number)
|
public void WritesNumericToAscii(ulong number)
|
||||||
{
|
{
|
||||||
var writerBuffer = _pipe.Writer;
|
var writerBuffer = _pipe.Writer;
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(writerBuffer);
|
var writer = new BufferWriter<PipeWriter>(writerBuffer);
|
||||||
writer.WriteNumeric(number);
|
writer.WriteNumeric(number);
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
writerBuffer.FlushAsync().GetAwaiter().GetResult();
|
writerBuffer.FlushAsync().GetAwaiter().GetResult();
|
||||||
|
|
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
public void WritesNumericAcrossSpanBoundaries(int gapSize)
|
public void WritesNumericAcrossSpanBoundaries(int gapSize)
|
||||||
{
|
{
|
||||||
var writerBuffer = _pipe.Writer;
|
var writerBuffer = _pipe.Writer;
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(writerBuffer);
|
var writer = new BufferWriter<PipeWriter>(writerBuffer);
|
||||||
// almost fill up the first block
|
// almost fill up the first block
|
||||||
var spacer = new byte[writer.Span.Length - gapSize];
|
var spacer = new byte[writer.Span.Length - gapSize];
|
||||||
writer.Write(spacer);
|
writer.Write(spacer);
|
||||||
|
|
@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
public void EncodesAsAscii(string input, byte[] expected)
|
public void EncodesAsAscii(string input, byte[] expected)
|
||||||
{
|
{
|
||||||
var pipeWriter = _pipe.Writer;
|
var pipeWriter = _pipe.Writer;
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(pipeWriter);
|
var writer = new BufferWriter<PipeWriter>(pipeWriter);
|
||||||
writer.WriteAsciiNoValidation(input);
|
writer.WriteAsciiNoValidation(input);
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
pipeWriter.FlushAsync().GetAwaiter().GetResult();
|
pipeWriter.FlushAsync().GetAwaiter().GetResult();
|
||||||
|
|
@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
// WriteAscii doesn't validate if characters are in the ASCII range
|
// WriteAscii doesn't validate if characters are in the ASCII range
|
||||||
// but it shouldn't produce more than one byte per character
|
// but it shouldn't produce more than one byte per character
|
||||||
var writerBuffer = _pipe.Writer;
|
var writerBuffer = _pipe.Writer;
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(writerBuffer);
|
var writer = new BufferWriter<PipeWriter>(writerBuffer);
|
||||||
writer.WriteAsciiNoValidation(input);
|
writer.WriteAsciiNoValidation(input);
|
||||||
writer.Commit();
|
writer.Commit();
|
||||||
writerBuffer.FlushAsync().GetAwaiter().GetResult();
|
writerBuffer.FlushAsync().GetAwaiter().GetResult();
|
||||||
|
|
@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
{
|
{
|
||||||
const byte maxAscii = 0x7f;
|
const byte maxAscii = 0x7f;
|
||||||
var writerBuffer = _pipe.Writer;
|
var writerBuffer = _pipe.Writer;
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(writerBuffer);
|
var writer = new BufferWriter<PipeWriter>(writerBuffer);
|
||||||
for (var i = 0; i < maxAscii; i++)
|
for (var i = 0; i < maxAscii; i++)
|
||||||
{
|
{
|
||||||
writer.WriteAsciiNoValidation(new string((char)i, 1));
|
writer.WriteAsciiNoValidation(new string((char)i, 1));
|
||||||
|
|
@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
{
|
{
|
||||||
var testString = new string(' ', stringLength);
|
var testString = new string(' ', stringLength);
|
||||||
var writerBuffer = _pipe.Writer;
|
var writerBuffer = _pipe.Writer;
|
||||||
var writer = new CountingBufferWriter<PipeWriter>(writerBuffer);
|
var writer = new BufferWriter<PipeWriter>(writerBuffer);
|
||||||
// almost fill up the first block
|
// almost fill up the first block
|
||||||
var spacer = new byte[writer.Span.Length - gapSize];
|
var spacer = new byte[writer.Span.Length - gapSize];
|
||||||
writer.Write(spacer);
|
writer.Write(spacer);
|
||||||
|
|
|
||||||
|
|
@ -548,7 +548,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
return true;
|
return true;
|
||||||
}}
|
}}
|
||||||
{(loop.ClassName == "HttpResponseHeaders" ? $@"
|
{(loop.ClassName == "HttpResponseHeaders" ? $@"
|
||||||
internal void CopyToFast(ref CountingBufferWriter<PipeWriter> output)
|
internal void CopyToFast(ref BufferWriter<PipeWriter> output)
|
||||||
{{
|
{{
|
||||||
var tempBits = _bits | (_contentLength.HasValue ? {1L << 63}L : 0);
|
var tempBits = _bits | (_contentLength.HasValue ? {1L << 63}L : 0);
|
||||||
{Each(loop.Headers.Where(header => header.Identifier != "ContentLength").OrderBy(h => !h.PrimaryHeader), header => $@"
|
{Each(loop.Headers.Where(header => header.Identifier != "ContentLength").OrderBy(h => !h.PrimaryHeader), header => $@"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue