1*27b03b36SApple OSS Distributions /*
2*27b03b36SApple OSS Distributions * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
3*27b03b36SApple OSS Distributions *
4*27b03b36SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*27b03b36SApple OSS Distributions *
6*27b03b36SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*27b03b36SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*27b03b36SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*27b03b36SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*27b03b36SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*27b03b36SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*27b03b36SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*27b03b36SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*27b03b36SApple OSS Distributions *
15*27b03b36SApple OSS Distributions * Please obtain a copy of the License at
16*27b03b36SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*27b03b36SApple OSS Distributions *
18*27b03b36SApple OSS Distributions * The Original Code and all software distributed under the License are
19*27b03b36SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*27b03b36SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*27b03b36SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*27b03b36SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*27b03b36SApple OSS Distributions * Please see the License for the specific language governing rights and
24*27b03b36SApple OSS Distributions * limitations under the License.
25*27b03b36SApple OSS Distributions *
26*27b03b36SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*27b03b36SApple OSS Distributions */
28*27b03b36SApple OSS Distributions /* adler32.c -- compute the Adler-32 checksum of a data stream
29*27b03b36SApple OSS Distributions * Copyright (C) 1995-2004 Mark Adler
30*27b03b36SApple OSS Distributions * For conditions of distribution and use, see copyright notice in zlib.h
31*27b03b36SApple OSS Distributions */
32*27b03b36SApple OSS Distributions
33*27b03b36SApple OSS Distributions /* @(#) $Id$ */
34*27b03b36SApple OSS Distributions
35*27b03b36SApple OSS Distributions
36*27b03b36SApple OSS Distributions #define ZLIB_INTERNAL
37*27b03b36SApple OSS Distributions #if KERNEL
38*27b03b36SApple OSS Distributions #include <libkern/zlib.h>
39*27b03b36SApple OSS Distributions #else
40*27b03b36SApple OSS Distributions #include "zlib.h"
41*27b03b36SApple OSS Distributions #endif /* KERNEL */
42*27b03b36SApple OSS Distributions
43*27b03b36SApple OSS Distributions
44*27b03b36SApple OSS Distributions #define BASE 65521UL /* largest prime smaller than 65536 */
45*27b03b36SApple OSS Distributions #define NMAX 5552
46*27b03b36SApple OSS Distributions /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
47*27b03b36SApple OSS Distributions
48*27b03b36SApple OSS Distributions #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
49*27b03b36SApple OSS Distributions #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
50*27b03b36SApple OSS Distributions #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
51*27b03b36SApple OSS Distributions #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
52*27b03b36SApple OSS Distributions #define DO16(buf) DO8(buf,0); DO8(buf,8);
53*27b03b36SApple OSS Distributions
54*27b03b36SApple OSS Distributions /* use NO_DIVIDE if your processor does not do division in hardware */
55*27b03b36SApple OSS Distributions #ifdef NO_DIVIDE
56*27b03b36SApple OSS Distributions # define MOD(a) \
57*27b03b36SApple OSS Distributions do { \
58*27b03b36SApple OSS Distributions if (a >= (BASE << 16)) a -= (BASE << 16); \
59*27b03b36SApple OSS Distributions if (a >= (BASE << 15)) a -= (BASE << 15); \
60*27b03b36SApple OSS Distributions if (a >= (BASE << 14)) a -= (BASE << 14); \
61*27b03b36SApple OSS Distributions if (a >= (BASE << 13)) a -= (BASE << 13); \
62*27b03b36SApple OSS Distributions if (a >= (BASE << 12)) a -= (BASE << 12); \
63*27b03b36SApple OSS Distributions if (a >= (BASE << 11)) a -= (BASE << 11); \
64*27b03b36SApple OSS Distributions if (a >= (BASE << 10)) a -= (BASE << 10); \
65*27b03b36SApple OSS Distributions if (a >= (BASE << 9)) a -= (BASE << 9); \
66*27b03b36SApple OSS Distributions if (a >= (BASE << 8)) a -= (BASE << 8); \
67*27b03b36SApple OSS Distributions if (a >= (BASE << 7)) a -= (BASE << 7); \
68*27b03b36SApple OSS Distributions if (a >= (BASE << 6)) a -= (BASE << 6); \
69*27b03b36SApple OSS Distributions if (a >= (BASE << 5)) a -= (BASE << 5); \
70*27b03b36SApple OSS Distributions if (a >= (BASE << 4)) a -= (BASE << 4); \
71*27b03b36SApple OSS Distributions if (a >= (BASE << 3)) a -= (BASE << 3); \
72*27b03b36SApple OSS Distributions if (a >= (BASE << 2)) a -= (BASE << 2); \
73*27b03b36SApple OSS Distributions if (a >= (BASE << 1)) a -= (BASE << 1); \
74*27b03b36SApple OSS Distributions if (a >= BASE) a -= BASE; \
75*27b03b36SApple OSS Distributions } while (0)
76*27b03b36SApple OSS Distributions # define MOD4(a) \
77*27b03b36SApple OSS Distributions do { \
78*27b03b36SApple OSS Distributions if (a >= (BASE << 4)) a -= (BASE << 4); \
79*27b03b36SApple OSS Distributions if (a >= (BASE << 3)) a -= (BASE << 3); \
80*27b03b36SApple OSS Distributions if (a >= (BASE << 2)) a -= (BASE << 2); \
81*27b03b36SApple OSS Distributions if (a >= (BASE << 1)) a -= (BASE << 1); \
82*27b03b36SApple OSS Distributions if (a >= BASE) a -= BASE; \
83*27b03b36SApple OSS Distributions } while (0)
84*27b03b36SApple OSS Distributions #else
85*27b03b36SApple OSS Distributions # define MOD(a) a %= BASE
86*27b03b36SApple OSS Distributions # define MOD4(a) a %= BASE
87*27b03b36SApple OSS Distributions #endif
88*27b03b36SApple OSS Distributions
89*27b03b36SApple OSS Distributions /* ========================================================================= */
90*27b03b36SApple OSS Distributions uLong ZEXPORT
adler32(uLong adler,const Bytef * buf,uInt len)91*27b03b36SApple OSS Distributions adler32(uLong adler, const Bytef *buf, uInt len)
92*27b03b36SApple OSS Distributions {
93*27b03b36SApple OSS Distributions unsigned long sum2;
94*27b03b36SApple OSS Distributions unsigned n;
95*27b03b36SApple OSS Distributions
96*27b03b36SApple OSS Distributions /* split Adler-32 into component sums */
97*27b03b36SApple OSS Distributions sum2 = (adler >> 16) & 0xffff;
98*27b03b36SApple OSS Distributions adler &= 0xffff;
99*27b03b36SApple OSS Distributions
100*27b03b36SApple OSS Distributions /* in case user likes doing a byte at a time, keep it fast */
101*27b03b36SApple OSS Distributions if (len == 1) {
102*27b03b36SApple OSS Distributions adler += buf[0];
103*27b03b36SApple OSS Distributions if (adler >= BASE)
104*27b03b36SApple OSS Distributions adler -= BASE;
105*27b03b36SApple OSS Distributions sum2 += adler;
106*27b03b36SApple OSS Distributions if (sum2 >= BASE)
107*27b03b36SApple OSS Distributions sum2 -= BASE;
108*27b03b36SApple OSS Distributions return adler | (sum2 << 16);
109*27b03b36SApple OSS Distributions }
110*27b03b36SApple OSS Distributions
111*27b03b36SApple OSS Distributions /* initial Adler-32 value (deferred check for len == 1 speed) */
112*27b03b36SApple OSS Distributions if (buf == Z_NULL)
113*27b03b36SApple OSS Distributions return 1L;
114*27b03b36SApple OSS Distributions
115*27b03b36SApple OSS Distributions /* in case short lengths are provided, keep it somewhat fast */
116*27b03b36SApple OSS Distributions if (len < 16) {
117*27b03b36SApple OSS Distributions while (len--) {
118*27b03b36SApple OSS Distributions adler += *buf++;
119*27b03b36SApple OSS Distributions sum2 += adler;
120*27b03b36SApple OSS Distributions }
121*27b03b36SApple OSS Distributions if (adler >= BASE)
122*27b03b36SApple OSS Distributions adler -= BASE;
123*27b03b36SApple OSS Distributions MOD4(sum2); /* only added so many BASE's */
124*27b03b36SApple OSS Distributions return adler | (sum2 << 16);
125*27b03b36SApple OSS Distributions }
126*27b03b36SApple OSS Distributions
127*27b03b36SApple OSS Distributions
128*27b03b36SApple OSS Distributions /* do length NMAX blocks -- requires just one modulo operation */
129*27b03b36SApple OSS Distributions while (len >= NMAX) {
130*27b03b36SApple OSS Distributions len -= NMAX;
131*27b03b36SApple OSS Distributions n = NMAX / 16; /* NMAX is divisible by 16 */
132*27b03b36SApple OSS Distributions do {
133*27b03b36SApple OSS Distributions DO16(buf); /* 16 sums unrolled */
134*27b03b36SApple OSS Distributions buf += 16;
135*27b03b36SApple OSS Distributions } while (--n);
136*27b03b36SApple OSS Distributions MOD(adler);
137*27b03b36SApple OSS Distributions MOD(sum2);
138*27b03b36SApple OSS Distributions }
139*27b03b36SApple OSS Distributions
140*27b03b36SApple OSS Distributions /* do remaining bytes (less than NMAX, still just one modulo) */
141*27b03b36SApple OSS Distributions if (len) { /* avoid modulos if none remaining */
142*27b03b36SApple OSS Distributions while (len >= 16) {
143*27b03b36SApple OSS Distributions len -= 16;
144*27b03b36SApple OSS Distributions DO16(buf);
145*27b03b36SApple OSS Distributions buf += 16;
146*27b03b36SApple OSS Distributions }
147*27b03b36SApple OSS Distributions while (len--) {
148*27b03b36SApple OSS Distributions adler += *buf++;
149*27b03b36SApple OSS Distributions sum2 += adler;
150*27b03b36SApple OSS Distributions }
151*27b03b36SApple OSS Distributions MOD(adler);
152*27b03b36SApple OSS Distributions MOD(sum2);
153*27b03b36SApple OSS Distributions }
154*27b03b36SApple OSS Distributions
155*27b03b36SApple OSS Distributions /* return recombined sums */
156*27b03b36SApple OSS Distributions return adler | (sum2 << 16);
157*27b03b36SApple OSS Distributions }
158*27b03b36SApple OSS Distributions
159*27b03b36SApple OSS Distributions /* ========================================================================= */
160*27b03b36SApple OSS Distributions uLong ZEXPORT
adler32_combine(uLong adler1,uLong adler2,z_off_t len2)161*27b03b36SApple OSS Distributions adler32_combine(uLong adler1, uLong adler2, z_off_t len2)
162*27b03b36SApple OSS Distributions {
163*27b03b36SApple OSS Distributions unsigned long sum1;
164*27b03b36SApple OSS Distributions unsigned long sum2;
165*27b03b36SApple OSS Distributions unsigned rem;
166*27b03b36SApple OSS Distributions
167*27b03b36SApple OSS Distributions /* the derivation of this formula is left as an exercise for the reader */
168*27b03b36SApple OSS Distributions rem = (unsigned)(len2 % BASE);
169*27b03b36SApple OSS Distributions sum1 = adler1 & 0xffff;
170*27b03b36SApple OSS Distributions sum2 = rem * sum1;
171*27b03b36SApple OSS Distributions MOD(sum2);
172*27b03b36SApple OSS Distributions sum1 += (adler2 & 0xffff) + BASE - 1;
173*27b03b36SApple OSS Distributions sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
174*27b03b36SApple OSS Distributions if (sum1 > BASE) sum1 -= BASE;
175*27b03b36SApple OSS Distributions if (sum1 > BASE) sum1 -= BASE;
176*27b03b36SApple OSS Distributions if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
177*27b03b36SApple OSS Distributions if (sum2 > BASE) sum2 -= BASE;
178*27b03b36SApple OSS Distributions return sum1 | (sum2 << 16);
179*27b03b36SApple OSS Distributions }
180