diff --git a/substrate/runtime-codec/src/lib.rs b/substrate/runtime-codec/src/lib.rs index f31fa3cf94..0599953156 100644 --- a/substrate/runtime-codec/src/lib.rs +++ b/substrate/runtime-codec/src/lib.rs @@ -28,7 +28,6 @@ mod keyedvec; pub use self::endiansensitive::EndianSensitive; pub use self::slicable::{Slicable, NonTrivialSlicable}; -pub use self::streamreader::StreamReader; pub use self::joiner::Joiner; pub use self::keyedvec::KeyedVec; diff --git a/substrate/runtime-codec/src/slicable.rs b/substrate/runtime-codec/src/slicable.rs index 82b527c771..1d76fb851e 100644 --- a/substrate/runtime-codec/src/slicable.rs +++ b/substrate/runtime-codec/src/slicable.rs @@ -23,115 +23,108 @@ use super::endiansensitive::EndianSensitive; /// Trait that allows zero-copy read/write of value-references to/from slices in LE format. pub trait Slicable: Sized { - /// Attempt to deserialise the value from a slice. - fn from_slice(value: &[u8]) -> Option { - Self::set_as_slice(|out, offset| if value.len() >= out.len() + offset { - let value = &value[offset..]; - let len = out.len(); - out.copy_from_slice(&value[0..len]); - true - } else { - false - }) - } + /// Attempt to deserialise the value from a slice. Ignore trailing bytes and + /// set the slice's start to just after the last byte consumed. + /// + /// If `None` is returned, then the slice should be unmodified. + fn from_slice(value: &mut &[u8]) -> Option; + /// Convert self to an owned vector. fn to_vec(&self) -> Vec { self.as_slice_then(|s| s.to_vec()) } - fn set_as_slice bool>(fill_slice: F) -> Option; - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec()) - } - fn size_of(_value: &[u8]) -> Option; + /// Convert self to a slice and then invoke the given closure with it. + fn as_slice_then R>(&self, f: F) -> R; } /// Trait to mark that a type is not trivially (essentially "in place") serialisable. pub trait NonTrivialSlicable: Slicable {} impl Slicable for T { - fn set_as_slice bool>(fill_slice: F) -> Option { + fn from_slice(value: &mut &[u8]) -> Option { let size = mem::size_of::(); assert!(size > 0, "EndianSensitive can never be implemented for a zero-sized type."); - let mut result: T = unsafe { mem::zeroed() }; - let result_slice = unsafe { - let ptr = &mut result as *mut _ as *mut u8; - slice::from_raw_parts_mut(ptr, size) - }; - if fill_slice(result_slice, 0) { - Some(result.from_le()) + if value.len() >= size { + let x: T = unsafe { ::std::ptr::read(value.as_ptr() as *const T) }; + *value = &value[size..]; + Some(x.from_le()) } else { None } } + fn as_slice_then R>(&self, f: F) -> R { - let size = mem::size_of::(); - assert!(size > 0, "EndianSensitive can never be implemented for a zero-sized type."); self.as_le_then(|le| { + let size = mem::size_of::(); let value_slice = unsafe { let ptr = le as *const _ as *const u8; - slice::from_raw_parts(ptr, size) + if size != 0 { + slice::from_raw_parts(ptr, size) + } else { + &[] + } }; + f(value_slice) }) } - fn size_of(_value: &[u8]) -> Option { - Some(mem::size_of::()) - } } impl Slicable for Vec { - fn from_slice(value: &[u8]) -> Option { - Some(value[4..].to_vec()) - } - fn set_as_slice bool>(fill_slice: F) -> Option { - u32::set_as_slice(&fill_slice).and_then(|len| { - let mut v = Vec::with_capacity(len as usize); - unsafe { v.set_len(len as usize); } - if fill_slice(&mut v, 4) { - Some(v) - } else { - None - } + fn from_slice(value: &mut &[u8]) -> Option { + u32::from_slice(value).map(move |len| { + let len = len as usize; + let res = value[..len].to_vec(); + *value = &value[len..]; + res }) } - fn to_vec(&self) -> Vec { - let mut r: Vec = Vec::new().join(&(self.len() as u32)); - r.extend_from_slice(&self); - r + fn as_slice_then R>(&self, f: F) -> R { + f(&self.to_vec()) } - fn size_of(data: &[u8]) -> Option { - u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) + + fn to_vec(&self) -> Vec { + let len = self.len(); + assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements."); + + let mut r: Vec = Vec::new().join(&(len as u32)); + r.extend_from_slice(self); + r } } impl NonTrivialSlicable for Vec where Vec: Slicable {} impl Slicable for Vec { - fn from_slice(value: &[u8]) -> Option { - let len = Self::size_of(&value[0..4])?; - let mut off = 4; - let mut r = Vec::new(); - while off < len { - let element_len = T::size_of(&value[off..])?; - r.push(T::from_slice(&value[off..off + element_len])?); - off += element_len; - } - Some(r) + fn from_slice(value: &mut &[u8]) -> Option { + u32::from_slice(value).and_then(move |len| { + let len = len as usize; + let mut r = Vec::with_capacity(len); + for _ in 0..len { + match T::from_slice(value) { + None => return None, + Some(v) => r.push(v), + } + } + + Some(r) + }) } - fn set_as_slice bool>(_fill_slice: F) -> Option { - unimplemented!(); + fn as_slice_then R>(&self, f: F) -> R { + f(&self.to_vec()) } fn to_vec(&self) -> Vec { - let vecs = self.iter().map(Slicable::to_vec).collect::>(); - let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a}); - let mut r = Vec::new().join(&(len as u32)); - vecs.iter().for_each(|v| r.extend_from_slice(v)); - r - } + use std::iter::Extend; - fn size_of(data: &[u8]) -> Option { - u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize) + let len = self.len(); + assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements."); + + let mut r: Vec = Vec::new().join(&(len as u32)); + for item in self { + r.extend(item.to_vec()); + } + r } } diff --git a/substrate/runtime-codec/src/streamreader.rs b/substrate/runtime-codec/src/streamreader.rs deleted file mode 100644 index 33056a5ac3..0000000000 --- a/substrate/runtime-codec/src/streamreader.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot 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. - -// Polkadot 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 Polkadot. If not, see . - -//! Deserialiser. - -use slicable::Slicable; - -/// Simple deserialiser. -pub struct StreamReader<'a> { - data: &'a [u8], - offset: usize, -} - -impl<'a> StreamReader<'a> { - /// Create a new deserialiser based on the `data`. - pub fn new(data: &'a [u8]) -> Self { - StreamReader { - data: data, - offset: 0, - } - } - - /// Deserialise a single item from the data stream. - pub fn read(&mut self) -> Option { - let size = T::size_of(&self.data[self.offset..])?; - let new_offset = self.offset + size; - let slice = &self.data[self.offset..new_offset]; - self.offset = new_offset; - Slicable::from_slice(slice) - } -} -/* -// Not in use yet -// TODO: introduce fn size_will_be(&self) -> usize; to Slicable trait and implement -struct StreamWriter<'a> { - data: &'a mut[u8], - offset: usize, -} - -impl<'a> StreamWriter<'a> { - pub fn new(data: &'a mut[u8]) -> Self { - StreamWriter { - data: data, - offset: 0, - } - } - pub fn write(&mut self, value: &T) -> bool { - value.as_slice_then(|s| { - let new_offset = self.offset + s.len(); - if self.data.len() <= new_offset { - let slice = &mut self.data[self.offset..new_offset]; - self.offset = new_offset; - slice.copy_from_slice(s); - true - } else { - false - } - }) - } -} -*/