1use crate::{parse_header, parse_record, Header, Record};
3use nom::{error::ErrorKind, number::Endianness, Err};
4use std::io::BufRead;
5
6#[derive(PartialEq, Debug)]
8pub enum Block {
9 Header(Header),
13 Record(Record),
17
18 Error(ErrorKind),
20}
21
22pub struct PcapIterator<T: BufRead> {
24 first_block: bool,
25 reader: T,
26 endianness: Endianness,
27 nano_sec: bool,
28}
29impl<T: BufRead> PcapIterator<T> {
30 pub fn new(stream: T) -> PcapIterator<T> {
31 PcapIterator {
32 first_block: true,
33 reader: stream,
34 endianness: Endianness::Big,
35 nano_sec: false,
36 }
37 }
38}
39
40impl<T: BufRead> Iterator for PcapIterator<T> {
41 type Item = Block;
42 fn next(&mut self) -> Option<Block> {
43 let first_block = self.first_block;
46 let endianness = self.endianness;
47 let nano_sec = self.nano_sec;
48
49 self.reader
50 .fill_buf()
51 .and_then(|b| {
52 (if first_block {
53 parse_header(b)
54 .and_then(|(u, h)| Ok(Some((b.len() - u.len(), Block::Header(h)))))
55 } else {
56 parse_record(b, endianness, nano_sec)
57 .and_then(|(u, r)| Ok(Some((b.len() - u.len(), Block::Record(r)))))
58 })
59 .or_else(|e| match e {
60 Err::Incomplete(_)
61 | Err::Error((_, ErrorKind::Complete))
62 | Err::Failure((_, ErrorKind::Complete)) => Ok(None),
63 Err::Error((_, e)) | Err::Failure((_, e)) => Ok(Some((0, Block::Error(e)))),
64 })
65 })
66 .unwrap_or(None)
67 .and_then(|(c, block)| {
68 self.first_block = false;
69 if c != 0 {
70 self.reader.consume(c);
71 }
72 if let Block::Header(ref h) = block {
73 self.endianness = h.endianness;
74 self.nano_sec = h.nano_sec;
75 }
76 Some(block)
77 })
78 }
79}