@@ -45,8 +45,28 @@ public override void Flush()
4545{
4646}
4747
48- public override int Read ( byte [ ] buffer , int offset , int count ) =>
49- ReadAsync ( buffer , offset , count ) . GetAwaiter ( ) . GetResult ( ) ;
48+ public override int Read ( byte [ ] buffer , int offset , int count )
49+ {
50+ if ( buffer is null )
51+ {
52+ throw new ArgumentNullException ( nameof ( buffer ) ) ;
53+ }
54+
55+ return ReadInternal ( new Span < byte > ( buffer , offset , count ) ) ;
56+ }
57+
58+ public override int ReadByte ( )
59+ {
60+ Span < byte > oneByte = stackalloc byte [ 1 ] ;
61+ return ReadInternal ( oneByte ) == 0 ? - 1 : oneByte [ 0 ] ;
62+ }
63+
64+ private int ReadInternal ( Span < byte > buffer )
65+ {
66+ ValueTask < ReadResult > vt = _pipeReader . ReadAsync ( ) ;
67+ ReadResult result = vt . IsCompletedSuccessfully ? vt . Result : vt . AsTask ( ) . Result ;
68+ return HandleReadResult ( result , buffer ) ;
69+ }
5070
5171public override long Seek ( long offset , SeekOrigin origin ) => throw new NotSupportedException ( ) ;
5272
@@ -71,6 +91,11 @@ public override Task<int> ReadAsync(byte[] buffer, int offset, int count, Cancel
7191}
7292
7393#if( ! NETSTANDARD2_0 && ! NETFRAMEWORK )
94+ public override int Read ( Span < byte > buffer )
95+ {
96+ return ReadInternal ( buffer ) ;
97+ }
98+
7499public override ValueTask < int > ReadAsync ( Memory < byte > buffer , CancellationToken cancellationToken = default )
75100{
76101return ReadAsyncInternal ( buffer , cancellationToken ) ;
@@ -80,7 +105,11 @@ public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken
80105private async ValueTask < int > ReadAsyncInternal ( Memory < byte > buffer , CancellationToken cancellationToken )
81106{
82107ReadResult result = await _pipeReader . ReadAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
108+ return HandleReadResult ( result , buffer . Span ) ;
109+ }
83110
111+ private int HandleReadResult ( ReadResult result , Span < byte > buffer )
112+ {
84113if ( result . IsCanceled )
85114{
86115ThrowHelper . ThrowOperationCanceledException_ReadCanceled ( ) ;
@@ -98,7 +127,7 @@ private async ValueTask<int> ReadAsyncInternal(Memory<byte> buffer, Cancellation
98127
99128ReadOnlySequence < byte > slice = actual == bufferLength ? sequence : sequence . Slice ( 0 , actual ) ;
100129consumed = slice . End ;
101- slice . CopyTo ( buffer . Span ) ;
130+ slice . CopyTo ( buffer ) ;
102131
103132return actual ;
104133}