use bytes::{Bytes, Buf, BufMut}; use errors::*; use std::io::Cursor; mod std_impls; mod write; pub use self::write::*; pub trait DnsPacketData: Sized { fn deserialize(data: &mut Cursor) -> Result; fn serialize(&self, context: &mut DnsPacketWriteContext, packet: &mut Vec) -> Result<()>; } pub fn deserialize_with(data: Bytes, parser: F) -> Result where F: FnOnce(&mut Cursor) -> Result, { let mut c = Cursor::new(data); let result = parser(&mut c)?; ensure!(!c.has_remaining(), "data remaining: {} bytes", c.remaining()); Ok(result) } pub fn remaining_bytes(data: &mut Cursor) -> Bytes { let pos = data.position() as usize; let len = data.remaining(); let result = data.get_ref().slice(pos, pos + len); data.advance(len); result } pub fn short_blob(data: &mut Cursor) -> Result { check_enough_data!(data, 1, "short blob length"); let blob_len = data.get_u8() as usize; check_enough_data!(data, blob_len, "short blob content"); let pos = data.position() as usize; let blob = data.get_ref().slice(pos, pos + blob_len); data.advance(blob_len); Ok(blob) } pub fn write_short_blob(data: &[u8], packet: &mut Vec) -> Result<()> { ensure!(data.len() < 256, "short blob must be at most 255 bytes long"); packet.reserve(data.len() + 1); packet.put_u8(data.len() as u8); packet.put_slice(data); Ok(()) }