// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Parity is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Parity. If not, see . //! Binary representation of types use util::{U256, U512, H256, H512, H2048, Address}; use std::mem; use std::collections::{VecDeque, BTreeMap}; use std::ops::Range; use super::Handshake; #[derive(Debug)] pub enum BinaryConvertErrorKind { SizeMismatch { expected: usize, found: usize, }, TargetPayloadEmpty, UnexpectedVariant(u8), MissingLengthValue, InconsistentBoundaries, NotSupported, } #[derive(Debug)] pub struct BinaryConvertError { member_tree: Vec<&'static str>, kind: BinaryConvertErrorKind, } impl BinaryConvertError { pub fn size(expected: usize, found: usize) -> BinaryConvertError { BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::SizeMismatch { expected: expected, found: found, } } } pub fn empty() -> BinaryConvertError { BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::TargetPayloadEmpty } } pub fn variant(val: u8) -> BinaryConvertError { BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::UnexpectedVariant(val) } } pub fn length() -> BinaryConvertError { BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::MissingLengthValue } } pub fn boundaries() -> BinaryConvertError { BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::InconsistentBoundaries } } pub fn not_supported() -> BinaryConvertError { BinaryConvertError { member_tree: Vec::new(), kind: BinaryConvertErrorKind::NotSupported } } pub fn named(mut self, name: &'static str) -> BinaryConvertError { self.member_tree.push(name); self } } #[derive(Debug)] pub enum BinaryError { Serialization(BinaryConvertError), Io(::std::io::Error), } impl From<::std::io::Error> for BinaryError { fn from(err: ::std::io::Error) -> Self { BinaryError::Io(err) } } impl From for BinaryError { fn from(err: BinaryConvertError) -> Self { BinaryError::Serialization(err) } } pub trait BinaryConvertable : Sized { fn size(&self) -> usize { mem::size_of::() } fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError>; fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result; fn from_empty_bytes() -> Result { Err(BinaryConvertError::size(mem::size_of::(), 0)) } 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], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { match *self { None => Err(BinaryConvertError::empty()), Some(ref val) => val.to_bytes(buffer, length_stack) } } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { if buffer.len() == 0 { return Self::from_empty_bytes(); } Ok(Some(try!(T::from_bytes(buffer, length_stack)))) } fn from_empty_bytes() -> Result { Ok(None) } fn len_params() -> usize { 1 } } impl BinaryConvertable for Result<(), E> { fn size(&self) -> usize { match *self { Ok(_) => 0, Err(ref e) => e.size(), } } fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { match *self { Ok(_) => Err(BinaryConvertError::empty()), Err(ref e) => Ok(try!(e.to_bytes(buffer, length_stack))), } } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { Ok(Err(try!(E::from_bytes(&buffer, length_stack)))) } fn from_empty_bytes() -> Result { Ok(Ok(())) } fn len_params() -> usize { 1 } } impl BinaryConvertable for Result { fn size(&self) -> usize { match *self { Ok(ref r) => r.size(), Err(_) => 0, } } fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { match *self { Ok(ref r) => Ok(try!(r.to_bytes(buffer, length_stack))), Err(_) => Err(BinaryConvertError::empty()), } } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { Ok(Ok(try!(R::from_bytes(&buffer, length_stack)))) } fn from_empty_bytes() -> Result { Ok(Err(())) } fn len_params() -> usize { 1 } } impl BinaryConvertable for Result { fn size(&self) -> usize { 1usize + match *self { Ok(ref r) => r.size(), Err(ref e) => e.size(), } } fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { match *self { Ok(ref r) => { buffer[0] = 0; if r.size() > 0 { Ok(try!(r.to_bytes(&mut buffer[1..], length_stack))) } else { Ok(()) } }, Err(ref e) => { buffer[0] = 1; if e.size() > 0 { Ok(try!(e.to_bytes(&mut buffer[1..], length_stack))) } else { Ok(()) } }, } } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { match buffer[0] { 0 => { match buffer.len() { 1 => Ok(Ok(try!(R::from_empty_bytes()))), _ => Ok(Ok(try!(R::from_bytes(&buffer[1..], length_stack)))), } } 1 => Ok(Err(try!(E::from_bytes(&buffer[1..], length_stack)))), _ => Err(BinaryConvertError::variant(buffer[0])) } } fn len_params() -> usize { 1 } } impl BinaryConvertable for BTreeMap where K : BinaryConvertable + Ord, V: BinaryConvertable { fn size(&self) -> usize { 0usize + match K::len_params() { 0 => mem::size_of::() * self.len(), _ => self.iter().fold(0usize, |acc, (k, _)| acc + k.size()) } + match V::len_params() { 0 => mem::size_of::() * self.len(), _ => self.iter().fold(0usize, |acc, (_, v)| acc + v.size()) } } fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { let mut offset = 0usize; for (key, val) in self.iter() { let key_size = match K::len_params() { 0 => mem::size_of::(), _ => { let size = key.size(); length_stack.push_back(size); size } }; let val_size = match K::len_params() { 0 => mem::size_of::(), _ => { let size = val.size(); length_stack.push_back(size); size } }; if key_size > 0 { let item_end = offset + key_size; try!(key.to_bytes(&mut buffer[offset..item_end], length_stack)); offset = item_end; } if val_size > 0 { let item_end = offset + key_size; try!(val.to_bytes(&mut buffer[offset..item_end], length_stack)); offset = item_end; } } Ok(()) } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { let mut index = 0; let mut result = Self::new(); if buffer.len() == 0 { return Ok(result); } loop { let key_size = match K::len_params() { 0 => mem::size_of::(), _ => try!(length_stack.pop_front().ok_or(BinaryConvertError::length())), }; let key = if key_size == 0 { try!(K::from_empty_bytes()) } else { if index + key_size > buffer.len() { return Err(BinaryConvertError::boundaries()) } try!(K::from_bytes(&buffer[index..index+key_size], length_stack)) }; index = index + key_size; let val_size = match V::len_params() { 0 => mem::size_of::(), _ => try!(length_stack.pop_front().ok_or(BinaryConvertError::length())), }; let val = if val_size == 0 { try!(V::from_empty_bytes()) } else { if index + val_size > buffer.len() { return Err(BinaryConvertError::boundaries()) } try!(V::from_bytes(&buffer[index..index+val_size], length_stack)) }; result.insert(key, val); index = index + val_size; if index == buffer.len() { break; } if index > buffer.len() { return Err(BinaryConvertError::boundaries()) } } Ok(result) } fn from_empty_bytes() -> Result { Ok(Self::new()) } fn len_params() -> usize { 1 } } impl BinaryConvertable for VecDeque 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], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { let mut offset = 0usize; for item in self.iter() { let next_size = match T::len_params() { 0 => mem::size_of::(), _ => { let size = item.size(); length_stack.push_back(size); size }, }; if next_size > 0 { let item_end = offset + next_size; try!(item.to_bytes(&mut buffer[offset..item_end], length_stack)); offset = item_end; } } Ok(()) } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { let mut index = 0; let mut result = Self::with_capacity( match T::len_params() { 0 => buffer.len() / mem::size_of::(), _ => 128, }); if buffer.len() == 0 { return Ok(result); } loop { let next_size = match T::len_params() { 0 => mem::size_of::(), _ => try!(length_stack.pop_front().ok_or(BinaryConvertError::length())), }; let item = if next_size == 0 { try!(T::from_empty_bytes()) } else { if index + next_size > buffer.len() { return Err(BinaryConvertError::boundaries()) } try!(T::from_bytes(&buffer[index..index+next_size], length_stack)) }; result.push_back(item); index = index + next_size; if index == buffer.len() { break; } if index > buffer.len() { return Err(BinaryConvertError::boundaries()) } } Ok(result) } fn from_empty_bytes() -> Result { Ok(Self::new()) } 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], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { let mut offset = 0usize; for item in self.iter() { let next_size = match T::len_params() { 0 => mem::size_of::(), _ => { let size = item.size(); length_stack.push_back(size); size }, }; if next_size > 0 { let item_end = offset + next_size; try!(item.to_bytes(&mut buffer[offset..item_end], length_stack)); offset = item_end; } } Ok(()) } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { let mut index = 0; let mut result = Self::with_capacity( match T::len_params() { 0 => buffer.len() / mem::size_of::(), _ => 128, }); if buffer.len() == 0 { return Ok(result); } loop { let next_size = match T::len_params() { 0 => mem::size_of::(), _ => try!(length_stack.pop_front().ok_or(BinaryConvertError::length())), }; let item = if next_size == 0 { try!(T::from_empty_bytes()) } else { if index + next_size > buffer.len() { return Err(BinaryConvertError::boundaries()) } try!(T::from_bytes(&buffer[index..index+next_size], length_stack)) }; result.push(item); index = index + next_size; if index == buffer.len() { break; } if index > buffer.len() { return Err(BinaryConvertError::boundaries()) } } Ok(result) } fn from_empty_bytes() -> Result { Ok(Self::new()) } fn len_params() -> usize { 1 } } impl BinaryConvertable for String { fn size(&self) -> usize { self.as_bytes().len() } fn from_empty_bytes() -> Result { Ok(String::new()) } fn to_bytes(&self, buffer: &mut [u8], _length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { buffer[..].clone_from_slice(self.as_bytes()); Ok(()) } fn from_bytes(buffer: &[u8], _length_stack: &mut VecDeque) -> Result { Ok(::std::str::from_utf8(buffer).unwrap().to_owned()) } fn len_params() -> usize { 1 } } impl BinaryConvertable for Range where T: BinaryConvertable { fn size(&self) -> usize { mem::size_of::() * 2 } fn from_empty_bytes() -> Result { Err(BinaryConvertError::empty()) } fn to_bytes(&self, buffer: &mut[u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { try!(self.start.to_bytes(&mut buffer[..mem::size_of::()], length_stack)); try!(self.end.to_bytes(&mut buffer[mem::size_of::() + 1..], length_stack)); Ok(()) } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { Ok(try!(T::from_bytes(&buffer[..mem::size_of::()], length_stack))..try!(T::from_bytes(&buffer[mem::size_of::()+1..], length_stack))) } fn len_params() -> usize { assert_eq!(0, T::len_params()); 0 } } impl BinaryConvertable for ::std::cell::RefCell where T: BinaryConvertable { fn size(&self) -> usize { self.borrow().size() } fn from_empty_bytes() -> Result { Ok(::std::cell::RefCell::new(try!(T::from_empty_bytes()))) } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { Ok(::std::cell::RefCell::new(try!(T::from_bytes(buffer, length_stack)))) } fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { try!(self.borrow().to_bytes(buffer, length_stack)); Ok(()) } fn len_params() -> usize { T::len_params() } } impl BinaryConvertable for ::std::cell::Cell where T: BinaryConvertable + Copy { fn size(&self) -> usize { self.get().size() } fn from_empty_bytes() -> Result { Ok(::std::cell::Cell::new(try!(T::from_empty_bytes()))) } fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { Ok(::std::cell::Cell::new(try!(T::from_bytes(buffer, length_stack)))) } fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { try!(self.get().to_bytes(buffer, length_stack)); Ok(()) } fn len_params() -> usize { T::len_params() } } impl BinaryConvertable for Vec { fn size(&self) -> usize { self.len() } fn from_empty_bytes() -> Result { Ok(Vec::new()) } fn to_bytes(&self, buffer: &mut [u8], _length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { buffer[..].clone_from_slice(&self[..]); Ok(()) } fn from_bytes(buffer: &[u8], _length_stack: &mut VecDeque) -> Result { let mut res = Self::with_capacity(buffer.len()); unsafe { res.set_len(buffer.len()) } res[..].clone_from_slice(&buffer[..]); Ok(res) } fn len_params() -> usize { 1 } } pub fn deserialize_from(r: &mut R) -> Result where R: ::std::io::Read, T: BinaryConvertable { let mut fake_stack = VecDeque::new(); match T::len_params() { 0 => { let fixed_size = mem::size_of::(); let mut payload_buffer = Vec::with_capacity(fixed_size); unsafe { payload_buffer.set_len(fixed_size); } let bytes_read = try!(r.read(&mut payload_buffer)); if bytes_read != mem::size_of::() { return Err(BinaryError::Serialization(BinaryConvertError::size(fixed_size, bytes_read))) } Ok(try!(T::from_bytes(&payload_buffer[..], &mut fake_stack))) }, _ => { let mut payload = Vec::new(); try!(r.read_to_end(&mut payload)); let stack_len = try!(u64::from_bytes(&payload[0..8], &mut fake_stack)) as usize; let mut length_stack = VecDeque::::with_capacity(stack_len); if stack_len > 0 { for idx in 0..stack_len { let stack_item = try!(u64::from_bytes(&payload[8 + idx*8..8 + (idx+1)*8], &mut fake_stack)); length_stack.push_back(stack_item as usize); } } //try!(r.read(&mut size_buffer).map_err(|_| BinaryConvertError)); let size = try!(u64::from_bytes(&payload[8+stack_len*8..16+stack_len*8], &mut fake_stack)) as usize; match size { 0 => { Ok(try!(T::from_empty_bytes())) }, _ => { Ok(try!(T::from_bytes(&payload[16+stack_len*8..], &mut length_stack))) } } }, } } pub fn deserialize(buffer: &[u8]) -> Result { use std::io::Cursor; let mut buff = Cursor::new(buffer); deserialize_from::(&mut buff) } pub fn serialize_into(t: &T, w: &mut W) -> Result<(), BinaryError> where W: ::std::io::Write, T: BinaryConvertable { let mut fake_stack = VecDeque::new(); match T::len_params() { 0 => { let fixed_size = mem::size_of::(); let mut buffer = Vec::with_capacity(fixed_size); unsafe { buffer.set_len(fixed_size); } try!(t.to_bytes(&mut buffer[..], &mut fake_stack)); try!(w.write(&buffer[..])); Ok(()) }, _ => { let mut length_stack = VecDeque::::new(); let mut size_buffer = [0u8; 8]; let size = t.size(); if size == 0 { try!(w.write(&size_buffer)); try!(w.write(&size_buffer)); return Ok(()); } let mut buffer = Vec::with_capacity(size); unsafe { buffer.set_len(size); } try!(t.to_bytes(&mut buffer[..], &mut length_stack)); let stack_len = length_stack.len(); try!((stack_len as u64).to_bytes(&mut size_buffer[..], &mut fake_stack)); try!(w.write(&size_buffer[..])); if stack_len > 0 { let mut header_buffer = Vec::with_capacity(stack_len * 8); unsafe { header_buffer.set_len(stack_len * 8); }; try!((stack_len as u64).to_bytes(&mut header_buffer[0..8], &mut fake_stack)); let mut idx = 0; loop { match length_stack.pop_front() { Some(val) => try!((val as u64).to_bytes(&mut header_buffer[idx * 8..(idx+1) * 8], &mut fake_stack)), None => { break; } } idx = idx + 1; } try!(w.write(&header_buffer[..])); } try!((size as u64).to_bytes(&mut size_buffer[..], &mut fake_stack)); try!(w.write(&size_buffer[..])); try!(w.write(&buffer[..])); Ok(()) }, } } pub fn serialize(t: &T) -> Result, BinaryError> { use std::io::Cursor; let mut buff = Cursor::new(Vec::new()); try!(serialize_into(t, &mut buff)); let into_inner = buff.into_inner(); Ok(into_inner) } #[macro_export] macro_rules! binary_fixed_size { ($target_ty: ty) => { impl BinaryConvertable for $target_ty where $target_ty: Copy { fn from_bytes(bytes: &[u8], _length_stack: &mut ::std::collections::VecDeque) -> Result { let size = ::std::mem::size_of::<$target_ty>(); match bytes.len().cmp(&size) { ::std::cmp::Ordering::Equal => (), _ => return Err(BinaryConvertError::size(size, bytes.len())), }; let res: Self = unsafe { let mut temp = ::std::mem::zeroed(); let temp_ptr = &mut temp as *mut _ as *mut u8; ::std::ptr::copy_nonoverlapping(bytes.as_ptr(), temp_ptr, size); temp }; Ok(res) } fn to_bytes(&self, buffer: &mut [u8], _length_stack: &mut ::std::collections::VecDeque) -> Result<(), BinaryConvertError> { let sz = ::std::mem::size_of::<$target_ty>(); let ip: *const $target_ty = self; let ptr: *const u8 = ip as *const _; unsafe { ::std::ptr::copy(ptr, buffer.as_mut_ptr(), sz); } Ok(()) } } } } /// Fixed-sized version of Handshake struct #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct BinHandshake { api_version: BinVersion, protocol_version: BinVersion, } /// Shorten version of semver Version without `pre` and `build` information #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct BinVersion { pub major: u64, pub minor: u64, pub patch: u64, } impl From for BinHandshake { fn from(other: Handshake) -> Self { BinHandshake { api_version: BinVersion::from(other.api_version), protocol_version: BinVersion::from(other.protocol_version), } } } impl BinHandshake { pub fn to_semver(self) -> Handshake { Handshake { api_version: self.api_version.to_semver(), protocol_version: self.protocol_version.to_semver(), } } } impl BinVersion { pub fn to_semver(self) -> ::semver::Version { ::semver::Version { major: self.major, minor: self.minor, patch: self.patch, pre: vec![], build: vec![], } } } impl From<::semver::Version> for BinVersion { fn from(other: ::semver::Version) -> Self { BinVersion { major: other.major, minor: other.minor, patch: other.patch, } } } binary_fixed_size!(u16); binary_fixed_size!(u64); binary_fixed_size!(u32); binary_fixed_size!(usize); binary_fixed_size!(i32); binary_fixed_size!(bool); binary_fixed_size!(U256); binary_fixed_size!(U512); binary_fixed_size!(H256); binary_fixed_size!(H512); binary_fixed_size!(H2048); binary_fixed_size!(Address); binary_fixed_size!(BinHandshake); binary_fixed_size!(BinVersion); impl BinaryConvertable for ::semver::Version { fn from_bytes(bytes: &[u8], length_stack: &mut ::std::collections::VecDeque) -> Result { BinVersion::from_bytes(bytes, length_stack).map(BinVersion::to_semver) } fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut ::std::collections::VecDeque) -> Result<(), BinaryConvertError> { BinVersion::from(self.clone()).to_bytes(buffer, length_stack) } } #[test] fn vec_serialize() { let mut v = Vec::new(); v.push(5u64); v.push(10u64); let mut length_stack = VecDeque::new(); let mut data = Vec::with_capacity(v.size()); unsafe { data.set_len(v.size()); } let result = v.to_bytes(&mut data[..], &mut length_stack); assert!(result.is_ok()); assert_eq!(5, data[0]); assert_eq!(0, data[1]); assert_eq!(10, data[8]); assert_eq!(0, data[12]); } #[test] fn calculates_size() { let mut v = Vec::new(); v.push(5u64); v.push(10u64); assert_eq!(16, v.size()); } #[test] fn vec_deserialize() { let data = [ 10u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, ]; let mut length_stack = VecDeque::new(); let vec = Vec::::from_bytes(&data[..], &mut length_stack).unwrap(); assert_eq!(vec![10u64, 5u64], vec); } #[test] fn vec_deserialize_chained() { let mut v = Vec::new(); v.push(Some(5u64)); v.push(Some(10u64)); v.push(None); v.push(Some(12u64)); let mut length_stack = VecDeque::new(); let mut data = Vec::with_capacity(v.size()); unsafe { data.set_len(v.size()); } let result = v.to_bytes(&mut data[..], &mut length_stack); assert!(result.is_ok()); assert_eq!(4, length_stack.len()); } #[test] fn vec_serialize_deserialize() { let mut v = Vec::new(); v.push(Some(5u64)); v.push(None); v.push(Some(10u64)); v.push(None); v.push(Some(12u64)); let mut data = Vec::with_capacity(v.size()); unsafe { data.set_len(v.size()); } let mut length_stack = VecDeque::new(); v.to_bytes(&mut data[..], &mut length_stack).unwrap(); let de_v = Vec::>::from_bytes(&data[..], &mut length_stack).unwrap(); assert_eq!(v, de_v); } #[test] fn serialize_into_ok() { use std::io::Cursor; let mut buff = Cursor::new(vec![0; 128]); let mut v = Vec::new(); v.push(Some(5u64)); v.push(None); v.push(Some(10u64)); v.push(None); v.push(Some(12u64)); serialize_into(&v, &mut buff).unwrap(); assert_eq!(5, buff.get_ref()[0]); assert_eq!(8, buff.get_ref()[8]); assert_eq!(0, buff.get_ref()[16]); assert_eq!(8, buff.get_ref()[24]); } #[test] fn deserialize_from_ok() { use std::io::Cursor; let mut buff = Cursor::new(vec![ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 10u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, ]); let vec = deserialize_from::, _>(&mut buff).unwrap(); assert_eq!(vec![10u64, 5u64], vec); } #[test] fn serialize_into_deserialize_from() { use std::io::{Cursor, SeekFrom, Seek}; let mut buff = Cursor::new(Vec::new()); let mut v = Vec::new(); v.push(Some(5u64)); v.push(None); v.push(Some(10u64)); v.push(None); v.push(Some(12u64)); serialize_into(&v, &mut buff).unwrap(); buff.seek(SeekFrom::Start(0)).unwrap(); let de_v = deserialize_from::>, _>(&mut buff).unwrap(); assert_eq!(v, de_v); } #[test] fn serialize_vec_str() { // empty let source = Vec::::new(); let serialized = serialize(&source).unwrap(); let deserialized = deserialize::>(&serialized).unwrap(); assert_eq!(source, deserialized); // with few values let mut source = Vec::::new(); source.push("val1".to_owned()); source.push("val2".to_owned()); let serialized = serialize(&source).unwrap(); let deserialized = deserialize::>(&serialized).unwrap(); assert_eq!(source, deserialized); } #[test] fn serialize_opt_str() { // none let source: Option = None; let serialized = serialize(&source).unwrap(); let deserialized = deserialize::>(&serialized).unwrap(); assert_eq!(source, deserialized); // value let source: Option = Some("i have value".to_owned()); let serialized = serialize(&source).unwrap(); let deserialized = deserialize::>(&serialized).unwrap(); assert_eq!(source, deserialized); } #[test] fn serialize_opt_vec() { use std::io::Cursor; let mut buff = Cursor::new(Vec::new()); let optional_vec: Option> = None; serialize_into(&optional_vec, &mut buff).unwrap(); assert_eq!(&vec![0u8; 16], buff.get_ref()); } #[test] fn serialize_opt_vec_payload() { let optional_vec: Option> = None; let payload = serialize(&optional_vec).unwrap(); assert_eq!(vec![0u8;16], payload); } #[test] fn deserialize_opt_vec() { use std::io::Cursor; let mut buff = Cursor::new(vec![0u8; 16]); let vec = deserialize_from::>, _>(&mut buff).unwrap(); assert!(vec.is_none()); } #[test] fn deserialize_simple_err() { use std::io::Cursor; let mut buff = Cursor::new(vec![0u8; 16]); let result = deserialize_from::, _>(&mut buff).unwrap(); assert!(result.is_ok()); } #[test] fn serialize_opt_vec_in_out() { use std::io::{Cursor, SeekFrom, Seek}; let mut buff = Cursor::new(Vec::new()); let optional_vec: Option> = None; serialize_into(&optional_vec, &mut buff).unwrap(); buff.seek(SeekFrom::Start(0)).unwrap(); let vec = deserialize_from::>, _>(&mut buff).unwrap(); assert!(vec.is_none()); } #[test] fn serialize_err_opt_vec_in_out() { use std::io::{Cursor, SeekFrom, Seek}; let mut buff = Cursor::new(Vec::new()); let optional_vec: Result>, u32> = Ok(None); serialize_into(&optional_vec, &mut buff).unwrap(); buff.seek(SeekFrom::Start(0)).unwrap(); let vec = deserialize_from::>, u32>, _>(&mut buff).unwrap(); assert!(vec.is_ok()); } #[test] fn serialize_btree() { use std::io::{Cursor, SeekFrom, Seek}; let mut buff = Cursor::new(Vec::new()); let mut btree = BTreeMap::new(); btree.insert(1u64, 5u64); serialize_into(&btree, &mut buff).unwrap(); buff.seek(SeekFrom::Start(0)).unwrap(); let res = deserialize_from::, _>(&mut buff).unwrap(); assert_eq!(res[&1u64], 5u64); } #[test] fn serialize_refcell() { use std::cell::RefCell; let source = RefCell::new(vec![5u32, 12u32, 19u32]); let serialized = serialize(&source).unwrap(); let deserialized = deserialize::>>(&serialized).unwrap(); assert_eq!(source, deserialized); } #[test] fn serialize_cell() { use std::cell::Cell; use std::str::FromStr; let source = Cell::new(U256::from_str("01231231231239999").unwrap()); let serialized = serialize(&source).unwrap(); let deserialized = deserialize::>(&serialized).unwrap(); assert_eq!(source, deserialized); } #[test] fn serialize_handshake() { use std::io::{Cursor, SeekFrom, Seek}; let mut buff = Cursor::new(Vec::new()); let handshake = Handshake { api_version: ::semver::Version::parse("1.2.0").unwrap(), protocol_version: ::semver::Version::parse("1.2.0").unwrap(), }; serialize_into(&BinHandshake::from(handshake.clone()), &mut buff).unwrap(); buff.seek(SeekFrom::Start(0)).unwrap(); let res = deserialize_from::(&mut buff).unwrap().to_semver(); assert_eq!(res, handshake); } #[test] fn serialize_invalid_size() { // value let deserialized = deserialize::(&[]); match deserialized { Err(BinaryError::Serialization( BinaryConvertError { kind: BinaryConvertErrorKind::SizeMismatch { expected: 8, found: 0 }, member_tree: _ })) => {}, other => panic!("Not a size mismatched error but: {:?}", other), } } #[test] fn serialize_boundaries() { // value let deserialized = deserialize::>( &[ // payload header 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, // 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 4u8, 1u8, 1u8, /* not 4 bytes */ ] ); match deserialized { Err(BinaryError::Serialization( BinaryConvertError { kind: BinaryConvertErrorKind::InconsistentBoundaries, member_tree: _ })) => {}, other => panic!("Not an inconsistent boundaries error but: {:?}", other), } } #[test] fn serialize_empty_try() { // value let mut stack = VecDeque::new(); let mut data = vec![0u8; 16]; let sample: Option> = None; let serialized = sample.to_bytes(&mut data, &mut stack); match serialized { Err(BinaryConvertError { kind: BinaryConvertErrorKind::TargetPayloadEmpty, member_tree: _ }) => {}, other => panic!("Not an error about empty payload to be produced but: {:?}", other), } } #[test] fn serialize_not_enough_lengths() { // value let deserialized = deserialize::>>( &[ // payload header 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, // does not matter because no length param for the first option 0u8, ] ); match deserialized { Err(BinaryError::Serialization( BinaryConvertError { kind: BinaryConvertErrorKind::MissingLengthValue, member_tree: _ })) => {}, other => panic!("Not an missing length param error but: {:?}", other), } } #[test] fn vec_of_vecs() { let sample = vec![vec![5u8, 10u8], vec![], vec![9u8, 11u8]]; let serialized = serialize(&sample).unwrap(); let deserialized = deserialize::>>(&serialized).unwrap(); assert_eq!(sample, deserialized); // empty let sample: Vec> = vec![]; let serialized = serialize(&sample).unwrap(); let deserialized = deserialize::>>(&serialized).unwrap(); assert_eq!(sample, deserialized); }