ffmpeg_sidecar/
read_until_any.rs1use std::io::{BufRead, ErrorKind, Result};
4
5pub fn read_until_any<R: BufRead + ?Sized>(
10 r: &mut R,
11 delims: &[u8],
12 buf: &mut Vec<u8>,
13) -> Result<usize> {
14 let mut read = 0;
15 loop {
16 let (done, used) = {
17 let available = match r.fill_buf() {
18 Ok(n) => n,
19 Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
20 Err(e) => return Err(e),
21 };
22
23 let start_delims = if read == 0 {
24 available
25 .iter()
26 .take_while(|&&b| delims.iter().any(|&d| d == b))
27 .count()
28 } else {
29 0
30 };
31
32 let first_delim_index = available
34 .iter()
35 .skip(start_delims)
36 .position(|&b| delims.iter().any(|&d| d == b))
37 .map(|i| i + start_delims);
38
39 match first_delim_index {
40 Some(i) => {
41 buf.extend_from_slice(&available[..=i]);
42 (true, i + 1)
43 }
44 None => {
45 buf.extend_from_slice(available);
46 (false, available.len())
47 }
48 }
49 };
50 r.consume(used);
51 read += used;
52
53 if done {
54 return Ok(read);
55 }
56
57 if used == 0 && buf.iter().all(|&b| delims.iter().any(|&d| d == b)) {
59 return Ok(0);
60 }
61
62 if used == 0 {
63 return Ok(read);
64 }
65 }
66}