use crate::cursor::Cursor;
use crate::Input;
#[cfg_attr(feature = "perf-inline", inline(always))]
pub(crate) fn find_fwd_imp(needles: &[u8], haystack: &[u8], at: usize) -> Option<usize> {
let bs = needles;
let i = match needles.len() {
1 => memchr::memchr(bs[0], &haystack[at..])?,
2 => memchr::memchr2(bs[0], bs[1], &haystack[at..])?,
3 => memchr::memchr3(bs[0], bs[1], bs[2], &haystack[at..])?,
0 => panic!("cannot find with empty needles"),
n => panic!("invalid needles length: {}", n),
};
Some(at + i)
}
#[cfg_attr(feature = "perf-inline", inline(always))]
pub(crate) fn find_fwd<C: Cursor>(
needles: &[u8],
input: &mut Input<C>,
at: usize,
) -> Option<usize> {
if let Some(pos) = find_fwd_imp(needles, input.chunk(), at) {
return Some(pos);
}
while input.chunk_offset() + input.chunk().len() < input.end() && input.advance() {
if let Some(pos) = find_fwd_imp(needles, input.chunk(), 0) {
return Some(pos);
}
}
None
}
#[cfg_attr(feature = "perf-inline", inline(always))]
pub(crate) fn find_rev_imp(needles: &[u8], haystack: &[u8], at: usize) -> Option<usize> {
let bs = needles;
match needles.len() {
1 => memchr::memrchr(bs[0], &haystack[..at]),
2 => memchr::memrchr2(bs[0], bs[1], &haystack[..at]),
3 => memchr::memrchr3(bs[0], bs[1], bs[2], &haystack[..at]),
0 => panic!("cannot find with empty needles"),
n => panic!("invalid needles length: {}", n),
}
}
#[cfg_attr(feature = "perf-inline", inline(always))]
pub(crate) fn find_rev<C: Cursor>(
needles: &[u8],
input: &mut Input<C>,
at: usize,
) -> Option<usize> {
if let Some(pos) = find_rev_imp(needles, input.chunk(), at) {
return Some(pos);
}
while input.start() < input.chunk_offset() && input.backtrack() {
if let Some(pos) = find_rev_imp(needles, input.chunk(), input.chunk().len()) {
return Some(pos);
}
}
None
}