1
- use crate :: cmp;
1
+ mod buffer;
2
+
2
3
use crate :: fmt;
3
4
use crate :: io:: {
4
5
self , BufRead , IoSliceMut , Read , ReadBuf , Seek , SeekFrom , SizeHint , DEFAULT_BUF_SIZE ,
5
6
} ;
6
- use crate :: mem :: MaybeUninit ;
7
+ use buffer :: Buffer ;
7
8
8
9
/// The `BufReader<R>` struct adds buffering to any reader.
9
10
///
@@ -48,10 +49,7 @@ use crate::mem::MaybeUninit;
48
49
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
49
50
pub struct BufReader < R > {
50
51
inner : R ,
51
- buf : Box < [ MaybeUninit < u8 > ] > ,
52
- pos : usize ,
53
- cap : usize ,
54
- init : usize ,
52
+ buf : Buffer ,
55
53
}
56
54
57
55
impl < R : Read > BufReader < R > {
@@ -93,8 +91,7 @@ impl<R: Read> BufReader<R> {
93
91
/// ```
94
92
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
95
93
pub fn with_capacity ( capacity : usize , inner : R ) -> BufReader < R > {
96
- let buf = Box :: new_uninit_slice ( capacity) ;
97
- BufReader { inner, buf, pos : 0 , cap : 0 , init : 0 }
94
+ BufReader { inner, buf : Buffer :: with_capacity ( capacity) }
98
95
}
99
96
}
100
97
@@ -170,8 +167,7 @@ impl<R> BufReader<R> {
170
167
/// ```
171
168
#[ stable( feature = "bufreader_buffer" , since = "1.37.0" ) ]
172
169
pub fn buffer ( & self ) -> & [ u8 ] {
173
- // SAFETY: self.cap is always <= self.init, so self.buf[self.pos..self.cap] is always init
174
- unsafe { MaybeUninit :: slice_assume_init_ref ( & self . buf [ self . pos ..self . cap ] ) }
170
+ self . buf . buffer ( )
175
171
}
176
172
177
173
/// Returns the number of bytes the internal buffer can hold at once.
@@ -194,7 +190,7 @@ impl<R> BufReader<R> {
194
190
/// ```
195
191
#[ stable( feature = "buffered_io_capacity" , since = "1.46.0" ) ]
196
192
pub fn capacity ( & self ) -> usize {
197
- self . buf . len ( )
193
+ self . buf . capacity ( )
198
194
}
199
195
200
196
/// Unwraps this `BufReader<R>`, returning the underlying reader.
@@ -224,8 +220,7 @@ impl<R> BufReader<R> {
224
220
/// Invalidates all data in the internal buffer.
225
221
#[ inline]
226
222
fn discard_buffer ( & mut self ) {
227
- self . pos = 0 ;
228
- self . cap = 0 ;
223
+ self . buf . discard_buffer ( )
229
224
}
230
225
}
231
226
@@ -236,15 +231,15 @@ impl<R: Seek> BufReader<R> {
236
231
/// must track this information themselves if it is required.
237
232
#[ stable( feature = "bufreader_seek_relative" , since = "1.53.0" ) ]
238
233
pub fn seek_relative ( & mut self , offset : i64 ) -> io:: Result < ( ) > {
239
- let pos = self . pos as u64 ;
234
+ let pos = self . buf . pos ( ) as u64 ;
240
235
if offset < 0 {
241
- if let Some ( new_pos ) = pos. checked_sub ( ( -offset) as u64 ) {
242
- self . pos = new_pos as usize ;
236
+ if let Some ( _ ) = pos. checked_sub ( ( -offset) as u64 ) {
237
+ self . buf . unconsume ( ( -offset ) as usize ) ;
243
238
return Ok ( ( ) ) ;
244
239
}
245
240
} else if let Some ( new_pos) = pos. checked_add ( offset as u64 ) {
246
- if new_pos <= self . cap as u64 {
247
- self . pos = new_pos as usize ;
241
+ if new_pos <= self . buf . filled ( ) as u64 {
242
+ self . buf . consume ( offset as usize ) ;
248
243
return Ok ( ( ) ) ;
249
244
}
250
245
}
@@ -259,7 +254,7 @@ impl<R: Read> Read for BufReader<R> {
259
254
// If we don't have any buffered data and we're doing a massive read
260
255
// (larger than our internal buffer), bypass our internal buffer
261
256
// entirely.
262
- if self . pos == self . cap && buf. len ( ) >= self . buf . len ( ) {
257
+ if self . buf . pos ( ) == self . buf . filled ( ) && buf. len ( ) >= self . capacity ( ) {
263
258
self . discard_buffer ( ) ;
264
259
return self . inner . read ( buf) ;
265
260
}
@@ -275,7 +270,7 @@ impl<R: Read> Read for BufReader<R> {
275
270
// If we don't have any buffered data and we're doing a massive read
276
271
// (larger than our internal buffer), bypass our internal buffer
277
272
// entirely.
278
- if self . pos == self . cap && buf. remaining ( ) >= self . buf . len ( ) {
273
+ if self . buf . pos ( ) == self . buf . filled ( ) && buf. remaining ( ) >= self . capacity ( ) {
279
274
self . discard_buffer ( ) ;
280
275
return self . inner . read_buf ( buf) ;
281
276
}
@@ -295,9 +290,7 @@ impl<R: Read> Read for BufReader<R> {
295
290
// generation for the common path where the buffer has enough bytes to fill the passed-in
296
291
// buffer.
297
292
fn read_exact ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < ( ) > {
298
- if self . buffer ( ) . len ( ) >= buf. len ( ) {
299
- buf. copy_from_slice ( & self . buffer ( ) [ ..buf. len ( ) ] ) ;
300
- self . consume ( buf. len ( ) ) ;
293
+ if self . buf . consume_with ( buf. len ( ) , |claimed| buf. copy_from_slice ( claimed) ) {
301
294
return Ok ( ( ) ) ;
302
295
}
303
296
@@ -306,7 +299,7 @@ impl<R: Read> Read for BufReader<R> {
306
299
307
300
fn read_vectored ( & mut self , bufs : & mut [ IoSliceMut < ' _ > ] ) -> io:: Result < usize > {
308
301
let total_len = bufs. iter ( ) . map ( |b| b. len ( ) ) . sum :: < usize > ( ) ;
309
- if self . pos == self . cap && total_len >= self . buf . len ( ) {
302
+ if self . buf . pos ( ) == self . buf . filled ( ) && total_len >= self . capacity ( ) {
310
303
self . discard_buffer ( ) ;
311
304
return self . inner . read_vectored ( bufs) ;
312
305
}
@@ -325,8 +318,9 @@ impl<R: Read> Read for BufReader<R> {
325
318
// The inner reader might have an optimized `read_to_end`. Drain our buffer and then
326
319
// delegate to the inner implementation.
327
320
fn read_to_end ( & mut self , buf : & mut Vec < u8 > ) -> io:: Result < usize > {
328
- let nread = self . cap - self . pos ;
329
- buf. extend_from_slice ( & self . buffer ( ) ) ;
321
+ let inner_buf = self . buffer ( ) ;
322
+ buf. extend_from_slice ( inner_buf) ;
323
+ let nread = inner_buf. len ( ) ;
330
324
self . discard_buffer ( ) ;
331
325
Ok ( nread + self . inner . read_to_end ( buf) ?)
332
326
}
@@ -371,33 +365,11 @@ impl<R: Read> Read for BufReader<R> {
371
365
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
372
366
impl < R : Read > BufRead for BufReader < R > {
373
367
fn fill_buf ( & mut self ) -> io:: Result < & [ u8 ] > {
374
- // If we've reached the end of our internal buffer then we need to fetch
375
- // some more data from the underlying reader.
376
- // Branch using `>=` instead of the more correct `==`
377
- // to tell the compiler that the pos..cap slice is always valid.
378
- if self . pos >= self . cap {
379
- debug_assert ! ( self . pos == self . cap) ;
380
-
381
- let mut readbuf = ReadBuf :: uninit ( & mut self . buf ) ;
382
-
383
- // SAFETY: `self.init` is either 0 or set to `readbuf.initialized_len()`
384
- // from the last time this function was called
385
- unsafe {
386
- readbuf. assume_init ( self . init ) ;
387
- }
388
-
389
- self . inner . read_buf ( & mut readbuf) ?;
390
-
391
- self . cap = readbuf. filled_len ( ) ;
392
- self . init = readbuf. initialized_len ( ) ;
393
-
394
- self . pos = 0 ;
395
- }
396
- Ok ( self . buffer ( ) )
368
+ self . buf . fill_buf ( & mut self . inner )
397
369
}
398
370
399
371
fn consume ( & mut self , amt : usize ) {
400
- self . pos = cmp :: min ( self . pos + amt, self . cap ) ;
372
+ self . buf . consume ( amt)
401
373
}
402
374
}
403
375
@@ -409,7 +381,10 @@ where
409
381
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
410
382
fmt. debug_struct ( "BufReader" )
411
383
. field ( "reader" , & self . inner )
412
- . field ( "buffer" , & format_args ! ( "{}/{}" , self . cap - self . pos, self . buf. len( ) ) )
384
+ . field (
385
+ "buffer" ,
386
+ & format_args ! ( "{}/{}" , self . buf. filled( ) - self . buf. pos( ) , self . capacity( ) ) ,
387
+ )
413
388
. finish ( )
414
389
}
415
390
}
@@ -441,7 +416,7 @@ impl<R: Seek> Seek for BufReader<R> {
441
416
fn seek ( & mut self , pos : SeekFrom ) -> io:: Result < u64 > {
442
417
let result: u64 ;
443
418
if let SeekFrom :: Current ( n) = pos {
444
- let remainder = ( self . cap - self . pos ) as i64 ;
419
+ let remainder = ( self . buf . filled ( ) - self . buf . pos ( ) ) as i64 ;
445
420
// it should be safe to assume that remainder fits within an i64 as the alternative
446
421
// means we managed to allocate 8 exbibytes and that's absurd.
447
422
// But it's not out of the realm of possibility for some weird underlying reader to
@@ -499,7 +474,7 @@ impl<R: Seek> Seek for BufReader<R> {
499
474
/// }
500
475
/// ```
501
476
fn stream_position ( & mut self ) -> io:: Result < u64 > {
502
- let remainder = ( self . cap - self . pos ) as u64 ;
477
+ let remainder = ( self . buf . filled ( ) - self . buf . pos ( ) ) as u64 ;
503
478
self . inner . stream_position ( ) . map ( |pos| {
504
479
pos. checked_sub ( remainder) . expect (
505
480
"overflow when subtracting remaining buffer size from inner stream position" ,
0 commit comments