esvm_rlp/
impls.rs

1// Copyright 2015-2017 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::{cmp, mem, str};
10use byteorder::{ByteOrder, BigEndian};
11use traits::{Encodable, Decodable};
12use stream::RlpStream;
13use {UntrustedRlp, DecoderError};
14
15pub fn decode_usize(bytes: &[u8]) -> Result<usize, DecoderError> {
16	match bytes.len() {
17		l if l <= mem::size_of::<usize>() => {
18			if bytes[0] == 0 {
19				return Err(DecoderError::RlpInvalidIndirection);
20			}
21			let mut res = 0usize;
22			for i in 0..l {
23				let shift = (l - 1 - i) * 8;
24				res = res + ((bytes[i] as usize) << shift);
25			}
26			Ok(res)
27		}
28		_ => Err(DecoderError::RlpIsTooBig),
29	}
30}
31
32impl Encodable for bool {
33	fn rlp_append(&self, s: &mut RlpStream) {
34		if *self {
35			s.encoder().encode_value(&[1]);
36		} else {
37			s.encoder().encode_value(&[0]);
38		}
39	}
40}
41
42impl Decodable for bool {
43	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
44		rlp.decoder().decode_value(|bytes| {
45			match bytes.len() {
46				0 => Ok(false),
47				1 => Ok(bytes[0] != 0),
48				_ => Err(DecoderError::RlpIsTooBig),
49			}
50		})
51	}
52}
53
54impl<'a> Encodable for &'a [u8] {
55	fn rlp_append(&self, s: &mut RlpStream) {
56		s.encoder().encode_value(self);
57	}
58}
59
60impl Encodable for Vec<u8> {
61	fn rlp_append(&self, s: &mut RlpStream) {
62		s.encoder().encode_value(self);
63	}
64}
65
66impl Decodable for Vec<u8> {
67	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
68		rlp.decoder().decode_value(|bytes| {
69			Ok(bytes.to_vec())
70		})
71	}
72}
73
74impl<T> Encodable for Option<T> where T: Encodable {
75	fn rlp_append(&self, s: &mut RlpStream) {
76		match *self {
77			None => {
78				s.begin_list(0);
79			},
80			Some(ref value) => {
81				s.begin_list(1);
82				s.append(value);
83			}
84		}
85	}
86}
87
88impl<T> Decodable for Option<T> where T: Decodable {
89	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
90		let items = rlp.item_count()?;
91		match items {
92			1 => rlp.val_at(0).map(Some),
93			0 => Ok(None),
94			_ => Err(DecoderError::RlpIncorrectListLen),
95		}
96	}
97}
98
99impl Encodable for u8 {
100	fn rlp_append(&self, s: &mut RlpStream) {
101		if *self != 0 {
102			s.encoder().encode_value(&[*self]);
103		} else {
104			s.encoder().encode_value(&[]);
105		}
106	}
107}
108
109impl Decodable for u8 {
110	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
111		rlp.decoder().decode_value(|bytes| {
112			match bytes.len() {
113				1 if bytes[0] != 0 => Ok(bytes[0]),
114				0 => Ok(0),
115				1 => Err(DecoderError::RlpInvalidIndirection),
116				_ => Err(DecoderError::RlpIsTooBig),
117			}
118		})
119	}
120}
121
122macro_rules! impl_encodable_for_u {
123	($name: ident, $func: ident, $size: expr) => {
124		impl Encodable for $name {
125			fn rlp_append(&self, s: &mut RlpStream) {
126				let leading_empty_bytes = self.leading_zeros() as usize / 8;
127				let mut buffer = [0u8; $size];
128				BigEndian::$func(&mut buffer, *self);
129				s.encoder().encode_value(&buffer[leading_empty_bytes..]);
130			}
131		}
132	}
133}
134
135macro_rules! impl_decodable_for_u {
136	($name: ident) => {
137		impl Decodable for $name {
138			fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
139				rlp.decoder().decode_value(|bytes| {
140					match bytes.len() {
141						0 | 1 => u8::decode(rlp).map(|v| v as $name),
142						l if l <= mem::size_of::<$name>() => {
143							if bytes[0] == 0 {
144								return Err(DecoderError::RlpInvalidIndirection);
145							}
146							let mut res = 0 as $name;
147							for i in 0..l {
148								let shift = (l - 1 - i) * 8;
149								res = res + ((bytes[i] as $name) << shift);
150							}
151							Ok(res)
152						}
153						_ => Err(DecoderError::RlpIsTooBig),
154					}
155				})
156			}
157		}
158	}
159}
160
161impl_encodable_for_u!(u16, write_u16, 2);
162impl_encodable_for_u!(u32, write_u32, 4);
163impl_encodable_for_u!(u64, write_u64, 8);
164
165impl_decodable_for_u!(u16);
166impl_decodable_for_u!(u32);
167impl_decodable_for_u!(u64);
168
169impl Encodable for usize {
170	fn rlp_append(&self, s: &mut RlpStream) {
171		(*self as u64).rlp_append(s);
172	}
173}
174
175impl Decodable for usize {
176	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
177		u64::decode(rlp).map(|value| value as usize)
178	}
179}
180
181macro_rules! impl_encodable_for_hash {
182	($name: ident) => {
183		impl Encodable for $name {
184			fn rlp_append(&self, s: &mut RlpStream) {
185				s.encoder().encode_value(self);
186			}
187		}
188	}
189}
190
191macro_rules! impl_decodable_for_hash {
192	($name: ident, $size: expr) => {
193		impl Decodable for $name {
194			fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
195				rlp.decoder().decode_value(|bytes| match bytes.len().cmp(&$size) {
196					cmp::Ordering::Less => Err(DecoderError::RlpIsTooShort),
197					cmp::Ordering::Greater => Err(DecoderError::RlpIsTooBig),
198					cmp::Ordering::Equal => {
199						let mut t = [0u8; $size];
200						t.copy_from_slice(bytes);
201						Ok($name(t))
202					}
203				})
204			}
205		}
206	}
207}
208
209impl<'a> Encodable for &'a str {
210	fn rlp_append(&self, s: &mut RlpStream) {
211		s.encoder().encode_value(self.as_bytes());
212	}
213}
214
215impl Encodable for String {
216	fn rlp_append(&self, s: &mut RlpStream) {
217		s.encoder().encode_value(self.as_bytes());
218	}
219}
220
221impl Decodable for String {
222	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
223		rlp.decoder().decode_value(|bytes| {
224			match str::from_utf8(bytes) {
225				Ok(s) => Ok(s.to_owned()),
226				// consider better error type here
227				Err(_err) => Err(DecoderError::RlpExpectedToBeData),
228			}
229		})
230	}
231}