crc32.hpp
Go to the documentation of this file.
1 #include <array>
2 #include <cstddef>
3 #include <cstdint>
4 
5 namespace mcap::internal {
6 
26 template <size_t Polynomial, size_t NumTables>
27 struct CRC32Table {
28 private:
29  std::array<uint32_t, 256 * NumTables> table = {};
30 
31 public:
32  constexpr CRC32Table() {
33  for (uint32_t i = 0; i < 256; i++) {
34  uint32_t r = i;
35  r = ((r & 1) * Polynomial) ^ (r >> 1);
36  r = ((r & 1) * Polynomial) ^ (r >> 1);
37  r = ((r & 1) * Polynomial) ^ (r >> 1);
38  r = ((r & 1) * Polynomial) ^ (r >> 1);
39  r = ((r & 1) * Polynomial) ^ (r >> 1);
40  r = ((r & 1) * Polynomial) ^ (r >> 1);
41  r = ((r & 1) * Polynomial) ^ (r >> 1);
42  r = ((r & 1) * Polynomial) ^ (r >> 1);
43  table[i] = r;
44  }
45  for (size_t i = 256; i < table.size(); i++) {
46  uint32_t value = table[i - 256];
47  table[i] = table[value & 0xff] ^ (value >> 8);
48  }
49  }
50 
51  constexpr uint32_t operator[](size_t index) const {
52  return table[index];
53  }
54 };
55 
56 inline uint32_t getUint32LE(const std::byte* data) {
57  return (uint32_t(data[0]) << 0) | (uint32_t(data[1]) << 8) | (uint32_t(data[2]) << 16) |
58  (uint32_t(data[3]) << 24);
59 }
60 
62 
66 static constexpr uint32_t CRC32_INIT = 0xffffffff;
67 
74 inline uint32_t crc32Update(const uint32_t prev, const std::byte* const data, const size_t length) {
75  // Process bytes one by one until we reach the proper alignment.
76  uint32_t r = prev;
77  size_t offset = 0;
78  for (; (uintptr_t(data + offset) & alignof(uint32_t)) != 0 && offset < length; offset++) {
79  r = CRC32_TABLE[(r ^ uint8_t(data[offset])) & 0xff] ^ (r >> 8);
80  }
81  if (offset == length) {
82  return r;
83  }
84 
85  // Process 8 bytes (2 uint32s) at a time.
86  size_t remainingBytes = length - offset;
87  for (; remainingBytes >= 8; offset += 8, remainingBytes -= 8) {
88  r ^= getUint32LE(data + offset);
89  uint32_t r2 = getUint32LE(data + offset + 4);
90  r = CRC32_TABLE[0 * 256 + ((r2 >> 24) & 0xff)] ^ CRC32_TABLE[1 * 256 + ((r2 >> 16) & 0xff)] ^
91  CRC32_TABLE[2 * 256 + ((r2 >> 8) & 0xff)] ^ CRC32_TABLE[3 * 256 + ((r2 >> 0) & 0xff)] ^
92  CRC32_TABLE[4 * 256 + ((r >> 24) & 0xff)] ^ CRC32_TABLE[5 * 256 + ((r >> 16) & 0xff)] ^
93  CRC32_TABLE[6 * 256 + ((r >> 8) & 0xff)] ^ CRC32_TABLE[7 * 256 + ((r >> 0) & 0xff)];
94  }
95 
96  // Process any remaining bytes one by one.
97  for (; offset < length; offset++) {
98  r = CRC32_TABLE[(r ^ uint8_t(data[offset])) & 0xff] ^ (r >> 8);
99  }
100  return r;
101 }
102 
104 inline uint32_t crc32Final(uint32_t crc) {
105  return crc ^ 0xffffffff;
106 }
107 
108 } // namespace mcap::internal
mcap::internal::CRC32Table::table
std::array< uint32_t, 256 *NumTables > table
Definition: crc32.hpp:29
mcap::internal::CRC32Table::CRC32Table
constexpr CRC32Table()
Definition: crc32.hpp:32
detail::uintptr_t
uint128_t uintptr_t
Definition: format.h:444
mcap::internal::CRC32_INIT
static constexpr uint32_t CRC32_INIT
Definition: crc32.hpp:66
mcap::internal::CRC32Table::operator[]
constexpr uint32_t operator[](size_t index) const
Definition: crc32.hpp:51
mcap::internal
Definition: crc32.hpp:5
mcap::internal::CRC32_TABLE
static constexpr CRC32Table< 0xedb88320, 8 > CRC32_TABLE
Definition: crc32.hpp:61
mcap::internal::CRC32Table
Definition: crc32.hpp:27
mcap::internal::crc32Final
uint32_t crc32Final(uint32_t crc)
Definition: crc32.hpp:104
mcap::internal::getUint32LE
uint32_t getUint32LE(const std::byte *data)
Definition: crc32.hpp:56
mqtt_test.data
dictionary data
Definition: mqtt_test.py:22
mcap::internal::crc32Update
uint32_t crc32Update(const uint32_t prev, const std::byte *const data, const size_t length)
Definition: crc32.hpp:74


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:43