use std::io::Write;
use byteorder_slice::{BigEndian, LittleEndian};
use super::RawPcapPacket;
use crate::errors::*;
use crate::pcap::{PcapHeader, PcapPacket};
use crate::{Endianness, TsResolution};
#[derive(Debug)]
pub struct PcapWriter<W: Write> {
endianness: Endianness,
snaplen: u32,
ts_resolution: TsResolution,
writer: W,
}
impl<W: Write> PcapWriter<W> {
pub fn new(writer: W) -> PcapResult<PcapWriter<W>> {
let header = PcapHeader { endianness: Endianness::native(), ..Default::default() };
PcapWriter::with_header(writer, header)
}
pub fn with_header(mut writer: W, header: PcapHeader) -> PcapResult<PcapWriter<W>> {
header.write_to(&mut writer)?;
Ok(PcapWriter {
endianness: header.endianness,
snaplen: header.snaplen,
ts_resolution: header.ts_resolution,
writer,
})
}
pub fn into_writer(self) -> W {
self.writer
}
pub fn write_packet(&mut self, packet: &PcapPacket) -> PcapResult<usize> {
if packet.len() > self.snaplen {
return Err(PcapError::PacketTooLarge(packet.len(), self.snaplen));
}
let raw_packet = packet.as_raw_packet(self.ts_resolution);
self.write_raw_packet(&raw_packet)
}
pub fn write_raw_packet(&mut self, packet: &RawPcapPacket) -> PcapResult<usize> {
match self.endianness {
Endianness::Big => packet.write_to::<_, BigEndian>(&mut self.writer),
Endianness::Little => packet.write_to::<_, LittleEndian>(&mut self.writer),
}
}
pub fn flush(&mut self) -> PcapResult<()> {
self.writer.flush().map_err(PcapError::IoError)
}
pub fn endianness(&self) -> Endianness {
self.endianness
}
pub fn snaplen(&self) -> u32 {
self.snaplen
}
pub fn ts_resolution(&self) -> TsResolution {
self.ts_resolution
}
}