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 indices_size = self.witness_elements * 4;
let content_len = content_with_indices_len - indices_size;
w.emit_slice(&self.content[..content_len])?;
Ok(content_len + len.size())
Ok(w.emit_slice(&self.content[..content_len])? + len.size())
}
}

View File

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

View File

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