/src/zlib-ng/arch/generic/adler32_c.c
Line | Count | Source |
1 | | /* adler32.c -- compute the Adler-32 checksum of a data stream |
2 | | * Copyright (C) 1995-2011, 2016 Mark Adler |
3 | | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | | */ |
5 | | |
6 | | #include "zbuild.h" |
7 | | #include "arch_functions.h" |
8 | | |
9 | | #ifdef ADLER32_FALLBACK |
10 | | |
11 | | #include "functable.h" |
12 | | #include "adler32_p.h" |
13 | | |
14 | 0 | Z_INTERNAL uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len) { |
15 | 0 | uint32_t sum2; |
16 | 0 | size_t n; |
17 | | |
18 | | /* split Adler-32 into component sums */ |
19 | 0 | sum2 = (adler >> 16) & 0xffff; |
20 | 0 | adler &= 0xffff; |
21 | | |
22 | | /* in case user likes doing a byte at a time, keep it fast */ |
23 | 0 | if (UNLIKELY(len == 1)) |
24 | 0 | return adler32_copy_tail(adler, NULL, buf, 1, sum2, 1, 1, 0); |
25 | | |
26 | | /* in case short lengths are provided, keep it somewhat fast */ |
27 | 0 | if (UNLIKELY(len < 16)) |
28 | 0 | return adler32_copy_tail(adler, NULL, buf, len, sum2, 1, 15, 0); |
29 | | |
30 | | /* Align source to 8 bytes so SWAR loads are naturally aligned */ |
31 | 0 | size_t align_diff = ALIGN_DIFF(buf, 8); |
32 | 0 | if (align_diff) { |
33 | 0 | adler32_copy_align(&adler, NULL, buf, align_diff, &sum2, 7, 0); |
34 | 0 | buf += align_diff; |
35 | 0 | len -= align_diff; |
36 | 0 | } |
37 | | |
38 | | /* do length NMAX blocks -- requires just one modulo operation */ |
39 | 0 | while (len >= NMAX) { |
40 | 0 | len -= NMAX; |
41 | 0 | n = NMAX; |
42 | |
|
43 | 0 | do { |
44 | 0 | size_t chunk = MIN(ALIGN_DOWN(n, (size_t)8), (size_t)ADLER32_SWAR_MAX_BYTES); |
45 | 0 | adler32_swar(&adler, NULL, buf, chunk, &sum2, 0); |
46 | 0 | buf += chunk; |
47 | 0 | n -= chunk; |
48 | 0 | } while (n >= 8); |
49 | |
|
50 | 0 | adler %= BASE; |
51 | 0 | sum2 %= BASE; |
52 | 0 | } |
53 | | |
54 | | /* do remaining bytes (less than NMAX, still just one modulo) */ |
55 | 0 | return adler32_copy_tail(adler, NULL, buf, len, sum2, len != 0, NMAX - 1, 0); |
56 | 0 | } |
57 | | |
58 | 0 | Z_INTERNAL uint32_t adler32_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { |
59 | 0 | adler = adler32_c(adler, src, len); |
60 | 0 | memcpy(dst, src, len); |
61 | 0 | return adler; |
62 | 0 | } |
63 | | |
64 | | #endif /* ADLER32_FALLBACK */ |