From 2d29c34892ca7d4a8c5bdaf92b3f161cf6f4a6c6 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 11 Sep 2018 00:13:44 +0200 Subject: [PATCH] Add (untested) ssz decode macro --- ssz/src/impls.rs | 42 +++++++++++++++++++++++++++++++++++++++++- ssz/src/lib.rs | 8 ++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/ssz/src/impls.rs b/ssz/src/impls.rs index 863dfa0f1c..82f3393513 100644 --- a/ssz/src/impls.rs +++ b/ssz/src/impls.rs @@ -1,10 +1,50 @@ /* * Implementations for various types */ -use super::{ Encodable, SszStream }; +use super::{ + DecodeError, + Decodable, + Encodable, + SszStream +}; use super::bytes::{ BytesMut, BufMut }; use super::ethereum_types::{ H256, U256 }; +macro_rules! impl_decodable_for_uint { + ($type: ident, $bit_size: expr) => { + impl Decodable for $type { + type Decoded = $type; + + fn ssz_decode<$type>(bytes: &[u8]) + -> Result + { + // TOOD: figure out if than can be done at compile time + // instead of runtime (where I assume it happens). + assert!(0 < $bit_size && + $bit_size <= 64 && + $bit_size % 8 == 0); + let bytes_required = $bit_size / 8; + if bytes_required == bytes.len() { + let mut result = 0; + for i in 0..bytes.len() { + let offset = (bytes.len() - i - 1) * 8; + result = (bytes[i] << offset) | result; + }; + Ok(result.into()) + } else { + match bytes_required > bytes.len() { + true => Err(DecodeError::TooLong), + false => Err(DecodeError::TooShort), + } + } + } + } + } +} + +impl_decodable_for_uint!(u64, 64 / 8); +impl_decodable_for_uint!(u16, 16 / 8); + impl Encodable for u8 { fn ssz_append(&self, s: &mut SszStream) { s.buffer.append(&mut vec![*self]); diff --git a/ssz/src/lib.rs b/ssz/src/lib.rs index f050d54833..a3fa9d9445 100644 --- a/ssz/src/lib.rs +++ b/ssz/src/lib.rs @@ -18,13 +18,21 @@ pub trait Encodable { fn ssz_append(&self, s: &mut SszStream); } +pub trait Decodable { + type Decoded; + + fn ssz_decode(bytes: &[u8]) -> Result; +} + pub struct SszStream { buffer: Vec } #[derive(Debug)] pub enum DecodeError { + OutOfBounds, TooShort, + TooLong, } impl SszStream {