From ef34b3d9aa58e156623395d606be5fca16d21d27 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 17 Apr 2016 14:06:14 +0300 Subject: [PATCH] convertables --- util/src/bytes.rs | 69 ++++++++++++++++++++++++++++-------------- util/src/keys/store.rs | 2 +- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/util/src/bytes.rs b/util/src/bytes.rs index 231ad2512..f714b3d55 100644 --- a/util/src/bytes.rs +++ b/util/src/bytes.rs @@ -37,6 +37,8 @@ use std::slice; use std::ops::{Deref, DerefMut}; use hash::FixedHash; use elastic_array::*; +use std::mem; +use std::cmp::Ordering; /// Vector like object pub trait VecLike { @@ -249,8 +251,6 @@ pub trait FromRawBytes : Sized { impl FromRawBytes for T where T: FixedHash { fn from_bytes(bytes: &[u8]) -> Result { - use std::mem; - use std::cmp::Ordering; match bytes.len().cmp(&mem::size_of::()) { Ordering::Less => return Err(FromBytesError::NotLongEnough), Ordering::Greater => return Err(FromBytesError::TooLong), @@ -265,9 +265,6 @@ impl FromRawBytes for T where T: FixedHash { impl FromRawBytes for u16 { fn from_bytes(bytes: &[u8]) -> Result { - use std::mem; - use std::cmp::Ordering; - match bytes.len().cmp(&2) { Ordering::Less => return Err(FromBytesError::NotLongEnough), Ordering::Greater => return Err(FromBytesError::TooLong), @@ -282,54 +279,78 @@ impl FromRawBytes for u16 { /// Value that can be serialized from variable-length byte array pub trait FromRawBytesVariable : Sized { /// Create value from slice - fn from_bytes(d: &[u8]) -> Result; + fn from_bytes_variable(bytes: &[u8]) -> Result; } impl FromRawBytesVariable for T where T: FromRawBytes { - fn from_bytes(bytes: &[u8],) -> Result { - match bytes.len().cmp(&::std::mem::size_of::()) { + fn from_bytes_variable(bytes: &[u8]) -> Result { + match bytes.len().cmp(&mem::size_of::()) { Ordering::Less => return Err(FromBytesError::NotLongEnough), Ordering::Greater => return Err(FromBytesError::TooLong), Ordering::Equal => () }; - T::from_bytes(d) + T::from_bytes(bytes) } } impl FromRawBytesVariable for String { - fn from_bytes_var(bytes: &[u8], _len: u64) -> Result { + fn from_bytes_variable(bytes: &[u8]) -> Result { Ok(::std::str::from_utf8(bytes).unwrap().to_owned()) } } impl FromRawBytesVariable for Vec where T: FromRawBytes { - fn from_bytes_var(d: &[u8], len: u64) -> Result { - let size_of_t = ::std::mem::size_of::(); - let length_in_chunks = len as usize / size_of_t; + fn from_bytes_variable(bytes: &[u8]) -> Result { + let size_of_t = mem::size_of::(); + let length_in_chunks = bytes.len() / size_of_t; - let mut result = Vec::with_capacity(length_in_chunks as usize); - unsafe { result.set_len(length_in_chunks as usize) }; - for i in 0..length_in_chunks { *result.get_mut(i).unwrap() = try!(T::from_bytes(&d[size_of_t * i..size_of_t * (i+1)])) } + let mut result = Vec::with_capacity(length_in_chunks ); + 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)])) + } Ok(result) } } impl FromRawBytes for (V1, T2) where V1: FromRawBytesVariable, T2: FromRawBytes { - fn from_bytes(d: &[u8]) -> Result { + fn from_bytes(bytes: &[u8]) -> Result { let header = 8usize; - let mut map: (u64, ) = unsafe { ::std::mem::uninitialized() }; + let mut map: (u64, ) = unsafe { mem::uninitialized() }; - if d.len() < header { return Err(FromBytesError::NotLongEnough); } - map.copy_raw(&d[0..header]); + if bytes.len() < header { return Err(FromBytesError::NotLongEnough); } + map.copy_raw(&bytes[0..header]); Ok(( - try!(V1::from_bytes_var(&d[header..header + (map.0 as usize)], map.0)), - try!(T2::from_bytes(&d[header + (map.0 as usize)..d.len()])), + try!(V1::from_bytes_variable(&bytes[header..header + (map.0 as usize)])), + try!(T2::from_bytes(&bytes[header + (map.0 as usize)..bytes.len()])), )) } } +impl BytesConvertable for (Vec, T2) where V1: BytesConvertable, T2: BytesConvertable { + fn bytes(&self) -> &[u8] { + let header = 8usize; + let mut result = Vec::new(header + self.0.len() * mem::size_of::() + mem::size_of::()); + + *result[0..header] = (self.0.len() as u64).as_slice(); + for i in 0..self.0.len() { + *result[header + i*mem::size_of::()..header + (i+1)*mem::size_of::()] = + self.0[i].as_slice(); + } + *result[header + self.0.len()..result.len()] = self.1.as_slice(); + } + +} + +impl FromRawBytesVariable for Vec { + fn from_bytes_variable(bytes: &[u8]) -> Result, FromBytesError> { + Ok(bytes.clone().to_vec()) + } +} + #[test] fn fax_raw() { let mut x = [255u8; 4]; @@ -399,6 +420,8 @@ fn raw_bytes_from_tuple() { type Tup = (Vec, u16); let tup_from = Tup::from_bytes(&bytes).unwrap(); - assert_eq!(tup, tup_from); + + let bytes_to = Tup::as_slice(); + assert_eq!(bytes_to, bytes); } diff --git a/util/src/keys/store.rs b/util/src/keys/store.rs index 8b53b3d85..ddd22bb6c 100644 --- a/util/src/keys/store.rs +++ b/util/src/keys/store.rs @@ -324,7 +324,7 @@ impl EncryptedHashMap for SecretStore { } }; - match Value::from_bytes_var(&val, val.len() as u64) { + match Value::from_bytes_variable(&val) { Ok(value) => Ok(value), Err(bytes_error) => Err(EncryptedHashMapError::InvalidValueFormat(bytes_error)) }