Commit e68f935
committed
Auto merge of #98943 - WilliamVenner:feat/bufread_skip_until, r=dtolnay
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>2 files changed
+114
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2044 | 2044 | | |
2045 | 2045 | | |
2046 | 2046 | | |
| 2047 | + | |
| 2048 | + | |
| 2049 | + | |
| 2050 | + | |
| 2051 | + | |
| 2052 | + | |
| 2053 | + | |
| 2054 | + | |
| 2055 | + | |
| 2056 | + | |
| 2057 | + | |
| 2058 | + | |
| 2059 | + | |
| 2060 | + | |
| 2061 | + | |
| 2062 | + | |
| 2063 | + | |
| 2064 | + | |
| 2065 | + | |
| 2066 | + | |
| 2067 | + | |
| 2068 | + | |
2047 | 2069 | | |
2048 | 2070 | | |
2049 | 2071 | | |
| |||
2247 | 2269 | | |
2248 | 2270 | | |
2249 | 2271 | | |
| 2272 | + | |
| 2273 | + | |
| 2274 | + | |
| 2275 | + | |
| 2276 | + | |
| 2277 | + | |
| 2278 | + | |
| 2279 | + | |
| 2280 | + | |
| 2281 | + | |
| 2282 | + | |
| 2283 | + | |
| 2284 | + | |
| 2285 | + | |
| 2286 | + | |
| 2287 | + | |
| 2288 | + | |
| 2289 | + | |
| 2290 | + | |
| 2291 | + | |
| 2292 | + | |
| 2293 | + | |
| 2294 | + | |
| 2295 | + | |
| 2296 | + | |
| 2297 | + | |
| 2298 | + | |
| 2299 | + | |
| 2300 | + | |
| 2301 | + | |
| 2302 | + | |
| 2303 | + | |
| 2304 | + | |
| 2305 | + | |
| 2306 | + | |
| 2307 | + | |
| 2308 | + | |
| 2309 | + | |
| 2310 | + | |
| 2311 | + | |
| 2312 | + | |
| 2313 | + | |
| 2314 | + | |
| 2315 | + | |
| 2316 | + | |
| 2317 | + | |
| 2318 | + | |
| 2319 | + | |
| 2320 | + | |
| 2321 | + | |
| 2322 | + | |
| 2323 | + | |
| 2324 | + | |
| 2325 | + | |
| 2326 | + | |
| 2327 | + | |
| 2328 | + | |
| 2329 | + | |
| 2330 | + | |
| 2331 | + | |
| 2332 | + | |
| 2333 | + | |
2250 | 2334 | | |
2251 | 2335 | | |
2252 | 2336 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
28 | 58 | | |
29 | 59 | | |
30 | 60 | | |
| |||
0 commit comments