@@ -67,21 +67,22 @@ impl<W: Write> Writer for W {
67
67
/// Wrap buffering support for implementations of Read.
68
68
/// A [`Read`]er which keeps an internal buffer to avoid hitting the underlying stream directly for
69
69
/// every read, implementing [`BufRead`].
70
- pub struct BufReader < ' a , R : Read > {
70
+ ///
71
+ /// In order to avoid reading bytes past the first object, and those bytes then ending up getting
72
+ /// dropped, this BufReader operates in one-byte-increments.
73
+ struct BufReader < ' a , R : Read > {
71
74
inner : & ' a mut R ,
72
- buf : [ u8 ; 4096 ] ,
73
- pos : usize ,
74
- limit : usize ,
75
+ buf : [ u8 ; 1 ] ,
76
+ is_consumed : bool
75
77
}
76
78
77
79
impl < ' a , R : Read > BufReader < ' a , R > {
78
80
/// Creates a [`BufReader`] which will read from the given `inner`.
79
81
pub fn new ( inner : & ' a mut R ) -> Self {
80
82
BufReader {
81
83
inner,
82
- buf : [ 0 ; 4096 ] ,
83
- pos : 0 ,
84
- limit : 0 ,
84
+ buf : [ 0 ; 1 ] ,
85
+ is_consumed : true
85
86
}
86
87
}
87
88
}
@@ -100,21 +101,24 @@ impl<'a, R: Read> Read for BufReader<'a, R> {
100
101
impl < ' a , R : Read > BufRead for BufReader < ' a , R > {
101
102
#[ inline]
102
103
fn fill_buf ( & mut self ) -> io:: Result < & [ u8 ] > {
103
- if self . pos < self . limit {
104
- Ok ( & self . buf [ self . pos ..self . limit ] )
105
- } else {
104
+ if self . is_consumed {
106
105
let count = self . inner . read ( & mut self . buf [ ..] ) ?;
107
- debug_assert ! ( count <= self . buf . len ( ) , "read gave us a garbage length" ) ;
108
- self . pos = 0 ;
109
- self . limit = cmp :: min ( count , self . buf . len ( ) ) ;
110
- Ok ( & self . buf [ .. self . limit ] )
106
+ debug_assert ! ( count <= 1 , "read gave us a garbage length" ) ;
107
+
108
+ // upon hitting EOF, assume the byte is already consumed
109
+ self . is_consumed = count == 0 ;
111
110
}
111
+
112
+ Ok ( & self . buf [ ..] )
112
113
}
113
114
114
115
#[ inline]
115
116
fn consume ( & mut self , amount : usize ) {
116
- debug_assert ! ( self . pos. saturating_add( amount) <= self . limit, "Cannot consume more than was provided" ) ;
117
- self . pos += amount;
117
+ if amount >= 1 {
118
+ debug_assert_eq ! ( amount, 1 , "Can only consume one byte" ) ;
119
+ debug_assert ! ( !self . is_consumed, "Cannot consume more than had been read" ) ;
120
+ self . is_consumed = true ;
121
+ }
118
122
}
119
123
}
120
124
0 commit comments