openethereum/util/rlp/src/rlpin.rs

173 lines
4.2 KiB
Rust
Raw Normal View History

// Copyright 2015-2017 Parity Technologies (UK) Ltd.
2016-02-05 13:40:41 +01:00
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
2016-01-15 21:03:38 +01:00
use std::fmt;
use rustc_serialize::hex::ToHex;
use ::{View, DecoderError, UntrustedRlp, PayloadInfo, Prototype, RlpDecodable};
2015-12-07 16:32:06 +01:00
2015-12-07 23:47:26 +01:00
impl<'a> From<UntrustedRlp<'a>> for Rlp<'a> {
fn from(rlp: UntrustedRlp<'a>) -> Rlp<'a> {
Rlp { rlp: rlp }
}
}
2015-12-07 16:32:06 +01:00
/// Data-oriented view onto trusted rlp-slice.
///
2015-12-07 16:32:06 +01:00
/// Unlikely to `UntrustedRlp` doesn't bother you with error
/// handling. It assumes that you know what you are doing.
2015-12-07 23:47:26 +01:00
#[derive(Debug)]
2015-12-07 16:32:06 +01:00
pub struct Rlp<'a> {
rlp: UntrustedRlp<'a>
}
2016-01-15 21:03:38 +01:00
impl<'a> fmt::Display for Rlp<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.rlp)
}
}
2015-12-07 23:47:26 +01:00
impl<'a, 'view> View<'a, 'view> for Rlp<'a> where 'a: 'view {
2015-12-07 16:32:06 +01:00
type Prototype = Prototype;
type PayloadInfo = PayloadInfo;
type Data = &'a [u8];
type Item = Rlp<'a>;
2015-12-07 23:47:26 +01:00
type Iter = RlpIterator<'a, 'view>;
2015-12-07 16:32:06 +01:00
/// Create a new instance of `Rlp`
fn new(bytes: &'a [u8]) -> Rlp<'a> {
Rlp {
rlp: UntrustedRlp::new(bytes)
}
}
2016-01-08 15:52:43 +01:00
fn as_raw(&'view self) -> &'a [u8] {
self.rlp.as_raw()
2015-12-07 16:32:06 +01:00
}
fn prototype(&self) -> Self::Prototype {
2015-12-07 23:47:26 +01:00
self.rlp.prototype().unwrap()
2015-12-07 16:32:06 +01:00
}
fn payload_info(&self) -> Self::PayloadInfo {
2015-12-07 23:47:26 +01:00
self.rlp.payload_info().unwrap()
2015-12-07 16:32:06 +01:00
}
fn data(&'view self) -> Self::Data {
2015-12-07 23:47:26 +01:00
self.rlp.data().unwrap()
2015-12-07 16:32:06 +01:00
}
fn item_count(&self) -> usize {
2015-12-07 23:47:26 +01:00
self.rlp.item_count()
2015-12-07 16:32:06 +01:00
}
fn size(&self) -> usize {
2015-12-07 23:47:26 +01:00
self.rlp.size()
2015-12-07 16:32:06 +01:00
}
fn at(&'view self, index: usize) -> Self::Item {
2015-12-07 23:47:26 +01:00
From::from(self.rlp.at(index).unwrap())
2015-12-07 16:32:06 +01:00
}
fn is_null(&self) -> bool {
2015-12-07 23:47:26 +01:00
self.rlp.is_null()
2015-12-07 16:32:06 +01:00
}
fn is_empty(&self) -> bool {
2015-12-07 23:47:26 +01:00
self.rlp.is_empty()
2015-12-07 16:32:06 +01:00
}
fn is_list(&self) -> bool {
2015-12-07 23:47:26 +01:00
self.rlp.is_list()
2015-12-07 16:32:06 +01:00
}
fn is_data(&self) -> bool {
2015-12-07 23:47:26 +01:00
self.rlp.is_data()
2015-12-07 16:32:06 +01:00
}
fn is_int(&self) -> bool {
2015-12-07 23:47:26 +01:00
self.rlp.is_int()
}
fn iter(&'view self) -> Self::Iter {
self.into_iter()
}
2016-01-29 13:59:29 +01:00
fn as_val<T>(&self) -> Result<T, DecoderError> where T: RlpDecodable {
2015-12-07 23:47:26 +01:00
self.rlp.as_val()
}
2015-12-08 14:44:22 +01:00
2016-01-29 13:59:29 +01:00
fn val_at<T>(&self, index: usize) -> Result<T, DecoderError> where T: RlpDecodable {
2015-12-08 14:44:22 +01:00
self.at(index).rlp.as_val()
}
2015-12-07 23:47:26 +01:00
}
impl <'a, 'view> Rlp<'a> where 'a: 'view {
fn view_as_val<T, R>(r: &'view R) -> T where R: View<'a, 'view>, T: RlpDecodable {
2015-12-08 00:07:07 +01:00
let res: Result<T, DecoderError> = r.as_val();
res.unwrap_or_else(|e| panic!("DecodeError: {}, {}", e, r.as_raw().to_hex()))
2015-12-07 23:47:26 +01:00
}
2016-02-03 16:43:48 +01:00
/// Decode into an object
2016-01-29 13:59:29 +01:00
pub fn as_val<T>(&self) -> T where T: RlpDecodable {
2015-12-08 14:44:22 +01:00
Self::view_as_val(self)
}
2016-02-03 16:43:48 +01:00
/// Decode list item at given index into an object
2016-01-29 13:59:29 +01:00
pub fn val_at<T>(&self, index: usize) -> T where T: RlpDecodable {
2015-12-08 14:44:22 +01:00
Self::view_as_val(&self.at(index))
2015-12-07 23:47:26 +01:00
}
}
/// Iterator over trusted rlp-slice list elements.
pub struct RlpIterator<'a, 'view> where 'a: 'view {
rlp: &'view Rlp<'a>,
index: usize
}
impl<'a, 'view> IntoIterator for &'view Rlp<'a> where 'a: 'view {
type Item = Rlp<'a>;
type IntoIter = RlpIterator<'a, 'view>;
fn into_iter(self) -> Self::IntoIter {
RlpIterator {
rlp: self,
index: 0,
}
}
}
impl<'a, 'view> Iterator for RlpIterator<'a, 'view> {
type Item = Rlp<'a>;
fn next(&mut self) -> Option<Rlp<'a>> {
let index = self.index;
let result = self.rlp.rlp.at(index).ok().map(From::from);
2015-12-07 23:47:26 +01:00
self.index += 1;
result
2015-12-07 16:32:06 +01:00
}
}
2016-01-15 21:25:55 +01:00
#[test]
fn break_it() {
use rustc_serialize::hex::FromHex;
use bigint::prelude::U256;
let h: Vec<u8> = FromHex::from_hex("f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap();
2016-01-15 21:25:55 +01:00
let r: Rlp = Rlp::new(&h);
let u: U256 = r.val_at(1);
assert_eq!(format!("{}", u), "19526463837540678066");
2016-01-15 21:25:55 +01:00
}