csv_sniffer/
snip.rs

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}