// Rust Bitcoin Library // Written in 2014 by // Andrew Poelstra // // To the extent possible under law, the author(s) have dedicated all // copyright and related and neighboring rights to this software to // the public domain worldwide. This software is distributed without // any warranty. // // You should have received a copy of the CC0 Public Domain Dedication // along with this software. // If not, see . // //! # Network Serialization //! //! This module defines the `Serializable` trait which is used for //! (de)serializing Bitcoin objects for transmission on the network. //! It also defines (de)serialization routines for many primitives. //! use collections::Vec; use std::io::{IoError, IoResult, OtherIoError, MemReader, MemWriter}; use network::encodable::{ConsensusDecodable, ConsensusEncodable}; use util::hash::Sha256dHash; /// Objects which are referred to by hash pub trait BitcoinHash { /// Produces a Sha256dHash which can be used to refer to the object fn bitcoin_hash(&self) -> Sha256dHash; } impl BitcoinHash for Vec { fn bitcoin_hash(&self) -> Sha256dHash { Sha256dHash::from_data(self.as_slice()) } } /// Encode an object into a vector pub fn serialize, IoError>>(obj: &T) -> IoResult> { let mut encoder = RawEncoder::new(MemWriter::new()); try!(obj.consensus_encode(&mut encoder)); Ok(encoder.unwrap().unwrap()) } /// Deserialize an object from a vector pub fn deserialize, IoError>>(data: Vec) -> IoResult { let mut decoder = RawDecoder::new(MemReader::new(data)); ConsensusDecodable::consensus_decode(&mut decoder) } /// An encoder for raw binary data pub struct RawEncoder { writer: W } /// An decoder for raw binary data pub struct RawDecoder { reader: R } impl RawEncoder { /// Constructor pub fn new(writer: W) -> RawEncoder { RawEncoder { writer: writer } } /// Returns the underlying Writer pub fn unwrap(self) -> W { self.writer } } impl RawDecoder { /// Constructor pub fn new(reader: R) -> RawDecoder { RawDecoder { reader: reader } } /// Returns the underlying Reader pub fn unwrap(self) -> R { self.reader } } /// A simple Encoder trait pub trait SimpleEncoder { /// Output a 64-bit uint fn emit_u64(&mut self, v: u64) -> Result<(), E>; /// Output a 32-bit uint fn emit_u32(&mut self, v: u32) -> Result<(), E>; /// Output a 16-bit uint fn emit_u16(&mut self, v: u16) -> Result<(), E>; /// Output a 8-bit uint fn emit_u8(&mut self, v: u8) -> Result<(), E>; /// Output a 64-bit int fn emit_i64(&mut self, v: i64) -> Result<(), E>; /// Output a 32-bit int fn emit_i32(&mut self, v: i32) -> Result<(), E>; /// Output a 16-bit int fn emit_i16(&mut self, v: i16) -> Result<(), E>; /// Output a 8-bit int fn emit_i8(&mut self, v: i8) -> Result<(), E>; /// Output a boolean fn emit_bool(&mut self, v: bool) -> Result<(), E>; } /// A simple Decoder trait pub trait SimpleDecoder { /// Read a 64-bit uint fn read_u64(&mut self) -> Result; /// Read a 32-bit uint fn read_u32(&mut self) -> Result; /// Read a 16-bit uint fn read_u16(&mut self) -> Result; /// Read a 8-bit uint fn read_u8(&mut self) -> Result; /// Read a 64-bit int fn read_i64(&mut self) -> Result; /// Read a 32-bit int fn read_i32(&mut self) -> Result; /// Read a 16-bit int fn read_i16(&mut self) -> Result; /// Read a 8-bit int fn read_i8(&mut self) -> Result; /// Read a boolean fn read_bool(&mut self) -> Result; /// Signal a decoding error fn error(&mut self, err: &str) -> E; } // TODO: trait reform: impl SimpleEncoder for every Encoder, ditto for Decoder impl SimpleEncoder for RawEncoder { #[inline] fn emit_u64(&mut self, v: u64) -> IoResult<()> { self.writer.write_le_u64(v) } #[inline] fn emit_u32(&mut self, v: u32) -> IoResult<()> { self.writer.write_le_u32(v) } #[inline] fn emit_u16(&mut self, v: u16) -> IoResult<()> { self.writer.write_le_u16(v) } #[inline] fn emit_u8(&mut self, v: u8) -> IoResult<()> { self.writer.write_u8(v) } #[inline] fn emit_i64(&mut self, v: i64) -> IoResult<()> { self.writer.write_le_i64(v) } #[inline] fn emit_i32(&mut self, v: i32) -> IoResult<()> { self.writer.write_le_i32(v) } #[inline] fn emit_i16(&mut self, v: i16) -> IoResult<()> { self.writer.write_le_i16(v) } #[inline] fn emit_i8(&mut self, v: i8) -> IoResult<()> { self.writer.write_i8(v) } #[inline] fn emit_bool(&mut self, v: bool) -> IoResult<()> { self.writer.write_i8(if v {1} else {0}) } } impl SimpleDecoder for RawDecoder { #[inline] fn read_u64(&mut self) -> IoResult { self.reader.read_le_u64() } #[inline] fn read_u32(&mut self) -> IoResult { self.reader.read_le_u32() } #[inline] fn read_u16(&mut self) -> IoResult { self.reader.read_le_u16() } #[inline] fn read_u8(&mut self) -> IoResult { self.reader.read_u8() } #[inline] fn read_i64(&mut self) -> IoResult { self.reader.read_le_i64() } #[inline] fn read_i32(&mut self) -> IoResult { self.reader.read_le_i32() } #[inline] fn read_i16(&mut self) -> IoResult { self.reader.read_le_i16() } #[inline] fn read_i8(&mut self) -> IoResult { self.reader.read_i8() } #[inline] fn read_bool(&mut self) -> IoResult { self.reader.read_u8().map(|res| res != 0) } #[inline] fn error(&mut self, err: &str) -> IoError { IoError { kind: OtherIoError, desc: "parse error", detail: Some(err.to_string()) } } } // Aren't really any tests here.. the main functions are serialize and // deserialize, which get the crap tested out of them it every other // module.