diff --git a/core/src/core/transaction.rs b/core/src/core/transaction.rs index 5af9ccd7..6884cc85 100644 --- a/core/src/core/transaction.rs +++ b/core/src/core/transaction.rs @@ -304,7 +304,7 @@ pub enum Output { impl Writeable for Output { fn write(&self, writer: &mut Writer) -> Result<(), ser::Error> { try!(writer.write_fixed_bytes(&self.commitment().unwrap())); - writer.write_bytes(&mut self.proof().unwrap().bytes()) + writer.write_bytes(&self.proof().unwrap().bytes()) } } diff --git a/core/src/ser.rs b/core/src/ser.rs index a0e09c7a..4ffd516e 100644 --- a/core/src/ser.rs +++ b/core/src/ser.rs @@ -21,7 +21,7 @@ use std::{error, fmt}; use std::io::{self, Write, Read}; -use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian}; +use byteorder::{ByteOrder, ReadBytesExt, BigEndian}; /// Possible errors deriving from serializing or deserializing. #[derive(Debug)] @@ -85,21 +85,48 @@ pub trait AsFixedBytes { /// written to an underlying stream or container (depending on implementation). pub trait Writer { /// Writes a u8 as bytes - fn write_u8(&mut self, n: u8) -> Result<(), Error>; + fn write_u8(&mut self, n: u8) -> Result<(), Error> { + self.write_fixed_bytes(&[n]) + } + /// Writes a u16 as bytes - fn write_u16(&mut self, n: u16) -> Result<(), Error>; + fn write_u16(&mut self, n: u16) -> Result<(), Error> { + let mut bytes = [0; 2]; + BigEndian::write_u16(&mut bytes, n); + self.write_fixed_bytes(&bytes) + } + /// Writes a u32 as bytes - fn write_u32(&mut self, n: u32) -> Result<(), Error>; + fn write_u32(&mut self, n: u32) -> Result<(), Error> { + let mut bytes = [0; 4]; + BigEndian::write_u32(&mut bytes, n); + self.write_fixed_bytes(&bytes) + } + /// Writes a u64 as bytes - fn write_u64(&mut self, n: u64) -> Result<(), Error>; + fn write_u64(&mut self, n: u64) -> Result<(), Error> { + let mut bytes = [0; 8]; + BigEndian::write_u64(&mut bytes, n); + self.write_fixed_bytes(&bytes) + } + /// Writes a i64 as bytes - fn write_i64(&mut self, n: i64) -> Result<(), Error>; - /// Writes a variable length `Vec`, the length of the `Vec` is encoded as a + fn write_i64(&mut self, n: i64) -> Result<(), Error> { + let mut bytes = [0; 8]; + BigEndian::write_i64(&mut bytes, n); + self.write_fixed_bytes(&bytes) + } + + /// Writes a variable number of bytes. The length is encoded as a 64-bit /// prefix. - fn write_bytes(&mut self, data: &[u8]) -> Result<(), Error>; + fn write_bytes(&mut self, bytes: &AsFixedBytes) -> Result<(), Error> { + try!(self.write_u64(bytes.as_fixed_bytes().len() as u64)); + self.write_fixed_bytes(bytes) + } + /// Writes a fixed number of bytes from something that can turn itself into /// a `&[u8]`. The reader is expected to know the actual length on read. - fn write_fixed_bytes(&mut self, b32: &AsFixedBytes) -> Result<(), Error>; + fn write_fixed_bytes(&mut self, fixed: &AsFixedBytes) -> Result<(), Error>; } /// Implementations defined how different numbers and binary structures are @@ -225,38 +252,8 @@ struct BinWriter<'a> { } impl<'a> Writer for BinWriter<'a> { - fn write_u8(&mut self, n: u8) -> Result<(), Error> { - try!(self.sink.write_u8(n)); - Ok(()) - } - fn write_u16(&mut self, n: u16) -> Result<(), Error> { - try!(self.sink.write_u16::(n)); - Ok(()) - } - fn write_u32(&mut self, n: u32) -> Result<(), Error> { - try!(self.sink.write_u32::(n)); - Ok(()) - } - - fn write_u64(&mut self, n: u64) -> Result<(), Error> { - try!(self.sink.write_u64::(n)); - Ok(()) - } - - fn write_i64(&mut self, n: i64) -> Result<(), Error> { - try!(self.sink.write_i64::(n)); - Ok(()) - } - - - fn write_bytes(&mut self, data: &[u8]) -> Result<(), Error> { - try!(self.write_u64(data.len() as u64)); - try!(self.sink.write_all(data)); - Ok(()) - } - - fn write_fixed_bytes(&mut self, b32: &AsFixedBytes) -> Result<(), Error> { - let bs = b32.as_fixed_bytes(); + fn write_fixed_bytes(&mut self, fixed: &AsFixedBytes) -> Result<(), Error> { + let bs = fixed.as_fixed_bytes(); try!(self.sink.write_all(bs)); Ok(()) } @@ -276,6 +273,16 @@ impl_slice_bytes!(::secp::key::SecretKey); impl_slice_bytes!(::secp::Signature); impl_slice_bytes!(::secp::pedersen::Commitment); impl_slice_bytes!(Vec); +impl_slice_bytes!([u8; 1]); +impl_slice_bytes!([u8; 2]); +impl_slice_bytes!([u8; 4]); +impl_slice_bytes!([u8; 8]); + +impl<'a> AsFixedBytes for &'a [u8] { + fn as_fixed_bytes(&self) -> &[u8] { + *self + } +} impl AsFixedBytes for ::core::hash::Hash { fn as_fixed_bytes(&self) -> &[u8] {