X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Futil%2Fser.rs;h=7f795fe46a23defb08494c03f1eef71396bfd670;hb=1f1f82569a1774d2f6cb84e1de3c55dc733022c8;hp=cd5e6a0db2cdb1959e9fcd9b69b930c3b30f9edd;hpb=51ba6ad2e95d4ddb172b4d4d4b067f94fcdb0aac;p=rust-lightning diff --git a/src/util/ser.rs b/src/util/ser.rs index cd5e6a0d..7f795fe4 100644 --- a/src/util/ser.rs +++ b/src/util/ser.rs @@ -1,5 +1,5 @@ use std::result::Result; -use std::io::{Read, Write}; +use std::io::Read; use std::collections::HashMap; use std::hash::Hash; use std::mem; @@ -15,147 +15,106 @@ use util::byte_utils::{be64_to_array, be32_to_array, be16_to_array, slice_to_be1 const MAX_BUF_SIZE: usize = 64 * 1024; -/// A struct that holds an std::io::Write-impl'ing object and implements various -/// rust-lightning-specific write functions. -pub struct Writer { writer: W } -/// A struct that holds an std::io::Read-impl'ing object and implements various -/// rust-lightning-specific read functions. -pub struct Reader { reader: R } +/// A trait that is similar to std::io::Write. +/// An impl is provided for any type that also impls std::io::Write. +pub trait Writer { + /// Writes the given buf out. See std::io::Write::write_all for more + fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error>; +} + +impl Writer for W { + fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { + ::write_all(self, buf) + } +} /// A trait that various rust-lightning types implement allowing them to be written out to a Writer -pub trait Writeable { +pub trait Writeable { /// Writes self out to the given Writer - fn write(&self, writer: &mut Writer) -> Result<(), DecodeError>; + fn write(&self, writer: &mut W) -> Result<(), DecodeError>; } -/// A trait that various rust-lightning types implement allowing them to be read in from a Reader +/// A trait that various rust-lightning types implement allowing them to be read in from a Read pub trait Readable where Self: Sized, R: Read { - /// Reads a Self in from the given Reader - fn read(reader: &mut Reader) -> Result; + /// Reads a Self in from the given Read + fn read(reader: &mut R) -> Result; } -impl Writer { - /// Creates a new Writer from an std::io::Write-impl'ing object - pub fn new(writer: W) -> Writer { - return Writer { writer } - } - /// Consumes this object and returns the original writer - pub fn into_inner(self) -> W { self.writer } - /// Gets a reference to the original writer - pub fn get_ref(&self) -> &W { &self.writer } - fn write_u64(&mut self, v: u64) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&be64_to_array(v))?) - } - fn write_u32(&mut self, v: u32) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&be32_to_array(v))?) - } - fn write_u16(&mut self, v: u16) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&be16_to_array(v))?) - } - fn write_u8(&mut self, v: u8) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&[v])?) - } - fn write_bool(&mut self, v: bool) -> Result<(), DecodeError> { - Ok(self.writer.write_all(&[if v {1} else {0}])?) - } - pub(crate) fn write_all(&mut self, v: &[u8]) -> Result<(), DecodeError> { - Ok(self.writer.write_all(v)?) +macro_rules! impl_writeable_primitive { + ($val_type:ty, $meth_write:ident, $len: expr, $meth_read:ident) => { + impl Writeable for $val_type { + #[inline] + fn write(&self, writer: &mut W) -> Result<(), DecodeError> { + Ok(writer.write_all(&$meth_write(*self))?) + } + } + impl Readable for $val_type { + #[inline] + fn read(reader: &mut R) -> Result<$val_type, DecodeError> { + let mut buf = [0; $len]; + reader.read_exact(&mut buf)?; + Ok($meth_read(&buf)) + } + } } } -impl Reader { - /// Creates a new Reader from an std::io::Read-impl'ing object - pub fn new(reader: R) -> Reader { - return Reader { reader } - } - /// Consumes this object and returns the original reader - pub fn into_inner(self) -> R { self.reader } - /// Gets a reference to the original reader - pub fn get_ref(&self) -> &R { &self.reader } +impl_writeable_primitive!(u64, be64_to_array, 8, slice_to_be64); +impl_writeable_primitive!(u32, be32_to_array, 4, slice_to_be32); +impl_writeable_primitive!(u16, be16_to_array, 2, slice_to_be16); - fn read_u64(&mut self) -> Result { - let mut buf = [0; 8]; - self.reader.read_exact(&mut buf)?; - Ok(slice_to_be64(&buf)) - } - - fn read_u32(&mut self) -> Result { - let mut buf = [0; 4]; - self.reader.read_exact(&mut buf)?; - Ok(slice_to_be32(&buf)) - } - - fn read_u16(&mut self) -> Result { - let mut buf = [0; 2]; - self.reader.read_exact(&mut buf)?; - Ok(slice_to_be16(&buf)) +impl Writeable for u8 { + #[inline] + fn write(&self, writer: &mut W) -> Result<(), DecodeError> { + Ok(writer.write_all(&[*self])?) } - - fn read_u8(&mut self) -> Result { +} +impl Readable for u8 { + #[inline] + fn read(reader: &mut R) -> Result { let mut buf = [0; 1]; - self.reader.read_exact(&mut buf)?; + reader.read_exact(&mut buf)?; Ok(buf[0]) } - fn read_bool(&mut self) -> Result { +} + +impl Writeable for bool { + #[inline] + fn write(&self, writer: &mut W) -> Result<(), DecodeError> { + Ok(writer.write_all(&[if *self {1} else {0}])?) + } +} +impl Readable for bool { + #[inline] + fn read(reader: &mut R) -> Result { let mut buf = [0; 1]; - self.reader.read_exact(&mut buf)?; + reader.read_exact(&mut buf)?; if buf[0] != 0 && buf[0] != 1 { return Err(DecodeError::InvalidValue); } Ok(buf[0] == 1) } - pub(crate) fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), DecodeError> { - Ok(self.reader.read_exact(buf)?) - } - pub(crate) fn read_to_end(&mut self, buf: &mut Vec) -> Result { - Ok(self.reader.read_to_end(buf)?) - } } -macro_rules! impl_writeable_primitive { - ($val_type:ty, $meth_write:ident, $meth_read:ident) => { - impl Writeable for $val_type { - #[inline] - fn write(&self, writer: &mut Writer) -> Result<(), DecodeError> { - writer.$meth_write(*self) - } - } - impl Readable for $val_type { - #[inline] - fn read(reader: &mut Reader) -> Result<$val_type, DecodeError> { - reader.$meth_read() - } - } - } -} - -impl_writeable_primitive!(u64, write_u64, read_u64); -impl_writeable_primitive!(u32, write_u32, read_u32); -impl_writeable_primitive!(u16, write_u16, read_u16); -impl_writeable_primitive!(u8, write_u8, read_u8); -impl_writeable_primitive!(bool, write_bool, read_bool); - // u8 arrays macro_rules! impl_array { ( $size:expr ) => ( - impl Writeable for [u8; $size] - where W: Write + impl Writeable for [u8; $size] { #[inline] - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { w.write_all(self)?; Ok(()) } } - impl Readable for [u8; $size] - where R: Read + impl Readable for [u8; $size] { #[inline] - fn read(r: &mut Reader) -> Result { + fn read(r: &mut R) -> Result { let mut buf = [0u8; $size]; r.read_exact(&mut buf)?; Ok(buf) @@ -172,12 +131,12 @@ impl_array!(1300); // for OnionPacket.hop_data // HashMap impl Writeable for HashMap - where W: Write, + where W: Writer, K: Writeable + Eq + Hash, V: Writeable { #[inline] - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { (self.len() as u16).write(w)?; for (key, value) in self.iter() { key.write(w)?; @@ -193,7 +152,7 @@ impl Readable for HashMap V: Readable { #[inline] - fn read(r: &mut Reader) -> Result { + fn read(r: &mut R) -> Result { let len: u16 = Readable::read(r)?; let mut ret = HashMap::with_capacity(len as usize); for _ in 0..len { @@ -204,9 +163,9 @@ impl Readable for HashMap } // Vectors -impl> Writeable for Vec { +impl> Writeable for Vec { #[inline] - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { let byte_size = (self.len() as usize) .checked_mul(mem::size_of::()) .ok_or(DecodeError::BadLengthDescriptor)?; @@ -224,7 +183,7 @@ impl> Writeable for Vec { impl> Readable for Vec { #[inline] - fn read(r: &mut Reader) -> Result { + fn read(r: &mut R) -> Result { let len: u16 = Readable::read(r)?; let byte_size = (len as usize) .checked_mul(mem::size_of::()) @@ -238,14 +197,14 @@ impl> Readable for Vec { } } -impl Writeable for Script { - fn write(&self, w: &mut Writer) -> Result<(), DecodeError> { +impl Writeable for Script { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { self.to_bytes().to_vec().write(w) } } impl Readable for Script { - fn read(r: &mut Reader) -> Result { + fn read(r: &mut R) -> Result { let len = >::read(r)? as usize; let mut buf = vec![0; len]; r.read_exact(&mut buf)?; @@ -253,8 +212,8 @@ impl Readable for Script { } } -impl Writeable for Option