/* Compute the CRC up to a z_word_t boundary. */
size_t align_diff = (size_t)MIN(ALIGN_DIFF(buf, BRAID_W), len);
- len -= align_diff;
- while (align_diff--)
- CRC_DO1;
+ if (align_diff) {
+ c = crc32_copy_small(c, NULL, buf, align_diff, BRAID_W - 1, 0);
+ len -= align_diff;
+ buf += align_diff;
+ }
/* Compute the CRC on as many BRAID_N z_word_t blocks as are available. */
blks = len / (BRAID_N * BRAID_W);
#endif /* BRAID_W */
/* Complete the computation of the CRC on any remaining bytes. */
- return crc32_copy_small(c, NULL, buf, len, 0);
+ return crc32_copy_small(c, NULL, buf, len, (BRAID_N * BRAID_W) - 1, 0);
}
Z_INTERNAL uint32_t crc32_braid(uint32_t crc, const uint8_t *buf, size_t len) {
}
if (copy_len > 0) {
- crc = crc32_copy_small(~crc, dst, src, copy_len, COPY);
+ crc = ~crc32_copy_small(~crc, dst, src, copy_len, 31, COPY);
src += copy_len;
len -= copy_len;
if (COPY) {
/* crc32_p.h -- Private inline functions and macros shared with
* different computation of the CRC-32 checksum
* of a data stream.
- * Copyright (C) 1995-2011, 2016 Mark Adler
+ * Copyright (C) 2026 Nathan Moinvaziri
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#ifndef CRC32_P_H
#define CRC32_P_H
-#define CRC_DO1 c = crc_table[(c ^ *buf++) & 0xff] ^ (c >> 8)
-#define CRC_DO8 CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1
+#define CRC_DO1(c, buf, i) c = crc_table[(c ^ buf[i]) & 0xff] ^ (c >> 8)
+#define CRC_DO2(c, buf, i) {CRC_DO1(c, buf, i); CRC_DO1(c, buf, i+1);}
+#define CRC_DO4(c, buf, i) {CRC_DO2(c, buf, i); CRC_DO2(c, buf, i+2);}
+#define CRC_DO8(c, buf, i) {CRC_DO4(c, buf, i); CRC_DO4(c, buf, i+4);}
-Z_FORCEINLINE static uint32_t crc32_copy_small(uint32_t crc, uint8_t *dst, const uint8_t *buf, size_t len, const int COPY) {
- uint32_t c = crc;
- if (COPY) {
- memcpy(dst, buf, len);
+Z_FORCEINLINE static uint32_t crc32_copy_small(uint32_t crc, uint8_t *dst, const uint8_t *buf, size_t len,
+ const int MAX_LEN, const int COPY) {
+ if (MAX_LEN >= 8) {
+ while (len >= 8) {
+ if (COPY) {
+ memcpy(dst, buf, 8);
+ dst += 8;
+ }
+ CRC_DO8(crc, buf, 0);
+ buf += 8;
+ len -= 8;
+ }
}
- while (len >= 8) {
- len -= 8;
- CRC_DO8;
+ if (len & 4) {
+ if (COPY) {
+ memcpy(dst, buf, 4);
+ dst += 4;
+ }
+ CRC_DO4(crc, buf, 0);
+ buf += 4;
}
- while (len--) {
- CRC_DO1;
+ if (len & 2) {
+ if (COPY) {
+ memcpy(dst, buf, 2);
+ dst += 2;
+ }
+ CRC_DO2(crc, buf, 0);
+ buf += 2;
+ }
+ if (len & 1) {
+ if (COPY)
+ *dst = *buf;
+ CRC_DO1(crc, buf, 0);
}
- return ~c;
+ return crc;
}
#endif /* CRC32_P_H */