Coverage Report

Created: 2026-10-28 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zlib-rs-0.6.8/src/adler32/generic.rs
Line
Count
Source
1
use super::{BASE, NMAX};
2
3
const UNROLL_MORE: bool = true;
4
5
// macros for loop unrolling
6
macro_rules! do1 {
7
    ($sum1:expr, $sum2:expr, $chunk:expr, $i:expr) => {
8
        // SAFETY: $i is bounded by either [0, 8] or [0, 16], and the caller ensures the chunk is
9
        // long enough, so we can omit bound checking.
10
        $sum1 += unsafe { *$chunk.get_unchecked($i) } as u32;
11
        $sum2 += $sum1;
12
    };
13
}
14
15
macro_rules! do2 {
16
    ($sum1:expr, $sum2:expr, $chunk:expr, $i:expr) => {
17
        do1!($sum1, $sum2, $chunk, $i);
18
        do1!($sum1, $sum2, $chunk, $i + 1);
19
    };
20
}
21
22
macro_rules! do4 {
23
    ($sum1:expr, $sum2:expr, $chunk:expr, $i:expr) => {
24
        do2!($sum1, $sum2, $chunk, $i);
25
        do2!($sum1, $sum2, $chunk, $i + 2);
26
    };
27
}
28
29
macro_rules! do8 {
30
    ($sum1:expr, $sum2:expr, $chunk:expr, $i:expr) => {
31
        do4!($sum1, $sum2, $chunk, $i);
32
        do4!($sum1, $sum2, $chunk, $i + 4);
33
    };
34
}
35
36
macro_rules! do16 {
37
    ($sum1:expr, $sum2:expr, $chunk:expr) => {
38
        do8!($sum1, $sum2, $chunk, 0);
39
        do8!($sum1, $sum2, $chunk, 8);
40
    };
41
}
42
43
0
pub fn adler32_rust(mut adler: u32, buf: &[u8]) -> u32 {
44
    /* split Adler-32 into component sums */
45
0
    let mut sum2 = (adler >> 16) & 0xffff;
46
0
    adler &= 0xffff;
47
48
    /* in case user likes doing a byte at a time, keep it fast */
49
0
    if buf.len() == 1 {
50
0
        return adler32_len_1(adler, buf, sum2);
51
0
    }
52
53
    /* initial Adler-32 value (deferred check for len == 1 speed) */
54
0
    if buf.is_empty() {
55
0
        return adler | (sum2 << 16);
56
0
    }
57
58
    /* in case short lengths are provided, keep it somewhat fast */
59
0
    if buf.len() < 16 {
60
0
        return adler32_len_16(adler, buf, sum2);
61
0
    }
62
63
0
    let mut it = buf.chunks_exact(NMAX as usize);
64
0
    for big_chunk in it.by_ref() {
65
        const N: usize = if UNROLL_MORE { 16 } else { 8 } as usize;
66
0
        let it = big_chunk.chunks_exact(N);
67
0
        for chunk in it {
68
0
            if N == 16 {
69
0
                do16!(adler, sum2, chunk);
70
0
            } else {
71
0
                do8!(adler, sum2, chunk, 0);
72
0
            }
73
        }
74
75
0
        adler %= BASE;
76
0
        sum2 %= BASE;
77
    }
78
79
    /* do remaining bytes (less than NMAX, still just one modulo) */
80
0
    adler32_len_64(adler, it.remainder(), sum2)
81
0
}
82
83
0
pub(crate) fn adler32_len_1(mut adler: u32, buf: &[u8], mut sum2: u32) -> u32 {
84
0
    adler += buf[0] as u32;
85
0
    adler %= BASE;
86
0
    sum2 += adler;
87
0
    sum2 %= BASE;
88
0
    adler | (sum2 << 16)
89
0
}
90
91
0
pub(crate) fn adler32_len_16(mut adler: u32, buf: &[u8], mut sum2: u32) -> u32 {
92
0
    for b in buf {
93
0
        adler += (*b) as u32;
94
0
        sum2 += adler;
95
0
    }
96
97
0
    adler %= BASE;
98
0
    sum2 %= BASE; /* only added so many BASE's */
99
    /* return recombined sums */
100
0
    adler | (sum2 << 16)
101
0
}
102
103
0
pub(crate) fn adler32_len_64(mut adler: u32, buf: &[u8], mut sum2: u32) -> u32 {
104
    const N: usize = if UNROLL_MORE { 16 } else { 8 };
105
0
    let mut it = buf.chunks_exact(N);
106
0
    for chunk in it.by_ref() {
107
0
        if N == 16 {
108
0
            do16!(adler, sum2, chunk);
109
0
        } else {
110
0
            do8!(adler, sum2, chunk, 0);
111
0
        }
112
    }
113
114
    /* Process tail (len < 16).  */
115
0
    adler32_len_16(adler, it.remainder(), sum2)
116
0
}