@@ -194,6 +194,31 @@ impl<R: Read> BufReader<R> {
194
194
pub fn into_inner ( self ) -> R { self . inner }
195
195
}
196
196
197
+ impl < R : Seek > BufReader < R > {
198
+ /// Seeks relative to the current position. If the new position lies within the buffer,
199
+ /// the buffer will not be flushed, allowing for more efficient seeks.
200
+ /// This method does not return the location of the underlying reader, so the caller
201
+ /// must track this information themselves if it is required.
202
+ #[ unstable( feature = "bufreader_seek_relative" , issue = "31100" ) ]
203
+ pub fn seek_relative ( & mut self , offset : i64 ) -> io:: Result < ( ) > {
204
+ let pos = self . pos as u64 ;
205
+ if offset < 0 {
206
+ if let Some ( new_pos) = pos. checked_sub ( ( -offset) as u64 ) {
207
+ self . pos = new_pos as usize ;
208
+ return Ok ( ( ) )
209
+ }
210
+ } else {
211
+ if let Some ( new_pos) = pos. checked_add ( offset as u64 ) {
212
+ if new_pos <= self . cap as u64 {
213
+ self . pos = new_pos as usize ;
214
+ return Ok ( ( ) )
215
+ }
216
+ }
217
+ }
218
+ self . seek ( SeekFrom :: Current ( offset) ) . map ( |_|( ) )
219
+ }
220
+ }
221
+
197
222
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
198
223
impl < R : Read > Read for BufReader < R > {
199
224
fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
@@ -942,6 +967,23 @@ mod tests {
942
967
assert_eq ! ( reader. seek( SeekFrom :: Current ( -2 ) ) . ok( ) , Some ( 3 ) ) ;
943
968
}
944
969
970
+ #[ test]
971
+ fn test_buffered_reader_seek_relative ( ) {
972
+ let inner: & [ u8 ] = & [ 5 , 6 , 7 , 0 , 1 , 2 , 3 , 4 ] ;
973
+ let mut reader = BufReader :: with_capacity ( 2 , io:: Cursor :: new ( inner) ) ;
974
+
975
+ assert ! ( reader. seek_relative( 3 ) . is_ok( ) ) ;
976
+ assert_eq ! ( reader. fill_buf( ) . ok( ) , Some ( & [ 0 , 1 ] [ ..] ) ) ;
977
+ assert ! ( reader. seek_relative( 0 ) . is_ok( ) ) ;
978
+ assert_eq ! ( reader. fill_buf( ) . ok( ) , Some ( & [ 0 , 1 ] [ ..] ) ) ;
979
+ assert ! ( reader. seek_relative( 1 ) . is_ok( ) ) ;
980
+ assert_eq ! ( reader. fill_buf( ) . ok( ) , Some ( & [ 1 ] [ ..] ) ) ;
981
+ assert ! ( reader. seek_relative( -1 ) . is_ok( ) ) ;
982
+ assert_eq ! ( reader. fill_buf( ) . ok( ) , Some ( & [ 0 , 1 ] [ ..] ) ) ;
983
+ assert ! ( reader. seek_relative( 2 ) . is_ok( ) ) ;
984
+ assert_eq ! ( reader. fill_buf( ) . ok( ) , Some ( & [ 2 , 3 ] [ ..] ) ) ;
985
+ }
986
+
945
987
#[ test]
946
988
fn test_buffered_reader_seek_underflow ( ) {
947
989
// gimmick reader that yields its position modulo 256 for each byte
0 commit comments