Exemple #1
0
        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);
                 }
             }
         }
     }
 }
Exemple #5
0
        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;
            }
        }
Exemple #6
0
        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());
        }
Exemple #7
0
        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));
 }