1use crate::hash::{HashKind, ObjectHash, get_hash_kind};
2use sha1::{Digest, Sha1};
3use std::io;
4use std::io::{BufRead, Read};
5pub fn read_bytes(file: &mut impl Read, len: usize) -> io::Result<Vec<u8>> {
6 let mut buf = vec![0; len];
7 file.read_exact(&mut buf)?;
8 Ok(buf)
9}
10
11pub fn read_sha(file: &mut impl Read) -> io::Result<ObjectHash> {
12 ObjectHash::from_stream(file)
13}
14
15pub struct CountingReader<R> {
18 pub inner: R,
19 pub bytes_read: u64,
20}
21
22impl<R> CountingReader<R> {
23 pub fn new(inner: R) -> Self {
25 Self {
26 inner,
27 bytes_read: 0,
28 }
29 }
30}
31
32impl<R: Read> Read for CountingReader<R> {
33 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
34 let n = self.inner.read(buf)?;
35 self.bytes_read += n as u64;
36 Ok(n)
37 }
38}
39
40impl<R: BufRead> BufRead for CountingReader<R> {
41 fn fill_buf(&mut self) -> io::Result<&[u8]> {
42 self.inner.fill_buf()
43 }
44
45 fn consume(&mut self, amt: usize) {
46 self.bytes_read += amt as u64;
47 self.inner.consume(amt);
48 }
49}
50#[derive(Clone)]
54pub enum HashAlgorithm {
55 Sha1(Sha1),
56 Sha256(sha2::Sha256),
57 }
59impl HashAlgorithm {
60 pub fn update(&mut self, data: &[u8]) {
62 match self {
63 HashAlgorithm::Sha1(hasher) => hasher.update(data),
64 HashAlgorithm::Sha256(hasher) => hasher.update(data),
65 }
66 }
67 pub fn finalize(self) -> Vec<u8> {
69 match self {
70 HashAlgorithm::Sha1(hasher) => hasher.finalize().to_vec(),
71 HashAlgorithm::Sha256(hasher) => hasher.finalize().to_vec(),
72 }
73 }
74 pub fn new() -> Self {
75 match get_hash_kind() {
76 HashKind::Sha1 => HashAlgorithm::Sha1(Sha1::new()),
77 HashKind::Sha256 => HashAlgorithm::Sha256(sha2::Sha256::new()),
78 }
79 }
80}
81impl std::io::Write for HashAlgorithm {
82 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
83 self.update(buf);
84 Ok(buf.len())
85 }
86 fn flush(&mut self) -> io::Result<()> {
87 Ok(())
88 }
89}
90impl Default for HashAlgorithm {
91 fn default() -> Self {
92 Self::new()
93 }
94}