]> git.proxmox.com Git - rustc.git/blame - src/vendor/flate2/src/crc.rs
New upstream version 1.22.1+dfsg1
[rustc.git] / src / vendor / flate2 / src / crc.rs
CommitLineData
7cac9316
XL
1//! Simple CRC bindings backed by miniz.c
2
3use std::io::prelude::*;
4use std::io;
5use libc;
6
7use ffi;
8
ea8adc8c
XL
9/// The CRC calculated by a [`CrcReader`].
10///
11/// [`CrcReader`]: struct.CrcReader.html
12#[derive(Debug)]
7cac9316
XL
13pub struct Crc {
14 crc: libc::c_ulong,
15 amt: u32,
16}
17
ea8adc8c
XL
18/// A wrapper around a [`Read`] that calculates the CRC.
19///
20/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
21#[derive(Debug)]
7cac9316
XL
22pub struct CrcReader<R> {
23 inner: R,
24 crc: Crc,
25}
26
27impl Crc {
28 /// Create a new CRC.
29 pub fn new() -> Crc {
30 Crc { crc: 0, amt: 0 }
31 }
32
33 /// bla
34 pub fn sum(&self) -> u32 {
35 self.crc as u32
36 }
37
38 /// The number of bytes that have been used to calculate the CRC.
39 /// This value is only accurate if the amount is lower than 2^32.
40 pub fn amount(&self) -> u32 {
41 self.amt
42 }
43
44 /// Update the CRC with the bytes in `data`.
45 pub fn update(&mut self, data: &[u8]) {
46 self.amt = self.amt.wrapping_add(data.len() as u32);
47 self.crc = unsafe {
48 ffi::mz_crc32(self.crc, data.as_ptr(), data.len() as libc::size_t)
49 };
50 }
51
52 /// Reset the CRC.
53 pub fn reset(&mut self) {
54 self.crc = 0;
55 self.amt = 0;
56 }
57
58 /// Combine the CRC with the CRC for the subsequent block of bytes.
59 pub fn combine(&mut self, additional_crc: &Crc) {
60 self.crc = unsafe {
61 ffi::mz_crc32_combine(self.crc as ::libc::c_ulong,
62 additional_crc.crc as ::libc::c_ulong,
63 additional_crc.amt as ::libc::off_t)
64 };
65 self.amt += additional_crc.amt;
66 }
67}
68
69impl<R: Read> CrcReader<R> {
70 /// Create a new CrcReader.
71 pub fn new(r: R) -> CrcReader<R> {
72 CrcReader {
73 inner: r,
74 crc: Crc::new(),
75 }
76 }
ea8adc8c 77}
7cac9316 78
ea8adc8c 79impl<R> CrcReader<R> {
7cac9316
XL
80 /// Get the Crc for this CrcReader.
81 pub fn crc(&self) -> &Crc {
82 &self.crc
83 }
84
85 /// Get the reader that is wrapped by this CrcReader.
86 pub fn into_inner(self) -> R {
87 self.inner
88 }
89
90 /// Get the reader that is wrapped by this CrcReader by reference.
91 pub fn get_ref(&self) -> &R {
92 &self.inner
93 }
94
95 /// Get a mutable reference to the reader that is wrapped by this CrcReader.
96 pub fn get_mut(&mut self) -> &mut R {
97 &mut self.inner
98 }
99
100 /// Reset the Crc in this CrcReader.
101 pub fn reset(&mut self) {
102 self.crc.reset();
103 }
104}
105
106impl<R: Read> Read for CrcReader<R> {
107 fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
108 let amt = try!(self.inner.read(into));
109 self.crc.update(&into[..amt]);
110 Ok(amt)
111 }
112}
113
114impl<R: BufRead> BufRead for CrcReader<R> {
115 fn fill_buf(&mut self) -> io::Result<&[u8]> {
116 self.inner.fill_buf()
117 }
118 fn consume(&mut self, amt: usize) {
119 if let Ok(data) = self.inner.fill_buf() {
120 self.crc.update(&data[..amt]);
121 }
122 self.inner.consume(amt);
123 }
124}