@@ -41,6 +41,7 @@ public sealed class IndexedCapturingReader : IndexedReader
41
41
private readonly List < byte [ ] > _chunks = new List < byte [ ] > ( ) ;
42
42
private bool _isStreamFinished ;
43
43
private int _streamLength ;
44
+ private bool _streamLengthRead ;
44
45
private bool _streamLengthThrewException ;
45
46
46
47
public IndexedCapturingReader ( [ NotNull ] Stream stream , int chunkLength = DefaultChunkLength , bool isMotorolaByteOrder = true )
@@ -68,24 +69,42 @@ public override long Length
68
69
{
69
70
get
70
71
{
71
- if ( ! _streamLengthThrewException )
72
- {
73
- try
74
- {
75
- return _stream . Length ;
76
- }
77
- catch ( NotSupportedException )
78
- {
79
- _streamLengthThrewException = true ;
80
- }
81
- }
72
+ if ( TryGetStreamLength ( out var streamLength ) )
73
+ return streamLength ;
82
74
83
75
IsValidIndex ( int . MaxValue , 1 ) ;
84
76
Debug . Assert ( _isStreamFinished ) ;
85
77
return _streamLength ;
86
78
}
87
79
}
88
80
81
+ private bool TryGetStreamLength ( out long streamLength )
82
+ {
83
+ if ( _streamLengthRead )
84
+ {
85
+ streamLength = _streamLength ;
86
+ return true ;
87
+ }
88
+
89
+ if ( ! _streamLengthThrewException )
90
+ {
91
+ try
92
+ {
93
+ _streamLength = checked ( ( int ) _stream . Length ) ;
94
+ streamLength = _streamLength ;
95
+ _streamLengthRead = true ;
96
+ return true ;
97
+ }
98
+ catch ( NotSupportedException )
99
+ {
100
+ _streamLengthThrewException = true ;
101
+ }
102
+ }
103
+
104
+ streamLength = default ;
105
+ return false ;
106
+ }
107
+
89
108
/// <summary>Ensures that the buffered bytes extend to cover the specified index. If not, an attempt is made
90
109
/// to read to that point.</summary>
91
110
/// <remarks>If the stream ends before the point is reached, a <see cref="BufferBoundsException"/> is raised.</remarks>
@@ -119,6 +138,10 @@ protected override bool IsValidIndex(int index, int bytesRequested)
119
138
return false ;
120
139
121
140
var endIndex = ( int ) endIndexLong ;
141
+
142
+ if ( TryGetStreamLength ( out var streamLength ) )
143
+ return endIndex < streamLength ;
144
+
122
145
if ( _isStreamFinished )
123
146
return endIndex < _streamLength ;
124
147
@@ -139,6 +162,7 @@ protected override bool IsValidIndex(int index, int bytesRequested)
139
162
// the stream has ended, which may be ok
140
163
_isStreamFinished = true ;
141
164
_streamLength = _chunks . Count * _chunkLength + totalBytesRead ;
165
+ _streamLengthRead = true ;
142
166
// check we have enough bytes for the requested index
143
167
if ( endIndex >= _streamLength )
144
168
{
0 commit comments