Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add encoded_len and bytes written #252

Merged
merged 3 commits into from
Dec 5, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions src/multihash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,30 @@ impl<const S: usize> Multihash<S> {
Ok(result)
}

/// Writes a multihash to a byte stream.
pub fn write<W: io::Write>(&self, w: W) -> Result<(), Error> {
/// Writes a multihash to a byte stream, returning the written size.
pub fn write<W: io::Write>(&self, w: W) -> Result<usize, Error> {
write_multihash(w, self.code(), self.size(), self.digest())
}

/// Returns the length in bytes needed to encode this multihash into bytes.
pub fn encoded_len(&self) -> usize {
let mut code_buf = varint_encode::u64_buffer();
let code = varint_encode::u64(self.code, &mut code_buf);

let mut size_buf = varint_encode::u8_buffer();
let size = varint_encode::u8(self.size, &mut size_buf);

code.len() + size.len() + usize::from(self.size)
}

#[cfg(feature = "alloc")]
/// Returns the bytes of a multihash.
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::with_capacity(self.size().into());
self.write(&mut bytes)
let written = self
.write(&mut bytes)
.expect("writing to a vec should never fail");
debug_assert_eq!(written, bytes.len());
bytes
}

Expand Down Expand Up @@ -293,7 +306,7 @@ impl<const S: usize> parity_scale_codec::Decode for Multihash<S> {
}

/// Writes the multihash to a byte stream.
pub fn write_multihash<W>(mut w: W, code: u64, size: u8, digest: &[u8]) -> Result<(), Error>
pub fn write_multihash<W>(mut w: W, code: u64, size: u8, digest: &[u8]) -> Result<usize, Error>
where
W: io::Write,
{
Expand All @@ -303,10 +316,13 @@ where
let mut size_buf = varint_encode::u8_buffer();
let size = varint_encode::u8(size, &mut size_buf);

let written = code.len() + size.len() + digest.len();

w.write_all(code)?;
w.write_all(size)?;
w.write_all(digest)?;
Ok(())

Ok(written)
}

/// Reads a multihash from a byte stream that contains a full multihash (code, size and the digest)
Expand Down Expand Up @@ -361,9 +377,10 @@ mod tests {
fn roundtrip() {
let hash = Code::Sha2_256.digest(b"hello world");
let mut buf = [0u8; 35];
hash.write(&mut buf[..]).unwrap();
let written = hash.write(&mut buf[..]).unwrap();
let hash2 = Multihash::<32>::read(&buf[..]).unwrap();
assert_eq!(hash, hash2);
assert_eq!(hash.encoded_len(), written);
}

#[test]
Expand Down