fst/raw/
counting_writer.rs

1use std::io;
2
3use crate::raw::crc32::CheckSummer;
4
5/// Wraps any writer that counts and checksums bytes written.
6pub struct CountingWriter<W> {
7    wtr: W,
8    cnt: u64,
9    summer: CheckSummer,
10}
11
12impl<W: io::Write> CountingWriter<W> {
13    /// Wrap the given writer with a counter.
14    pub fn new(wtr: W) -> CountingWriter<W> {
15        CountingWriter { wtr, cnt: 0, summer: CheckSummer::new() }
16    }
17
18    /// Return the total number of bytes written to the underlying writer.
19    ///
20    /// The count returned is the sum of all counts resulting from a call
21    /// to `write`.
22    pub fn count(&self) -> u64 {
23        self.cnt
24    }
25
26    /// Returns the masked CRC32C checksum of the bytes written so far.
27    ///
28    /// This "masked" checksum is the same one used by the Snappy frame format.
29    /// Masking is supposed to make the checksum robust with respect to data
30    /// that contains the checksum itself.
31    pub fn masked_checksum(&self) -> u32 {
32        self.summer.masked()
33    }
34
35    /// Unwrap the counting writer and return the inner writer.
36    pub fn into_inner(self) -> W {
37        self.wtr
38    }
39
40    /// Gets a reference to the underlying writer.
41    pub fn get_ref(&self) -> &W {
42        &self.wtr
43    }
44}
45
46impl<W: io::Write> io::Write for CountingWriter<W> {
47    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
48        self.summer.update(buf);
49        let n = self.wtr.write(buf)?;
50        self.cnt += n as u64;
51        Ok(n)
52    }
53
54    fn flush(&mut self) -> io::Result<()> {
55        self.wtr.flush()
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::CountingWriter;
62    use std::io::Write;
63
64    #[test]
65    fn counts_bytes() {
66        let mut wtr = CountingWriter::new(vec![]);
67        wtr.write_all(b"foobar").unwrap();
68        assert_eq!(wtr.count(), 6);
69    }
70}