use memchr::memchr2_iter;
use std::io::{BufRead};
use super::*;
fn count_lines(buf: &[u8], eol: u8) -> usize {
bytecount::count(buf, eol)
}
pub fn read_num_file_tot_lines<R: BufRead>(reader: &mut R) -> usize {
let mut count = 0;
loop {
let buffer = reader.fill_buf().unwrap();
let length = buffer.len();
count += count_lines(&buffer[0..length], b'\n');
reader.consume(length);
if length < BUF_SIZE {
break;
}
}
count
}
pub fn read_num_file_lines<R: BufRead>(reader: & mut R, com: u8) -> usize {
let mut count = 0;
loop {
let length = {
let buffer = reader.fill_buf().unwrap();
let mut i = 0;
let mut newline = memchr2_iter(b'\n', b'\r', buffer);
let length = buffer.len();
while i < length {
if (buffer[i] == b' ') | (buffer[i] == b'\t') {
i += 1;
} else if (buffer[i] == b'\n') | (buffer[i] == b'\r') | (buffer[i] == com) {
let val = newline.next();
i = match val {
Some(val) => val + 1,
None => length,
};
} else {
count += 1;
let val = newline.next();
i = match val {
Some(val) => val + 1,
None => length,
};
}
}
length
};
reader.consume(length);
if length < BUF_SIZE {
break;
}
}
count
}
pub(crate) fn skip_header_lines<R: BufRead>(reader: & mut R, fln: &mut usize, cmt: u8, sk_h: usize) {
if sk_h > 0 {
let mut count = 0;
loop {
let length = {
let buffer = reader.fill_buf().unwrap();
let mut i = 0;
let mut newline = memchr2_iter(b'\n', b'\r', buffer);
let length = buffer.len();
while i < length {
if (buffer[i] == b' ') | (buffer[i] == b'\t') {
i += 1;
} else if (buffer[i] == b'\n') | (buffer[i] == b'\r') | (buffer[i] == cmt) {
let val = newline.next();
i = match val {
Some(val) => val + 1,
None => length + 1,
};
*fln += 1;
} else {
count += 1;
let val = newline.next();
i = match val {
Some(val) => val + 1,
None => length + 1,
};
*fln += 1;
}
if count == sk_h {
break;
}
}
i - 1
};
reader.consume(length);
if count == sk_h || length < BUF_SIZE {
break;
}
}
}
}
pub fn count_num_fields<R: BufRead>(reader:&mut R, cmt: u8, delim: u8, delim_ws: bool) -> usize {
let mut field_counter = 0;
enum ParseState {CmtNwLine, Field, Space, Delim}
let mut state = ParseState::CmtNwLine;
loop {
let length = {
let buffer = reader.fill_buf().unwrap();
let mut i = 0;
let mut newline = memchr2_iter(b'\n', b'\r', buffer);
let length = buffer.len();
while i < length {
if (buffer[i] == delim) & !delim_ws {
state = match state {
ParseState::CmtNwLine => {
field_counter = 1;
ParseState::Delim
}
ParseState::Delim => ParseState::Delim,
ParseState::Field => {
field_counter += 1;
ParseState::Delim
}
ParseState::Space => {
field_counter += 1;
ParseState::Delim
}
};
i += 1;
}
else if (buffer[i] == b' ') | (buffer[i] == b'\t') {
if delim_ws {
state = match state {
ParseState::CmtNwLine => {
field_counter = 1;
ParseState::Delim
}
ParseState::Delim => ParseState::Delim,
ParseState::Field => {
field_counter += 1;
ParseState::Delim
}
ParseState::Space => {
field_counter += 1;
ParseState::Delim
}
};
} else {
state = match state {
ParseState::CmtNwLine => ParseState::Space,
ParseState::Delim => ParseState::Space,
ParseState::Field => ParseState::Field,
ParseState::Space => ParseState::Space,
};
}
i += 1;
}
else if (buffer[i] == b'\n') | (buffer[i] == b'\r') | (buffer[i] == cmt) {
if field_counter == 0 {
let val = newline.next();
i = match val {
Some(val) => val + 1,
None => length + 1,
};
}
else {
if let ParseState::Delim = state { field_counter -= 1 };
return field_counter;
}
}
else {
state = match state {
ParseState::CmtNwLine => {
field_counter = 1;
ParseState::Field
}
ParseState::Delim => ParseState::Field,
ParseState::Field => ParseState::Field,
ParseState::Space => {
if field_counter == 0 {
field_counter += 1;
}
ParseState::Field
}
};
i += 1;
}
}
i - 1
};
reader.consume(length);
if length < BUF_SIZE {
break;
}
}
field_counter
}