mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
e68f935117
Add `BufRead::skip_until` Alternative version of `BufRead::read_until` that simply discards data, rather than copying it into a buffer. Useful for situations like skipping irrelevant data in a binary file format that is NUL-terminated. <details> <summary>Benchmark</summary> ``` running 2 tests test bench_read_until ... bench: 123 ns/iter (+/- 6) test bench_skip_until ... bench: 66 ns/iter (+/- 3) ``` ```rs #![feature(test)] extern crate test; use test::Bencher; use std::io::{ErrorKind, BufRead}; fn skip_until<R: BufRead + ?Sized>(r: &mut R, delim: u8) -> Result<usize, std::io::Error> { let mut read = 0; loop { let (done, used) = { let available = match r.fill_buf() { Ok(n) => n, Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, Err(e) => return Err(e), }; match memchr::memchr(delim, available) { Some(i) => (true, i + 1), None => (false, available.len()), } }; r.consume(used); read += used; if done || used == 0 { return Ok(read); } } } const STR: &[u8] = b"Ferris\0Hello, world!\0"; #[bench] fn bench_skip_until(b: &mut Bencher) { b.iter(|| { let mut io = std::io::Cursor::new(test::black_box(STR)); skip_until(&mut io, b'\0').unwrap(); let mut hello = Vec::with_capacity(b"Hello, world!\0".len()); let num_bytes = io.read_until(b'\0', &mut hello).unwrap(); assert_eq!(num_bytes, b"Hello, world!\0".len()); assert_eq!(hello, b"Hello, world!\0"); }); } #[bench] fn bench_read_until(b: &mut Bencher) { b.iter(|| { let mut io = std::io::Cursor::new(test::black_box(STR)); io.read_until(b'\0', &mut Vec::new()).unwrap(); let mut hello = Vec::with_capacity(b"Hello, world!\0".len()); let num_bytes = io.read_until(b'\0', &mut hello).unwrap(); assert_eq!(num_bytes, b"Hello, world!\0".len()); assert_eq!(hello, b"Hello, world!\0"); }); } ``` </details> |
||
---|---|---|
.. | ||
benches | ||
src | ||
tests | ||
build.rs | ||
Cargo.toml |