summaryrefslogtreecommitdiff
path: root/functable.c
diff options
context:
space:
mode:
authorDaniel Black <danielgb@au.ibm.com>2018-02-16 21:41:44 +1100
committerHans Kristian Rosbach <hk-github@circlestorm.org>2018-02-16 11:41:44 +0100
commit9ec0d91a0178d61e0cde400959156b85718438ad (patch)
tree4635d71dc8c08ce251f04aea3ab1f23a20f07486 /functable.c
parent8f6bf0a1a947f661edb8754f3e32b4a8f668269c (diff)
wrap crc32 in functable (#145)
* wrap crc32 in functable * change internal crc32 api to use uint64_t rather than size_t for length
Diffstat (limited to 'functable.c')
-rw-r--r--functable.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/functable.c b/functable.c
index 06dc41f..3921fc9 100644
--- a/functable.c
+++ b/functable.c
@@ -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);
+}