X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Futil%2Fser.rs;h=7f795fe46a23defb08494c03f1eef71396bfd670;hb=1f1f82569a1774d2f6cb84e1de3c55dc733022c8;hp=1944519d05316186f3bec612ac8d5b8612523e0c;hpb=c3e225597d3981410644b84ad1e7b02c7a6bc7c7;p=rust-lightning diff --git a/src/util/ser.rs b/src/util/ser.rs index 1944519d0..7f795fe46 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; @@ -13,135 +13,108 @@ use ln::msgs::DecodeError; use util::byte_utils::{be64_to_array, be32_to_array, be16_to_array, slice_to_be16, slice_to_be32, slice_to_be64}; -const MAX_BUF_SIZE: usize = 16 * 1024; +const MAX_BUF_SIZE: usize = 64 * 1024; -pub struct Writer { writer: W } -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) + } +} -pub trait Writeable { - fn write(&self, writer: &mut Writer) -> Result<(), DecodeError>; +/// A trait that various rust-lightning types implement allowing them to be written out to a Writer +pub trait Writeable { + /// Writes self out to the given Writer + fn write(&self, writer: &mut W) -> Result<(), DecodeError>; } +/// 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 { - fn read(reader: &mut Reader) -> Result; + /// Reads a Self in from the given Read + fn read(reader: &mut R) -> Result; } -impl Writer { - pub fn new(writer: W) -> Writer { - return Writer { writer } - } - pub fn into_inner(self) -> W { self.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 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 { - pub fn new(reader: R) -> Reader { - return Reader { reader } - } - pub fn into_inner(self) -> R { self.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 fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), DecodeError> { - Ok(self.reader.read_exact(buf)?) - } - pub 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) @@ -158,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)?; @@ -179,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 { @@ -190,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)?; @@ -210,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::()) @@ -224,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)?; @@ -239,8 +212,8 @@ impl Readable for Script { } } -impl Writeable for Option