Merge pull request #59 from ethcore/generic_reader

Generic Reader
This commit is contained in:
Svyatoslav Nikolsky 2016-10-31 11:41:29 +03:00 committed by GitHub
commit ea83fc0e75
46 changed files with 238 additions and 134 deletions

View File

@ -1,3 +1,4 @@
use std::io;
use hex::FromHex;
use hash::H256;
use ser::{
@ -23,7 +24,7 @@ impl Serializable for Block {
}
impl Deserializable for Block {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = Block {
block_header: try!(reader.read()),
transactions: try!(reader.read_list()),
@ -35,7 +36,7 @@ impl Deserializable for Block {
impl From<&'static str> for Block {
fn from(s: &'static str) -> Self {
deserialize(&s.from_hex().unwrap()).unwrap()
deserialize(&s.from_hex().unwrap() as &[u8]).unwrap()
}
}

View File

@ -1,4 +1,4 @@
use std::fmt;
use std::{fmt, io};
use ser::{
Deserializable, Reader, Error as ReaderError,
Serializable, Stream, serialize
@ -48,7 +48,7 @@ impl Serializable for BlockHeader {
}
impl Deserializable for BlockHeader {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let block_header = BlockHeader {
version: try!(reader.read()),
previous_header_hash: try!(reader.read()),

View File

@ -1,7 +1,7 @@
//! Bitcoin trainsaction.
//! https://en.bitcoin.it/wiki/Protocol_documentation#tx
use std::io;
use heapsize::HeapSizeOf;
use hex::FromHex;
use bytes::Bytes;
@ -51,7 +51,7 @@ impl Serializable for OutPoint {
}
impl Deserializable for OutPoint {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = OutPoint {
hash: try!(reader.read()),
index: try!(reader.read()),
@ -95,7 +95,7 @@ impl Serializable for TransactionInput {
}
impl Deserializable for TransactionInput {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = TransactionInput {
previous_output: try!(reader.read()),
script_sig: try!(reader.read()),
@ -147,7 +147,7 @@ impl Serializable for TransactionOutput {
}
impl Deserializable for TransactionOutput {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = TransactionOutput {
value: try!(reader.read()),
script_pubkey: try!(reader.read()),
@ -209,7 +209,7 @@ impl Serializable for Transaction {
}
impl Deserializable for Transaction {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = Transaction {
version: try!(reader.read()),
inputs: try!(reader.read_list()),
@ -223,7 +223,7 @@ impl Deserializable for Transaction {
impl From<&'static str> for Transaction {
fn from(s: &'static str) -> Self {
deserialize(&s.from_hex().unwrap()).unwrap()
deserialize(&s.from_hex().unwrap() as &[u8]).unwrap()
}
}

View File

@ -210,7 +210,7 @@ impl Storage {
.into_iter()
.filter_map(|tx_hash| {
self.transaction_bytes(&tx_hash).and_then(|tx_bytes| {
match serialization::deserialize::<chain::Transaction>(&tx_bytes) {
match serialization::deserialize::<_, chain::Transaction>(tx_bytes.as_ref()) {
Ok(tx) => Some(tx),
Err(e) => {
self.db_error(format!("Error deserializing transaction, possible db corruption ({:?})", e));
@ -304,7 +304,7 @@ impl Store for Storage {
self.get(COL_BLOCK_HEADERS, &*block_hash)
.and_then(|header_bytes| {
let transactions = self.block_transactions_by_hash(&block_hash);;
let maybe_header = match serialization::deserialize::<chain::BlockHeader>(&header_bytes) {
let maybe_header = match serialization::deserialize::<_, chain::BlockHeader>(header_bytes.as_ref()) {
Ok(header) => Some(header),
Err(e) => {
self.db_error(format!("Error deserializing header, possible db corruption ({:?})", e));
@ -374,7 +374,7 @@ impl Store for Storage {
fn transaction(&self, hash: &H256) -> Option<chain::Transaction> {
self.transaction_bytes(hash).and_then(|tx_bytes| {
serialization::deserialize(&tx_bytes).map_err(
serialization::deserialize(tx_bytes.as_ref()).map_err(
|e| self.db_error(format!("Error deserializing transaction, possible db corruption ({:?})", e))
).ok()
})

View File

@ -1,3 +1,4 @@
use std::io;
use bytes::Bytes;
use ser::{
Stream, Serializable,
@ -22,7 +23,7 @@ impl Serializable for NetAddress {
}
impl Deserializable for NetAddress {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let net = NetAddress {
services: try!(reader.read()),
address: try!(reader.read()),
@ -35,7 +36,7 @@ impl Deserializable for NetAddress {
impl From<&'static str> for NetAddress {
fn from(s: &'static str) -> Self {
let bytes: Bytes = s.into();
deserialize(&bytes).unwrap()
deserialize(bytes.as_ref()).unwrap()
}
}
@ -65,7 +66,7 @@ mod tests {
#[test]
fn test_net_address_deserialize() {
let bytes = vec![
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x01,
0x20, 0x8d
];
@ -76,7 +77,7 @@ mod tests {
port: 8333.into(),
};
assert_eq!(expected, deserialize(&bytes).unwrap());
assert_eq!(expected, deserialize(&bytes as &[u8]).unwrap());
}
#[test]

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
use chain::{BlockHeader, ShortTransactionID};
use common::PrefilledTransaction;
@ -21,7 +22,7 @@ impl Serializable for BlockHeaderAndIDs {
}
impl Deserializable for BlockHeaderAndIDs {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let header= BlockHeaderAndIDs {
header: try!(reader.read()),
nonce: try!(reader.read()),

View File

@ -1,3 +1,4 @@
use std::io;
use hash::H256;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
use chain::Transaction;
@ -17,7 +18,7 @@ impl Serializable for BlockTransactions {
}
impl Deserializable for BlockTransactions {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let block_transactions = BlockTransactions {
blockhash: try!(reader.read()),
transactions: try!(reader.read_list()),

View File

@ -1,3 +1,4 @@
use std::io;
use hash::H256;
use ser::{
Serializable, Stream, CompactInteger,
@ -24,7 +25,7 @@ impl Serializable for BlockTransactionsRequest {
}
impl Deserializable for BlockTransactionsRequest {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let blockhash = try!(reader.read());
let indexes: Vec<CompactInteger> = try!(reader.read_list());

View File

@ -1,4 +1,4 @@
use std::{str, fmt};
use std::{str, fmt, io};
use std::ascii::AsciiExt;
use hash::H96;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
@ -57,7 +57,7 @@ impl Serializable for Command {
}
impl Deserializable for Command {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
reader.read().map(Command)
}
}
@ -101,7 +101,7 @@ mod tests {
let raw: Bytes = "76657273696f6e0000000000".into();
let expected: Command = "version".into();
assert_eq!(expected, deserialize::<Command>(&raw).unwrap());
assert_eq!(expected, deserialize::<_, Command>(raw.as_ref()).unwrap());
}
#[test]

View File

@ -1,3 +1,4 @@
use std::io;
use hash::H256;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
@ -37,7 +38,7 @@ impl Serializable for InventoryType {
}
impl Deserializable for InventoryType {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let t: u32 = try!(reader.read());
InventoryType::from_u32(t).ok_or(ReaderError::MalformedData)
}
@ -58,7 +59,7 @@ impl Serializable for InventoryVector {
}
impl Deserializable for InventoryVector {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let vec = InventoryVector {
inv_type: try!(reader.read()),
hash: try!(reader.read()),
@ -95,7 +96,7 @@ mod tests {
hash: 4u8.into(),
};
assert_eq!(expected, deserialize(&raw).unwrap());
assert_eq!(expected, deserialize(raw.as_ref()).unwrap());
}
#[test]

View File

@ -1,4 +1,4 @@
use std::{str, net};
use std::{str, net, io};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
@ -49,20 +49,24 @@ impl Serializable for IpAddress {
}
impl Deserializable for IpAddress {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let mut bytes = try!(reader.read_slice(12));
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let bytes: &mut [u8] = &mut [0u8; 12];
try!(reader.read_slice(bytes));
if bytes == &[0u8; 12] {
let address = try!(reader.read_slice(4));
let mut address: &mut [u8] = &mut [0u8; 4];
try!(reader.read_slice(address));
let address = net::Ipv4Addr::new(address[0], address[1], address[2], address[3]);
Ok(IpAddress(net::IpAddr::V4(address)))
} else {
// compiler needs some help here...
let mut b = bytes as &[u8];
let address = net::Ipv6Addr::new(
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(bytes.read_u16::<BigEndian>()),
try!(b.read_u16::<BigEndian>()),
try!(b.read_u16::<BigEndian>()),
try!(b.read_u16::<BigEndian>()),
try!(b.read_u16::<BigEndian>()),
try!(b.read_u16::<BigEndian>()),
try!(b.read_u16::<BigEndian>()),
try!(reader.read_u16::<BigEndian>()),
try!(reader.read_u16::<BigEndian>())
);
@ -87,9 +91,9 @@ mod test {
#[test]
fn test_ip_deserialize() {
let ip: IpAddress = deserialize(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x01]).unwrap();
let ip: IpAddress = deserialize(&[0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x01] as &[u8]).unwrap();
assert_eq!(ip, IpAddress(net::IpAddr::V6("::ffff:a00:1".parse().unwrap())));
let ip: IpAddress = deserialize(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01]).unwrap();
let ip: IpAddress = deserialize(&[0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01] as &[u8]).unwrap();
assert_eq!(ip, IpAddress(net::IpAddr::V4("10.0.0.1".parse().unwrap())));
}
}

View File

@ -1,3 +1,4 @@
use std::io;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
@ -23,7 +24,7 @@ impl Serializable for Port {
}
impl Deserializable for Port {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
Ok(try!(reader.read_u16::<BigEndian>().map(Port)))
}
}
@ -41,7 +42,7 @@ mod tests {
#[test]
fn test_port_deserialize() {
assert_eq!(Port::from(1), deserialize(&[0x00, 0x01]).unwrap());
assert_eq!(Port::from(0x1234), deserialize(&[0x12, 0x34]).unwrap());
assert_eq!(Port::from(1), deserialize(&[0x00u8, 0x01] as &[u8]).unwrap());
assert_eq!(Port::from(0x1234), deserialize(&[0x12u8, 0x34] as &[u8]).unwrap());
}
}

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{
Serializable, Stream, CompactInteger,
Deserializable, Reader, Error as ReaderError
@ -19,7 +20,7 @@ impl Serializable for PrefilledTransaction {
}
impl Deserializable for PrefilledTransaction {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let compact: CompactInteger = try!(reader.read());
let tx = PrefilledTransaction {
index: compact.into(),

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{
Serializable, Stream,
Deserializable, Reader, Error as ReaderError
@ -88,7 +89,7 @@ impl Serializable for Services {
}
impl Deserializable for Services {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
reader.read().map(Services)
}
}

View File

@ -1,9 +1,10 @@
use std::io;
use ser::{Reader, Stream};
use MessageResult;
pub trait Payload: Send + 'static {
fn version() -> u32;
fn command() -> &'static str;
fn deserialize_payload(reader: &mut Reader, version: u32) -> MessageResult<Self> where Self: Sized;
fn deserialize_payload<T>(reader: &mut Reader<T>, version: u32) -> MessageResult<Self> where Self: Sized, T: io::Read;
fn serialize_payload(&self, stream: &mut Stream, version: u32) -> MessageResult<()>;
}

View File

@ -11,12 +11,12 @@ pub fn deserialize_payload<T>(buffer: &[u8], version: u32) -> Result<T, Error> w
Ok(result)
}
pub struct PayloadReader<'a> {
reader: Reader<'a>,
pub struct PayloadReader<T> {
reader: Reader<T>,
version: u32,
}
impl<'a> PayloadReader<'a> {
impl<'a> PayloadReader<&'a [u8]> {
pub fn new(buffer: &'a [u8], version: u32) -> Self {
PayloadReader {
reader: Reader::new(buffer),
@ -32,7 +32,7 @@ impl<'a> PayloadReader<'a> {
T::deserialize_payload(&mut self.reader, self.version)
}
pub fn is_finished(&self) -> bool {
pub fn is_finished(&mut self) -> bool {
self.reader.is_finished()
}
}

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{
Serializable, Stream,
Deserializable, Reader, Error as ReaderError,
@ -28,7 +29,7 @@ impl Payload for Addr {
"addr"
}
fn deserialize_payload(reader: &mut Reader, version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, version: u32) -> MessageResult<Self> where T: io::Read {
let result = if version < 31402 {
reader.read().map(Addr::V0)
} else {
@ -69,7 +70,7 @@ impl Serializable for AddressEntry {
}
impl Deserializable for AddressEntry {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let entry = AddressEntry {
timestamp: try!(reader.read()),
address: try!(reader.read()),
@ -91,7 +92,7 @@ impl Serializable for V31402 {
}
impl Deserializable for V31402 {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = V31402 {
addresses: try!(reader.read_list_max(1000)),
};
@ -112,7 +113,7 @@ impl Serializable for V0 {
}
impl Deserializable for V0 {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = V0 {
addresses: try!(reader.read_list_max(1000)),
};
@ -173,7 +174,7 @@ mod tests {
],
};
assert_eq!(expected, deserialize(&raw).unwrap());
assert_eq!(expected, deserialize(raw.as_ref()).unwrap());
}
}

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use chain::Block as ChainBlock;
use {Payload, MessageResult};
@ -16,7 +17,7 @@ impl Payload for Block {
"block"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let tx = Block {
block: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use common::BlockTransactions;
use {MessageResult, Payload};
@ -16,7 +17,7 @@ impl Payload for BlockTxn {
"blocktxn"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let block = BlockTxn {
request: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use common::BlockHeaderAndIDs;
use {Payload, MessageResult};
@ -16,7 +17,7 @@ impl Payload for CompactBlock {
"cmpctblock"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let block = CompactBlock {
header: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -15,7 +16,7 @@ impl Payload for FeeFilter {
"cmpctblock"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let fee_filter = FeeFilter {
fee_rate: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use bytes::Bytes;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -17,7 +18,7 @@ impl Payload for FilterAdd {
"filteradd"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let filteradd = FilterAdd {
data: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -13,7 +14,7 @@ impl Payload for FilterClear {
"filterclear"
}
fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(_reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
Ok(FilterClear)
}

View File

@ -1,3 +1,4 @@
use std::io;
use bytes::Bytes;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -20,7 +21,7 @@ impl Payload for FilterLoad {
"filterload"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let filterload = FilterLoad {
filter: try!(reader.read()),
hash_functions: try!(reader.read()),

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -13,7 +14,7 @@ impl Payload for GetAddr {
"getaddr"
}
fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(_reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
Ok(GetAddr)
}

View File

@ -1,3 +1,4 @@
use std::io;
use hash::H256;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -18,7 +19,7 @@ impl Payload for GetBlocks {
"getblocks"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let get_blocks = GetBlocks {
version: try!(reader.read()),
block_locator_hashes: try!(reader.read_list_max(500)),

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use common::BlockTransactionsRequest;
use {Payload, MessageResult};
@ -16,7 +17,7 @@ impl Payload for GetBlockTxn {
"getblocktxn"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let get_block = GetBlockTxn {
request: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use common::InventoryVector;
use {Payload, MessageResult};
@ -16,7 +17,7 @@ impl Payload for GetData {
"getdata"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let inv = GetData {
inventory: try!(reader.read_list_max(50_000)),
};

View File

@ -1,3 +1,4 @@
use std::io;
use hash::H256;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -18,7 +19,7 @@ impl Payload for GetHeaders {
"getheaders"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let get_blocks = GetHeaders {
version: try!(reader.read()),
block_locator_hashes: try!(reader.read_list_max(2000)),

View File

@ -1,3 +1,4 @@
use std::io;
use chain::BlockHeader;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -17,7 +18,7 @@ impl Payload for Headers {
"headers"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let headers = Headers {
headers: try!(reader.read_list()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use common::InventoryVector;
use {Payload, MessageResult};
@ -16,7 +17,7 @@ impl Payload for Inv {
"inv"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let inv = Inv {
inventory: try!(reader.read_list_max(50_000)),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -13,7 +14,7 @@ impl Payload for MemPool {
"mempool"
}
fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(_reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
Ok(MemPool)
}

View File

@ -1,3 +1,4 @@
use std::io;
use hash::H256;
use bytes::Bytes;
use ser::{Stream, Reader};
@ -21,7 +22,7 @@ impl Payload for MerkleBlock {
"merkleblock"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let merkle_block = MerkleBlock {
block_header: try!(reader.read()),
total_transactions: try!(reader.read()),

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use common::InventoryVector;
use {Payload, MessageResult};
@ -16,7 +17,7 @@ impl Payload for NotFound {
"notfound"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let inv = NotFound {
inventory: try!(reader.read_list_max(50_000)),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {MessageResult, Payload};
@ -23,7 +24,7 @@ impl Payload for Ping {
"ping"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let ping = Ping {
nonce: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -23,7 +24,7 @@ impl Payload for Pong {
"pong"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let pong = Pong {
nonce: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
use {Payload, MessageResult};
@ -45,7 +46,7 @@ impl Serializable for RejectCode {
}
impl Deserializable for RejectCode {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let v: u8 = try!(reader.read());
RejectCode::from_u8(v).ok_or_else(|| ReaderError::MalformedData)
}
@ -68,7 +69,7 @@ impl Payload for Reject {
"reject"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let reject = Reject {
message: try!(reader.read()),
code: try!(reader.read()),

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -16,7 +17,7 @@ impl Payload for SendCompact {
"sendcmpct"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let send_compact = SendCompact {
first: try!(reader.read()),
second: try!(reader.read()),

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -13,7 +14,7 @@ impl Payload for SendHeaders {
"sendheaders"
}
fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(_reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
Ok(SendHeaders)
}

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use chain::Transaction;
use {Payload, MessageResult};
@ -16,7 +17,7 @@ impl Payload for Tx {
"tx"
}
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let tx = Tx {
transaction: try!(reader.read()),
};

View File

@ -1,3 +1,4 @@
use std::io;
use ser::{Stream, Reader};
use {Payload, MessageResult};
@ -13,7 +14,7 @@ impl Payload for Verack {
"verack"
}
fn deserialize_payload(_reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(_reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
Ok(Verack)
}

View File

@ -1,3 +1,4 @@
use std::io;
use bytes::Bytes;
use ser::{
Serializable, Stream,
@ -24,7 +25,7 @@ impl Payload for Version {
}
// version package is an serialization excpetion
fn deserialize_payload(reader: &mut Reader, _version: u32) -> MessageResult<Self> where Self: Sized {
fn deserialize_payload<T>(reader: &mut Reader<T>, _version: u32) -> MessageResult<Self> where T: io::Read {
let simple: V0 = try!(reader.read());
if simple.version < 106 {
@ -111,7 +112,7 @@ impl Serializable for V0 {
}
impl Deserializable for V0 {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = V0 {
version: try!(reader.read()),
services: try!(reader.read()),
@ -134,7 +135,7 @@ impl Serializable for V106 {
}
impl Deserializable for V106 {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = V106 {
from: try!(reader.read()),
nonce: try!(reader.read()),
@ -153,7 +154,7 @@ impl Serializable for V70001 {
}
impl Deserializable for V70001 {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = V70001 {
relay: try!(reader.read()),
};

View File

@ -1,7 +1,7 @@
//! A type of variable-length integer commonly used in the Bitcoin P2P protocol and Bitcoin serialized data structures.
//! https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers
use std::fmt;
use std::{fmt, io};
use {
Serializable, Stream,
Deserializable, Reader, Error as ReaderError
@ -94,7 +94,7 @@ impl Serializable for CompactInteger {
}
impl Deserializable for CompactInteger {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let result = match try!(reader.read::<u8>()) {
i @ 0...0xfc => i.into(),
0xfd => try!(reader.read::<u16>()).into(),

View File

@ -1,3 +1,4 @@
use std::io;
use bytes::Bytes;
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use hash::{H32, H48, H96, H160, H256, H264, H512, H520};
@ -90,7 +91,7 @@ impl Serializable for u64 {
impl Deserializable for bool {
#[inline]
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
let value = try!(reader.read_u8());
match value {
0 => Ok(false),
@ -102,42 +103,42 @@ impl Deserializable for bool {
impl Deserializable for i32 {
#[inline]
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
Ok(try!(reader.read_i32::<LittleEndian>()))
}
}
impl Deserializable for i64 {
#[inline]
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
Ok(try!(reader.read_i64::<LittleEndian>()))
}
}
impl Deserializable for u8 {
#[inline]
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
Ok(try!(reader.read_u8()))
}
}
impl Deserializable for u16 {
#[inline]
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
Ok(try!(reader.read_u16::<LittleEndian>()))
}
}
impl Deserializable for u32 {
#[inline]
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
Ok(try!(reader.read_u32::<LittleEndian>()))
}
}
impl Deserializable for u64 {
#[inline]
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
Ok(try!(reader.read_u64::<LittleEndian>()))
}
}
@ -158,7 +159,7 @@ impl Serializable for String {
}
impl Deserializable for String {
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
let bytes: Bytes = try!(reader.read());
Ok(String::from_utf8_lossy(&bytes).into_owned())
}
@ -178,10 +179,9 @@ macro_rules! impl_ser_for_hash {
}
impl Deserializable for $name {
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
let slice = try!(reader.read_slice($size));
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
let mut result = Self::default();
result.copy_from_slice(slice);
try!(reader.read_slice(&mut *result));
Ok(result)
}
}
@ -211,16 +211,18 @@ impl Serializable for Bytes {
}
impl Deserializable for Bytes {
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where T: io::Read {
let len = try!(reader.read::<CompactInteger>());
reader.read_slice(len.into()).map(|b| b.to_vec().into())
let mut bytes = Bytes::new_with_len(len.into());
try!(reader.read_slice(&mut bytes));
Ok(bytes)
}
}
#[cfg(test)]
mod tests {
use bytes::Bytes;
use {serialize, deserialize, Stream, Reader, Error};
use {serialize, deserialize, deserialize_iterator, Stream, Reader, Error};
#[test]
fn test_reader_read() {
@ -241,6 +243,19 @@ mod tests {
assert_eq!(Error::UnexpectedEnd, reader.read::<u8>().unwrap_err());
}
#[test]
fn test_reader_iterator() {
let buffer = vec![
1u8, 0,
2, 0,
3, 0,
4, 0,
];
let result = deserialize_iterator(&buffer as &[u8]).collect::<Result<Vec<u16>, _>>().unwrap();
assert_eq!(result, vec![1u16, 2, 3, 4]);
}
#[test]
fn test_stream_append() {
let mut stream = Stream::default();
@ -265,7 +280,7 @@ mod tests {
fn test_bytes_deserialize() {
let raw: Bytes = "020145".into();
let expected: Bytes = "0145".into();
assert_eq!(expected, deserialize(&raw).unwrap());
assert_eq!(expected, deserialize(raw.as_ref()).unwrap());
}
#[test]
@ -289,10 +304,10 @@ mod tests {
fn test_string_deserialize() {
let raw: Bytes = "0776657273696f6e".into();
let expected: String = "version".into();
assert_eq!(expected, deserialize::<String>(&raw).unwrap());
assert_eq!(expected, deserialize::<_, String>(raw.as_ref()).unwrap());
let raw: Bytes = "00".into();
let expected: String = "".into();
assert_eq!(expected, deserialize::<String>(&raw).unwrap());
assert_eq!(expected, deserialize::<_, String>(raw.as_ref()).unwrap());
}
#[test]

View File

@ -9,5 +9,5 @@ pub mod stream;
pub use primitives::{hash, bytes};
pub use compact_integer::CompactInteger;
pub use self::reader::{Reader, Deserializable, deserialize, Error};
pub use self::reader::{Reader, Deserializable, deserialize, deserialize_iterator, Error};
pub use self::stream::{Stream, Serializable, serialize, serialized_list_size};

View File

@ -1,14 +1,21 @@
use std::{io, cmp};
use std::{io, marker};
use compact_integer::CompactInteger;
pub fn deserialize<T>(buffer: &[u8]) -> Result<T, Error> where T: Deserializable {
let mut reader = Reader::new(buffer);
pub fn deserialize<R, T>(buffer: R) -> Result<T, Error> where R: io::Read, T: Deserializable {
let mut reader = Reader::from_read(buffer);
let result = try!(reader.read());
if !reader.is_finished() {
return Err(Error::UnreadData);
}
Ok(result)
match reader.is_finished() {
false => Err(Error::UnreadData),
true => Ok(result),
}
}
pub fn deserialize_iterator<R, T>(buffer: R) -> ReadIterator<R, T> where R: io::Read, T: Deserializable {
ReadIterator {
reader: Reader::from_read(buffer),
iter_type: marker::PhantomData,
}
}
#[derive(Debug, PartialEq)]
@ -25,29 +32,50 @@ impl From<io::Error> for Error {
}
pub trait Deserializable {
fn deserialize(reader: &mut Reader) -> Result<Self, Error> where Self: Sized;
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, Error> where Self: Sized, T: io::Read;
}
/// Bitcoin structures reader.
#[derive(Debug)]
pub struct Reader<'a> {
buffer: &'a [u8],
read: usize,
pub struct Reader<T> {
buffer: T,
peeked: Option<u8>,
}
impl<'a> io::Read for Reader<'a> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
let to_read = cmp::min(self.buffer.len() - self.read, buf.len());
buf[0..to_read].copy_from_slice(&self.buffer[self.read..self.read + to_read]);
self.read += to_read;
Ok(to_read)
impl<'a> Reader<&'a [u8]> {
/// Convenient way of creating for slice of bytes
pub fn new(buffer: &'a [u8]) -> Self {
Reader {
buffer: buffer,
peeked: None,
}
}
}
impl<'a> Reader<'a> {
pub fn new(buffer: &'a [u8]) -> Reader {
impl<T> io::Read for Reader<T> where T: io::Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
// most of the times, there will be nothing in peeked,
// so to make it as efficient as possible, check it
// only once
match self.peeked.take() {
None => io::Read::read(&mut self.buffer, buf),
Some(peeked) if buf.is_empty() => {
self.peeked = Some(peeked);
Ok(0)
},
Some(peeked) => {
buf[0] = peeked;
io::Read::read(&mut self.buffer, &mut buf[1..]).map(|x| x + 1)
},
}
}
}
impl<R> Reader<R> where R: io::Read {
pub fn from_read(read: R) -> Self {
Reader {
buffer: buffer,
read: 0,
buffer: read,
peeked: None,
}
}
@ -55,14 +83,8 @@ impl<'a> Reader<'a> {
T::deserialize(self)
}
pub fn read_slice(&mut self, len: usize) -> Result<&'a [u8], Error> {
if self.read + len > self.buffer.len() {
return Err(Error::UnexpectedEnd);
}
let result = &self.buffer[self.read..self.read + len];
self.read += len;
Ok(result)
pub fn read_slice(&mut self, bytes: &mut [u8]) -> Result<(), Error> {
io::Read::read_exact(self, bytes).map_err(|_| Error::UnexpectedEnd)
}
pub fn read_list<T>(&mut self) -> Result<Vec<T>, Error> where T: Deserializable {
@ -91,8 +113,35 @@ impl<'a> Reader<'a> {
Ok(result)
}
/// Returns true if reading is finished.
pub fn is_finished(&self) -> bool {
self.read == self.buffer.len()
pub fn is_finished(&mut self) -> bool {
if self.peeked.is_some() {
return false;
}
let peek: &mut [u8] = &mut [0u8];
match self.read_slice(peek) {
Ok(_) => {
self.peeked = Some(peek[0]);
false
},
Err(_) => true,
}
}
}
/// Should be used to iterate over structures of the same type
pub struct ReadIterator<R, T> {
reader: Reader<R>,
iter_type: marker::PhantomData<T>,
}
impl<R, T> Iterator for ReadIterator<R, T> where R: io::Read, T: Deserializable {
type Item = Result<T, Error>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.is_finished() {
true => None,
false => Some(self.reader.read())
}
}
}