don't create intermediate Vec's while serializing messages

This commit is contained in:
Milo Turner 2020-03-09 14:28:34 -04:00
parent 6652ddb3d1
commit 87fd190378
2 changed files with 19 additions and 12 deletions

View File

@ -17,7 +17,9 @@ pub struct DesError;
pub trait SerDes: Sized {
fn des(data: &[u8]) -> Result<Self, DesError>;
fn ser_into(self) -> Vec<u8>;
// `buf.len()` must be >= `MAX_SERIALIZED_SIZE`
fn ser_to(&self, buf: &mut [u8]) -> usize;
}
impl SerDes for UpMsg {
@ -25,23 +27,27 @@ impl SerDes for UpMsg {
Ok(UpMsg::Data(data.into()))
}
fn ser_into(self) -> Vec<u8> {
fn ser_to(&self, buf: &mut [u8]) -> usize {
match self {
UpMsg::Data(data) => data,
UpMsg::Data(data) => {
let len = data.len();
buf[..len].copy_from_slice(&data[..]);
len
}
}
}
}
impl SerDes for DownMsg {
fn des(data: &[u8]) -> Result<Self, DesError> {
if data == [0] {
Ok(DownMsg::Ack)
} else {
Err(DesError)
match data.first() {
Some(0) => Ok(DownMsg::Ack),
_ => Err(DesError),
}
}
fn ser_into(self) -> Vec<u8> {
vec![0]
fn ser_to(&self, buf: &mut [u8]) -> usize {
buf[0] = 0;
1
}
}

View File

@ -55,9 +55,10 @@ impl<F, T> Peer<F, T> {
where
F: SerDes,
{
let targ = self.targ.ok_or(SendError::NoTarget)?;
let data = msg.ser_into();
let _n_sent = self.sock.send_to(&data, targ).await?;
let mut buf = [0u8; msg::MAX_SERIALIZED_SIZE];
let len = msg.ser_to(&mut buf);
let who = self.targ.ok_or(SendError::NoTarget)?;
let _n_sent = self.sock.send_to(&buf[..len], who).await?;
Ok(())
}