private Task WriteAsync( ReadOnlySpan <byte> buffer, CancellationToken cancellationToken) { var writableBuffer = default(PipeWriter); long bytesWritten = 0; lock (_contextLock) { if (_completed) { return(Task.CompletedTask); } writableBuffer = _pipeWriter; var writer = new CountingBufferWriter <PipeWriter>(writableBuffer); if (buffer.Length > 0) { writer.Write(buffer); _unflushedBytes += buffer.Length; _totalBytesCommitted += buffer.Length; } writer.Commit(); bytesWritten = _unflushedBytes; _unflushedBytes = 0; } return(FlushAsync(writableBuffer, bytesWritten, cancellationToken)); }
internal static int WriteBeginChunkBytes(ref CountingBufferWriter <PipeWriter> start, int dataCount) { var chunkSegment = BeginChunkBytes(dataCount); start.Write(new ReadOnlySpan <byte>(chunkSegment.Array, chunkSegment.Offset, chunkSegment.Count)); return(chunkSegment.Count); }
private Task WriteAsync( ReadOnlySpan <byte> buffer, CancellationToken cancellationToken = default) { lock (_contextLock) { if (_completed) { return(Task.CompletedTask); } var writer = new CountingBufferWriter <PipeWriter>(_pipeWriter); if (buffer.Length > 0) { writer.Write(buffer); _unflushedBytes += buffer.Length; _totalBytesCommitted += buffer.Length; } writer.Commit(); var bytesWritten = _unflushedBytes; _unflushedBytes = 0; return(_flusher.FlushAsync(bytesWritten, this, cancellationToken)); } }
internal void CopyTo(ref CountingBufferWriter <PipeWriter> buffer) { CopyToFast(ref buffer); if (MaybeUnknown != null) { foreach (var kv in MaybeUnknown) { foreach (var value in kv.Value) { if (value != null) { buffer.Write(_CrLf); PipelineExtensions.WriteAsciiNoValidation(ref buffer, kv.Key); buffer.Write(_colonSpace); PipelineExtensions.WriteAsciiNoValidation(ref buffer, value); } } } } }
public void WriteResponseHeaders(int statusCode, string reasonPhrase, HttpResponseHeaders responseHeaders) { lock (_contextLock) { if (_completed) { return; } var buffer = _pipeWriter; var writer = new CountingBufferWriter <PipeWriter>(buffer); writer.Write(_bytesHttpVersion11); var statusBytes = ReasonPhrases.ToStatusBytes(statusCode, reasonPhrase); writer.Write(statusBytes); responseHeaders.CopyTo(ref writer); writer.Write(_bytesEndHeaders); writer.Commit(); _unflushedBytes += writer.BytesCommitted; _totalBytesCommitted += writer.BytesCommitted; } }
public void WritesNumericAcrossSpanBoundaries(int gapSize) { var writerBuffer = _pipe.Writer; var writer = new CountingBufferWriter <PipeWriter>(writerBuffer); // almost fill up the first block var spacer = new byte[writer.Span.Length - gapSize]; writer.Write(spacer); var bufferLength = writer.Span.Length; writer.WriteNumeric(ulong.MaxValue); Assert.NotEqual(bufferLength, writer.Span.Length); writer.Commit(); writerBuffer.FlushAsync().GetAwaiter().GetResult(); var reader = _pipe.Reader.ReadAsync().GetAwaiter().GetResult(); var numAsString = ulong.MaxValue.ToString(); var written = reader.Buffer.Slice(spacer.Length, numAsString.Length); Assert.False(written.IsSingleSegment, "The buffer should cross spans"); AssertExtensions.Equal(Encoding.ASCII.GetBytes(numAsString), written.ToArray()); }
public void WritesAsciiAcrossBlockBoundaries(int stringLength, int gapSize) { var testString = new string(' ', stringLength); var writerBuffer = _pipe.Writer; var writer = new CountingBufferWriter <PipeWriter>(writerBuffer); // almost fill up the first block var spacer = new byte[writer.Span.Length - gapSize]; writer.Write(spacer); Assert.Equal(gapSize, writer.Span.Length); var bufferLength = writer.Span.Length; writer.WriteAsciiNoValidation(testString); Assert.NotEqual(bufferLength, writer.Span.Length); writer.Commit(); writerBuffer.FlushAsync().GetAwaiter().GetResult(); var reader = _pipe.Reader.ReadAsync().GetAwaiter().GetResult(); var written = reader.Buffer.Slice(spacer.Length, stringLength); Assert.False(written.IsSingleSegment, "The buffer should cross spans"); AssertExtensions.Equal(Encoding.ASCII.GetBytes(testString), written.ToArray()); }
internal static void WriteEndChunkBytes(ref CountingBufferWriter <PipeWriter> start) { start.Write(new ReadOnlySpan <byte>(_endChunkBytes.Array, _endChunkBytes.Offset, _endChunkBytes.Count)); }