Пример #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));
            }
        }
Пример #4
0
        public void WriteAsciiNoValidationWritesOnlyOneBytePerChar(string input)
        {
            // WriteAscii doesn't validate if characters are in the ASCII range
            // but it shouldn't produce more than one byte per character
            var writerBuffer = _pipe.Writer;
            var writer       = new CountingBufferWriter <PipeWriter>(writerBuffer);

            writer.WriteAsciiNoValidation(input);
            writer.Commit();
            writerBuffer.FlushAsync().GetAwaiter().GetResult();
            var reader = _pipe.Reader.ReadAsync().GetAwaiter().GetResult();

            Assert.Equal(input.Length, reader.Buffer.Length);
        }
Пример #5
0
        public void WritesNumericToAscii(ulong number)
        {
            var writerBuffer = _pipe.Writer;
            var writer       = new CountingBufferWriter <PipeWriter>(writerBuffer);

            writer.WriteNumeric(number);
            writer.Commit();
            writerBuffer.FlushAsync().GetAwaiter().GetResult();

            var reader   = _pipe.Reader.ReadAsync().GetAwaiter().GetResult();
            var numAsStr = number.ToString();
            var expected = Encoding.ASCII.GetBytes(numAsStr);

            AssertExtensions.Equal(expected, reader.Buffer.Slice(0, numAsStr.Length).ToArray());
        }
 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);
                 }
             }
         }
     }
 }
Пример #7
0
        public void WriteAsciiNoValidation()
        {
            const byte maxAscii     = 0x7f;
            var        writerBuffer = _pipe.Writer;
            var        writer       = new CountingBufferWriter <PipeWriter>(writerBuffer);

            for (var i = 0; i < maxAscii; i++)
            {
                writer.WriteAsciiNoValidation(new string((char)i, 1));
            }
            writer.Commit();
            writerBuffer.FlushAsync().GetAwaiter().GetResult();

            var reader = _pipe.Reader.ReadAsync().GetAwaiter().GetResult();
            var data   = reader.Buffer.Slice(0, maxAscii).ToArray();

            for (var i = 0; i < maxAscii; i++)
            {
                Assert.Equal(i, data[i]);
            }
        }
Пример #8
0
        public void EncodesAsAscii(string input, byte[] expected)
        {
            var pipeWriter = _pipe.Writer;
            var writer     = new CountingBufferWriter <PipeWriter>(pipeWriter);

            writer.WriteAsciiNoValidation(input);
            writer.Commit();
            pipeWriter.FlushAsync().GetAwaiter().GetResult();
            pipeWriter.Complete();

            var reader = _pipe.Reader.ReadAsync().GetAwaiter().GetResult();

            if (expected.Length > 0)
            {
                AssertExtensions.Equal(
                    expected,
                    reader.Buffer.ToArray());
            }
            else
            {
                Assert.Equal(0, reader.Buffer.Length);
            }
        }
Пример #9
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());
        }
Пример #10
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());
        }
Пример #11
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;
            }
        }
 internal static void WriteEndChunkBytes(ref CountingBufferWriter <PipeWriter> start)
 {
     start.Write(new ReadOnlySpan <byte>(_endChunkBytes.Array, _endChunkBytes.Offset, _endChunkBytes.Count));
 }