[erlang-patches] Patch to add zlib:crc32_combine/4 and zlib:adler32_combine/4
Matthew Dempsky
matthew@REDACTED
Tue Nov 6 21:41:13 CET 2007
I wrote an Erlang module to concatenate zlib compressed data, but to
generate proper zlib and gzip trailers, I need to compute the adler32
and crc32 checksums. adler32 has a simple algebraic structure that
makes it easy to implement in just a few lines of Erlang code (give it
a shot---it's fun :-), but combining crc32 checksums involves
computing x*2^n in a Galois field (which isn't so fun in Erlang).
Anyways, I noticed the zlib C library already provides functions for
these, but they're not exposed by the Erlang interface... so I wrote
the patch below. (I'm mainly interested in crc32_combine, but I
thought it would be nice to have adler32_combine for completeness.)
--- erts/emulator/drivers/common/zlib_drv.c.orig 2007-11-06
11:44:12.000000000 -0800
+++ erts/emulator/drivers/common/zlib_drv.c 2007-11-06 11:30:11.000000000 -0800
@@ -55,6 +55,9 @@
#define ADLER32_1 21
#define ADLER32_2 22
+#define CRC32_COMBINE 23
+#define ADLER32_COMBINE 24
+
#define DEFAULT_BUFSZ 4000
static int zlib_init(void);
@@ -597,6 +600,26 @@
adler = adler32(adler, buf+4, len-4);
return zlib_value(adler, rbuf, rlen);
}
+
+ case CRC32_COMBINE: {
+ uLong crc1, crc2, len2;
+ if (len != 12) goto badarg;
+ crc1 = i32(buf);
+ crc2 = i32(buf+4);
+ len2 = i32(buf+8);
+ crc1 = crc32_combine(crc1, crc2, len2);
+ return zlib_value(crc1, rbuf, rlen);
+ }
+
+ case ADLER32_COMBINE: {
+ uLong adler1, adler2, len2;
+ if (len != 12) goto badarg;
+ adler1 = i32(buf);
+ adler2 = i32(buf+4);
+ len2 = i32(buf+8);
+ adler1 = adler32_combine(adler1, adler2, len2);
+ return zlib_value(adler1, rbuf, rlen);
+ }
}
badarg:
--- lib/kernel/src/zlib.erl.orig 2007-11-06 11:20:14.000000000 -0800
+++ lib/kernel/src/zlib.erl 2007-11-06 11:43:28.000000000 -0800
@@ -25,6 +25,7 @@
inflateSync/1,inflateReset/1,inflate/2,inflateEnd/1,
setBufSize/2,getBufSize/1,
crc32/1,crc32/2,crc32/3,adler32/2,adler32/3,getQSize/1,
+ crc32_combine/4,adler32_combine/4,
compress/1,uncompress/1,zip/1,unzip/1,
gzip/1,gunzip/1]).
@@ -108,6 +109,9 @@
-define(ADLER32_1, 21).
-define(ADLER32_2, 22).
+-define(CRC32_COMBINE, 23).
+-define(ADLER32_COMBINE, 24).
+
%% open a z_stream
open() ->
open_port({spawn, zlib_drv}, [binary]).
@@ -213,6 +217,16 @@
adler32(_Z, _Adler, _Binary) ->
erlang:error(badarg).
+crc32_combine(Z, CRC1, CRC2, Len2) when is_integer(CRC1),
is_integer(CRC2), is_integer(Len2) ->
+ call(Z, ?CRC32_COMBINE, <<CRC1:32, CRC2:32, Len2:32>>);
+crc32_combine(_Z, _CRC1, _CRC2, _Len2) ->
+ erlang:error(badarg).
+
+adler32_combine(Z, Adler1, Adler2, Len2) when is_integer(Adler1),
is_integer(Adler2), is_integer(Len2) ->
+ call(Z, ?ADLER32_COMBINE, <<Adler1:32, Adler2:32, Len2:32>>);
+adler32_combine(_Z, _Adler1, _Adler2, _Len2) ->
+ erlang:error(badarg).
+
getQSize(Z) ->
call(Z, ?GET_QSIZE, []).
More information about the erlang-patches
mailing list