88 lines
1.9 KiB
C++
88 lines
1.9 KiB
C++
#ifndef CONNECTIVITY_CHECKSUM_HPP
|
|
#define CONNECTIVITY_CHECKSUM_HPP
|
|
|
|
#include <zlib.h>
|
|
|
|
#include <boost/assert.hpp>
|
|
|
|
#include <array>
|
|
#include <climits>
|
|
#include <cstdint>
|
|
|
|
namespace osrm::util
|
|
{
|
|
|
|
struct ConnectivityChecksum
|
|
{
|
|
ConnectivityChecksum() : checksum(0), length(0), byte_number(0), bit_number(0) {}
|
|
|
|
void process_byte(unsigned char byte)
|
|
{
|
|
BOOST_ASSERT(byte_number < buffer.size());
|
|
|
|
if (bit_number > 0)
|
|
{
|
|
bit_number = 0;
|
|
++byte_number;
|
|
++length;
|
|
}
|
|
flush_bytes();
|
|
|
|
buffer[byte_number] = byte;
|
|
++byte_number;
|
|
++length;
|
|
flush_bytes();
|
|
|
|
buffer[byte_number] = 0;
|
|
}
|
|
|
|
void process_bit(bool bit)
|
|
{
|
|
BOOST_ASSERT(byte_number < buffer.size());
|
|
BOOST_ASSERT(bit_number < CHAR_BIT);
|
|
|
|
buffer[byte_number] = (buffer[byte_number] << 1) | static_cast<unsigned char>(bit);
|
|
if (++bit_number >= CHAR_BIT)
|
|
{
|
|
bit_number = 0;
|
|
++byte_number;
|
|
++length;
|
|
flush_bytes();
|
|
buffer[byte_number] = 0;
|
|
}
|
|
}
|
|
|
|
std::uint32_t update_checksum(std::uint32_t current)
|
|
{
|
|
if (bit_number > 0)
|
|
{
|
|
++byte_number;
|
|
++length;
|
|
}
|
|
checksum = crc32(checksum, buffer.data(), byte_number);
|
|
checksum = crc32_combine(current, checksum, length);
|
|
length = byte_number = bit_number = 0;
|
|
buffer[byte_number] = 0;
|
|
return checksum;
|
|
}
|
|
|
|
private:
|
|
void flush_bytes()
|
|
{
|
|
if (byte_number >= buffer.size())
|
|
{
|
|
checksum = crc32(checksum, buffer.data(), buffer.size());
|
|
byte_number = 0;
|
|
}
|
|
}
|
|
|
|
std::array<unsigned char, 64> buffer;
|
|
std::uint32_t checksum;
|
|
std::size_t length;
|
|
std::size_t byte_number;
|
|
unsigned char bit_number;
|
|
};
|
|
} // namespace osrm::util
|
|
|
|
#endif
|