use std::io::{self, Error, ErrorKind, Read, Write};
use super::Marshallable;
use crate::{kbucket::BinaryID, K_ID_LEN_BYTES, K_NONCE_LEN};
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Header {
pub(crate) binary_id: BinaryID,
pub(crate) sender_port: u16,
pub(crate) network_id: u8,
pub(crate) reserved: [u8; 2],
}
impl Header {
pub fn binary_id(&self) -> &BinaryID {
&self.binary_id
}
}
impl Marshallable for Header {
fn marshal_binary<W: Write>(&self, writer: &mut W) -> io::Result<()> {
if !self.binary_id.verify_nonce() {
return Err(Error::new(ErrorKind::Other, "Invalid Nonce"));
}
writer.write_all(self.binary_id.as_binary())?;
writer.write_all(self.binary_id.nonce())?;
writer.write_all(&self.sender_port.to_le_bytes())?;
writer.write_all(&[self.network_id])?;
writer.write_all(&self.reserved)?;
Ok(())
}
fn unmarshal_binary<R: Read>(reader: &mut R) -> io::Result<Self>
where
Self: Sized,
{
let mut id = [0; K_ID_LEN_BYTES];
reader.read_exact(&mut id)?;
let mut nonce = [0; K_NONCE_LEN];
reader.read_exact(&mut nonce)?;
let binary_id = BinaryID::from_nonce(id, nonce)?;
let mut port_buffer = [0; 2];
reader.read_exact(&mut port_buffer)?;
let sender_port = u16::from_le_bytes(port_buffer);
let mut network_id = [0; 1];
reader.read_exact(&mut network_id)?;
let network_id = network_id[0];
let mut reserved = [0; 2];
reader.read_exact(&mut reserved)?;
Ok(Header {
binary_id,
sender_port,
network_id,
reserved,
})
}
}