Return encoded length from WriteExt::emit_slice

We would like to add a `emit_varint` function, however doing so requires
that we can get access to the length of a slice when we are encoding it
so we can use `emit_slice` to implement `emit_varint`. It would be
easier to do so if `emit_slice` returned the length of the slice.

In preparation for adding `emit_varint` (and removing the `VarInt` type)
return the encoded length of a slice from `WriteExt::emit_slice`.

(Patch originally written by Steven, cherry-pick and patch description
written by Tobin.)

Co-developed-by: Tobin C. Harding <me@tobin.cc>
This commit is contained in:
Steven Roose 2023-10-19 17:56:33 +01:00 committed by Tobin C. Harding
parent 40ba08f369
commit 003db025c1
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
3 changed files with 12 additions and 16 deletions

View File

@ -239,8 +239,7 @@ impl Encodable for Witness {
let content_with_indices_len = self.content.len(); let content_with_indices_len = self.content.len();
let indices_size = self.witness_elements * 4; let indices_size = self.witness_elements * 4;
let content_len = content_with_indices_len - indices_size; let content_len = content_with_indices_len - indices_size;
w.emit_slice(&self.content[..content_len])?; Ok(w.emit_slice(&self.content[..content_len])? + len.size())
Ok(content_len + len.size())
} }
} }

View File

@ -209,7 +209,7 @@ pub trait WriteExt: Write {
fn emit_bool(&mut self, v: bool) -> Result<(), io::Error>; fn emit_bool(&mut self, v: bool) -> Result<(), io::Error>;
/// Outputs a byte slice. /// Outputs a byte slice.
fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error>; fn emit_slice(&mut self, v: &[u8]) -> Result<usize, io::Error>;
} }
/// Extensions of `Read` to decode data as per Bitcoin consensus. /// Extensions of `Read` to decode data as per Bitcoin consensus.
@ -274,7 +274,10 @@ impl<W: Write + ?Sized> WriteExt for W {
#[inline] #[inline]
fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> { self.write_all(&[v as u8]) } fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> { self.write_all(&[v as u8]) }
#[inline] #[inline]
fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error> { self.write_all(v) } fn emit_slice(&mut self, v: &[u8]) -> Result<usize, io::Error> {
self.write_all(v)?;
Ok(v.len())
}
} }
impl<R: Read + ?Sized> ReadExt for R { impl<R: Read + ?Sized> ReadExt for R {
@ -546,8 +549,7 @@ impl Encodable for String {
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> { fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let b = self.as_bytes(); let b = self.as_bytes();
let vi_len = VarInt(b.len().to_u64()).consensus_encode(w)?; let vi_len = VarInt(b.len().to_u64()).consensus_encode(w)?;
w.emit_slice(b)?; Ok(vi_len + w.emit_slice(b)?)
Ok(vi_len + b.len())
} }
} }
@ -564,8 +566,7 @@ impl Encodable for Cow<'static, str> {
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> { fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let b = self.as_bytes(); let b = self.as_bytes();
let vi_len = VarInt(b.len().to_u64()).consensus_encode(w)?; let vi_len = VarInt(b.len().to_u64()).consensus_encode(w)?;
w.emit_slice(b)?; Ok(vi_len + w.emit_slice(b)?)
Ok(vi_len + b.len())
} }
} }
@ -586,8 +587,7 @@ macro_rules! impl_array {
&self, &self,
w: &mut W, w: &mut W,
) -> core::result::Result<usize, io::Error> { ) -> core::result::Result<usize, io::Error> {
w.emit_slice(&self[..])?; Ok(w.emit_slice(&self[..])?)
Ok(self.len())
} }
} }
@ -701,8 +701,7 @@ pub(crate) fn consensus_encode_with_size<W: Write + ?Sized>(
w: &mut W, w: &mut W,
) -> Result<usize, io::Error> { ) -> Result<usize, io::Error> {
let vi_len = VarInt(data.len().to_u64()).consensus_encode(w)?; let vi_len = VarInt(data.len().to_u64()).consensus_encode(w)?;
w.emit_slice(data)?; Ok(vi_len + w.emit_slice(data)?)
Ok(vi_len + data.len())
} }
struct ReadBytesFromFiniteReaderOpts { struct ReadBytesFromFiniteReaderOpts {
@ -779,8 +778,7 @@ impl Encodable for CheckedData {
.expect("network message use u32 as length") .expect("network message use u32 as length")
.consensus_encode(w)?; .consensus_encode(w)?;
self.checksum().consensus_encode(w)?; self.checksum().consensus_encode(w)?;
w.emit_slice(&self.data)?; Ok(8 + w.emit_slice(&self.data)?)
Ok(8 + self.data.len())
} }
} }

View File

@ -148,8 +148,7 @@ impl Encodable for AddrV2 {
) -> Result<usize, io::Error> { ) -> Result<usize, io::Error> {
let len = network.consensus_encode(w)? let len = network.consensus_encode(w)?
+ VarInt::from(bytes.len()).consensus_encode(w)? + VarInt::from(bytes.len()).consensus_encode(w)?
+ bytes.len(); + w.emit_slice(bytes)?;
w.emit_slice(bytes)?;
Ok(len) Ok(len)
} }
Ok(match *self { Ok(match *self {