// Boost CRC library crc.hpp header file -----------------------------------// | |
// Copyright 2001, 2004 Daryle Walker. Use, modification, and distribution are | |
// subject to the Boost Software License, Version 1.0. (See accompanying file | |
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.) | |
// See <http://www.boost.org/libs/crc/> for the library's home page. | |
#ifndef BOOST_CRC_HPP | |
#define BOOST_CRC_HPP | |
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc. | |
#include <boost/integer.hpp> // for boost::uint_t | |
#include <climits> // for CHAR_BIT, etc. | |
#include <cstddef> // for std::size_t | |
#include <boost/limits.hpp> // for std::numeric_limits | |
// The type of CRC parameters that can go in a template should be related | |
// on the CRC's bit count. This macro expresses that type in a compact | |
// form, but also allows an alternate type for compilers that don't support | |
// dependent types (in template value-parameters). | |
#if !(defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) || (defined(BOOST_MSVC) && (BOOST_MSVC <= 1300))) | |
#define BOOST_CRC_PARM_TYPE typename ::boost::uint_t<Bits>::fast | |
#else | |
#define BOOST_CRC_PARM_TYPE unsigned long | |
#endif | |
// Some compilers [MS VC++ 6] cannot correctly set up several versions of a | |
// function template unless every template argument can be unambiguously | |
// deduced from the function arguments. (The bug is hidden if only one version | |
// is needed.) Since all of the CRC function templates have this problem, the | |
// workaround is to make up a dummy function argument that encodes the template | |
// arguments. Calls to such template functions need all their template | |
// arguments explicitly specified. At least one compiler that needs this | |
// workaround also needs the default value for the dummy argument to be | |
// specified in the definition. | |
#if defined(__GNUC__) || !defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) | |
#define BOOST_CRC_DUMMY_PARM_TYPE | |
#define BOOST_CRC_DUMMY_INIT | |
#define BOOST_ACRC_DUMMY_PARM_TYPE | |
#define BOOST_ACRC_DUMMY_INIT | |
#else | |
namespace boost { namespace detail { | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
struct dummy_crc_argument { }; | |
} } | |
#define BOOST_CRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument<Bits, \ | |
TruncPoly, InitRem, FinalXor, ReflectIn, ReflectRem> *p_ | |
#define BOOST_CRC_DUMMY_INIT BOOST_CRC_DUMMY_PARM_TYPE = 0 | |
#define BOOST_ACRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument<Bits, \ | |
TruncPoly, 0, 0, false, false> *p_ | |
#define BOOST_ACRC_DUMMY_INIT BOOST_ACRC_DUMMY_PARM_TYPE = 0 | |
#endif | |
namespace boost | |
{ | |
// Forward declarations ----------------------------------------------------// | |
template < std::size_t Bits > | |
class crc_basic; | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u, | |
BOOST_CRC_PARM_TYPE InitRem = 0u, | |
BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false, | |
bool ReflectRem = false > | |
class crc_optimal; | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
typename uint_t<Bits>::fast crc( void const *buffer, | |
std::size_t byte_count | |
BOOST_CRC_DUMMY_PARM_TYPE ); | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > | |
typename uint_t<Bits>::fast augmented_crc( void const *buffer, | |
std::size_t byte_count, typename uint_t<Bits>::fast initial_remainder | |
BOOST_ACRC_DUMMY_PARM_TYPE ); | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > | |
typename uint_t<Bits>::fast augmented_crc( void const *buffer, | |
std::size_t byte_count | |
BOOST_ACRC_DUMMY_PARM_TYPE ); | |
typedef crc_optimal<16, 0x8005, 0, 0, true, true> crc_16_type; | |
typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_type; | |
typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type; | |
typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> | |
crc_32_type; | |
// Forward declarations for implementation detail stuff --------------------// | |
// (Just for the stuff that will be needed for the next two sections) | |
namespace detail | |
{ | |
template < std::size_t Bits > | |
struct mask_uint_t; | |
template < > | |
struct mask_uint_t< std::numeric_limits<unsigned char>::digits >; | |
#if USHRT_MAX > UCHAR_MAX | |
template < > | |
struct mask_uint_t< std::numeric_limits<unsigned short>::digits >; | |
#endif | |
#if UINT_MAX > USHRT_MAX | |
template < > | |
struct mask_uint_t< std::numeric_limits<unsigned int>::digits >; | |
#endif | |
#if ULONG_MAX > UINT_MAX | |
template < > | |
struct mask_uint_t< std::numeric_limits<unsigned long>::digits >; | |
#endif | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > | |
struct crc_table_t; | |
template < std::size_t Bits, bool DoReflect > | |
class crc_helper; | |
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
template < std::size_t Bits > | |
class crc_helper< Bits, false >; | |
#endif | |
} // namespace detail | |
// Simple cyclic redundancy code (CRC) class declaration -------------------// | |
template < std::size_t Bits > | |
class crc_basic | |
{ | |
// Implementation type | |
typedef detail::mask_uint_t<Bits> masking_type; | |
public: | |
// Type | |
typedef typename masking_type::least value_type; | |
// Constant for the template parameter | |
BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); | |
// Constructor | |
explicit crc_basic( value_type truncated_polynominal, | |
value_type initial_remainder = 0, value_type final_xor_value = 0, | |
bool reflect_input = false, bool reflect_remainder = false ); | |
// Internal Operations | |
value_type get_truncated_polynominal() const; | |
value_type get_initial_remainder() const; | |
value_type get_final_xor_value() const; | |
bool get_reflect_input() const; | |
bool get_reflect_remainder() const; | |
value_type get_interim_remainder() const; | |
void reset( value_type new_rem ); | |
void reset(); | |
// External Operations | |
void process_bit( bool bit ); | |
void process_bits( unsigned char bits, std::size_t bit_count ); | |
void process_byte( unsigned char byte ); | |
void process_block( void const *bytes_begin, void const *bytes_end ); | |
void process_bytes( void const *buffer, std::size_t byte_count ); | |
value_type checksum() const; | |
private: | |
// Member data | |
value_type rem_; | |
value_type poly_, init_, final_; // non-const to allow assignability | |
bool rft_in_, rft_out_; // non-const to allow assignability | |
}; // boost::crc_basic | |
// Optimized cyclic redundancy code (CRC) class declaration ----------------// | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
class crc_optimal | |
{ | |
// Implementation type | |
typedef detail::mask_uint_t<Bits> masking_type; | |
public: | |
// Type | |
typedef typename masking_type::fast value_type; | |
// Constants for the template parameters | |
BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); | |
BOOST_STATIC_CONSTANT( value_type, truncated_polynominal = TruncPoly ); | |
BOOST_STATIC_CONSTANT( value_type, initial_remainder = InitRem ); | |
BOOST_STATIC_CONSTANT( value_type, final_xor_value = FinalXor ); | |
BOOST_STATIC_CONSTANT( bool, reflect_input = ReflectIn ); | |
BOOST_STATIC_CONSTANT( bool, reflect_remainder = ReflectRem ); | |
// Constructor | |
explicit crc_optimal( value_type init_rem = InitRem ); | |
// Internal Operations | |
value_type get_truncated_polynominal() const; | |
value_type get_initial_remainder() const; | |
value_type get_final_xor_value() const; | |
bool get_reflect_input() const; | |
bool get_reflect_remainder() const; | |
value_type get_interim_remainder() const; | |
void reset( value_type new_rem = InitRem ); | |
// External Operations | |
void process_byte( unsigned char byte ); | |
void process_block( void const *bytes_begin, void const *bytes_end ); | |
void process_bytes( void const *buffer, std::size_t byte_count ); | |
value_type checksum() const; | |
// Operators | |
void operator ()( unsigned char byte ); | |
value_type operator ()() const; | |
private: | |
// The implementation of output reflection depends on both reflect states. | |
BOOST_STATIC_CONSTANT( bool, reflect_output = (ReflectRem != ReflectIn) ); | |
#ifndef __BORLANDC__ | |
#define BOOST_CRC_REF_OUT_VAL reflect_output | |
#else | |
typedef crc_optimal self_type; | |
#define BOOST_CRC_REF_OUT_VAL (self_type::reflect_output) | |
#endif | |
// More implementation types | |
typedef detail::crc_table_t<Bits, TruncPoly, ReflectIn> crc_table_type; | |
typedef detail::crc_helper<Bits, ReflectIn> helper_type; | |
typedef detail::crc_helper<Bits, BOOST_CRC_REF_OUT_VAL> reflect_out_type; | |
#undef BOOST_CRC_REF_OUT_VAL | |
// Member data | |
value_type rem_; | |
}; // boost::crc_optimal | |
// Implementation detail stuff ---------------------------------------------// | |
namespace detail | |
{ | |
// Forward declarations for more implementation details | |
template < std::size_t Bits > | |
struct high_uint_t; | |
template < std::size_t Bits > | |
struct reflector; | |
// Traits class for mask; given the bit number | |
// (1-based), get the mask for that bit by itself. | |
template < std::size_t Bits > | |
struct high_uint_t | |
: boost::uint_t< Bits > | |
{ | |
typedef boost::uint_t<Bits> base_type; | |
typedef typename base_type::least least; | |
typedef typename base_type::fast fast; | |
#if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 | |
static const least high_bit = 1ul << ( Bits - 1u ); | |
static const fast high_bit_fast = 1ul << ( Bits - 1u ); | |
#else | |
BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << ( Bits | |
- 1u )) ); | |
BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << ( Bits | |
- 1u )) ); | |
#endif | |
}; // boost::detail::high_uint_t | |
// Reflection routine class wrapper | |
// (since MS VC++ 6 couldn't handle the unwrapped version) | |
template < std::size_t Bits > | |
struct reflector | |
{ | |
typedef typename boost::uint_t<Bits>::fast value_type; | |
static value_type reflect( value_type x ); | |
}; // boost::detail::reflector | |
// Function that reflects its argument | |
template < std::size_t Bits > | |
typename reflector<Bits>::value_type | |
reflector<Bits>::reflect | |
( | |
typename reflector<Bits>::value_type x | |
) | |
{ | |
value_type reflection = 0; | |
value_type const one = 1; | |
for ( std::size_t i = 0 ; i < Bits ; ++i, x >>= 1 ) | |
{ | |
if ( x & one ) | |
{ | |
reflection |= ( one << (Bits - 1u - i) ); | |
} | |
} | |
return reflection; | |
} | |
// Traits class for masks; given the bit number (1-based), | |
// get the mask for that bit and its lower bits. | |
template < std::size_t Bits > | |
struct mask_uint_t | |
: high_uint_t< Bits > | |
{ | |
typedef high_uint_t<Bits> base_type; | |
typedef typename base_type::least least; | |
typedef typename base_type::fast fast; | |
#ifndef __BORLANDC__ | |
using base_type::high_bit; | |
using base_type::high_bit_fast; | |
#else | |
BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); | |
BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); | |
#endif | |
#if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 | |
static const least sig_bits = (~( ~( 0ul ) << Bits )) ; | |
#else | |
BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) ); | |
#endif | |
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 | |
// Work around a weird bug that ICEs the compiler in build_c_cast | |
BOOST_STATIC_CONSTANT( fast, sig_bits_fast = static_cast<fast>(sig_bits) ); | |
#else | |
BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); | |
#endif | |
}; // boost::detail::mask_uint_t | |
template < > | |
struct mask_uint_t< std::numeric_limits<unsigned char>::digits > | |
: high_uint_t< std::numeric_limits<unsigned char>::digits > | |
{ | |
typedef high_uint_t<std::numeric_limits<unsigned char>::digits> | |
base_type; | |
typedef base_type::least least; | |
typedef base_type::fast fast; | |
#ifndef __BORLANDC__ | |
using base_type::high_bit; | |
using base_type::high_bit_fast; | |
#else | |
BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); | |
BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); | |
#endif | |
BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); | |
BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); | |
}; // boost::detail::mask_uint_t | |
#if USHRT_MAX > UCHAR_MAX | |
template < > | |
struct mask_uint_t< std::numeric_limits<unsigned short>::digits > | |
: high_uint_t< std::numeric_limits<unsigned short>::digits > | |
{ | |
typedef high_uint_t<std::numeric_limits<unsigned short>::digits> | |
base_type; | |
typedef base_type::least least; | |
typedef base_type::fast fast; | |
#ifndef __BORLANDC__ | |
using base_type::high_bit; | |
using base_type::high_bit_fast; | |
#else | |
BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); | |
BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); | |
#endif | |
BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); | |
BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); | |
}; // boost::detail::mask_uint_t | |
#endif | |
#if UINT_MAX > USHRT_MAX | |
template < > | |
struct mask_uint_t< std::numeric_limits<unsigned int>::digits > | |
: high_uint_t< std::numeric_limits<unsigned int>::digits > | |
{ | |
typedef high_uint_t<std::numeric_limits<unsigned int>::digits> | |
base_type; | |
typedef base_type::least least; | |
typedef base_type::fast fast; | |
#ifndef __BORLANDC__ | |
using base_type::high_bit; | |
using base_type::high_bit_fast; | |
#else | |
BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); | |
BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); | |
#endif | |
BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); | |
BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); | |
}; // boost::detail::mask_uint_t | |
#endif | |
#if ULONG_MAX > UINT_MAX | |
template < > | |
struct mask_uint_t< std::numeric_limits<unsigned long>::digits > | |
: high_uint_t< std::numeric_limits<unsigned long>::digits > | |
{ | |
typedef high_uint_t<std::numeric_limits<unsigned long>::digits> | |
base_type; | |
typedef base_type::least least; | |
typedef base_type::fast fast; | |
#ifndef __BORLANDC__ | |
using base_type::high_bit; | |
using base_type::high_bit_fast; | |
#else | |
BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit ); | |
BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast ); | |
#endif | |
BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); | |
BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); | |
}; // boost::detail::mask_uint_t | |
#endif | |
// CRC table generator | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > | |
struct crc_table_t | |
{ | |
BOOST_STATIC_CONSTANT( std::size_t, byte_combos = (1ul << CHAR_BIT) ); | |
typedef mask_uint_t<Bits> masking_type; | |
typedef typename masking_type::fast value_type; | |
#if defined(__BORLANDC__) && defined(_M_IX86) && (__BORLANDC__ == 0x560) | |
// for some reason Borland's command line compiler (version 0x560) | |
// chokes over this unless we do the calculation for it: | |
typedef value_type table_type[ 0x100 ]; | |
#elif defined(__GNUC__) | |
// old versions of GCC (before 4.0.2) choke on using byte_combos | |
// as a constant expression when compiling with -pedantic. | |
typedef value_type table_type[1ul << CHAR_BIT]; | |
#else | |
typedef value_type table_type[ byte_combos ]; | |
#endif | |
static void init_table(); | |
static table_type table_; | |
}; // boost::detail::crc_table_t | |
// CRC table generator static data member definition | |
// (Some compilers [Borland C++] require the initializer to be present.) | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > | |
typename crc_table_t<Bits, TruncPoly, Reflect>::table_type | |
crc_table_t<Bits, TruncPoly, Reflect>::table_ | |
= { 0 }; | |
// Populate CRC lookup table | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > | |
void | |
crc_table_t<Bits, TruncPoly, Reflect>::init_table | |
( | |
) | |
{ | |
// compute table only on the first run | |
static bool did_init = false; | |
if ( did_init ) return; | |
// factor-out constants to avoid recalculation | |
value_type const fast_hi_bit = masking_type::high_bit_fast; | |
unsigned char const byte_hi_bit = 1u << (CHAR_BIT - 1u); | |
// loop over every possible dividend value | |
unsigned char dividend = 0; | |
do | |
{ | |
value_type remainder = 0; | |
// go through all the dividend's bits | |
for ( unsigned char mask = byte_hi_bit ; mask ; mask >>= 1 ) | |
{ | |
// check if divisor fits | |
if ( dividend & mask ) | |
{ | |
remainder ^= fast_hi_bit; | |
} | |
// do polynominal division | |
if ( remainder & fast_hi_bit ) | |
{ | |
remainder <<= 1; | |
remainder ^= TruncPoly; | |
} | |
else | |
{ | |
remainder <<= 1; | |
} | |
} | |
table_[ crc_helper<CHAR_BIT, Reflect>::reflect(dividend) ] | |
= crc_helper<Bits, Reflect>::reflect( remainder ); | |
} | |
while ( ++dividend ); | |
did_init = true; | |
} | |
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
// Align the msb of the remainder to a byte | |
template < std::size_t Bits, bool RightShift > | |
class remainder | |
{ | |
public: | |
typedef typename uint_t<Bits>::fast value_type; | |
static unsigned char align_msb( value_type rem ) | |
{ return rem >> (Bits - CHAR_BIT); } | |
}; | |
// Specialization for the case that the remainder has less | |
// bits than a byte: align the remainder msb to the byte msb | |
template < std::size_t Bits > | |
class remainder< Bits, false > | |
{ | |
public: | |
typedef typename uint_t<Bits>::fast value_type; | |
static unsigned char align_msb( value_type rem ) | |
{ return rem << (CHAR_BIT - Bits); } | |
}; | |
#endif | |
// CRC helper routines | |
template < std::size_t Bits, bool DoReflect > | |
class crc_helper | |
{ | |
public: | |
// Type | |
typedef typename uint_t<Bits>::fast value_type; | |
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
// Possibly reflect a remainder | |
static value_type reflect( value_type x ) | |
{ return detail::reflector<Bits>::reflect( x ); } | |
// Compare a byte to the remainder's highest byte | |
static unsigned char index( value_type rem, unsigned char x ) | |
{ return x ^ rem; } | |
// Shift out the remainder's highest byte | |
static value_type shift( value_type rem ) | |
{ return rem >> CHAR_BIT; } | |
#else | |
// Possibly reflect a remainder | |
static value_type reflect( value_type x ) | |
{ return DoReflect ? detail::reflector<Bits>::reflect( x ) : x; } | |
// Compare a byte to the remainder's highest byte | |
static unsigned char index( value_type rem, unsigned char x ) | |
{ return x ^ ( DoReflect ? rem : | |
((Bits>CHAR_BIT)?( rem >> (Bits - CHAR_BIT) ) : | |
( rem << (CHAR_BIT - Bits) ))); } | |
// Shift out the remainder's highest byte | |
static value_type shift( value_type rem ) | |
{ return DoReflect ? rem >> CHAR_BIT : rem << CHAR_BIT; } | |
#endif | |
}; // boost::detail::crc_helper | |
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
template < std::size_t Bits > | |
class crc_helper<Bits, false> | |
{ | |
public: | |
// Type | |
typedef typename uint_t<Bits>::fast value_type; | |
// Possibly reflect a remainder | |
static value_type reflect( value_type x ) | |
{ return x; } | |
// Compare a byte to the remainder's highest byte | |
static unsigned char index( value_type rem, unsigned char x ) | |
{ return x ^ remainder<Bits,(Bits>CHAR_BIT)>::align_msb( rem ); } | |
// Shift out the remainder's highest byte | |
static value_type shift( value_type rem ) | |
{ return rem << CHAR_BIT; } | |
}; // boost::detail::crc_helper | |
#endif | |
} // namespace detail | |
// Simple CRC class function definitions -----------------------------------// | |
template < std::size_t Bits > | |
inline | |
crc_basic<Bits>::crc_basic | |
( | |
typename crc_basic<Bits>::value_type truncated_polynominal, | |
typename crc_basic<Bits>::value_type initial_remainder, // = 0 | |
typename crc_basic<Bits>::value_type final_xor_value, // = 0 | |
bool reflect_input, // = false | |
bool reflect_remainder // = false | |
) | |
: rem_( initial_remainder ), poly_( truncated_polynominal ) | |
, init_( initial_remainder ), final_( final_xor_value ) | |
, rft_in_( reflect_input ), rft_out_( reflect_remainder ) | |
{ | |
} | |
template < std::size_t Bits > | |
inline | |
typename crc_basic<Bits>::value_type | |
crc_basic<Bits>::get_truncated_polynominal | |
( | |
) const | |
{ | |
return poly_; | |
} | |
template < std::size_t Bits > | |
inline | |
typename crc_basic<Bits>::value_type | |
crc_basic<Bits>::get_initial_remainder | |
( | |
) const | |
{ | |
return init_; | |
} | |
template < std::size_t Bits > | |
inline | |
typename crc_basic<Bits>::value_type | |
crc_basic<Bits>::get_final_xor_value | |
( | |
) const | |
{ | |
return final_; | |
} | |
template < std::size_t Bits > | |
inline | |
bool | |
crc_basic<Bits>::get_reflect_input | |
( | |
) const | |
{ | |
return rft_in_; | |
} | |
template < std::size_t Bits > | |
inline | |
bool | |
crc_basic<Bits>::get_reflect_remainder | |
( | |
) const | |
{ | |
return rft_out_; | |
} | |
template < std::size_t Bits > | |
inline | |
typename crc_basic<Bits>::value_type | |
crc_basic<Bits>::get_interim_remainder | |
( | |
) const | |
{ | |
return rem_ & masking_type::sig_bits; | |
} | |
template < std::size_t Bits > | |
inline | |
void | |
crc_basic<Bits>::reset | |
( | |
typename crc_basic<Bits>::value_type new_rem | |
) | |
{ | |
rem_ = new_rem; | |
} | |
template < std::size_t Bits > | |
inline | |
void | |
crc_basic<Bits>::reset | |
( | |
) | |
{ | |
this->reset( this->get_initial_remainder() ); | |
} | |
template < std::size_t Bits > | |
inline | |
void | |
crc_basic<Bits>::process_bit | |
( | |
bool bit | |
) | |
{ | |
value_type const high_bit_mask = masking_type::high_bit; | |
// compare the new bit with the remainder's highest | |
rem_ ^= ( bit ? high_bit_mask : 0u ); | |
// a full polynominal division step is done when the highest bit is one | |
bool const do_poly_div = static_cast<bool>( rem_ & high_bit_mask ); | |
// shift out the highest bit | |
rem_ <<= 1; | |
// carry out the division, if needed | |
if ( do_poly_div ) | |
{ | |
rem_ ^= poly_; | |
} | |
} | |
template < std::size_t Bits > | |
void | |
crc_basic<Bits>::process_bits | |
( | |
unsigned char bits, | |
std::size_t bit_count | |
) | |
{ | |
// ignore the bits above the ones we want | |
bits <<= CHAR_BIT - bit_count; | |
// compute the CRC for each bit, starting with the upper ones | |
unsigned char const high_bit_mask = 1u << ( CHAR_BIT - 1u ); | |
for ( std::size_t i = bit_count ; i > 0u ; --i, bits <<= 1u ) | |
{ | |
process_bit( static_cast<bool>(bits & high_bit_mask) ); | |
} | |
} | |
template < std::size_t Bits > | |
inline | |
void | |
crc_basic<Bits>::process_byte | |
( | |
unsigned char byte | |
) | |
{ | |
process_bits( (rft_in_ ? detail::reflector<CHAR_BIT>::reflect(byte) | |
: byte), CHAR_BIT ); | |
} | |
template < std::size_t Bits > | |
void | |
crc_basic<Bits>::process_block | |
( | |
void const * bytes_begin, | |
void const * bytes_end | |
) | |
{ | |
for ( unsigned char const * p | |
= static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p ) | |
{ | |
process_byte( *p ); | |
} | |
} | |
template < std::size_t Bits > | |
inline | |
void | |
crc_basic<Bits>::process_bytes | |
( | |
void const * buffer, | |
std::size_t byte_count | |
) | |
{ | |
unsigned char const * const b = static_cast<unsigned char const *>( | |
buffer ); | |
process_block( b, b + byte_count ); | |
} | |
template < std::size_t Bits > | |
inline | |
typename crc_basic<Bits>::value_type | |
crc_basic<Bits>::checksum | |
( | |
) const | |
{ | |
return ( (rft_out_ ? detail::reflector<Bits>::reflect( rem_ ) : rem_) | |
^ final_ ) & masking_type::sig_bits; | |
} | |
// Optimized CRC class function definitions --------------------------------// | |
// Macro to compact code | |
#define BOOST_CRC_OPTIMAL_NAME crc_optimal<Bits, TruncPoly, InitRem, \ | |
FinalXor, ReflectIn, ReflectRem> | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
BOOST_CRC_OPTIMAL_NAME::crc_optimal | |
( | |
typename BOOST_CRC_OPTIMAL_NAME::value_type init_rem // = InitRem | |
) | |
: rem_( helper_type::reflect(init_rem) ) | |
{ | |
crc_table_type::init_table(); | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
typename BOOST_CRC_OPTIMAL_NAME::value_type | |
BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal | |
( | |
) const | |
{ | |
return TruncPoly; | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
typename BOOST_CRC_OPTIMAL_NAME::value_type | |
BOOST_CRC_OPTIMAL_NAME::get_initial_remainder | |
( | |
) const | |
{ | |
return InitRem; | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
typename BOOST_CRC_OPTIMAL_NAME::value_type | |
BOOST_CRC_OPTIMAL_NAME::get_final_xor_value | |
( | |
) const | |
{ | |
return FinalXor; | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
bool | |
BOOST_CRC_OPTIMAL_NAME::get_reflect_input | |
( | |
) const | |
{ | |
return ReflectIn; | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
bool | |
BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder | |
( | |
) const | |
{ | |
return ReflectRem; | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
typename BOOST_CRC_OPTIMAL_NAME::value_type | |
BOOST_CRC_OPTIMAL_NAME::get_interim_remainder | |
( | |
) const | |
{ | |
// Interim remainder should be _un_-reflected, so we have to undo it. | |
return helper_type::reflect( rem_ ) & masking_type::sig_bits_fast; | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
void | |
BOOST_CRC_OPTIMAL_NAME::reset | |
( | |
typename BOOST_CRC_OPTIMAL_NAME::value_type new_rem // = InitRem | |
) | |
{ | |
rem_ = helper_type::reflect( new_rem ); | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
void | |
BOOST_CRC_OPTIMAL_NAME::process_byte | |
( | |
unsigned char byte | |
) | |
{ | |
process_bytes( &byte, sizeof(byte) ); | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
void | |
BOOST_CRC_OPTIMAL_NAME::process_block | |
( | |
void const * bytes_begin, | |
void const * bytes_end | |
) | |
{ | |
// Recompute the CRC for each byte passed | |
for ( unsigned char const * p | |
= static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p ) | |
{ | |
// Compare the new byte with the remainder's higher bits to | |
// get the new bits, shift out the remainder's current higher | |
// bits, and update the remainder with the polynominal division | |
// of the new bits. | |
unsigned char const byte_index = helper_type::index( rem_, *p ); | |
rem_ = helper_type::shift( rem_ ); | |
rem_ ^= crc_table_type::table_[ byte_index ]; | |
} | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
void | |
BOOST_CRC_OPTIMAL_NAME::process_bytes | |
( | |
void const * buffer, | |
std::size_t byte_count | |
) | |
{ | |
unsigned char const * const b = static_cast<unsigned char const *>( | |
buffer ); | |
process_block( b, b + byte_count ); | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
typename BOOST_CRC_OPTIMAL_NAME::value_type | |
BOOST_CRC_OPTIMAL_NAME::checksum | |
( | |
) const | |
{ | |
return ( reflect_out_type::reflect(rem_) ^ get_final_xor_value() ) | |
& masking_type::sig_bits_fast; | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
void | |
BOOST_CRC_OPTIMAL_NAME::operator () | |
( | |
unsigned char byte | |
) | |
{ | |
process_byte( byte ); | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
typename BOOST_CRC_OPTIMAL_NAME::value_type | |
BOOST_CRC_OPTIMAL_NAME::operator () | |
( | |
) const | |
{ | |
return checksum(); | |
} | |
// CRC computation function definition -------------------------------------// | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, | |
BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, | |
bool ReflectIn, bool ReflectRem > | |
inline | |
typename uint_t<Bits>::fast | |
crc | |
( | |
void const * buffer, | |
std::size_t byte_count | |
BOOST_CRC_DUMMY_INIT | |
) | |
{ | |
BOOST_CRC_OPTIMAL_NAME computer; | |
computer.process_bytes( buffer, byte_count ); | |
return computer.checksum(); | |
} | |
// Augmented-message CRC computation function definitions ------------------// | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > | |
typename uint_t<Bits>::fast | |
augmented_crc | |
( | |
void const * buffer, | |
std::size_t byte_count, | |
typename uint_t<Bits>::fast initial_remainder | |
BOOST_ACRC_DUMMY_INIT | |
) | |
{ | |
typedef unsigned char byte_type; | |
typedef detail::mask_uint_t<Bits> masking_type; | |
typedef detail::crc_table_t<Bits, TruncPoly, false> crc_table_type; | |
typename masking_type::fast rem = initial_remainder; | |
byte_type const * const b = static_cast<byte_type const *>( buffer ); | |
byte_type const * const e = b + byte_count; | |
crc_table_type::init_table(); | |
for ( byte_type const * p = b ; p < e ; ++p ) | |
{ | |
// Use the current top byte as the table index to the next | |
// "partial product." Shift out that top byte, shifting in | |
// the next augmented-message byte. Complete the division. | |
byte_type const byte_index = rem >> ( Bits - CHAR_BIT ); | |
rem <<= CHAR_BIT; | |
rem |= *p; | |
rem ^= crc_table_type::table_[ byte_index ]; | |
} | |
return rem & masking_type::sig_bits_fast; | |
} | |
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > | |
inline | |
typename uint_t<Bits>::fast | |
augmented_crc | |
( | |
void const * buffer, | |
std::size_t byte_count | |
BOOST_ACRC_DUMMY_INIT | |
) | |
{ | |
// The last function argument has its type specified so the other version of | |
// augmented_crc will be called. If the cast wasn't in place, and the | |
// BOOST_ACRC_DUMMY_INIT added a third argument (for a workaround), the "0" | |
// would match as that third argument, leading to infinite recursion. | |
return augmented_crc<Bits, TruncPoly>( buffer, byte_count, | |
static_cast<typename uint_t<Bits>::fast>(0) ); | |
} | |
} // namespace boost | |
// Undo header-private macros | |
#undef BOOST_CRC_OPTIMAL_NAME | |
#undef BOOST_ACRC_DUMMY_INIT | |
#undef BOOST_ACRC_DUMMY_PARM_TYPE | |
#undef BOOST_CRC_DUMMY_INIT | |
#undef BOOST_CRC_DUMMY_PARM_TYPE | |
#undef BOOST_CRC_PARM_TYPE | |
#endif // BOOST_CRC_HPP | |