diff options
author | Daniel Black <danielgb@au.ibm.com> | 2018-02-16 21:41:44 +1100 |
---|---|---|
committer | Hans Kristian Rosbach <hk-github@circlestorm.org> | 2018-02-16 11:41:44 +0100 |
commit | 9ec0d91a0178d61e0cde400959156b85718438ad (patch) | |
tree | 4635d71dc8c08ce251f04aea3ab1f23a20f07486 /functable.c | |
parent | 8f6bf0a1a947f661edb8754f3e32b4a8f668269c (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.c | 48 |
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); +} |