openethereum/util/src/bytes.rs

532 lines
14 KiB
Rust
Raw Normal View History

2016-02-05 13:40:41 +01:00
// Copyright 2015, 2016 Ethcore (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 <http://www.gnu.org/licenses/>.
2015-11-28 03:58:37 +01:00
//! Unified interfaces for bytes operations on basic types
2015-12-26 15:48:41 +01:00
//!
2015-11-25 02:53:35 +01:00
//! # Examples
2015-11-28 03:58:37 +01:00
//! ```rust
//! extern crate ethcore_util as util;
2015-12-26 15:48:41 +01:00
//!
2015-11-28 03:58:37 +01:00
//! fn bytes_convertable() {
//! use util::bytes::BytesConvertable;
//!
//! let arr = [0; 5];
//! let slice: &[u8] = arr.as_slice();
2015-11-28 03:58:37 +01:00
//! }
2015-12-26 15:48:41 +01:00
//!
2015-11-28 03:58:37 +01:00
//! fn main() {
//! bytes_convertable();
//! }
//! ```
2015-11-25 02:53:35 +01:00
use std::fmt;
2016-01-08 11:02:32 +01:00
use std::slice;
2016-01-13 15:14:24 +01:00
use std::ops::{Deref, DerefMut};
use hash::FixedHash;
2016-01-27 12:14:57 +01:00
use elastic_array::*;
2016-04-17 13:06:14 +02:00
use std::mem;
use std::cmp::Ordering;
2015-11-25 02:53:35 +01:00
2016-01-27 12:14:57 +01:00
/// Vector like object
pub trait VecLike<T> {
/// Add an element to the collection
2016-01-27 16:58:22 +01:00
fn vec_push(&mut self, value: T);
2016-01-27 12:14:57 +01:00
/// Add a slice to the collection
2016-01-27 16:58:22 +01:00
fn vec_extend(&mut self, slice: &[T]);
2016-01-27 12:14:57 +01:00
}
2016-01-27 16:58:22 +01:00
impl<T> VecLike<T> for Vec<T> where T: Copy {
fn vec_push(&mut self, value: T) {
Vec::<T>::push(self, value)
}
fn vec_extend(&mut self, slice: &[T]) {
Vec::<T>::extend_from_slice(self, slice)
}
}
2016-01-27 12:14:57 +01:00
macro_rules! impl_veclike_for_elastic_array {
($from: ident) => {
impl<T> VecLike<T> for $from<T> where T: Copy {
2016-01-27 16:58:22 +01:00
fn vec_push(&mut self, value: T) {
2016-01-27 12:14:57 +01:00
$from::<T>::push(self, value)
}
2016-01-27 16:58:22 +01:00
fn vec_extend(&mut self, slice: &[T]) {
2016-01-27 12:14:57 +01:00
$from::<T>::append_slice(self, slice)
}
}
}
}
impl_veclike_for_elastic_array!(ElasticArray16);
impl_veclike_for_elastic_array!(ElasticArray32);
impl_veclike_for_elastic_array!(ElasticArray1024);
/// Slie pretty print helper
2015-12-01 18:25:18 +01:00
pub struct PrettySlice<'a> (&'a [u8]);
impl<'a> fmt::Debug for PrettySlice<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for i in 0..self.0.len() {
2015-12-01 19:09:48 +01:00
match i > 0 {
true => { try!(write!(f, "·{:02x}", self.0[i])); },
false => { try!(write!(f, "{:02x}", self.0[i])); },
}
2015-12-01 18:25:18 +01:00
}
Ok(())
}
}
impl<'a> fmt::Display for PrettySlice<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for i in 0..self.0.len() {
try!(write!(f, "{:02x}", self.0[i]));
}
Ok(())
}
}
2016-02-03 13:20:32 +01:00
/// Trait to allow a type to be pretty-printed in `format!`, where unoverridable
/// defaults cannot otherwise be avoided.
2015-12-01 18:25:18 +01:00
pub trait ToPretty {
2016-02-03 13:20:32 +01:00
/// Convert a type into a derivative form in order to make `format!` print it prettily.
2015-12-01 18:25:18 +01:00
fn pretty(&self) -> PrettySlice;
2016-02-03 13:20:32 +01:00
/// Express the object as a hex string.
fn to_hex(&self) -> String {
format!("{}", self.pretty())
}
2015-12-01 18:25:18 +01:00
}
impl<'a> ToPretty for &'a [u8] {
fn pretty(&self) -> PrettySlice {
PrettySlice(self)
}
}
impl<'a> ToPretty for &'a Bytes {
fn pretty(&self) -> PrettySlice {
PrettySlice(self.as_slice())
2015-12-01 18:25:18 +01:00
}
}
impl ToPretty for Bytes {
fn pretty(&self) -> PrettySlice {
PrettySlice(self.as_slice())
2015-12-01 18:25:18 +01:00
}
}
2016-02-03 16:43:48 +01:00
/// A byte collection reference that can either be a slice or a vector
2016-01-13 15:14:24 +01:00
pub enum BytesRef<'a> {
2016-02-03 16:43:48 +01:00
/// This is a reference to a vector
2016-01-13 15:14:24 +01:00
Flexible(&'a mut Bytes),
2016-02-03 16:43:48 +01:00
/// This is a reference to a slice
2016-01-13 15:14:24 +01:00
Fixed(&'a mut [u8])
}
impl<'a> Deref for BytesRef<'a> {
type Target = [u8];
fn deref(&self) -> &[u8] {
2016-01-19 12:14:29 +01:00
match *self {
BytesRef::Flexible(ref bytes) => bytes,
2016-02-19 11:31:40 +01:00
BytesRef::Fixed(ref bytes) => bytes,
2016-01-13 15:14:24 +01:00
}
}
}
impl <'a> DerefMut for BytesRef<'a> {
fn deref_mut(&mut self) -> &mut [u8] {
2016-01-19 12:14:29 +01:00
match *self {
BytesRef::Flexible(ref mut bytes) => bytes,
2016-02-19 11:31:40 +01:00
BytesRef::Fixed(ref mut bytes) => bytes,
2016-01-13 15:14:24 +01:00
}
}
}
2015-11-28 03:58:37 +01:00
/// Vector of bytes
2015-11-28 00:14:40 +01:00
pub type Bytes = Vec<u8>;
2015-11-28 03:58:37 +01:00
/// Slice of bytes to underlying memory
2015-11-27 17:54:33 +01:00
pub trait BytesConvertable {
2016-02-03 13:20:32 +01:00
/// Get the underlying byte-wise representation of the value.
fn as_slice(&self) -> &[u8];
2016-02-03 13:20:32 +01:00
/// Get a copy of the underlying byte-wise representation.
2016-01-05 19:05:51 +01:00
fn to_bytes(&self) -> Bytes { self.as_slice().to_vec() }
2015-11-27 17:54:33 +01:00
}
2016-02-15 11:54:38 +01:00
impl<T> BytesConvertable for T where T: AsRef<[u8]> {
fn as_slice(&self) -> &[u8] { self.as_ref() }
}
2015-11-27 17:54:33 +01:00
#[test]
fn bytes_convertable() {
assert_eq!(vec![0x12u8, 0x34].as_slice(), &[0x12u8, 0x34]);
2016-03-14 10:53:37 +01:00
assert!([0u8; 0].as_slice().is_empty());
2015-11-27 17:54:33 +01:00
}
/// Simple trait to allow for raw population of a Sized object from a byte slice.
pub trait Populatable {
2016-01-08 11:02:32 +01:00
/// Copies a bunch of bytes `d` to `self`, overwriting as necessary.
///
/// If `d` is smaller, zero-out the remaining bytes.
2016-01-08 11:43:11 +01:00
fn populate_raw(&mut self, d: &[u8]) {
let mut s = self.as_slice_mut();
for i in 0..s.len() {
s[i] = if i < d.len() {d[i]} else {0};
}
}
2016-01-08 11:02:32 +01:00
/// Copies a bunch of bytes `d` to `self`, overwriting as necessary.
///
/// If `d` is smaller, will leave some bytes untouched.
2016-01-08 12:05:38 +01:00
fn copy_raw(&mut self, d: &[u8]) {
2016-01-08 11:43:11 +01:00
use std::io::Write;
self.as_slice_mut().write(d).unwrap();
2016-01-08 11:43:11 +01:00
}
/// Copies the raw representation of an object `d` to `self`, overwriting as necessary.
///
/// If `d` is smaller, zero-out the remaining bytes.
fn populate_raw_from(&mut self, d: &BytesConvertable) { self.populate_raw(d.as_slice()); }
/// Copies the raw representation of an object `d` to `self`, overwriting as necessary.
///
/// If `d` is smaller, will leave some bytes untouched.
2016-01-08 12:05:38 +01:00
fn copy_raw_from(&mut self, d: &BytesConvertable) { self.copy_raw(d.as_slice()); }
2016-01-08 11:43:11 +01:00
/// Get the raw slice for this object.
fn as_slice_mut(&mut self) -> &mut [u8];
}
impl<T> Populatable for T where T: Sized {
2016-01-08 11:43:11 +01:00
fn as_slice_mut(&mut self) -> &mut [u8] {
use std::mem;
unsafe {
slice::from_raw_parts_mut(self as *mut T as *mut u8, mem::size_of::<T>())
2016-01-08 11:43:11 +01:00
}
}
}
2016-01-08 11:02:32 +01:00
2016-01-08 11:43:11 +01:00
impl<T> Populatable for [T] where T: Sized {
fn as_slice_mut(&mut self) -> &mut [u8] {
2016-01-08 11:02:32 +01:00
use std::mem;
unsafe {
2016-01-08 11:43:11 +01:00
slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u8, mem::size_of::<T>() * self.len())
}
}
}
2016-01-08 11:02:32 +01:00
2016-02-17 00:32:16 +01:00
#[derive(Debug)]
/// Bytes array deserialization error
pub enum FromBytesError {
/// Not enough bytes for the requested type
NotLongEnough,
/// Too many bytes for the requested type
TooLong,
2016-04-17 17:18:25 +02:00
/// Invalid marker for (enums)
UnknownMarker,
2016-02-17 00:32:16 +01:00
}
/// Value that can be serialized from bytes array
pub trait FromRawBytes: Sized {
2016-02-17 00:32:16 +01:00
/// function that will instantiate and initialize object from slice
fn from_bytes(d: &[u8]) -> Result<Self, FromBytesError>;
}
2016-04-17 10:06:59 +02:00
impl<T> FromRawBytes for T where T: FixedHash {
2016-02-17 00:32:16 +01:00
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
match bytes.len().cmp(&mem::size_of::<T>()) {
Ordering::Less => return Err(FromBytesError::NotLongEnough),
Ordering::Greater => return Err(FromBytesError::TooLong),
Ordering::Equal => ()
};
let mut res = T::zero();
2016-02-17 00:32:16 +01:00
res.copy_raw(bytes);
Ok(res)
}
}
#[macro_export]
macro_rules! sized_binary_map {
($target_ty: ident) => {
impl FromRawBytes for $target_ty {
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
match bytes.len().cmp(&::std::mem::size_of::<$target_ty>()) {
::std::cmp::Ordering::Less => return Err(FromBytesError::NotLongEnough),
::std::cmp::Ordering::Greater => return Err(FromBytesError::TooLong),
::std::cmp::Ordering::Equal => ()
};
let mut res: Self = 0;
res.copy_raw(bytes);
Ok(res)
}
}
impl ToBytesWithMap for $target_ty {
fn to_bytes_map(&self) -> Vec<u8> {
let sz = ::std::mem::size_of::<$target_ty>();
let mut res = Vec::<u8>::with_capacity(sz);
let ip: *const $target_ty = self;
let ptr: *const u8 = ip as *const _;
unsafe {
res.set_len(sz);
::std::ptr::copy(ptr, res.as_mut_ptr(), sz);
}
res
}
}
2016-04-16 19:11:18 +02:00
}
}
sized_binary_map!(u16);
sized_binary_map!(u32);
sized_binary_map!(u64);
2016-04-17 10:06:59 +02:00
/// Value that can be serialized from variable-length byte array
pub trait FromRawBytesVariable: Sized {
2016-04-17 10:06:59 +02:00
/// Create value from slice
2016-04-17 13:06:14 +02:00
fn from_bytes_variable(bytes: &[u8]) -> Result<Self, FromBytesError>;
2016-04-17 10:06:59 +02:00
}
2016-04-16 19:11:18 +02:00
2016-04-17 10:06:59 +02:00
impl<T> FromRawBytesVariable for T where T: FromRawBytes {
2016-04-17 13:06:14 +02:00
fn from_bytes_variable(bytes: &[u8]) -> Result<Self, FromBytesError> {
match bytes.len().cmp(&mem::size_of::<T>()) {
2016-04-16 19:11:18 +02:00
Ordering::Less => return Err(FromBytesError::NotLongEnough),
Ordering::Greater => return Err(FromBytesError::TooLong),
Ordering::Equal => ()
};
2016-04-17 13:06:14 +02:00
T::from_bytes(bytes)
2016-04-16 19:11:18 +02:00
}
}
impl FromRawBytesVariable for String {
2016-04-17 13:06:14 +02:00
fn from_bytes_variable(bytes: &[u8]) -> Result<String, FromBytesError> {
2016-02-17 00:32:16 +01:00
Ok(::std::str::from_utf8(bytes).unwrap().to_owned())
}
}
2016-04-16 19:11:18 +02:00
impl<T> FromRawBytesVariable for Vec<T> where T: FromRawBytes {
2016-04-17 13:06:14 +02:00
fn from_bytes_variable(bytes: &[u8]) -> Result<Self, FromBytesError> {
let size_of_t = mem::size_of::<T>();
let length_in_chunks = bytes.len() / size_of_t;
let mut result = Vec::with_capacity(length_in_chunks);
2016-04-17 13:06:14 +02:00
unsafe { result.set_len(length_in_chunks) };
for i in 0..length_in_chunks {
*result.get_mut(i).unwrap() = try!(T::from_bytes(
&bytes[size_of_t * i..size_of_t * (i+1)]))
}
2016-04-16 19:11:18 +02:00
Ok(result)
}
}
impl<V1, T2> FromRawBytes for (V1, T2) where V1: FromRawBytesVariable, T2: FromRawBytes {
2016-04-17 13:06:14 +02:00
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
2016-04-16 19:11:18 +02:00
let header = 8usize;
let mut map: (u64, ) = (0,);
2016-04-16 19:11:18 +02:00
2016-04-17 13:06:14 +02:00
if bytes.len() < header { return Err(FromBytesError::NotLongEnough); }
map.copy_raw(&bytes[0..header]);
2016-04-16 19:11:18 +02:00
Ok((
2016-04-17 13:06:14 +02:00
try!(V1::from_bytes_variable(&bytes[header..header + (map.0 as usize)])),
try!(T2::from_bytes(&bytes[header + (map.0 as usize)..bytes.len()])),
2016-04-16 19:11:18 +02:00
))
2016-02-17 00:32:16 +01:00
}
}
2016-04-17 17:18:25 +02:00
impl<V1, V2, T3> FromRawBytes for (V1, V2, T3)
where V1: FromRawBytesVariable,
V2: FromRawBytesVariable,
T3: FromRawBytes
{
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
let header = 16usize;
let mut map: (u64, u64, ) = (0, 0,);
2016-04-17 17:18:25 +02:00
if bytes.len() < header { return Err(FromBytesError::NotLongEnough); }
map.copy_raw(&bytes[0..header]);
let map_1 = (header, header + map.0 as usize);
let map_2 = (map_1.1 as usize, map_1.1 as usize + map.1 as usize);
Ok((
try!(V1::from_bytes_variable(&bytes[map_1.0..map_1.1])),
try!(V2::from_bytes_variable(&bytes[map_2.0..map_2.1])),
try!(T3::from_bytes(&bytes[map_2.1..bytes.len()])),
))
}
}
impl<'a, V1, X1, T2> ToBytesWithMap for (X1, &'a T2) where V1: ToBytesWithMap, X1: Deref<Target=[V1]>, T2: ToBytesWithMap {
2016-04-17 17:18:25 +02:00
fn to_bytes_map(&self) -> Vec<u8> {
2016-04-17 13:06:14 +02:00
let header = 8usize;
2016-04-17 17:18:25 +02:00
let v1_size = mem::size_of::<V1>();
let mut result = Vec::with_capacity(header + self.0.len() * v1_size + mem::size_of::<T2>());
result.extend(((self.0.len() * v1_size) as u64).to_bytes_map());
2016-04-17 13:06:14 +02:00
for i in 0..self.0.len() {
2016-04-17 17:18:25 +02:00
result.extend(self.0[i].to_bytes_map());
2016-04-17 13:06:14 +02:00
}
2016-04-17 17:18:25 +02:00
result.extend(self.1.to_bytes_map());
result
2016-04-17 13:06:14 +02:00
}
}
impl<'a, V1, X1, V2, X2, T3> ToBytesWithMap for (X1, X2, &'a T3)
where V1: ToBytesWithMap, X1: Deref<Target=[V1]>,
V2: ToBytesWithMap, X2: Deref<Target=[V2]>,
2016-04-17 17:18:25 +02:00
T3: ToBytesWithMap
{
fn to_bytes_map(&self) -> Vec<u8> {
let header = 16usize;
let v1_size = mem::size_of::<V1>();
let v2_size = mem::size_of::<V2>();
let mut result = Vec::with_capacity(
header +
self.0.len() * v1_size +
self.1.len() * v2_size +
mem::size_of::<T3>()
);
result.extend(((self.0.len() * v1_size) as u64).to_bytes_map());
2016-04-17 18:12:10 +02:00
result.extend(((self.1.len() * v2_size) as u64).to_bytes_map());
2016-04-17 17:18:25 +02:00
for i in 0..self.0.len() {
result.extend(self.0[i].to_bytes_map());
}
for i in 0..self.1.len() {
result.extend(self.1[i].to_bytes_map());
}
result.extend(self.2.to_bytes_map());
result
}
}
2016-04-17 13:06:14 +02:00
impl FromRawBytesVariable for Vec<u8> {
fn from_bytes_variable(bytes: &[u8]) -> Result<Vec<u8>, FromBytesError> {
Ok(bytes.to_vec())
2016-04-17 13:06:14 +02:00
}
}
/// Value that serializes directly to variable-sized byte array and stores map
2016-04-17 17:18:25 +02:00
pub trait ToBytesWithMap {
/// serialize to variable-sized byte array and store map
2016-04-17 17:18:25 +02:00
fn to_bytes_map(&self) -> Vec<u8>;
}
impl<T> ToBytesWithMap for T where T: FixedHash {
fn to_bytes_map(&self) -> Vec<u8> {
self.as_slice().to_owned()
2016-04-17 17:18:25 +02:00
}
}
2016-01-08 11:02:32 +01:00
#[test]
2016-01-08 11:43:11 +01:00
fn fax_raw() {
2016-01-08 11:02:32 +01:00
let mut x = [255u8; 4];
2016-01-08 12:05:38 +01:00
x.copy_raw(&[1u8; 2][..]);
2016-01-08 11:02:32 +01:00
assert_eq!(x, [1u8, 1, 255, 255]);
2016-01-08 11:43:11 +01:00
let mut x = [255u8; 4];
2016-01-08 12:05:38 +01:00
x.copy_raw(&[1u8; 6][..]);
2016-01-08 11:02:32 +01:00
assert_eq!(x, [1u8, 1, 1, 1]);
}
#[test]
fn populate_raw() {
let mut x = [255u8; 4];
x.populate_raw(&[1u8; 2][..]);
assert_eq!(x, [1u8, 1, 0, 0]);
2016-01-08 11:43:11 +01:00
let mut x = [255u8; 4];
2016-01-08 11:02:32 +01:00
x.populate_raw(&[1u8; 6][..]);
assert_eq!(x, [1u8, 1, 1, 1]);
2016-01-08 11:43:11 +01:00
}
#[test]
fn populate_raw_dyn() {
let mut x = [255u8; 4];
x.populate_raw(&[1u8; 2][..]);
assert_eq!(&x[..], [1u8, 1, 0, 0]);
let mut x = [255u8; 4];
x.populate_raw(&[1u8; 6][..]);
assert_eq!(&x[..], [1u8, 1, 1, 1]);
}
#[test]
fn fax_raw_dyn() {
let mut x = [255u8; 4];
2016-01-08 12:05:38 +01:00
x.copy_raw(&[1u8; 2][..]);
2016-01-08 11:43:11 +01:00
assert_eq!(&x[..], [1u8, 1, 255, 255]);
let mut x = [255u8; 4];
2016-01-08 12:05:38 +01:00
x.copy_raw(&[1u8; 6][..]);
2016-01-08 11:43:11 +01:00
assert_eq!(&x[..], [1u8, 1, 1, 1]);
}
#[test]
fn populate_big_types() {
use hash::*;
let a = address_from_hex("ffffffffffffffffffffffffffffffffffffffff");
let mut h = h256_from_u64(0x69);
h.populate_raw_from(&a);
assert_eq!(h, h256_from_hex("ffffffffffffffffffffffffffffffffffffffff000000000000000000000000"));
let mut h = h256_from_u64(0x69);
2016-01-08 12:05:38 +01:00
h.copy_raw_from(&a);
assert_eq!(h, h256_from_hex("ffffffffffffffffffffffffffffffffffffffff000000000000000000000069"));
2016-01-13 15:14:24 +01:00
}
2016-04-16 19:11:18 +02:00
#[test]
fn raw_bytes_from_tuple() {
2016-04-21 15:56:35 +02:00
type Tup = (Vec<u16>, u16);
let tup: (&[u16], u16) = (&[1; 4], 10);
2016-04-16 19:11:18 +02:00
let bytes = vec![
// map
2016-04-17 10:06:59 +02:00
8u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
2016-04-16 19:11:18 +02:00
// four 1u16
2016-04-17 10:06:59 +02:00
1u8, 0u8,
1u8, 0u8,
1u8, 0u8,
1u8, 0u8,
2016-04-16 19:11:18 +02:00
// 10u16
2016-04-17 10:06:59 +02:00
10u8, 0u8];
2016-04-16 19:11:18 +02:00
let (v, x) = Tup::from_bytes(&bytes).unwrap();
assert_eq!(tup, (&v[..], x));
let tup_from = (v, x);
2016-04-17 13:06:14 +02:00
let tup_to = (tup_from.0, &tup_from.1);
2016-04-17 17:18:25 +02:00
let bytes_to = tup_to.to_bytes_map();
2016-04-17 13:06:14 +02:00
assert_eq!(bytes_to, bytes);
2016-04-16 19:11:18 +02:00
}
2016-04-17 18:12:10 +02:00
#[test]
fn bytes_map_from_triple() {
let data: (&[u16], &[u32], u64) = (&[2; 6], &[6; 3], 12u64);
let bytes_map = (data.0, data.1, &data.2).to_bytes_map();
2016-04-17 18:12:10 +02:00
assert_eq!(bytes_map, vec![
// data map 2 x u64
12, 0, 0, 0, 0, 0, 0, 0,
12, 0, 0, 0, 0, 0, 0, 0,
// vec![2u16; 6]
2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0,
// vec![6u32; 3]
6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0,
// 12u64
12, 0, 0, 0, 0, 0, 0, 0]);
}