// Copyright 2008,2009,2010 Massachusetts Institute of Technology.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/* Codership: stripped off C++ garbage to make this a normal C header */

#ifndef __CRC32C_H__
#define __CRC32C_H__

#include <stddef.h> // size_t
#include <stdint.h> // uint stuff

/** Returns the initial value for a CRC32-C computation. */
static inline uint32_t crc32cInit() {
    return 0xFFFFFFFF;
}

/** Pointer to a function that computes a CRC32C checksum.
@arg crc Previous CRC32C value, or crc32c_init().
@arg data Pointer to the data to be checksummed.
@arg length length of the data in bytes.
*/
typedef uint32_t (*CRC32CFunctionPtr)(uint32_t crc, const void* data, size_t length);

/** This will map automatically to the "best" CRC implementation. */
extern CRC32CFunctionPtr crc32c;

CRC32CFunctionPtr detectBestCRC32C();

/** Converts a partial CRC32-C computation to the final value. */
static inline uint32_t crc32cFinish(uint32_t crc) {
    return ~crc;
}

uint32_t crc32cSarwate   (uint32_t crc, const void* data, size_t length);
uint32_t crc32cSlicingBy4(uint32_t crc, const void* data, size_t length);
uint32_t crc32cSlicingBy8(uint32_t crc, const void* data, size_t length);

#if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64)
#define CRC32C_x86_64
#endif

#if defined(CRC32C_x86_64) || defined(__i386) || defined(_M_X86)
#define CRC32C_x86
#endif

#if !defined(CRC32C_x86)
#define CRC32C_NO_HARDWARE
#endif

#if !defined(CRC32C_NO_HARDWARE)
uint32_t crc32cHardware32(uint32_t crc, const void* data, size_t length);
uint32_t crc32cHardware64(uint32_t crc, const void* data, size_t length);
#endif /* !CRC32C_NO_HARDWARE */

#endif /* __CRC32C_H__ */
