Implement "seek_relative"
This commit is contained in:
parent
a18dea908c
commit
562ba04e45
1 changed files with 42 additions and 0 deletions
|
@ -194,6 +194,31 @@ impl<R: Read> BufReader<R> {
|
||||||
pub fn into_inner(self) -> R { self.inner }
|
pub fn into_inner(self) -> R { self.inner }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<R: Seek> BufReader<R> {
|
||||||
|
/// Seeks relative to the current position. If the new position lies within the buffer,
|
||||||
|
/// the buffer will not be flushed, allowing for more efficient seeks.
|
||||||
|
/// This method does not return the location of the underlying reader, so the caller
|
||||||
|
/// must track this information themselves if it is required.
|
||||||
|
#[unstable(feature = "bufreader_seek_relative", issue = "31100")]
|
||||||
|
pub fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
|
||||||
|
let pos = self.pos as u64;
|
||||||
|
if offset < 0 {
|
||||||
|
if let Some(new_pos) = pos.checked_sub((-offset) as u64) {
|
||||||
|
self.pos = new_pos as usize;
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let Some(new_pos) = pos.checked_add(offset as u64) {
|
||||||
|
if new_pos <= self.cap as u64 {
|
||||||
|
self.pos = new_pos as usize;
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.seek(SeekFrom::Current(offset)).map(|_|())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<R: Read> Read for BufReader<R> {
|
impl<R: Read> Read for BufReader<R> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
|
@ -942,6 +967,23 @@ mod tests {
|
||||||
assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
|
assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_buffered_reader_seek_relative() {
|
||||||
|
let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
|
||||||
|
let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
|
||||||
|
|
||||||
|
assert!(reader.seek_relative(3).is_ok());
|
||||||
|
assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
|
||||||
|
assert!(reader.seek_relative(0).is_ok());
|
||||||
|
assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
|
||||||
|
assert!(reader.seek_relative(1).is_ok());
|
||||||
|
assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
|
||||||
|
assert!(reader.seek_relative(-1).is_ok());
|
||||||
|
assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
|
||||||
|
assert!(reader.seek_relative(2).is_ok());
|
||||||
|
assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_buffered_reader_seek_underflow() {
|
fn test_buffered_reader_seek_underflow() {
|
||||||
// gimmick reader that yields its position modulo 256 for each byte
|
// gimmick reader that yields its position modulo 256 for each byte
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue