compute CRC32 */
| 858 | |
| 859 | /* compute CRC32 */ |
| 860 | uint32_t crc32(uint32_t prev, const void* data, size_t length) { |
| 861 | uint32_t crc = ~prev; |
| 862 | unsigned unaligned; |
| 863 | const uint8_t* current_char; |
| 864 | const uint32_t* current; |
| 865 | |
| 866 | unaligned = ALIGNOF_UINT32_T - ((uintptr_t)data % ALIGNOF_UINT32_T); |
| 867 | if (unaligned == ALIGNOF_UINT32_T) unaligned = 0; |
| 868 | |
| 869 | /* process a byte at a time until we hit an alignment boundary (max 3) */ |
| 870 | current_char = (const uint8_t*)data; |
| 871 | for (; unaligned && length; unaligned--, length--) |
| 872 | crc = (crc >> 8) ^ crc32_lookup[0][(crc & 0xFF) ^ *current_char++]; |
| 873 | |
| 874 | current = (const uint32_t*)current_char; |
| 875 | |
| 876 | /* process 64 bytes at once (Slicing-by-16) */ |
| 877 | |
| 878 | /* enabling optimization (at least -O2) automatically unrolls the inner for-loop */ |
| 879 | const size_t unroll = 4; |
| 880 | const size_t bytes_at_once = 16 * unroll; |
| 881 | |
| 882 | while (length >= bytes_at_once) { |
| 883 | size_t unrolling; |
| 884 | for (unrolling = 0; unrolling < unroll; unrolling++) { |
| 885 | #if ARROW_LITTLE_ENDIAN |
| 886 | uint32_t one = *current++ ^ crc; |
| 887 | uint32_t two = *current++; |
| 888 | uint32_t three = *current++; |
| 889 | uint32_t four = *current++; |
| 890 | crc = crc32_lookup[0][(four >> 24) & 0xFF] ^ crc32_lookup[1][(four >> 16) & 0xFF] ^ |
| 891 | crc32_lookup[2][(four >> 8) & 0xFF] ^ crc32_lookup[3][four & 0xFF] ^ |
| 892 | crc32_lookup[4][(three >> 24) & 0xFF] ^ |
| 893 | crc32_lookup[5][(three >> 16) & 0xFF] ^ crc32_lookup[6][(three >> 8) & 0xFF] ^ |
| 894 | crc32_lookup[7][three & 0xFF] ^ crc32_lookup[8][(two >> 24) & 0xFF] ^ |
| 895 | crc32_lookup[9][(two >> 16) & 0xFF] ^ crc32_lookup[10][(two >> 8) & 0xFF] ^ |
| 896 | crc32_lookup[11][two & 0xFF] ^ crc32_lookup[12][(one >> 24) & 0xFF] ^ |
| 897 | crc32_lookup[13][(one >> 16) & 0xFF] ^ crc32_lookup[14][(one >> 8) & 0xFF] ^ |
| 898 | crc32_lookup[15][one & 0xFF]; |
| 899 | #else |
| 900 | uint32_t one = *current++ ^ ::arrow::bit_util::ByteSwap(crc); |
| 901 | uint32_t two = *current++; |
| 902 | uint32_t three = *current++; |
| 903 | uint32_t four = *current++; |
| 904 | crc = crc32_lookup[0][four & 0xFF] ^ crc32_lookup[1][(four >> 8) & 0xFF] ^ |
| 905 | crc32_lookup[2][(four >> 16) & 0xFF] ^ crc32_lookup[3][(four >> 24) & 0xFF] ^ |
| 906 | crc32_lookup[4][three & 0xFF] ^ crc32_lookup[5][(three >> 8) & 0xFF] ^ |
| 907 | crc32_lookup[6][(three >> 16) & 0xFF] ^ |
| 908 | crc32_lookup[7][(three >> 24) & 0xFF] ^ crc32_lookup[8][two & 0xFF] ^ |
| 909 | crc32_lookup[9][(two >> 8) & 0xFF] ^ crc32_lookup[10][(two >> 16) & 0xFF] ^ |
| 910 | crc32_lookup[11][(two >> 24) & 0xFF] ^ crc32_lookup[12][one & 0xFF] ^ |
| 911 | crc32_lookup[13][(one >> 8) & 0xFF] ^ crc32_lookup[14][(one >> 16) & 0xFF] ^ |
| 912 | crc32_lookup[15][(one >> 24) & 0xFF]; |
| 913 | #endif |
| 914 | } |
| 915 | |
| 916 | length -= bytes_at_once; |
| 917 | } |