sevenz_rust2/writer/
source_reader.rs

1use std::io::Read;
2
3use crc32fast::Hasher;
4
5/// A wrapper around a reader that tracks read count and CRC32.
6///
7/// Used during compression to track how much data has been read and compute
8/// the CRC32 checksum of the data.
9pub struct SourceReader<R> {
10    reader: R,
11    size: usize,
12    crc: Hasher,
13    crc_value: u32,
14}
15
16impl<R> From<R> for SourceReader<R> {
17    fn from(value: R) -> Self {
18        Self::new(value)
19    }
20}
21
22impl<R: Read> Read for SourceReader<R> {
23    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
24        let n = self.reader.read(buf)?;
25        if self.crc_value == 0 {
26            if n > 0 {
27                self.size += n;
28                self.crc.update(&buf[..n]);
29            } else {
30                let crc = std::mem::replace(&mut self.crc, Hasher::new());
31                self.crc_value = crc.finalize();
32            }
33        }
34        Ok(n)
35    }
36}
37
38impl<R> SourceReader<R> {
39    /// Creates a new source reader wrapper.
40    ///
41    /// # Arguments
42    /// * `reader` - The underlying reader to wrap
43    pub fn new(reader: R) -> Self {
44        Self {
45            reader,
46            size: 0,
47            crc: Hasher::new(),
48            crc_value: 0,
49        }
50    }
51
52    /// Returns the total number of bytes read so far.
53    pub fn read_count(&self) -> usize {
54        self.size
55    }
56
57    /// Returns the CRC32 value of all data read.
58    ///
59    /// The CRC is only computed once all data has been read (when read returns 0).
60    pub fn crc_value(&self) -> u32 {
61        self.crc_value
62    }
63}