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