diff --git a/ipc/codegen/src/serialization.rs b/ipc/codegen/src/serialization.rs index adcaaf2bf..bfaa8e7e0 100644 --- a/ipc/codegen/src/serialization.rs +++ b/ipc/codegen/src/serialization.rs @@ -301,6 +301,7 @@ fn binary_expr_variant( let type_name = ::syntax::print::pprust::ty_to_string(&ty); let variant_ident = variant.node.name; + let variant_index_ident = builder.id(format!("{}", variant_index)); match variant.node.data { ast::VariantData::Unit(_) => { @@ -310,7 +311,7 @@ fn binary_expr_variant( Ok(BinaryArm { size: quote_arm!(cx, $pat => { 0usize } ), - write: quote_arm!(cx, $pat => { Ok(()) } ), + write: quote_arm!(cx, $pat => { buffer[0] = $variant_index_ident; Ok(()) } ), read: quote_arm!(cx, $pat => { } ), }) }, @@ -336,11 +337,14 @@ fn binary_expr_variant( )); let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read); - - let variant_index_ident = builder.id(format!("{}", variant_index)); Ok(BinaryArm { size: quote_arm!(cx, $pat => { $size_expr } ), - write: quote_arm!(cx, $pat => { buffer[0] = $variant_index_ident; let buffer = &mut buffer[1..]; $write_expr } ), + write: quote_arm!(cx, + $pat => { + buffer[0] = $variant_index_ident; + let buffer = &mut buffer[1..]; + $write_expr + }), read: quote_arm!(cx, $pat => { $read_expr } ), }) } @@ -369,7 +373,12 @@ fn binary_expr_variant( let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read); Ok(BinaryArm { size: quote_arm!(cx, $pat => { $size_expr } ), - write: quote_arm!(cx, $pat => { $write_expr } ), + write: quote_arm!(cx, + $pat => { + buffer[0] = $variant_index_ident; + let buffer = &mut buffer[1..]; + $write_expr + }), read: quote_arm!(cx, $pat => { $read_expr } ), }) }, diff --git a/ipc/rpc/src/binary.rs b/ipc/rpc/src/binary.rs index 7f73c8242..02f0da954 100644 --- a/ipc/rpc/src/binary.rs +++ b/ipc/rpc/src/binary.rs @@ -27,6 +27,67 @@ pub trait BinaryConvertable : Sized { fn to_bytes(&self, buffer: &mut [u8]) -> Result<(), BinaryConvertError>; fn from_bytes(buffer: &[u8]) -> Result; + + fn from_empty_bytes() -> Result { + Err(BinaryConvertError) + } + + fn len_params() -> usize { + 0 + } +} + +impl BinaryConvertable for Option where T: BinaryConvertable { + fn size(&self) -> usize { + match * self { None => 0, Some(ref val) => val.size() } + } + + fn to_bytes(&self, buffer: &mut [u8]) -> Result<(), BinaryConvertError> { + match *self { None => Err(BinaryConvertError), Some(ref val) => val.to_bytes(buffer) } + } + + fn from_bytes(buffer: &[u8]) -> Result { + Ok(Some(try!(T::from_bytes(buffer)))) + } + + fn from_empty_bytes() -> Result { + Ok(None) + } + + fn len_params() -> usize { + 1 + } +} + +impl BinaryConvertable for Vec where T: BinaryConvertable { + fn size(&self) -> usize { + match T::len_params() { + 0 => mem::size_of::() * self.len(), + _ => self.iter().fold(0usize, |acc, t| acc + t.size()), + } + } + + fn to_bytes(&self, buffer: &mut [u8]) -> Result<(), BinaryConvertError> { + let mut offset = 0usize; + for (index, item) in self.iter().enumerate() { + let item_end = offset + item.size(); + try!(item.to_bytes(&mut buffer[offset..item_end])); + offset = item_end; + } + Ok(()) + } + + fn from_bytes(buffer: &[u8]) -> Result { + Err(BinaryConvertError) + } + + fn from_empty_bytes() -> Result { + Ok(Self::new()) + } + + fn len_params() -> usize { + 1 + } } macro_rules! binary_fixed_size {