inflate/
checksum.rs
1use adler32::RollingAdler32;
2
3pub fn adler32_from_bytes(bytes: &[u8; 4]) -> u32 {
4 (bytes[3] as u32) | ((bytes[2] as u32) << 8) |
5 ((bytes[1] as u32) << 16) | ((bytes[0] as u32) << 24)
6}
7
8pub enum ChecksumType {
10 None,
14 Adler32(RollingAdler32),
18}
19
20pub struct Checksum {
21 checksum_type: ChecksumType,
22}
23
24impl Checksum {
25 #[inline]
26 pub fn none() -> Checksum {
27 Checksum::new(ChecksumType::None)
28 }
29
30 #[inline]
31 pub fn is_none(&self) -> bool {
32 match self.checksum_type {
33 ChecksumType::None => true,
34 _ => false,
35 }
36 }
37
38 #[inline]
39 pub fn zlib() -> Checksum {
40 Checksum::new(ChecksumType::Adler32(RollingAdler32::new()))
41 }
42
43 pub fn new(checksum_type: ChecksumType) -> Checksum {
44 Checksum {
45 checksum_type: checksum_type,
46 }
47 }
48
49 #[inline]
50 pub fn update(&mut self, bytes: &[u8]) {
51 match self.checksum_type {
52 ChecksumType::None => (),
53 ChecksumType::Adler32(ref mut c) => {
54 c.update_buffer(bytes);
55 }
56 }
57 }
58
59 pub fn check(&self, expected: u32) -> Result<(), String> {
60 match self.checksum_type {
61 ChecksumType::None => Ok(()),
62 ChecksumType::Adler32(ref c) => {
63 if c.hash() == expected {
64 Ok(())
65 } else {
66 Err("Checksum mismatch!".to_owned())
67 }
68 },
69 }
70
71 }
72
73 #[inline]
74 pub fn current_value(&self) -> u32 {
75 match self.checksum_type {
76 ChecksumType::Adler32(ref c) => c.hash(),
77 _ => 0,
78 }
79 }
80
81}
82
83#[cfg(test)]
84mod test {
85 use super::adler32_from_bytes;
86
87 #[test]
88 fn adler32() {
89 let bytes = [0x00, 0x00, 0x01, 0x0b];
90 assert_eq!(adler32_from_bytes(&bytes), 267);
91 }
92}