pub mod fwht;
pub mod h264;
use log::error;
use std::io;
pub trait StreamSplitter: Iterator<Item = Vec<u8>> {}
struct PatternSplitter<S: io::Read> {
pattern: Vec<u8>,
stream: io::Bytes<S>,
}
impl<S: io::Read> PatternSplitter<S> {
fn new(pattern: impl Into<Vec<u8>>, stream: S) -> Option<Self> {
let mut stream = stream.bytes();
let pattern = pattern.into();
let stream_start = (0..pattern.len())
.map(|_| stream.next().unwrap_or(Ok(0)).unwrap_or(0))
.collect::<Vec<_>>();
if stream_start == pattern {
Some(PatternSplitter { pattern, stream })
} else {
None
}
}
}
impl<S: io::Read> Iterator for PatternSplitter<S> {
type Item = Vec<u8>;
fn next(&mut self) -> Option<Self::Item> {
let mut frame_data: Vec<u8> = Vec::with_capacity(0x10000);
frame_data.extend(&self.pattern);
let mut header_window: Vec<u8> = Vec::with_capacity(self.pattern.len());
let mut header_iter = self.pattern.iter().peekable();
loop {
let b = match self.stream.next() {
Some(Ok(b)) => b,
None => {
frame_data.extend(&header_window);
return if frame_data.len() <= self.pattern.len() {
None
} else {
Some(frame_data)
};
}
Some(Err(e)) => {
error!("Error while reading stream: {}", e);
return None;
}
};
header_window.push(b);
if Some(&&b) == header_iter.peek() {
header_iter.next();
if header_iter.peek().is_none() {
return Some(frame_data);
}
} else {
frame_data.extend(&header_window);
if header_window.len() > 1 {
header_iter = self.pattern.iter().peekable();
}
header_window.clear();
}
}
}
}