From: Robert Spalek Date: Fri, 16 Jul 2004 10:47:37 +0000 (+0000) Subject: taken much faster implementation of Adler32 and put into a separate source-code X-Git-Tag: holmes-import~940 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=0d56b467cc2184f00a4e390f95596704d819dfa3;p=libucw.git taken much faster implementation of Adler32 and put into a separate source-code --- diff --git a/lib/Makefile b/lib/Makefile index 381190a0..f3e0529c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -20,7 +20,7 @@ LIBSH_MODS= \ db \ url urlkey finger \ mainloop exitstatus runcmd sighandler \ - lizard lizard-safe \ + lizard lizard-safe adler32 \ md5 md5hex \ base64 base224 diff --git a/lib/adler32.c b/lib/adler32.c new file mode 100644 index 00000000..613ed72d --- /dev/null +++ b/lib/adler32.c @@ -0,0 +1,78 @@ +/* + * adler32.c -- compute the Adler-32 checksum of a data stream + * + * Copyright (C) 1995--2003 Mark Adler + * + * Taken from zlib-1.2.1 and adjusted by Robert Spalek. For conditions of + * distribution and use, see copyright notice in zlib.h. + */ + +#include "lib/lib.h" +#include "lib/lizard.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +#endif + +uns +update_adler32(uns adler, byte *buf, uns len) +{ + uns s1 = adler & 0xffff; + uns s2 = (adler >> 16) & 0xffff; + int k; + + if (!buf) return 1L; + + while (len > 0) { + k = len < NMAX ? (int)len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + MOD(s1); + MOD(s2); + } + return (s2 << 16) | s1; +} + +uns +adler32(byte *buf, uns len) +{ + return update_adler32(1, buf, len); +} diff --git a/lib/lizard-safe.c b/lib/lizard-safe.c index 40a5aa3d..88e9aebd 100644 --- a/lib/lizard-safe.c +++ b/lib/lizard-safe.c @@ -103,24 +103,3 @@ lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length) signal_handler[SIGSEGV] = old_handler; return ptr; } - -#define BASE 65521 /* largest prime smaller than 65536 */ - -inline uns -update_adler32(uns adler, byte *ptr, uns len) - /* taken from RFC1950 */ -{ - uns s1 = adler & 0xffff; - uns s2 = (adler >> 16) & 0xffff; - for (uns n = 0; n < len; n++) { - s1 = (s1 + ptr[n]) % BASE; - s2 = (s2 + s1) % BASE; - } - return (s2 << 16) + s1; -} - -uns -adler32(byte *ptr, uns len) -{ - return update_adler32(1, ptr, len); -} diff --git a/lib/lizard.h b/lib/lizard.h index 838d683f..c701e6f2 100644 --- a/lib/lizard.h +++ b/lib/lizard.h @@ -37,6 +37,7 @@ struct lizard_buffer *lizard_alloc(void); void lizard_free(struct lizard_buffer *buf); byte *lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length); +/* adler32.c */ uns update_adler32(uns adler, byte *ptr, uns len); uns adler32(byte *ptr, uns len);