]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
wrap crc32 in functable (#145)
authorDaniel Black <danielgb@au.ibm.com>
Fri, 16 Feb 2018 10:41:44 +0000 (21:41 +1100)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Fri, 16 Feb 2018 10:41:44 +0000 (11:41 +0100)
* wrap crc32 in functable
* change internal crc32 api to use uint64_t rather than size_t for length

arch/aarch64/crc32_acle.c
arch/arm/crc32_acle.c
crc32.c
functable.c
functable.h
gzendian.h [new file with mode: 0644]

index 4e1de9a875534ed9a36e056a43122086dfb5cbb9..f4ea283e7fea44d2b5a9abf10da2e1fa80c94e96 100644 (file)
@@ -12,7 +12,7 @@
 #  include <stddef.h>
 #endif
 
-uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, size_t len) {
+uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, uint64_t len) {
     register uint32_t c;
     register const uint16_t *buf2;
     register const uint32_t *buf4;
index d8a35368ce4b8a8b6b901753e0853839f57f9be6..5fa3c8337f1dc8213aab90a9a7c1b186118df35a 100644 (file)
@@ -12,7 +12,7 @@
 #  include <stddef.h>
 #endif
 
-uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, size_t len) {
+uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, uint64_t len) {
     register uint32_t c;
     register const uint16_t *buf2;
     register const uint32_t *buf4;
diff --git a/crc32.c b/crc32.c
index 88e4c5b5a7f8ee6ac873fe0ed5ff6be9d45b2eec..8883358b72bc3538537621856752a5db93a63e20 100644 (file)
--- a/crc32.c
+++ b/crc32.c
 
 /* @(#) $Id$ */
 
-#ifdef __MINGW32__
-# include <sys/param.h>
-#elif defined(WIN32) || defined(_WIN32)
-# define LITTLE_ENDIAN 1234
-# define BIG_ENDIAN 4321
-# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM)
-#  define BYTE_ORDER LITTLE_ENDIAN
-# else
-#  error Unknown endianness!
-# endif
-#elif defined(__linux__)
-# include <endian.h>
-#elif defined(__APPLE__) || defined(__arm__) || defined(__aarch64__)
-# include <machine/endian.h>
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
-# include <sys/endian.h>
-#elif defined(__sun) || defined(sun)
-# include <sys/byteorder.h>
-# if !defined(LITTLE_ENDIAN)
-#  define LITTLE_ENDIAN 4321
-# endif
-# if !defined(BIG_ENDIAN)
-#  define BIG_ENDIAN 1234
-# endif
-# if !defined(BYTE_ORDER)
-#  if defined(_BIG_ENDIAN)
-#   define BYTE_ORDER BIG_ENDIAN
-#  else
-#   define BYTE_ORDER LITTLE_ENDIAN
-#  endif
-# endif
-#else
-# include <endian.h>
-#endif
+# include "gzendian.h"
 
 /*
   Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
 #endif /* MAKECRCH */
 
 #include "deflate.h"
+#include "functable.h"
 
-ZLIB_INTERNAL uint32_t crc32_generic(uint32_t, const unsigned char *, z_off64_t);
-
-#ifdef __ARM_FEATURE_CRC32
-extern uint32_t crc32_acle(uint32_t, const unsigned char *, z_off64_t);
-#endif
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-ZLIB_INTERNAL uint32_t crc32_little(uint32_t, const unsigned char *, size_t);
-#elif BYTE_ORDER == BIG_ENDIAN
-ZLIB_INTERNAL uint32_t crc32_big(uint32_t, const unsigned char *, size_t);
-#endif
 
 /* Local functions for crc concatenation */
 static uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec);
@@ -216,33 +173,15 @@ const uint32_t * ZEXPORT PREFIX(get_crc_table)(void) {
 uint32_t ZEXPORT PREFIX(crc32_z)(uint32_t crc, const unsigned char *buf, size_t len) {
     if (buf == NULL) return 0;
 
-#ifdef DYNAMIC_CRC_TABLE
-    if (crc_table_empty)
-        make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-
-    if (sizeof(void *) == sizeof(ptrdiff_t)) {
-#if BYTE_ORDER == LITTLE_ENDIAN
-#  if __ARM_FEATURE_CRC32
-        return crc32_acle(crc, buf, len);
-#  else
-        return crc32_little(crc, buf, len);
-#  endif
-#elif BYTE_ORDER == BIG_ENDIAN
-        return crc32_big(crc, buf, len);
-#endif
-    }
-
-    return crc32_generic(crc, buf, len);
+    return functable.crc32(crc, buf, len);
 }
-
 /* ========================================================================= */
 #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
 #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
 #define DO4 DO1; DO1; DO1; DO1
 
 /* ========================================================================= */
-ZLIB_INTERNAL uint32_t crc32_generic(uint32_t crc, const unsigned char *buf, z_off64_t len)
+ZLIB_INTERNAL uint32_t crc32_generic(uint32_t crc, const unsigned char *buf, uint64_t len)
 {
     crc = crc ^ 0xffffffff;
 
@@ -288,7 +227,7 @@ uint32_t ZEXPORT PREFIX(crc32)(uint32_t crc, const unsigned char *buf, uint32_t
 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
 
 /* ========================================================================= */
-ZLIB_INTERNAL uint32_t crc32_little(uint32_t crc, const unsigned char *buf, size_t len) {
+ZLIB_INTERNAL uint32_t crc32_little(uint32_t crc, const unsigned char *buf, uint64_t len) {
     register uint32_t c;
     register const uint32_t *buf4;
 
@@ -330,7 +269,7 @@ ZLIB_INTERNAL uint32_t crc32_little(uint32_t crc, const unsigned char *buf, size
 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
 
 /* ========================================================================= */
-ZLIB_INTERNAL uint32_t crc32_big(uint32_t crc, const unsigned char *buf, size_t len) {
+ZLIB_INTERNAL uint32_t crc32_big(uint32_t crc, const unsigned char *buf, uint64_t len) {
     register uint32_t c;
     register const uint32_t *buf4;
 
index 06dc41fb1b29d46f3c8b6b99476996b75cd30ac8..3921fc9de7288ba67f80554bd1d7005aedcd1a8b 100644 (file)
@@ -7,6 +7,8 @@
 #include "deflate.h"
 #include "deflate_p.h"
 
+#include "gzendian.h"
+
 #if defined(X86_CPUID)
 # include "arch/x86/x86.h"
 #endif
@@ -32,13 +34,26 @@ extern uint32_t adler32_c(uint32_t adler, const unsigned char *buf, size_t len);
 extern uint32_t adler32_neon(uint32_t adler, const unsigned char *buf, size_t len);
 #endif
 
+ZLIB_INTERNAL uint32_t crc32_generic(uint32_t, const unsigned char *, uint64_t);
+
+#ifdef __ARM_FEATURE_CRC32
+extern uint32_t crc32_acle(uint32_t, const unsigned char *, uint64_t);
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+extern uint32_t crc32_little(uint32_t, const unsigned char *, uint64_t);
+#elif BYTE_ORDER == BIG_ENDIAN
+extern uint32_t crc32_big(uint32_t, const unsigned char *, uint64_t);
+#endif
+
 /* stub definitions */
 ZLIB_INTERNAL Pos insert_string_stub(deflate_state *const s, const Pos str, unsigned int count);
 ZLIB_INTERNAL void fill_window_stub(deflate_state *s);
 ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, size_t len);
+ZLIB_INTERNAL uint32_t crc32_stub(uint32_t crc, const unsigned char *buf, uint64_t len);
 
 /* functable init */
-ZLIB_INTERNAL struct functable_s functable = {fill_window_stub,insert_string_stub,adler32_stub};
+ZLIB_INTERNAL struct functable_s functable = {fill_window_stub,insert_string_stub,adler32_stub,crc32_stub};
 
 
 /* stub functions */
@@ -82,3 +97,34 @@ ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, si
 
     return functable.adler32(adler, buf, len);
 }
+
+ZLIB_INTERNAL uint32_t crc32_stub(uint32_t crc, const unsigned char *buf, uint64_t len) {
+
+
+   Assert(sizeof(uint64_t) >= sizeof(size_t),
+          "crc32_z takes size_t but internally we have a uint64_t len");
+/* return a function pointer for optimized arches here after a capability test */
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+#if BYTE_ORDER == LITTLE_ENDIAN
+#  if __ARM_FEATURE_CRC32
+        functable.crc32=crc32_acle;
+#  else
+        functable.crc32=crc32_little;
+#  endif
+#elif BYTE_ORDER == BIG_ENDIAN
+        functable.crc32=crc32_big;
+#else
+#  error No endian defined
+#endif
+    } else {
+        functable.crc32=crc32_generic;
+    }
+
+    return functable.crc32(crc, buf, len);
+}
index 4e6f53ee8cff7328f1452eba38aa16ffaa00a9e9..a8e8b7068432436ce4a31cf7f2b0d6a5641bbe6a 100644 (file)
@@ -12,6 +12,7 @@ struct functable_s {
     void     (* fill_window)    (deflate_state *s);
     Pos      (* insert_string)  (deflate_state *const s, const Pos str, unsigned int count);
     uint32_t (* adler32)        (uint32_t adler, const unsigned char *buf, size_t len);
+    uint32_t (* crc32)          (uint32_t crc, const unsigned char *buf, uint64_t len);
 };
 
 ZLIB_INTERNAL extern struct functable_s functable;
diff --git a/gzendian.h b/gzendian.h
new file mode 100644 (file)
index 0000000..267467d
--- /dev/null
@@ -0,0 +1,41 @@
+/* gzendian.h -- define BYTE_ORDER for endian tests
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifndef ENDIAN_H_
+#define ENDIAN_H_
+
+#ifdef __MINGW32__
+# include <sys/param.h>
+#elif defined(WIN32) || defined(_WIN32)
+# define LITTLE_ENDIAN 1234
+# define BIG_ENDIAN 4321
+# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM)
+#  define BYTE_ORDER LITTLE_ENDIAN
+# else
+#  error Unknown endianness!
+# endif
+#elif defined(__APPLE__) || defined(__arm__) || defined(__aarch64__)
+# include <machine/endian.h>
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
+# include <sys/endian.h>
+#elif defined(__sun) || defined(sun)
+# include <sys/byteorder.h>
+# if !defined(LITTLE_ENDIAN)
+#  define LITTLE_ENDIAN 4321
+# endif
+# if !defined(BIG_ENDIAN)
+#  define BIG_ENDIAN 1234
+# endif
+# if !defined(BYTE_ORDER)
+#  if defined(_BIG_ENDIAN)
+#   define BYTE_ORDER BIG_ENDIAN
+#  else
+#   define BYTE_ORDER LITTLE_ENDIAN
+#  endif
+# endif
+#else
+# include <endian.h>
+#endif
+
+#endif