From 75f1908690baa876eaf08db98f53dfd328762fc5 Mon Sep 17 00:00:00 2001 From: Dietrich Epp Date: Sun, 10 Apr 2022 03:37:14 -0400 Subject: [PATCH] Add CRC-32 function --- lib/BUILD.bazel | 14 ++++++++++++++ lib/crc32.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/crc32.h | 9 +++++++++ lib/crc32_test.c | 22 ++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 lib/crc32.c create mode 100644 lib/crc32.h create mode 100644 lib/crc32_test.c diff --git a/lib/BUILD.bazel b/lib/BUILD.bazel index 09df080..4c48ef4 100644 --- a/lib/BUILD.bazel +++ b/lib/BUILD.bazel @@ -4,10 +4,12 @@ load("//bazel:copts.bzl", "COPTS") cc_library( name = "lib", srcs = [ + "crc32.c", "toolbox.c", "util.c", ], hdrs = [ + "crc32.h", "defs.h", "endian.h", "util.h", @@ -44,3 +46,15 @@ cc_test( ":test", ], ) + +cc_test( + name = "crc32_test", + size = "small", + srcs = [ + "crc32_test.c", + ], + copts = COPTS, + deps = [ + ":lib", + ], +) diff --git a/lib/crc32.c b/lib/crc32.c new file mode 100644 index 0000000..75f5742 --- /dev/null +++ b/lib/crc32.c @@ -0,0 +1,40 @@ +#include "lib/crc32.h" + +static int gCRCInitted; +static UInt32 gCRCTable[256]; + +static void CRC32Init(void) +{ + int i, j; + UInt32 v, u; + + for (i = 0; i < 256; i++) { + v = i; + for (j = 0; j < 8; j++) { + u = v; + v >>= 1; + if (u & 1) { + v ^= 0xedb88320; + } + } + gCRCTable[i] = v; + } + gCRCInitted = 1; +} + +UInt32 CRC32Update(UInt32 crc, const void *ptr, Size size) +{ + const UInt8 *p, *e; + + if (!gCRCInitted) { + CRC32Init(); + } + + crc = ~crc; + p = ptr; + e = p + size; + while (p < e) { + crc = (crc >> 8) ^ gCRCTable[(crc & 0xff) ^ *p++]; + } + return ~crc; +} diff --git a/lib/crc32.h b/lib/crc32.h new file mode 100644 index 0000000..803c539 --- /dev/null +++ b/lib/crc32.h @@ -0,0 +1,9 @@ +#ifndef CRC32_H +#define CRC32_H + +#include "lib/defs.h" + +/* Incrementally calculate a CRC32. This is the same CRC32 used by Gzip. */ +UInt32 CRC32Update(UInt32 crc, const void *ptr, Size size); + +#endif diff --git a/lib/crc32_test.c b/lib/crc32_test.c new file mode 100644 index 0000000..2cd3000 --- /dev/null +++ b/lib/crc32_test.c @@ -0,0 +1,22 @@ +#include "lib/crc32.h" + +#include + +static const char kTest[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'}; + +int main(int argc, char **argv) +{ + UInt32 expect; + UInt32 val; + + (void)argc; + (void)argv; + + expect = 0xcbf43926; + val = CRC32Update(0, kTest, sizeof(kTest)); + if (val != expect) { + fprintf(stderr, "Error: CRC = 0x%08x, expect 0x%08x\n", val, expect); + return 1; + } + return 0; +}