@@ -11,19 +11,25 @@ namespace BencodeNET.IO
1111 /// </summary>
1212 public class PipeBencodeReader
1313 {
14- private readonly PipeReader _reader ;
14+ /// <summary>
15+ /// The <see cref="PipeReader"/> to read from.
16+ /// </summary>
17+ protected readonly PipeReader _reader ;
1518
16- private bool _endOfStream ;
19+ /// <summary>
20+ /// Indicates if the <see cref="PipeReader"/> has been completed (i.e. "end of stream").
21+ /// </summary>
22+ protected bool _readerCompleted ;
1723
1824 /// <summary>
1925 /// The position in the pipe (number of read bytes/characters) (does not included peeked char).
2026 /// </summary>
21- public long Position { get ; set ; }
27+ public virtual long Position { get ; protected set ; }
2228
2329 /// <summary>
2430 /// The previously read/consumed char (does not include peeked char).
2531 /// </summary>
26- public char PreviousChar { get ; protected set ; }
32+ public virtual char PreviousChar { get ; protected set ; }
2733
2834 /// <summary>
2935 /// Creates a <see cref="PipeBencodeReader"/> that reads from the specified <see cref="PipeReader"/>.
@@ -37,18 +43,18 @@ public PipeBencodeReader(PipeReader reader)
3743 /// <summary>
3844 /// Peek at the next char in the pipe, without advancing the reader.
3945 /// </summary>
40- public ValueTask < char > PeekCharAsync ( CancellationToken cancellationToken = default )
46+ public virtual ValueTask < char > PeekCharAsync ( CancellationToken cancellationToken = default )
4147 => ReadCharAsync ( peek : true , cancellationToken ) ;
4248
4349 /// <summary>
4450 /// Read the next char in the pipe and advance the reader.
4551 /// </summary>
46- public ValueTask < char > ReadCharAsync ( CancellationToken cancellationToken = default )
52+ public virtual ValueTask < char > ReadCharAsync ( CancellationToken cancellationToken = default )
4753 => ReadCharAsync ( peek : false , cancellationToken ) ;
4854
4955 private ValueTask < char > ReadCharAsync ( bool peek = false , CancellationToken cancellationToken = default )
5056 {
51- if ( _endOfStream )
57+ if ( _readerCompleted )
5258 return new ValueTask < char > ( default ( char ) ) ;
5359
5460 if ( _reader . TryRead ( out var result ) )
@@ -67,12 +73,14 @@ private async ValueTask<char> ReadCharAsyncAwaited(bool peek, CancellationToken
6773 /// Reads the next char in the pipe and consumes it (advances the reader),
6874 /// unless <paramref name="peek"/> is <c>true</c>.
6975 /// </summary>
70- private char ReadCharConsume ( in ReadOnlySequence < byte > buffer , bool peek )
76+ /// <param name="buffer">The buffer to read from</param>
77+ /// <param name="peek">If true the char will not be consumed, i.e. the reader should not be advanced.</param>
78+ protected virtual char ReadCharConsume ( in ReadOnlySequence < byte > buffer , bool peek )
7179 {
7280 if ( buffer . IsEmpty )
7381 {
7482 // TODO: Add IsCompleted check?
75- _endOfStream = true ;
83+ _readerCompleted = true ;
7684 return default ;
7785 }
7886
@@ -98,9 +106,9 @@ private char ReadCharConsume(in ReadOnlySequence<byte> buffer, bool peek)
98106 /// </summary>
99107 /// <param name="bytes">The amount of bytes to read.</param>
100108 /// <param name="cancellationToken"></param>
101- public ValueTask < long > ReadAsync ( Memory < byte > bytes , CancellationToken cancellationToken = default )
109+ public virtual ValueTask < long > ReadAsync ( Memory < byte > bytes , CancellationToken cancellationToken = default )
102110 {
103- if ( bytes . Length == 0 || _endOfStream )
111+ if ( bytes . Length == 0 || _readerCompleted )
104112 return new ValueTask < long > ( 0 ) ;
105113
106114 if ( _reader . TryRead ( out var result ) && TryReadConsume ( result , bytes . Span , out var bytesRead ) )
@@ -123,7 +131,18 @@ private async ValueTask<long> ReadAsyncAwaited(Memory<byte> bytes, CancellationT
123131 }
124132 }
125133
126- private bool TryReadConsume ( ReadResult result , in Span < byte > bytes , out long bytesRead )
134+ /// <summary>
135+ /// Attempts to read the specified bytes from the reader and advances the reader if successful.
136+ /// If the end of the pipe is reached then the available bytes is read and returned, if any.
137+ /// <para>
138+ /// Returns <c>true</c> if any bytes was read or the reader was completed.
139+ /// </para>
140+ /// </summary>
141+ /// <param name="result">The read result from the pipe read operation.</param>
142+ /// <param name="bytes">The bytes to read.</param>
143+ /// <param name="bytesRead">The number of bytes read.</param>
144+ /// <returns></returns>
145+ protected virtual bool TryReadConsume ( ReadResult result , in Span < byte > bytes , out long bytesRead )
127146 {
128147 if ( result . IsCanceled ) throw new InvalidOperationException ( "Read operation cancelled." ) ;
129148
@@ -143,7 +162,7 @@ private bool TryReadConsume(ReadResult result, in Span<byte> bytes, out long byt
143162
144163 if ( result . IsCompleted )
145164 {
146- _endOfStream = true ;
165+ _readerCompleted = true ;
147166
148167 if ( buffer . IsEmpty )
149168 {
0 commit comments