#ifndef _TT_CRC_H_
#define _TT_CRC_H_

#include <sys/types.h>
#include <sys/cdefs.h>

/****************************************************************************************************************/

__BEGIN_DECLS
extern const unsigned char _libcipher_crc8_table[256];
extern const uint16 _libcipher_crc16_table[256];
extern const uint32 _libcipher_crc32_table[256];
__END_DECLS

/****************************************************************************************************************/

static inline __attribute__((__always_inline__)) unsigned int crc8_byte(unsigned int ch, unsigned int prev) {
  return _libcipher_crc8_table[ch ^ (prev & 0xFF)];
}

static inline __attribute__((__always_inline__)) unsigned int crc16_byte(unsigned int ch, unsigned int prev) {
  unsigned int crc_xor = _libcipher_crc16_table[(prev >> 8) & 0xFF];
  return (((prev << 8) | ch) ^ crc_xor) & 0xFFFF;
}

static inline __attribute__((__always_inline__)) unsigned int crc32_byte(unsigned int ch, unsigned int prev) {
  return _libcipher_crc32_table[(prev ^ ch) & 0xFF] ^ (prev >> 8);
}

/****************************************************************************************************************/

unsigned int crc8_buf(const void *buf, size_t len, unsigned int start);
unsigned int crc16_buf(const void *buf, size_t len, unsigned int start);
unsigned int crc32_buf(const void *buf, size_t len, unsigned int start);

/****************************************************************************************************************/
#endif
