1use std::cell::Cell;
10use std::fmt;
11use rustc_serialize::hex::ToHex;
12use impls::decode_usize;
13use {Decodable, DecoderError};
14
15#[derive(Copy, Clone, Debug)]
17struct OffsetCache {
18 index: usize,
19 offset: usize,
20}
21
22impl OffsetCache {
23 fn new(index: usize, offset: usize) -> OffsetCache {
24 OffsetCache {
25 index: index,
26 offset: offset,
27 }
28 }
29}
30
31#[derive(Debug)]
32pub enum Prototype {
34 Null,
36 Data(usize),
38 List(usize),
40}
41
42pub struct PayloadInfo {
44 pub header_len: usize,
46 pub value_len: usize,
48}
49
50fn calculate_payload_info(header_bytes: &[u8], len_of_len: usize) -> Result<PayloadInfo, DecoderError> {
51 let header_len = 1 + len_of_len;
52 match header_bytes.get(1) {
53 Some(&0) => return Err(DecoderError::RlpDataLenWithZeroPrefix),
54 None => return Err(DecoderError::RlpIsTooShort),
55 _ => (),
56 }
57 if header_bytes.len() < header_len { return Err(DecoderError::RlpIsTooShort); }
58 let value_len = decode_usize(&header_bytes[1..header_len])?;
59 Ok(PayloadInfo::new(header_len, value_len))
60}
61
62impl PayloadInfo {
63 fn new(header_len: usize, value_len: usize) -> PayloadInfo {
64 PayloadInfo {
65 header_len: header_len,
66 value_len: value_len,
67 }
68 }
69
70 pub fn total(&self) -> usize { self.header_len + self.value_len }
72
73 pub fn from(header_bytes: &[u8]) -> Result<PayloadInfo, DecoderError> {
75 match header_bytes.first().cloned() {
76 None => Err(DecoderError::RlpIsTooShort),
77 Some(0...0x7f) => Ok(PayloadInfo::new(0, 1)),
78 Some(l @ 0x80...0xb7) => Ok(PayloadInfo::new(1, l as usize - 0x80)),
79 Some(l @ 0xb8...0xbf) => {
80 let len_of_len = l as usize - 0xb7;
81 calculate_payload_info(header_bytes, len_of_len)
82 }
83 Some(l @ 0xc0...0xf7) => Ok(PayloadInfo::new(1, l as usize - 0xc0)),
84 Some(l @ 0xf8...0xff) => {
85 let len_of_len = l as usize - 0xf7;
86 calculate_payload_info(header_bytes, len_of_len)
87 },
88 _ => { unreachable!(); }
90 }
91 }
92}
93
94#[derive(Debug)]
101pub struct UntrustedRlp<'a> {
102 bytes: &'a [u8],
103 offset_cache: Cell<OffsetCache>,
104 count_cache: Cell<Option<usize>>,
105}
106
107impl<'a> Clone for UntrustedRlp<'a> {
108 fn clone(&self) -> UntrustedRlp<'a> {
109 UntrustedRlp {
110 bytes: self.bytes,
111 offset_cache: self.offset_cache.clone(),
112 count_cache: self.count_cache.clone(),
113 }
114 }
115}
116
117impl<'a> fmt::Display for UntrustedRlp<'a> {
118 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
119 match self.prototype() {
120 Ok(Prototype::Null) => write!(f, "null"),
121 Ok(Prototype::Data(_)) => write!(f, "\"0x{}\"", self.data().unwrap().to_hex()),
122 Ok(Prototype::List(len)) => {
123 write!(f, "[")?;
124 for i in 0..len-1 {
125 write!(f, "{}, ", self.at(i).unwrap())?;
126 }
127 write!(f, "{}", self.at(len - 1).unwrap())?;
128 write!(f, "]")
129 },
130 Err(err) => write!(f, "{:?}", err)
131 }
132 }
133}
134
135impl<'a, 'view> UntrustedRlp<'a> where 'a: 'view {
136 pub fn new(bytes: &'a [u8]) -> UntrustedRlp<'a> {
137 UntrustedRlp {
138 bytes: bytes,
139 offset_cache: Cell::new(OffsetCache::new(usize::max_value(), 0)),
140 count_cache: Cell::new(None)
141 }
142 }
143
144 pub fn as_raw(&'view self) -> &'a [u8] {
145 self.bytes
146 }
147
148 pub fn prototype(&self) -> Result<Prototype, DecoderError> {
149 if self.is_data() {
151 Ok(Prototype::Data(self.size()))
152 } else if self.is_list() {
153 self.item_count().map(Prototype::List)
154 } else {
155 Ok(Prototype::Null)
156 }
157 }
158
159 pub fn payload_info(&self) -> Result<PayloadInfo, DecoderError> {
160 BasicDecoder::payload_info(self.bytes)
161 }
162
163 pub fn data(&'view self) -> Result<&'a [u8], DecoderError> {
164 let pi = BasicDecoder::payload_info(self.bytes)?;
165 Ok(&self.bytes[pi.header_len..(pi.header_len + pi.value_len)])
166 }
167
168 pub fn item_count(&self) -> Result<usize, DecoderError> {
169 match self.is_list() {
170 true => match self.count_cache.get() {
171 Some(c) => Ok(c),
172 None => {
173 let c = self.iter().count();
174 self.count_cache.set(Some(c));
175 Ok(c)
176 }
177 },
178 false => Err(DecoderError::RlpExpectedToBeList),
179 }
180 }
181
182 pub fn size(&self) -> usize {
183 match self.is_data() {
184 true => BasicDecoder::payload_info(self.bytes).map(|b| b.value_len).unwrap_or(0),
186 false => 0
187 }
188 }
189
190 pub fn at(&'view self, index: usize) -> Result<UntrustedRlp<'a>, DecoderError> {
191 if !self.is_list() {
192 return Err(DecoderError::RlpExpectedToBeList);
193 }
194
195 let c = self.offset_cache.get();
198 let (mut bytes, to_skip) = match c.index <= index {
199 true => (UntrustedRlp::consume(self.bytes, c.offset)?, index - c.index),
200 false => (self.consume_list_payload()?, index),
201 };
202
203 bytes = UntrustedRlp::consume_items(bytes, to_skip)?;
205
206 self.offset_cache.set(OffsetCache::new(index, self.bytes.len() - bytes.len()));
208
209 let found = BasicDecoder::payload_info(bytes)?;
211 Ok(UntrustedRlp::new(&bytes[0..found.header_len + found.value_len]))
212 }
213
214 pub fn is_null(&self) -> bool {
215 self.bytes.len() == 0
216 }
217
218 pub fn is_empty(&self) -> bool {
219 !self.is_null() && (self.bytes[0] == 0xc0 || self.bytes[0] == 0x80)
220 }
221
222 pub fn is_list(&self) -> bool {
223 !self.is_null() && self.bytes[0] >= 0xc0
224 }
225
226 pub fn is_data(&self) -> bool {
227 !self.is_null() && self.bytes[0] < 0xc0
228 }
229
230 pub fn is_int(&self) -> bool {
231 if self.is_null() {
232 return false;
233 }
234
235 match self.bytes[0] {
236 0...0x80 => true,
237 0x81...0xb7 => self.bytes[1] != 0,
238 b @ 0xb8...0xbf => self.bytes[1 + b as usize - 0xb7] != 0,
239 _ => false
240 }
241 }
242
243 pub fn iter(&'view self) -> UntrustedRlpIterator<'a, 'view> {
244 self.into_iter()
245 }
246
247 pub fn as_val<T>(&self) -> Result<T, DecoderError> where T: Decodable {
248 T::decode(self)
249 }
250
251 pub fn as_list<T>(&self) -> Result<Vec<T>, DecoderError> where T: Decodable {
252 self.iter().map(|rlp| rlp.as_val()).collect()
253 }
254
255 pub fn val_at<T>(&self, index: usize) -> Result<T, DecoderError> where T: Decodable {
256 self.at(index)?.as_val()
257 }
258
259 pub fn list_at<T>(&self, index: usize) -> Result<Vec<T>, DecoderError> where T: Decodable {
260 self.at(index)?.as_list()
261 }
262
263 pub fn decoder(&self) -> BasicDecoder {
264 BasicDecoder::new(self.clone())
265 }
266
267 fn consume_list_payload(&self) -> Result<&'a [u8], DecoderError> {
269 let item = BasicDecoder::payload_info(self.bytes)?;
270 let bytes = UntrustedRlp::consume(self.bytes, item.header_len)?;
271 Ok(bytes)
272 }
273
274 fn consume_items(bytes: &'a [u8], items: usize) -> Result<&'a [u8], DecoderError> {
276 let mut result = bytes;
277 for _ in 0..items {
278 let i = BasicDecoder::payload_info(result)?;
279 result = UntrustedRlp::consume(result, (i.header_len + i.value_len))?;
280 }
281 Ok(result)
282 }
283
284
285 fn consume(bytes: &'a [u8], len: usize) -> Result<&'a [u8], DecoderError> {
287 match bytes.len() >= len {
288 true => Ok(&bytes[len..]),
289 false => Err(DecoderError::RlpIsTooShort),
290 }
291 }
292}
293
294pub struct UntrustedRlpIterator<'a, 'view> where 'a: 'view {
296 rlp: &'view UntrustedRlp<'a>,
297 index: usize,
298}
299
300impl<'a, 'view> IntoIterator for &'view UntrustedRlp<'a> where 'a: 'view {
301 type Item = UntrustedRlp<'a>;
302 type IntoIter = UntrustedRlpIterator<'a, 'view>;
303
304 fn into_iter(self) -> Self::IntoIter {
305 UntrustedRlpIterator {
306 rlp: self,
307 index: 0,
308 }
309 }
310}
311
312impl<'a, 'view> Iterator for UntrustedRlpIterator<'a, 'view> {
313 type Item = UntrustedRlp<'a>;
314
315 fn next(&mut self) -> Option<UntrustedRlp<'a>> {
316 let index = self.index;
317 let result = self.rlp.at(index).ok();
318 self.index += 1;
319 result
320 }
321}
322
323pub struct BasicDecoder<'a> {
324 rlp: UntrustedRlp<'a>
325}
326
327impl<'a> BasicDecoder<'a> {
328 pub fn new(rlp: UntrustedRlp<'a>) -> BasicDecoder<'a> {
329 BasicDecoder {
330 rlp: rlp
331 }
332 }
333
334 fn payload_info(bytes: &[u8]) -> Result<PayloadInfo, DecoderError> {
336 let item = PayloadInfo::from(bytes)?;
337 match item.header_len.checked_add(item.value_len) {
338 Some(x) if x <= bytes.len() => Ok(item),
339 _ => Err(DecoderError::RlpIsTooShort),
340 }
341 }
342
343 pub fn decode_value<T, F>(&self, f: F) -> Result<T, DecoderError>
344 where F: Fn(&[u8]) -> Result<T, DecoderError> {
345
346 let bytes = self.rlp.as_raw();
347
348 match bytes.first().cloned() {
349 None => Err(DecoderError::RlpIsTooShort),
351 Some(l @ 0...0x7f) => Ok(f(&[l])?),
353 Some(l @ 0x80...0xb7) => {
355 let last_index_of = 1 + l as usize - 0x80;
356 if bytes.len() < last_index_of {
357 return Err(DecoderError::RlpInconsistentLengthAndData);
358 }
359 let d = &bytes[1..last_index_of];
360 if l == 0x81 && d[0] < 0x80 {
361 return Err(DecoderError::RlpInvalidIndirection);
362 }
363 Ok(f(d)?)
364 },
365 Some(l @ 0xb8...0xbf) => {
367 let len_of_len = l as usize - 0xb7;
368 let begin_of_value = 1 as usize + len_of_len;
369 if bytes.len() < begin_of_value {
370 return Err(DecoderError::RlpInconsistentLengthAndData);
371 }
372 let len = decode_usize(&bytes[1..begin_of_value])?;
373
374 let last_index_of_value = begin_of_value + len;
375 if bytes.len() < last_index_of_value {
376 return Err(DecoderError::RlpInconsistentLengthAndData);
377 }
378 Ok(f(&bytes[begin_of_value..last_index_of_value])?)
379 }
380 _ => Err(DecoderError::RlpExpectedToBeData)
382 }
383 }
384}
385
386#[cfg(test)]
387mod tests {
388 use UntrustedRlp;
389
390 #[test]
391 fn test_rlp_display() {
392 use rustc_serialize::hex::FromHex;
393 let data = "f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".from_hex().unwrap();
394 let rlp = UntrustedRlp::new(&data);
395 assert_eq!(format!("{}", rlp), "[\"0x05\", \"0x010efbef67941f79b2\", \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\", \"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"]");
396 }
397}