use crate::blocks::PcapBlockOwned;
use crate::error::PcapError;
use crate::pcapng::*;
use crate::traits::PcapReaderIterator;
use circular::Buffer;
use nom::{Needed, Offset};
use std::io::Read;
pub struct PcapNGReader<R>
where
R: Read,
{
info: CurrentSectionInfo,
reader: R,
buffer: Buffer,
consumed: usize,
reader_exhausted: bool,
}
impl<R> PcapNGReader<R>
where
R: Read,
{
pub fn new(capacity: usize, reader: R) -> Result<PcapNGReader<R>, PcapError<&'static [u8]>> {
let buffer = Buffer::with_capacity(capacity);
Self::from_buffer(buffer, reader)
}
pub fn from_buffer(
mut buffer: Buffer,
mut reader: R,
) -> Result<PcapNGReader<R>, PcapError<&'static [u8]>> {
let sz = reader.read(buffer.space()).or(Err(PcapError::ReadError))?;
buffer.fill(sz);
let (_rem, _shb) = match parse_sectionheaderblock(buffer.data()) {
Ok((r, h)) => Ok((r, h)),
Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => Err(e.to_owned_vec()),
Err(nom::Err::Incomplete(Needed::Size(n))) => Err(PcapError::Incomplete(n.into())),
Err(nom::Err::Incomplete(Needed::Unknown)) => Err(PcapError::Incomplete(0)),
}?;
let info = CurrentSectionInfo::default();
Ok(PcapNGReader {
info,
reader,
buffer,
consumed: 0,
reader_exhausted: false,
})
}
}
impl<R> PcapReaderIterator for PcapNGReader<R>
where
R: Read,
{
fn next(&mut self) -> Result<(usize, PcapBlockOwned<'_>), PcapError<&[u8]>> {
if self.buffer.available_data() == 0
&& (self.buffer.position() == 0 && self.reader_exhausted)
{
return Err(PcapError::Eof);
}
let data = self.buffer.data();
let parse = if self.info.big_endian {
parse_block_be
} else {
parse_block_le
};
match parse(data) {
Ok((rem, b)) => {
let offset = data.offset(rem);
if let Block::SectionHeader(ref shb) = b {
self.info.big_endian = shb.big_endian();
}
Ok((offset, PcapBlockOwned::from(b)))
}
Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => Err(e),
Err(nom::Err::Incomplete(n)) => {
if self.reader_exhausted {
Err(PcapError::UnexpectedEof)
} else {
match n {
Needed::Size(n) => {
if self.buffer.available_data() + usize::from(n)
>= self.buffer.capacity()
{
Err(PcapError::BufferTooSmall)
} else {
Err(PcapError::Incomplete(n.into()))
}
}
Needed::Unknown => Err(PcapError::Incomplete(0)),
}
}
}
}
}
fn consume(&mut self, offset: usize) {
self.consumed += offset;
self.buffer.consume(offset);
}
fn consume_noshift(&mut self, offset: usize) {
self.consumed += offset;
self.buffer.consume_noshift(offset);
}
fn consumed(&self) -> usize {
self.consumed
}
fn refill(&mut self) -> Result<(), PcapError<&[u8]>> {
self.buffer.shift();
let space = self.buffer.space();
if space.is_empty() {
return Ok(());
}
let sz = self.reader.read(space).or(Err(PcapError::ReadError))?;
self.reader_exhausted = sz == 0;
self.buffer.fill(sz);
Ok(())
}
fn position(&self) -> usize {
self.buffer.position()
}
fn grow(&mut self, new_size: usize) -> bool {
self.buffer.grow(new_size)
}
fn data(&self) -> &[u8] {
self.buffer.data()
}
fn reader_exhausted(&self) -> bool {
self.reader_exhausted
}
}