use std::{ io::{BufRead, Read, Result, Write}, net::Ipv4Addr, }; pub fn write(mut writer: W, v: &[u8]) -> Result<()> { writer.write_all(v) } pub fn write_u8(mut writer: W, v: u8) -> Result<()> { writer.write_all(&[v]) } pub fn write_u16(mut writer: W, v: u16) -> Result<()> { writer.write_all(&u16::to_be_bytes(v)) } pub fn write_u32(mut writer: W, v: u32) -> Result<()> { writer.write_all(&u32::to_be_bytes(v)) } pub fn write_ipv4(mut writer: W, v: Ipv4Addr) -> Result<()> { writer.write_all(&v.octets()) } pub fn write_null_terminated_string(mut writer: W, v: &str) -> Result<()> { writer.write_all(v.as_bytes())?; writer.write_all(&[0u8]) } pub fn read_u8(mut reader: R) -> Result { let mut buf = [0u8; 1]; reader.read_exact(&mut buf)?; Ok(buf[0]) } pub fn read_u16(mut reader: R) -> Result { let mut buf = [0u8; 2]; reader.read_exact(&mut buf)?; Ok(u16::from_be_bytes(buf)) } pub fn read_u32(mut reader: R) -> Result { let mut buf = [0u8; 4]; reader.read_exact(&mut buf)?; Ok(u32::from_be_bytes(buf)) } pub fn read_arr(mut reader: R) -> Result<[u8; N]> { let mut buf = [0u8; N]; reader.read_exact(&mut buf)?; Ok(buf) } pub fn read_null_terminated_vec(mut reader: R) -> Result> { let mut buf = Vec::default(); reader.read_until(0, &mut buf)?; buf.pop(); Ok(buf) } pub fn read_null_terminated_string(reader: R) -> Result { let buf = read_null_terminated_vec(reader)?; Ok(String::from_utf8(buf).unwrap()) } pub fn read_len8_prefixed_vec(mut reader: R) -> Result> { let len = read_u8(&mut reader)?; let mut buf = vec![0u8; len as usize]; reader.read_exact(&mut buf)?; Ok(buf) } pub fn read_len8_prefixed_string(reader: R) -> Result { let buf = read_len8_prefixed_vec(reader)?; Ok(String::from_utf8(buf).unwrap()) } pub fn read_ipv4(reader: R) -> Result { Ok(Ipv4Addr::from_octets(read_arr(reader)?)) }