Merge rust-bitcoin/rust-bitcoin#3077: hashes: Add a new `hash_reader` function
0a045d87ea
hashes: Add a new hash_reader function (Tobin C. Harding) Pull request description: Add a function `hash_reader` that uses the `BufRead` trait to read bytes directly into the hash engine. Add the functionality to: - as a trait method in the `GeneralHash` trait with default implementation - as inherent functions to all the hash types Close: #3050 ACKs for top commit: Kixunil: ACK0a045d87ea
apoelstra: ACK0a045d87ea
successfully ran local tests Tree-SHA512: 225f1d72f7a6119313d36422a3f7dc026ddcd27de9c8712c5734ea6056bb21e4857814761dbf2383a7a87fa82573ffc2097f67d08a0785a93e691c1745d0db8c
This commit is contained in:
commit
d214dc7b09
|
@ -209,6 +209,13 @@ macro_rules! hash_type {
|
|||
Self::from_engine(engine)
|
||||
}
|
||||
|
||||
|
||||
/// Hashes the entire contents of the `reader`.
|
||||
#[cfg(feature = "bitcoin-io")]
|
||||
pub fn hash_reader<R: io::BufRead>(reader: &mut R) -> Result<Self, io::Error> {
|
||||
<Self as crate::GeneralHash>::hash_reader(reader)
|
||||
}
|
||||
|
||||
/// Returns the underlying byte array.
|
||||
pub const fn to_byte_array(self) -> [u8; $bits / 8] { self.0 }
|
||||
|
||||
|
|
|
@ -80,6 +80,9 @@ extern crate alloc;
|
|||
#[cfg(any(test, feature = "std"))]
|
||||
extern crate core;
|
||||
|
||||
#[cfg(feature = "bitcoin-io")]
|
||||
extern crate bitcoin_io as io;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
/// A generic serialization/deserialization framework.
|
||||
pub extern crate serde;
|
||||
|
@ -232,6 +235,27 @@ pub trait GeneralHash: Hash {
|
|||
}
|
||||
Self::from_engine(engine)
|
||||
}
|
||||
|
||||
/// Hashes the entire contents of the `reader`.
|
||||
#[cfg(feature = "bitcoin-io")]
|
||||
fn hash_reader<R: io::BufRead>(reader: &mut R) -> Result<Self, io::Error>
|
||||
where
|
||||
Self::Engine: Default,
|
||||
{
|
||||
let mut engine = Self::engine();
|
||||
loop {
|
||||
let bytes = reader.fill_buf()?;
|
||||
|
||||
let read = bytes.len();
|
||||
if read == 0 { // Empty slice means EOF.
|
||||
break
|
||||
}
|
||||
|
||||
engine.input(bytes);
|
||||
reader.consume(read);
|
||||
}
|
||||
Ok(Self::from_engine(engine))
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait which applies to hashes of all types.
|
||||
|
@ -298,7 +322,8 @@ impl std::error::Error for FromSliceError {}
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::sha256d;
|
||||
use super::*;
|
||||
use crate::{sha256, sha256d};
|
||||
|
||||
hash_newtype! {
|
||||
/// A test newtype
|
||||
|
@ -323,4 +348,13 @@ mod tests {
|
|||
let rinsed = hex.parse::<TestNewtype>().expect("failed to parse hex");
|
||||
assert_eq!(rinsed, orig)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash_reader() {
|
||||
let mut reader: &[u8] = b"hello";
|
||||
assert_eq!(
|
||||
sha256::Hash::hash_reader(&mut reader).unwrap(),
|
||||
sha256::Hash::hash(b"hello"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,24 @@ where
|
|||
Self::from_engine(engine)
|
||||
}
|
||||
|
||||
/// Hashes the entire contents of the `reader`.
|
||||
#[cfg(feature = "bitcoin-io")]
|
||||
pub fn hash_reader<R: io::BufRead>(reader: &mut R) -> Result<Self, io::Error> {
|
||||
let mut engine = Self::engine();
|
||||
loop {
|
||||
let bytes = reader.fill_buf()?;
|
||||
|
||||
let read = bytes.len();
|
||||
if read == 0 { // Empty slice means EOF.
|
||||
break
|
||||
}
|
||||
|
||||
engine.input(bytes);
|
||||
reader.consume(read);
|
||||
}
|
||||
Ok(Self::from_engine(engine))
|
||||
}
|
||||
|
||||
/// Returns the underlying byte array.
|
||||
pub const fn to_byte_array(self) -> [u8; 32] { self.0 }
|
||||
|
||||
|
@ -231,6 +249,13 @@ macro_rules! sha256t_hash_newtype {
|
|||
}
|
||||
Self::from_engine(engine)
|
||||
}
|
||||
|
||||
/// Hashes the entire contents of the `reader`.
|
||||
#[cfg(feature = "bitcoin-io")]
|
||||
#[allow(unused)] // the user of macro may not need this
|
||||
fn hash_reader<R: io::BufRead>(reader: &mut R) -> Result<Self, io::Error> {
|
||||
<$hash_name as $crate::GeneralHash>::hash_reader(reader)
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::GeneralHash for $hash_name {
|
||||
|
|
Loading…
Reference in New Issue