@@ -133,7 +133,29 @@ impl FileLoader for RealFileLoader {
133
133
file. read_buf_exact ( buf. unfilled ( ) ) ?;
134
134
// SAFETY: If the read_buf_exact call returns Ok(()), then we have
135
135
// read len bytes and initialized the buffer.
136
- Ok ( unsafe { bytes. assume_init ( ) } )
136
+ let bytes = unsafe { bytes. assume_init ( ) } ;
137
+
138
+ // At this point, we've read all the bytes that filesystem metadata reported exist.
139
+ // But we are not guaranteed to be at the end of the file, because we did not attempt to do
140
+ // a read with a non-zero-sized buffer and get Ok(0).
141
+ // So we do small read to a fixed-size buffer. If the read returns no bytes then we're
142
+ // already done, and we just return the Lrc we built above.
143
+ // If the read returns bytes however, we just fall back to reading into a Vec then turning
144
+ // that into an Lrc, losing our nice peak memory behavior. This fallback code path should
145
+ // be rarely exercised.
146
+
147
+ let mut probe = [ 0u8 ; 32 ] ;
148
+ let n = loop {
149
+ match file. read ( & mut probe) {
150
+ Ok ( 0 ) => return Ok ( bytes) ,
151
+ Err ( e) if e. kind ( ) == io:: ErrorKind :: Interrupted => continue ,
152
+ Err ( e) => return Err ( e) ,
153
+ Ok ( n) => break n,
154
+ }
155
+ } ;
156
+ let mut bytes: Vec < u8 > = bytes. iter ( ) . copied ( ) . chain ( probe[ ..n] . iter ( ) . copied ( ) ) . collect ( ) ;
157
+ file. read_to_end ( & mut bytes) ?;
158
+ Ok ( bytes. into ( ) )
137
159
}
138
160
}
139
161
0 commit comments