1use std::io::{Read, Seek, SeekFrom};
2
3use memchr;
4
5use error::*;
6
7pub(crate) fn preamble_skipcount<R: Read>(reader: &mut R, n_preamble_rows: usize) -> Result<usize> {
8 if n_preamble_rows == 0 {
9 return Ok(0);
10 }
11 let mut skipcount = 0;
12 loop {
13 let cap = 1 << 12;
14 let mut buffer = vec![0; cap];
15 unsafe {
16 buffer.set_len(cap);
17 }
18 let n_read = reader.read(&mut buffer)?;
19 let mut crlf_pos = 0;
20 let mut found = true;
21 for _ in 0..n_preamble_rows {
22 match memchr::memchr(b'\n', &buffer[crlf_pos..]) {
23 Some(pos) => {
24 crlf_pos += pos + 1;
25 }
26 None => {
27 found = false;
28 break;
29 }
30 }
31 }
32 if found {
33 skipcount += crlf_pos;
34 break;
35 } else {
36 skipcount += cap.min(n_read);
37 }
38 }
39 Ok(skipcount)
40}
41
42pub(crate) fn snip_preamble<R: Read + Seek>(mut reader: R, n_preamble_rows: usize) -> Result<()> {
43 let seek_point = preamble_skipcount(&mut reader, n_preamble_rows)?;
44 reader.seek(SeekFrom::Start(seek_point as u64))?;
45 Ok(())
46}