// 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 .) // See for the library's home page. #ifndef BOOST_CRC_HPP #define BOOST_CRC_HPP #include // for BOOST_STATIC_CONSTANT, etc. #include // for boost::uint_t #include // for CHAR_BIT, etc. #include // for std::size_t #include // 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::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 *p_ #define BOOST_CRC_DUMMY_INIT BOOST_CRC_DUMMY_PARM_TYPE = 0 #define BOOST_ACRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument *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::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::fast augmented_crc( void const *buffer, std::size_t byte_count, typename uint_t::fast initial_remainder BOOST_ACRC_DUMMY_PARM_TYPE ); template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > typename uint_t::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::digits >; #if USHRT_MAX > UCHAR_MAX template < > struct mask_uint_t< std::numeric_limits::digits >; #endif #if UINT_MAX > USHRT_MAX template < > struct mask_uint_t< std::numeric_limits::digits >; #endif #if ULONG_MAX > UINT_MAX template < > struct mask_uint_t< std::numeric_limits::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 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 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 crc_table_type; typedef detail::crc_helper helper_type; typedef detail::crc_helper 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 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::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::value_type reflector::reflect ( typename reflector::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 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(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::digits > : high_uint_t< std::numeric_limits::digits > { typedef high_uint_t::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::digits > : high_uint_t< std::numeric_limits::digits > { typedef high_uint_t::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::digits > : high_uint_t< std::numeric_limits::digits > { typedef high_uint_t::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::digits > : high_uint_t< std::numeric_limits::digits > { typedef high_uint_t::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 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::table_type crc_table_t::table_ = { 0 }; // Populate CRC lookup table template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect > void crc_table_t::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::reflect(dividend) ] = crc_helper::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::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::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::fast value_type; #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // Possibly reflect a remainder static value_type reflect( value_type x ) { return detail::reflector::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::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 { public: // Type typedef typename uint_t::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 ^ remainderCHAR_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::crc_basic ( typename crc_basic::value_type truncated_polynominal, typename crc_basic::value_type initial_remainder, // = 0 typename crc_basic::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::value_type crc_basic::get_truncated_polynominal ( ) const { return poly_; } template < std::size_t Bits > inline typename crc_basic::value_type crc_basic::get_initial_remainder ( ) const { return init_; } template < std::size_t Bits > inline typename crc_basic::value_type crc_basic::get_final_xor_value ( ) const { return final_; } template < std::size_t Bits > inline bool crc_basic::get_reflect_input ( ) const { return rft_in_; } template < std::size_t Bits > inline bool crc_basic::get_reflect_remainder ( ) const { return rft_out_; } template < std::size_t Bits > inline typename crc_basic::value_type crc_basic::get_interim_remainder ( ) const { return rem_ & masking_type::sig_bits; } template < std::size_t Bits > inline void crc_basic::reset ( typename crc_basic::value_type new_rem ) { rem_ = new_rem; } template < std::size_t Bits > inline void crc_basic::reset ( ) { this->reset( this->get_initial_remainder() ); } template < std::size_t Bits > inline void crc_basic::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( 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::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(bits & high_bit_mask) ); } } template < std::size_t Bits > inline void crc_basic::process_byte ( unsigned char byte ) { process_bits( (rft_in_ ? detail::reflector::reflect(byte) : byte), CHAR_BIT ); } template < std::size_t Bits > void crc_basic::process_block ( void const * bytes_begin, void const * bytes_end ) { for ( unsigned char const * p = static_cast(bytes_begin) ; p < bytes_end ; ++p ) { process_byte( *p ); } } template < std::size_t Bits > inline void crc_basic::process_bytes ( void const * buffer, std::size_t byte_count ) { unsigned char const * const b = static_cast( buffer ); process_block( b, b + byte_count ); } template < std::size_t Bits > inline typename crc_basic::value_type crc_basic::checksum ( ) const { return ( (rft_out_ ? detail::reflector::reflect( rem_ ) : rem_) ^ final_ ) & masking_type::sig_bits; } // Optimized CRC class function definitions --------------------------------// // Macro to compact code #define BOOST_CRC_OPTIMAL_NAME 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 > 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(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( 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::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::fast augmented_crc ( void const * buffer, std::size_t byte_count, typename uint_t::fast initial_remainder BOOST_ACRC_DUMMY_INIT ) { typedef unsigned char byte_type; typedef detail::mask_uint_t masking_type; typedef detail::crc_table_t crc_table_type; typename masking_type::fast rem = initial_remainder; byte_type const * const b = static_cast( 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::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( buffer, byte_count, static_cast::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