2307 lines
		
	
	
		
			93 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2307 lines
		
	
	
		
			93 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| //  Boost CRC library crc.hpp header file  -----------------------------------//
 | |
| 
 | |
| //  Copyright 2001, 2004, 2011 Daryle Walker.
 | |
| //  Distributed under the Boost Software License, Version 1.0.  (See the
 | |
| //  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.
 | |
| 
 | |
| /** \file
 | |
|     \brief  A collection of function templates and class templates that compute
 | |
|       various forms of Cyclic Redundancy Codes (CRCs).
 | |
| 
 | |
|     \author  Daryle Walker
 | |
| 
 | |
|     \version  1.5
 | |
| 
 | |
|     \copyright  Boost Software License, version 1.0
 | |
| 
 | |
|     Contains the declarations (and definitions) of various kinds of CRC
 | |
|     computation functions, function object types, and encapsulated policy types.
 | |
| 
 | |
|     \warning  The sample CRC-computer types were just checked against the
 | |
|       <a href="http://regregex.bbcmicro.net/crc-catalogue.htm">Catalogue of
 | |
|       parametrised CRC algorithms</a>.  New type aliases were added where I got
 | |
|       a standard wrong.  However, the mistaken <code>typedef</code>s are still
 | |
|       there for backwards compatibility.
 | |
|     \note  There are references to the <i>Rocksoft™ Model CRC
 | |
|       Algorithm</i>, as described within \"A Painless Guide to CRC Error
 | |
|       Detection Algorithms,\" linked from \"<a
 | |
|       href="http://www.ross.net/crc/crcpaper.html">CRC: A Paper On CRCs</a>\" by
 | |
|       Ross Williams.  It will be abbreviated \"RMCA\" in other documentation
 | |
|       blocks.
 | |
|  */
 | |
| 
 | |
| #ifndef BOOST_CRC_HPP
 | |
| #define BOOST_CRC_HPP
 | |
| 
 | |
| #include <boost/array.hpp>           // for boost::array
 | |
| #include <boost/config.hpp>          // for BOOST_STATIC_CONSTANT, etc.
 | |
| #include <boost/cstdint.hpp>         // for UINTMAX_C, boost::uintmax_t
 | |
| #include <boost/integer.hpp>         // for boost::uint_t
 | |
| #include <boost/type_traits/conditional.hpp>
 | |
| #include <boost/type_traits/integral_constant.hpp>
 | |
| 
 | |
| #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))
 | |
| #define BOOST_CRC_PARM_TYPE  typename ::boost::uint_t<Bits>::fast
 | |
| #else
 | |
| #define BOOST_CRC_PARM_TYPE  unsigned long
 | |
| #endif
 | |
| 
 | |
| namespace boost
 | |
| {
 | |
| 
 | |
| 
 | |
| //  Forward declarations  ----------------------------------------------------//
 | |
| 
 | |
| //! Bit-wise CRC computer
 | |
| template < std::size_t Bits >
 | |
|     class crc_basic;
 | |
| 
 | |
| //! Table-driven CRC computer, usable as a function object
 | |
| 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;
 | |
| 
 | |
| //! Compute the (unaugmented) CRC of a memory block
 | |
| 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);
 | |
| 
 | |
| //! Compute the CRC of a memory block, with any augmentation provided by user
 | |
| 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 = 0u);
 | |
| 
 | |
| //! Computation type for ARC|CRC-16|CRC-IBM|CRC-16/ARC|CRC-16/LHA standard
 | |
| typedef crc_optimal<16, 0x8005, 0, 0, true, true>         crc_16_type;
 | |
| //! Computation type for CRC-16/CCITT-FALSE standard
 | |
| typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false>  crc_ccitt_false_t;
 | |
| //! Computation type for the CRC mistakenly called the CCITT standard
 | |
| typedef crc_ccitt_false_t                                 crc_ccitt_type;
 | |
| //! Computation type for the actual
 | |
| //! KERMIT|CRC-16/CCITT|CRC-16/CCITT-TRUE|CRC-CCITT standard
 | |
| typedef crc_optimal<16, 0x1021, 0, 0, true, true>         crc_ccitt_true_t;
 | |
| //! Computation type that I mistakenly called the XMODEM standard; it inverts
 | |
| //! both reflection parameters and reflects the truncated divisor (Don't use?!)
 | |
| typedef crc_optimal<16, 0x8408, 0, 0, true, true>         crc_xmodem_type;
 | |
| //! Computation type for the actual XMODEM|ZMODEM|CRC-16/ACORN standard
 | |
| typedef crc_optimal<16, 0x1021, 0, 0, false, false>       crc_xmodem_t;
 | |
| 
 | |
| //! Computation type for CRC-32|CRC-32/ADCCP|PKZIP standard
 | |
| 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)
 | |
| 
 | |
| //! \cond
 | |
| namespace detail
 | |
| {
 | |
|     //! Mix-in class to add a possibly-reflecting member function
 | |
|     template < int BitLength, bool DoIt, int Id = 0 >
 | |
|         class possible_reflector;
 | |
| 
 | |
|     //! Mix-in class for byte-fed, table-driven CRC algorithms
 | |
|     template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect,
 | |
|      int Id = 0 >
 | |
|     class crc_driver;
 | |
| 
 | |
| }  // namespace detail
 | |
| //! \endcond
 | |
| 
 | |
| 
 | |
| //  Simple cyclic redundancy code (CRC) class declaration  -------------------//
 | |
| 
 | |
| /** Objects of this type compute the CRC checksum of submitted data, where said
 | |
|     data can be entered piecemeal through several different kinds of groupings.
 | |
|     Modulo-2 polynomial division steps are always performed bit-wise, without
 | |
|     the use of pre-computation tables.  Said division uses the altered
 | |
|     algorithm, so any data has to be unaugmented.
 | |
| 
 | |
|     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
 | |
| 
 | |
|     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
 | |
|       the RMCA)
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| class crc_basic
 | |
| {
 | |
| public:
 | |
|     // Type
 | |
|     /** \brief  The register type used for computations
 | |
| 
 | |
|         This type is used for CRC calculations and is the type for any returned
 | |
|         checksums and returned or submitted remainders, (truncated) divisors, or
 | |
|         XOR masks.  It is a built-in unsigned integer type.
 | |
|      */
 | |
|     typedef typename boost::uint_t<Bits>::fast  value_type;
 | |
| 
 | |
|     // Constant for the template parameter
 | |
|     //! A copy of \a Bits provided for meta-programming purposes
 | |
|     BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
 | |
| 
 | |
|     // Constructor (use the automatic copy-ctr, move-ctr, and dtr)
 | |
|     //! Create a computer, separately listing each needed parameter
 | |
|     explicit  crc_basic( value_type truncated_polynomial,
 | |
|                value_type initial_remainder = 0, value_type final_xor_value = 0,
 | |
|                bool reflect_input = false, bool reflect_remainder = false );
 | |
| 
 | |
|     // Internal Operations
 | |
|     //! Return the (truncated) polynomial divisor
 | |
|     value_type  get_truncated_polynominal() const;
 | |
|     //! Return what the polynomial remainder was set to during construction
 | |
|     value_type  get_initial_remainder() const;
 | |
|     //! Return the XOR-mask used during output processing
 | |
|     value_type  get_final_xor_value() const;
 | |
|     //! Check if input-bytes will be reflected before processing
 | |
|     bool        get_reflect_input() const;
 | |
|     //! Check if the remainder will be reflected during output processing
 | |
|     bool        get_reflect_remainder() const;
 | |
| 
 | |
|     //! Return the remainder based from already-processed bits
 | |
|     value_type  get_interim_remainder() const;
 | |
|     //! Change the interim remainder to a new value
 | |
|     void        reset( value_type new_rem );
 | |
|     //! Change the interim remainder back to the initial value
 | |
|     void        reset();
 | |
| 
 | |
|     // External Operations
 | |
|     //! Submit a single bit for input processing
 | |
|     void  process_bit( bool bit );
 | |
|     //! Submit the lowest \a bit_length bits of a byte for input processing
 | |
|     void  process_bits( unsigned char bits, std::size_t bit_length );
 | |
|     //! Submit a single byte for input processing
 | |
|     void  process_byte( unsigned char byte );
 | |
|     //! Submit a memory block for input processing, iterator-pair style
 | |
|     void  process_block( void const *bytes_begin, void const *bytes_end );
 | |
|     //! Submit a memory block for input processing, pointer-and-size style
 | |
|     void  process_bytes( void const *buffer, std::size_t byte_count );
 | |
| 
 | |
|     //! Return the checksum of the already-processed bits
 | |
|     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  ----------------//
 | |
| 
 | |
| /** Objects of this type compute the CRC checksum of submitted data, where said
 | |
|     data can be entered piecemeal through several different kinds of groupings.
 | |
|     Modulo-2 polynomial division steps are performed byte-wise, aided by the use
 | |
|     of pre-computation tables.  Said division uses the altered algorithm, so any
 | |
|     data has to be unaugmented.
 | |
| 
 | |
|     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
 | |
| 
 | |
|     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
 | |
|       the RMCA)
 | |
|     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
 | |
|       highest-order coefficient is omitted and always assumed to be 1.  Defaults
 | |
|       to \c 0, i.e. the only non-zero term is the implicit one for
 | |
|       x<sup><var>Bits</var></sup>.  (\e Poly from the RMCA)
 | |
|     \tparam InitRem  The (unaugmented) initial state of the polynomial
 | |
|       remainder.  Defaults to \c 0 if omitted.  (\e Init from the RMCA)
 | |
|     \tparam FinalXor  The (XOR) bit-mask to be applied to the output remainder,
 | |
|       after possible reflection but before returning.  Defaults to \c 0 (i.e. no
 | |
|       bit changes) if omitted.  (\e XorOut from the RMCA)
 | |
|     \tparam ReflectIn  If \c true, input bytes are read lowest-order bit first,
 | |
|       otherwise highest-order bit first.  Defaults to \c false if omitted.
 | |
|       (\e RefIn from the RMCA)
 | |
|     \tparam ReflectRem  If \c true, the output remainder is reflected before the
 | |
|       XOR-mask.  Defaults to \c false if omitted.  (\e RefOut from the RMCA)
 | |
| 
 | |
|     \todo  Get rid of the default value for \a TruncPoly.  Choosing a divisor is
 | |
|       an important decision with many factors, so a default is never useful,
 | |
|       especially a bad one.
 | |
|  */
 | |
| 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
 | |
| {
 | |
| public:
 | |
|     // Type
 | |
|     //! \copydoc  boost::crc_basic::value_type
 | |
|     typedef typename boost::uint_t<Bits>::fast  value_type;
 | |
| 
 | |
|     // Constants for the template parameters
 | |
|     //! \copydoc  boost::crc_basic::bit_count
 | |
|     BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
 | |
|     //! A copy of \a TruncPoly provided for meta-programming purposes
 | |
|     BOOST_STATIC_CONSTANT( value_type, truncated_polynominal = TruncPoly );
 | |
|     //! A copy of \a InitRem provided for meta-programming purposes
 | |
|     BOOST_STATIC_CONSTANT( value_type, initial_remainder = InitRem );
 | |
|     //! A copy of \a FinalXor provided for meta-programming purposes
 | |
|     BOOST_STATIC_CONSTANT( value_type, final_xor_value = FinalXor );
 | |
|     //! A copy of \a ReflectIn provided for meta-programming purposes
 | |
|     BOOST_STATIC_CONSTANT( bool, reflect_input = ReflectIn );
 | |
|     //! A copy of \a ReflectRem provided for meta-programming purposes
 | |
|     BOOST_STATIC_CONSTANT( bool, reflect_remainder = ReflectRem );
 | |
| 
 | |
|     // Constructor (use the automatic copy-ctr, move-ctr, and dtr)
 | |
|     //! Create a computer, giving an initial remainder if desired
 | |
|     explicit  crc_optimal( value_type init_rem = initial_remainder );
 | |
| 
 | |
|     // Internal Operations
 | |
|     //! \copybrief  boost::crc_basic::get_truncated_polynominal
 | |
|     value_type  get_truncated_polynominal() const;
 | |
|     //! \copybrief  boost::crc_basic::get_initial_remainder
 | |
|     value_type  get_initial_remainder() const;
 | |
|     //! \copybrief  boost::crc_basic::get_final_xor_value
 | |
|     value_type  get_final_xor_value() const;
 | |
|     //! \copybrief  boost::crc_basic::get_reflect_input
 | |
|     bool        get_reflect_input() const;
 | |
|     //! \copybrief  boost::crc_basic::get_reflect_remainder
 | |
|     bool        get_reflect_remainder() const;
 | |
| 
 | |
|     //! \copybrief  boost::crc_basic::get_interim_remainder
 | |
|     value_type  get_interim_remainder() const;
 | |
|     //! Change the interim remainder to either a given value or the initial one
 | |
|     void        reset( value_type new_rem = initial_remainder );
 | |
| 
 | |
|     // External Operations
 | |
|     //! \copybrief  boost::crc_basic::process_byte
 | |
|     void  process_byte( unsigned char byte );
 | |
|     //! \copybrief  boost::crc_basic::process_block
 | |
|     void  process_block( void const *bytes_begin, void const *bytes_end );
 | |
|     //! \copybrief  boost::crc_basic::process_bytes
 | |
|     void  process_bytes( void const *buffer, std::size_t byte_count );
 | |
| 
 | |
|     //! \copybrief  boost::crc_basic::checksum
 | |
|     value_type  checksum() const;
 | |
| 
 | |
|     // Operators
 | |
|     //! Submit a single byte for input processing, suitable for the STL
 | |
|     void        operator ()( unsigned char byte );
 | |
|     //! Return the checksum of the already-processed bits, suitable for the STL
 | |
|     value_type  operator ()() const;
 | |
| 
 | |
| private:
 | |
|     // Implementation types
 | |
|     // (Processing for reflected input gives reflected remainders, so you only
 | |
|     // have to apply output-reflection if Reflect-Remainder doesn't match
 | |
|     // Reflect-Input.)
 | |
|     typedef detail::possible_reflector<Bits, ReflectIn>     reflect_i_type;
 | |
|     typedef detail::crc_driver<Bits, TruncPoly, ReflectIn>  crc_table_type;
 | |
|     typedef detail::possible_reflector<Bits, ReflectRem != ReflectIn>
 | |
|       reflect_o_type;
 | |
| 
 | |
|     // Member data
 | |
|     value_type  rem_;
 | |
| 
 | |
| };  // boost::crc_optimal
 | |
| 
 | |
| 
 | |
| //  Implementation detail stuff  ---------------------------------------------//
 | |
| 
 | |
| //! \cond
 | |
| namespace detail
 | |
| {
 | |
|     /** \brief  Meta-programming integral constant for a single-bit bit-mask
 | |
| 
 | |
|         Generates a compile-time constant for a bit-mask that affects a single
 | |
|         bit.  The \c value will be 2<sup><var>BitIndex</var></sup>.  The \c type
 | |
|         will be the smallest built-in unsigned integer type that can contain the
 | |
|         value, unless there's a built-in type that the system can handle easier,
 | |
|         then the \c type will be smallest fast-handled unsigned integer type.
 | |
| 
 | |
|         \pre  0 \<= BitIndex \< \c std\::numeric_limits\<uintmax_t\>\::digits
 | |
| 
 | |
|         \tparam BitIndex  The place of the sole set bit.
 | |
|      */
 | |
|     template < int BitIndex >
 | |
|     struct high_bit_mask_c
 | |
|         : boost::integral_constant<typename boost::uint_t< BitIndex + 1 >::fast,
 | |
|            ( UINTMAX_C(1) << BitIndex )>
 | |
|     {};
 | |
| 
 | |
|     /** \brief  Meta-programming integral constant for a lowest-bits bit-mask
 | |
| 
 | |
|         Generates a compile-time constant for a bit-mask that affects the lowest
 | |
|         bits.  The \c value will be 2<sup><var>BitCount</var></sup> - 1.  The
 | |
|         \c type will be the smallest built-in unsigned integer type that can
 | |
|         contain the value, unless there's a built-in type that the system can
 | |
|         handle easier, then the \c type will be smallest fast-handled unsigned
 | |
|         integer type.
 | |
| 
 | |
|         \pre  0 \<= BitCount \<= \c std\::numeric_limits\<uintmax_t\>\::digits
 | |
| 
 | |
|         \tparam BitCount  The number of lowest-placed bits set.
 | |
|      */
 | |
|     template < int BitCount >
 | |
|     struct low_bits_mask_c
 | |
|         : boost::integral_constant<typename boost::uint_t< BitCount >::fast, (
 | |
|            BitCount ? (( (( UINTMAX_C(1) << (BitCount - 1) ) - 1u) << 1 ) |
 | |
|            UINTMAX_C( 1 )) : 0u )>
 | |
|     {};
 | |
| 
 | |
|     /** \brief  Reflects the bits of a number
 | |
| 
 | |
|         Reverses the order of the given number of bits within a value.  For
 | |
|         instance, if the given reflect count is 5, then the bit values for the
 | |
|         16- and 1-place will switch and the 8- and 2-place will switch, leaving
 | |
|         the other bits alone.  (The 4-place bit is in the middle, so it wouldn't
 | |
|         change.)
 | |
| 
 | |
|         \pre  \a Unsigned is a built-in unsigned integer type
 | |
|         \pre  0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits
 | |
| 
 | |
|         \tparam Unsigned  The type of \a x.
 | |
| 
 | |
|         \param x  The value to be (partially) reflected.
 | |
|         \param word_length  The number of low-order bits to reflect.  Defaults
 | |
|           to the total number of value bits in \a Unsigned.
 | |
| 
 | |
|         \return  The (partially) reflected value.
 | |
| 
 | |
|         \todo  Check if this is the fastest way.
 | |
|      */
 | |
|     template < typename Unsigned >
 | |
|     Unsigned  reflect_unsigned( Unsigned x, int word_length
 | |
|      = std::numeric_limits<Unsigned>::digits )
 | |
|     {
 | |
|         for ( Unsigned  l = 1u, h = l << (word_length - 1) ; h > l ; h >>= 1, l
 | |
|          <<= 1 )
 | |
|         {
 | |
|             Unsigned const  m = h | l, t = x & m;
 | |
| 
 | |
|             if ( (t == h) || (t == l) )
 | |
|                 x ^= m;
 | |
|         }
 | |
| 
 | |
|         return x;
 | |
|     }
 | |
| 
 | |
|     /** \brief  Make a byte-to-byte-reflection map
 | |
| 
 | |
|         Creates a mapping array so the results can be cached.  Uses
 | |
|         #reflect_unsigned to generate the element values.
 | |
| 
 | |
|         \return  An array <var>a</var> such that, for a given byte value
 | |
|           <var>i</var>, <code><var>a</var>[ <var>i</var> ]</code> resolves to
 | |
|           the reflected value of <var>i</var>.
 | |
|      */
 | |
|     boost::array< unsigned char, (UINTMAX_C( 1 ) << CHAR_BIT) >
 | |
|     inline make_byte_reflection_table()
 | |
|     {
 | |
|         boost::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )>  result;
 | |
|         unsigned char                                              i = 0u;
 | |
| 
 | |
|         do
 | |
|             result[ i ] = reflect_unsigned( i );
 | |
|         while ( ++i );
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     /** \brief  Reflects the bits of a single byte
 | |
| 
 | |
|         Reverses the order of all the bits within a value.  For instance, the
 | |
|         bit values for the 2<sup><code>CHAR_BIT</code> - 1</sup>- and 1-place
 | |
|         will switch and the 2<sup><code>CHAR_BIT</code> - 2</sup>- and 2-place
 | |
|         will switch, etc.
 | |
| 
 | |
|         \param x  The byte value to be reflected.
 | |
| 
 | |
|         \return  The reflected value.
 | |
| 
 | |
|         \note  Since this could be the most common type of reflection, and the
 | |
|           number of states is relatively small, the implementation pre-computes
 | |
|           and uses a table of all the results.
 | |
|      */
 | |
|     inline unsigned char  reflect_byte( unsigned char x )
 | |
|     {
 | |
|         static  boost::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> const
 | |
|           table = make_byte_reflection_table();
 | |
| 
 | |
|         return table[ x ];
 | |
|     }
 | |
| 
 | |
|     /** \brief  Reflects some bits within a single byte
 | |
| 
 | |
|         Like #reflect_unsigned, except it takes advantage of any (long-term)
 | |
|         speed gains #reflect_byte may bring.
 | |
| 
 | |
|         \pre  0 \< \a word_length \<= \c CHAR_BIT
 | |
| 
 | |
|         \param x  The value to be (partially) reflected.
 | |
|         \param word_length  The number of low-order bits to reflect.
 | |
| 
 | |
|         \return  The (partially) reflected value.
 | |
|      */
 | |
|     inline  unsigned char  reflect_sub_byte( unsigned char x, int word_length )
 | |
|     { return reflect_byte(x) >> (CHAR_BIT - word_length); }
 | |
| 
 | |
|     /** \brief  Possibly reflects the bits of a number
 | |
| 
 | |
|         Reverses the order of the given number of bits within a value.  For
 | |
|         instance, if the given reflect count is 5, then the bit values for the
 | |
|         16- and 1-place will switch and the 8- and 2-place will switch, leaving
 | |
|         the other bits alone.  (The 4-place bit is in the middle, so it wouldn't
 | |
|         change.)  This variant function allows the reflection be controlled by
 | |
|         an extra parameter, in case the decision to use reflection is made at
 | |
|         run-time.
 | |
| 
 | |
|         \pre  \a Unsigned is a built-in unsigned integer type
 | |
|         \pre  0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits
 | |
| 
 | |
|         \tparam Unsigned  The type of \a x.
 | |
| 
 | |
|         \param x  The value to be (partially) reflected.
 | |
|         \param reflect  Controls whether \a x is actually reflected (\c true) or
 | |
|           left alone (\c false).
 | |
|         \param word_length  The number of low-order bits to reflect.  Defaults
 | |
|           to the total number of value bits in \a Unsigned.
 | |
| 
 | |
|         \return  The possibly (partially) reflected value.
 | |
|      */
 | |
|     template < typename Unsigned >
 | |
|     inline
 | |
|     Unsigned  reflect_optionally( Unsigned x, bool reflect, int word_length
 | |
|      = std::numeric_limits<Unsigned>::digits )
 | |
|     { return reflect ? reflect_unsigned(x, word_length) : x; }
 | |
| 
 | |
|     /** \brief  Possibly reflects the bits of a single byte
 | |
| 
 | |
|         Uses #reflect_byte (if \a reflect is \c true).
 | |
| 
 | |
|         \param x  The byte value to be (possibly) reflected.
 | |
|         \param reflect  Whether (\c true) or not (\c false) \a x is reflected.
 | |
| 
 | |
|         \return  <code><var>reflect</var> ? reflect_byte(<var>x</var>) :
 | |
|           <var>x</var></code>
 | |
|      */
 | |
|     inline
 | |
|     unsigned char  reflect_byte_optionally( unsigned char x, bool reflect )
 | |
|     { return reflect ? reflect_byte(x) : x; }
 | |
| 
 | |
|     /** \brief  Update a CRC remainder by several bits, assuming a non-augmented
 | |
|           message
 | |
| 
 | |
|         Performs several steps of division required by the CRC algorithm, giving
 | |
|         a new remainder polynomial based on the divisor polynomial and the
 | |
|         synthesized dividend polynomial (from the old remainder and the
 | |
|         newly-provided input).  The computations assume that the CRC is directly
 | |
|         exposed from the remainder, without any zero-valued bits augmented to
 | |
|         the message bits.
 | |
| 
 | |
|         \pre  \a Register and \a Word are both built-in unsigned integer types
 | |
|         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
 | |
|           \::digits
 | |
|         \pre  0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits
 | |
| 
 | |
|         \tparam Register  The type used for representing the remainder and
 | |
|           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
 | |
|           is used as the coefficient of <i>x<sup>i</sup></i>.
 | |
|         \tparam Word  The type used for storing the incoming terms of the
 | |
|           dividend modulo-2 polynomial.  The bit at <code>2<sup>i</sup></code>
 | |
|           is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is
 | |
|           \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 -
 | |
|           i</sup></i> otherwise.
 | |
| 
 | |
|         \param[in]     register_length  The number of significant low-order bits
 | |
|           to be used from \a Register values.  It is the order of the modulo-2
 | |
|           polynomial remainder and one less than the divisor's order.
 | |
|         \param[in,out] remainder  The upper part of the dividend polynomial
 | |
|           before division, and the remainder polynomial after.
 | |
|         \param[in]     new_dividend_bits  The coefficients for the next
 | |
|           \a word_length lowest terms of the dividend polynomial.
 | |
|         \param[in]     truncated_divisor  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|         \param[in]     word_length  The number of lowest-order bits to read from
 | |
|           \a new_dividend_bits.
 | |
|         \param[in]     reflect  If \c false, read from the highest-order marked
 | |
|           bit from \a new_dividend_bits and go down, as normal.  Otherwise,
 | |
|           proceed from the lowest-order bit and go up.
 | |
| 
 | |
|         \note  This routine performs a modulo-2 polynomial division variant.
 | |
|           The exclusive-or operations are applied in a different order, since
 | |
|           that kind of operation is commutative and associative.  It also
 | |
|           assumes that the zero-valued augment string was applied before this
 | |
|           step, which means that the updated remainder can be directly used as
 | |
|           the final CRC.
 | |
|      */
 | |
|     template < typename Register, typename Word >
 | |
|     void  crc_modulo_word_update( int register_length, Register &remainder, Word
 | |
|      new_dividend_bits, Register truncated_divisor, int word_length, bool
 | |
|      reflect )
 | |
|     {
 | |
|         // Create this masking constant outside the loop.
 | |
|         Register const  high_bit_mask = UINTMAX_C(1) << (register_length - 1);
 | |
| 
 | |
|         // The natural reading order for division is highest digit/bit first.
 | |
|         // The "reflect" parameter switches this.  However, building a bit mask
 | |
|         // for the lowest bit is the easiest....
 | |
|         new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect,
 | |
|          word_length );
 | |
| 
 | |
|         // Perform modulo-2 division for each new dividend input bit
 | |
|         for ( int  i = word_length ; i ; --i, new_dividend_bits >>= 1 )
 | |
|         {
 | |
|             // compare the new bit with the remainder's highest
 | |
|             remainder ^= ( new_dividend_bits & 1u ) ? high_bit_mask : 0u;
 | |
| 
 | |
|             // perform modulo-2 division
 | |
|             bool const  quotient = remainder & high_bit_mask;
 | |
| 
 | |
|             remainder <<= 1;
 | |
|             remainder ^= quotient ? truncated_divisor : 0u;
 | |
| 
 | |
|             // The quotient isn't used for anything, so don't keep it.
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /** \brief  Update a CRC remainder by a single bit, assuming a non-augmented
 | |
|           message
 | |
| 
 | |
|         Performs the next step of division required by the CRC algorithm, giving
 | |
|         a new remainder polynomial based on the divisor polynomial and the
 | |
|         synthesized dividend polynomial (from the old remainder and the
 | |
|         newly-provided input).  The computations assume that the CRC is directly
 | |
|         exposed from the remainder, without any zero-valued bits augmented to
 | |
|         the message bits.
 | |
| 
 | |
|         \pre  \a Register is a built-in unsigned integer type
 | |
|         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
 | |
|           \::digits
 | |
| 
 | |
|         \tparam Register  The type used for representing the remainder and
 | |
|           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
 | |
|           is used as the coefficient of <i>x<sup>i</sup></i>.
 | |
| 
 | |
|         \param[in]     register_length  The number of significant low-order bits
 | |
|           to be used from \a Register values.  It is the order of the modulo-2
 | |
|           polynomial remainder and one less than the divisor's order.
 | |
|         \param[in,out] remainder  The upper part of the dividend polynomial
 | |
|           before division, and the remainder polynomial after.
 | |
|         \param[in]     new_dividend_bit  The coefficient for the constant term
 | |
|           of the dividend polynomial.
 | |
|         \param[in]     truncated_divisor  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
| 
 | |
|         \note  This routine performs a modulo-2 polynomial division variant.
 | |
|           The exclusive-or operations are applied in a different order, since
 | |
|           that kind of operation is commutative and associative.  It also
 | |
|           assumes that the zero-valued augment string was applied before this
 | |
|           step, which means that the updated remainder can be directly used as
 | |
|           the final CRC.
 | |
|      */
 | |
|     template < typename Register >
 | |
|     inline  void  crc_modulo_update( int register_length, Register &remainder,
 | |
|      bool new_dividend_bit, Register truncated_divisor )
 | |
|     {
 | |
|         crc_modulo_word_update( register_length, remainder,
 | |
|          static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false );
 | |
|     }
 | |
| 
 | |
|     /** \brief  Update a CRC remainder by several bits, assuming an augmented
 | |
|           message
 | |
| 
 | |
|         Performs several steps of division required by the CRC algorithm, giving
 | |
|         a new remainder polynomial based on the divisor polynomial and the
 | |
|         synthesized dividend polynomial (from the old remainder and the
 | |
|         newly-provided input).  The computations assume that a zero-valued
 | |
|         string of bits will be appended to the message before extracting the
 | |
|         CRC.
 | |
| 
 | |
|         \pre  \a Register and \a Word are both built-in unsigned integer types
 | |
|         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
 | |
|           \::digits
 | |
|         \pre  0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits
 | |
| 
 | |
|         \tparam Register  The type used for representing the remainder and
 | |
|           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
 | |
|           is used as the coefficient of <i>x<sup>i</sup></i>.
 | |
|         \tparam Word  The type used for storing the incoming terms of the
 | |
|           dividend modulo-2 polynomial.  The bit at <code>2<sup>i</sup></code>
 | |
|           is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is
 | |
|           \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 -
 | |
|           i</sup></i> otherwise.
 | |
| 
 | |
|         \param[in]     register_length  The number of significant low-order bits
 | |
|           to be used from \a Register values.  It is the order of the modulo-2
 | |
|           polynomial remainder and one less than the divisor's order.
 | |
|         \param[in,out] remainder  The upper part of the dividend polynomial
 | |
|           before division, and the remainder polynomial after.
 | |
|         \param[in]     new_dividend_bits  The coefficients for the next
 | |
|           \a word_length lowest terms of the dividend polynomial.
 | |
|         \param[in]     truncated_divisor  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|         \param[in]     word_length  The number of lowest-order bits to read from
 | |
|           \a new_dividend_bits.
 | |
|         \param[in]     reflect  If \c false, read from the highest-order marked
 | |
|           bit from \a new_dividend_bits and go down, as normal.  Otherwise,
 | |
|           proceed from the lowest-order bit and go up.
 | |
| 
 | |
|         \note  This routine performs straight-forward modulo-2 polynomial
 | |
|           division.  It assumes that an augment string will be processed at the
 | |
|           end of the message bits before doing CRC analysis.
 | |
|         \todo  Use this function somewhere so I can test it.
 | |
|      */
 | |
|     template < typename Register, typename Word >
 | |
|     void  augmented_crc_modulo_word_update( int register_length, Register
 | |
|      &remainder, Word new_dividend_bits, Register truncated_divisor, int
 | |
|      word_length, bool reflect )
 | |
|     {
 | |
|         // Create this masking constant outside the loop.
 | |
|         Register const  high_bit_mask = UINTMAX_C(1) << (register_length - 1);
 | |
| 
 | |
|         // The natural reading order for division is highest digit/bit first.
 | |
|         // The "reflect" parameter switches this.  However, building a bit mask
 | |
|         // for the lowest bit is the easiest....
 | |
|         new_dividend_bits = reflect_optionally( new_dividend_bits, not reflect,
 | |
|          word_length );
 | |
| 
 | |
|         // Perform modulo-2 division for each new dividend input bit
 | |
|         for ( int  i = word_length ; i ; --i, new_dividend_bits >>= 1 )
 | |
|         {
 | |
|             bool const  quotient = remainder & high_bit_mask;
 | |
| 
 | |
|             remainder <<= 1;
 | |
|             remainder |= new_dividend_bits & 1u;
 | |
|             remainder ^= quotient ? truncated_divisor : 0u;
 | |
| 
 | |
|             // The quotient isn't used for anything, so don't keep it.
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /** \brief  Update a CRC remainder by a single bit, assuming an augmented
 | |
|           message
 | |
| 
 | |
|         Performs the next step of division required by the CRC algorithm, giving
 | |
|         a new remainder polynomial based on the divisor polynomial and the
 | |
|         synthesized dividend polynomial (from the old remainder and the
 | |
|         newly-provided input).  The computations assume that a zero-valued
 | |
|         string of bits will be appended to the message before extracting the
 | |
|         CRC.
 | |
| 
 | |
|         \pre  \a Register is a built-in unsigned integer type
 | |
|         \pre  0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
 | |
|           \::digits
 | |
| 
 | |
|         \tparam Register  The type used for representing the remainder and
 | |
|           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
 | |
|           is used as the coefficient of <i>x<sup>i</sup></i>.
 | |
| 
 | |
|         \param[in]     register_length  The number of significant low-order bits
 | |
|           to be used from \a Register values.  It is the order of the modulo-2
 | |
|           polynomial remainder and one less than the divisor's order.
 | |
|         \param[in,out] remainder  The upper part of the dividend polynomial
 | |
|           before division, and the remainder polynomial after.
 | |
|         \param[in]     new_dividend_bit  The coefficient for the constant term
 | |
|           of the dividend polynomial.
 | |
|         \param[in]     truncated_divisor  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
| 
 | |
|         \note  This routine performs straight-forward modulo-2 polynomial
 | |
|           division.  It assumes that an augment string will be processed at the
 | |
|           end of the message bits before doing CRC analysis.
 | |
|         \todo  Use this function somewhere so I can test it.
 | |
|      */
 | |
|     template < typename Register >
 | |
|     inline  void  augmented_crc_modulo_update( int register_length, Register
 | |
|      &remainder, bool new_dividend_bit, Register truncated_divisor )
 | |
|     {
 | |
|         augmented_crc_modulo_word_update( register_length, remainder,
 | |
|          static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false );
 | |
|     }
 | |
| 
 | |
|     /** \brief  A mix-in class that returns its argument
 | |
| 
 | |
|         This class template makes a function object that returns its argument
 | |
|         as-is.  It's one case for #possible_reflector.
 | |
| 
 | |
|         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
 | |
|           \::digits
 | |
| 
 | |
|         \tparam BitLength  How many significant bits arguments have.
 | |
|      */
 | |
|     template < int BitLength >
 | |
|     class non_reflector
 | |
|     {
 | |
|     public:
 | |
|         /** \brief  The type to check for specialization
 | |
| 
 | |
|             This is a Boost integral constant indicating that this class
 | |
|             does not reflect its input values.
 | |
|          */
 | |
|         typedef boost::false_type                 is_reflecting_type;
 | |
|         /** \brief  The type to check for register bit length
 | |
| 
 | |
|             This is a Boost integral constant indicating how many
 | |
|             significant bits won't actually be reflected.
 | |
|          */
 | |
|         typedef boost::integral_constant< int, BitLength >      width_c;
 | |
|         /** \brief  The type of (not-)reflected values
 | |
| 
 | |
|             This type is the input and output type for the (possible-)
 | |
|             reflection function, which does nothing here.
 | |
|          */
 | |
|         typedef typename boost::uint_t< BitLength >::fast  value_type;
 | |
| 
 | |
|         /** \brief  Does nothing
 | |
| 
 | |
|             Returns the given value, not reflecting any part of it.
 | |
| 
 | |
|             \param x  The value to not be reflected.
 | |
| 
 | |
|             \return  \a x
 | |
|          */
 | |
|         inline  static  value_type  reflect_q( value_type x )
 | |
|         { return x; }
 | |
|     };
 | |
| 
 | |
|     /** \brief  A mix-in class that reflects (the lower part of) its argument,
 | |
|           generally for types larger than a byte
 | |
| 
 | |
|         This class template makes a function object that returns its argument
 | |
|         after reflecting its lower-order bits.  It's one sub-case for
 | |
|         #possible_reflector.
 | |
| 
 | |
|         \pre  \c CHAR_BIT \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t
 | |
|           \>\::digits
 | |
| 
 | |
|         \tparam BitLength  How many significant bits arguments have.
 | |
|      */
 | |
|     template < int BitLength >
 | |
|     class super_byte_reflector
 | |
|     {
 | |
|     public:
 | |
|         /** \brief  The type to check for specialization
 | |
| 
 | |
|             This is a Boost integral constant indicating that this class
 | |
|             does reflect its input values.
 | |
|          */
 | |
|         typedef boost::true_type                  is_reflecting_type;
 | |
|         /** \brief  The type to check for register bit length
 | |
| 
 | |
|             This is a Boost integral constant indicating how many
 | |
|             significant bits will be reflected.
 | |
|          */
 | |
|         typedef boost::integral_constant< int, BitLength >      width_c;
 | |
|         /** \brief  The type of reflected values
 | |
| 
 | |
|             This is both the input and output type for the reflection function.
 | |
|          */
 | |
|         typedef typename boost::uint_t< BitLength >::fast  value_type;
 | |
| 
 | |
|         /** \brief  Reflect (part of) the given value
 | |
| 
 | |
|             Reverses the order of the given number of bits within a value,
 | |
|             using #reflect_unsigned.
 | |
| 
 | |
|             \param x  The value to be (partially) reflected.
 | |
| 
 | |
|             \return  ( <var>x</var> &
 | |
|               ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT(
 | |
|               <var>x</var> & (2<sup><var>width_c</var>\::value</sup> -
 | |
|               1) )
 | |
|          */
 | |
|         inline  static  value_type  reflect_q( value_type x )
 | |
|         { return reflect_unsigned(x, width_c::value); }
 | |
|     };
 | |
| 
 | |
|     /** \brief  A mix-in class that reflects (the lower part of) its argument,
 | |
|           generally for bytes
 | |
| 
 | |
|         This class template makes a function object that returns its argument
 | |
|         after reflecting its lower-order bits.  It's one sub-case for
 | |
|         #possible_reflector.
 | |
| 
 | |
|         \pre  0 \< \a BitLength \<= \c CHAR_BIT
 | |
| 
 | |
|         \tparam BitLength  How many significant bits arguments have.
 | |
|      */
 | |
|     template < int BitLength >
 | |
|     class sub_type_reflector
 | |
|     {
 | |
|     public:
 | |
|         /** \brief  The type to check for specialization
 | |
| 
 | |
|             This is a Boost integral constant indicating that this class
 | |
|             does reflect its input values.
 | |
|          */
 | |
|         typedef boost::true_type              is_reflecting_type;
 | |
|         /** \brief  The type to check for register bit length
 | |
| 
 | |
|             This is a Boost integral constant indicating how many
 | |
|             significant bits will be reflected.
 | |
|          */
 | |
|         typedef boost::integral_constant< int, BitLength >  width_c;
 | |
|         /** \brief  The type of reflected values
 | |
| 
 | |
|             This is both the input and output type for the reflection function.
 | |
|          */
 | |
|         typedef unsigned char                          value_type;
 | |
| 
 | |
|         /** \brief  Reflect (part of) the given value
 | |
| 
 | |
|             Reverses the order of the given number of bits within a value,
 | |
|             using #reflect_sub_byte.
 | |
| 
 | |
|             \param x  The value to be (partially) reflected.
 | |
| 
 | |
|             \return  ( <var>x</var> &
 | |
|               ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT(
 | |
|               <var>x</var> & (2<sup><var>width_c</var>\::value</sup> -
 | |
|               1) )
 | |
|          */
 | |
|         inline  static  value_type  reflect_q( value_type x )
 | |
|         { return reflect_sub_byte(x, width_c::value); }
 | |
|     };
 | |
| 
 | |
|     /** \brief  A mix-in class that reflects (the lower part of) its argument
 | |
| 
 | |
|         This class template makes a function object that returns its argument
 | |
|         after reflecting its lower-order bits.  It's one case for
 | |
|         #possible_reflector.
 | |
| 
 | |
|         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
 | |
|           \::digits
 | |
| 
 | |
|         \tparam BitLength  How many significant bits arguments have.
 | |
|      */
 | |
|     template < int BitLength >
 | |
|     class reflector
 | |
|         : public boost::conditional< (BitLength > CHAR_BIT),
 | |
|           super_byte_reflector<BitLength>, sub_type_reflector<BitLength> >::type
 | |
|     { };
 | |
| 
 | |
|     /** This class template adds a member function #reflect_q that will
 | |
|         conditionally reflect its first argument, controlled by a compile-time
 | |
|         parameter.
 | |
| 
 | |
|         \pre  0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
 | |
|           \::digits
 | |
| 
 | |
|         \tparam BitLength  How many significant bits arguments have.
 | |
|         \tparam DoIt  \c true if #reflect_q will reflect, \c false if it should
 | |
|           return its argument unchanged.
 | |
|         \tparam Id  An extra differentiator if multiple copies of this class
 | |
|           template are mixed-in as base classes.  Defaults to 0 if omitted.
 | |
|      */
 | |
|     template < int BitLength, bool DoIt, int Id >
 | |
|     class possible_reflector
 | |
|         : public boost::conditional< DoIt, reflector<BitLength>,
 | |
|           non_reflector<BitLength> >::type
 | |
|     {
 | |
|     public:
 | |
|         /** \brief  The type to check for ID
 | |
| 
 | |
|             This is a Boost integral constant indicating what ID number this
 | |
|             instantiation used.
 | |
|          */
 | |
|         typedef boost::integral_constant<int, Id>  id_type;
 | |
|     };
 | |
| 
 | |
|     /** \brief  Find the composite remainder update effect from a fixed bit
 | |
|           sequence, for each potential sequence combination.
 | |
| 
 | |
|         For each value between 0 and 2<sup><var>SubOrder</var></sup> - 1,
 | |
|         computes the XOR mask corresponding to the composite effect they update
 | |
|         the incoming remainder, which is the upper part of the dividend that
 | |
|         gets (partially) pushed out of its register by the incoming value's
 | |
|         bits.  The composite value merges the \"partial products\" from each bit
 | |
|         of the value being updated individually.
 | |
| 
 | |
|         \pre  \a Register is a built-in unsigned integer type
 | |
|         \pre  0 \< \a SubOrder \<= \a register_length \<=
 | |
|           std\::numeric_limits\<\a Register\>\::digits
 | |
| 
 | |
|         \tparam SubOrder  The number of low-order significant bits of the trial
 | |
|           new dividends.
 | |
|         \tparam Register  The type used for representing the remainder and
 | |
|           divisor modulo-2 polynomials.  The bit at <code>2<sup>i</sup></code>
 | |
|           is used as the coefficient of <i>x<sup>i</sup></i>.
 | |
| 
 | |
|         \param[in] register_length  The number of significant low-order bits
 | |
|           to be used from \a Register values.  It is the order of the modulo-2
 | |
|           polynomial remainder and one less than the divisor's order.
 | |
|         \param[in] truncated_divisor  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|         \param[in] reflect  If \c false, read from the highest-order marked
 | |
|           bit from a new dividend's bits and go down, as normal.  Otherwise,
 | |
|           proceed from the lowest-order bit and go up.
 | |
| 
 | |
|         \return  An array such that the element at index <var>i</var> is the
 | |
|           composite effect XOR mask for value <var>i</var>.
 | |
| 
 | |
|         \note  This routine performs a modulo-2 polynomial division variant.
 | |
|           The exclusive-or operations are applied in a different order, since
 | |
|           that kind of operation is commutative and associative.  It also
 | |
|           assumes that the zero-valued augment string was applied before this
 | |
|           step, which means that the updated remainder can be directly used as
 | |
|           the final CRC.
 | |
|         \todo  Check that using the unaugmented-CRC division routines give the
 | |
|           same composite mask table as using augmented-CRC routines.
 | |
|      */
 | |
|     template < int SubOrder, typename Register >
 | |
|     boost::array< Register, (UINTMAX_C( 1 ) << SubOrder) >
 | |
|     make_partial_xor_products_table( int register_length, Register
 | |
|      truncated_divisor, bool reflect )
 | |
|     {
 | |
|         boost::array<Register, ( UINTMAX_C(1) << SubOrder )>  result;
 | |
| 
 | |
|         // Loop over every possible dividend value
 | |
|         for ( typename boost::uint_t<SubOrder + 1>::fast  dividend = 0u;
 | |
|          dividend < result.size() ; ++dividend )
 | |
|         {
 | |
|             Register  remainder = 0u;
 | |
| 
 | |
|             crc_modulo_word_update( register_length, remainder, dividend,
 | |
|              truncated_divisor, SubOrder, false );
 | |
|             result[ reflect_optionally(dividend, reflect, SubOrder) ] =
 | |
|              reflect_optionally( remainder, reflect, register_length );
 | |
|         }
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     /** \brief  A mix-in class for the table of table-driven CRC algorithms
 | |
| 
 | |
|         Encapsulates the parameters need to make a global (technically,
 | |
|         class-static) table usuable in CRC algorithms, and generates said
 | |
|         table.
 | |
| 
 | |
|         \pre  0 \< \a SubOrder \<= Order \<=
 | |
|           std\::numeric_limits\<uintmax_t\>\::digits
 | |
| 
 | |
|         \tparam Order  The order of the modulo-2 polynomial remainder and one
 | |
|           less than the divisor's order.
 | |
|         \tparam SubOrder  The number of low-order significant bits of the trial
 | |
|           new dividends.
 | |
|         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|         \tparam Reflect  If \c false, read from the highest-order marked
 | |
|           bit from a new dividend's bits and go down, as normal.  Otherwise,
 | |
|           proceed from the lowest-order bit and go up.
 | |
|      */
 | |
|     template < int Order, int SubOrder, boost::uintmax_t TruncatedPolynomial,
 | |
|      bool Reflect >
 | |
|     class crc_table_t
 | |
|     {
 | |
|     public:
 | |
|         /** \brief  The type to check for register bit length
 | |
| 
 | |
|             This is a Boost integral constant indicating how many
 | |
|             significant bits are in the remainder and (truncated) divisor.
 | |
|          */
 | |
|         typedef boost::integral_constant< int, Order >              width_c;
 | |
|         /** \brief  The type to check for index-unit bit length
 | |
| 
 | |
|             This is a Boost integral constant indicating how many
 | |
|             significant bits are in the trial new dividends.
 | |
|          */
 | |
|         typedef boost::integral_constant< int, SubOrder >      unit_width_c;
 | |
|         /** \brief  The type of registers
 | |
| 
 | |
|             This is the output type for the partial-product map.
 | |
|          */
 | |
|         typedef typename boost::uint_t< Order >::fast          value_type;
 | |
|         /** \brief  The type to check the divisor
 | |
| 
 | |
|             This is a Boost integral constant representing the (truncated)
 | |
|             divisor.
 | |
|          */
 | |
|         typedef boost::integral_constant< value_type, TruncatedPolynomial >
 | |
|           poly_c;
 | |
|         /** \brief  The type to check for reflection
 | |
| 
 | |
|             This is a Boost integral constant representing whether input
 | |
|             units should be read in reverse order.
 | |
|          */
 | |
|         typedef boost::integral_constant< bool, Reflect >           refin_c;
 | |
|         /** \brief  The type to check for map size
 | |
| 
 | |
|             This is a Boost integral constant representing the number of
 | |
|             elements in the partial-product map, based on the unit size.
 | |
|          */
 | |
|         typedef high_bit_mask_c< SubOrder >                  table_size_c;
 | |
|         /** \brief  The type of the unit TO partial-product map
 | |
| 
 | |
|             This is the array type that takes units as the index and said unit's
 | |
|             composite partial-product mask as the element.
 | |
|          */
 | |
|         typedef boost::array<value_type, table_size_c::value>  array_type;
 | |
|         /** \brief  Create a global array for the mapping table
 | |
| 
 | |
|             Creates an instance of a partial-product array with this class's
 | |
|             parameters.
 | |
| 
 | |
|             \return  A reference to a immutable array giving the partial-product
 | |
|               update XOR map for each potential sub-unit value.
 | |
|          */
 | |
|         static  array_type const &  get_table()
 | |
|         {
 | |
|             static  array_type const  table =
 | |
|              make_partial_xor_products_table<unit_width_c::value>(
 | |
|              width_c::value, poly_c::value, refin_c::value );
 | |
| 
 | |
|             return table;
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     /** \brief  A mix-in class that handles direct (i.e. non-reflected) byte-fed
 | |
|           table-driven CRC algorithms
 | |
| 
 | |
|         This class template adds member functions #augmented_crc_update and
 | |
|         #crc_update to update remainders from new input bytes.  The bytes aren't
 | |
|         reflected before processing.
 | |
| 
 | |
|         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
 | |
|           \::digits
 | |
| 
 | |
|         \tparam Order  The order of the modulo-2 polynomial remainder and one
 | |
|           less than the divisor's order.
 | |
|         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|      */
 | |
|     template < int Order, boost::uintmax_t TruncatedPolynomial >
 | |
|     class direct_byte_table_driven_crcs
 | |
|         : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false>
 | |
|     {
 | |
|         typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false>
 | |
|           base_type;
 | |
| 
 | |
|     public:
 | |
|         typedef typename base_type::value_type  value_type;
 | |
|         typedef typename base_type::array_type  array_type;
 | |
| 
 | |
|         /** \brief  Compute the updated remainder after reading some bytes
 | |
| 
 | |
|             The implementation reads from a table to speed-up applying
 | |
|             augmented-CRC updates byte-wise.
 | |
| 
 | |
|             \param remainder  The pre-update remainder
 | |
|             \param new_dividend_bytes  The address where the new bytes start
 | |
|             \param new_dividend_byte_count  The number of new bytes to read
 | |
| 
 | |
|             \return  The updated remainder
 | |
|          */
 | |
|         static  value_type  augmented_crc_update( value_type remainder, unsigned
 | |
|          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
 | |
|         {
 | |
|             static  array_type const &  table = base_type::get_table();
 | |
| 
 | |
|             while ( new_dividend_byte_count-- )
 | |
|             {
 | |
|                 // Locates the merged partial product based on the leading byte
 | |
|                 unsigned char const  index = ( remainder >> (Order - CHAR_BIT) )
 | |
|                  & UCHAR_MAX;
 | |
| 
 | |
|                 // Complete the multi-bit modulo-2 polynomial division
 | |
|                 remainder <<= CHAR_BIT;
 | |
|                 remainder |= *new_dividend_bytes++;
 | |
|                 remainder ^= table.elems[ index ];
 | |
|             }
 | |
| 
 | |
|             return remainder;
 | |
|         }
 | |
| 
 | |
|         /** \brief  Compute the updated remainder after reading some bytes
 | |
| 
 | |
|             The implementation reads from a table to speed-up applying
 | |
|             unaugmented-CRC updates byte-wise.
 | |
| 
 | |
|             \param remainder  The pre-update remainder
 | |
|             \param new_dividend_bytes  The address where the new bytes start
 | |
|             \param new_dividend_byte_count  The number of new bytes to read
 | |
| 
 | |
|             \return  The updated remainder
 | |
|          */
 | |
|         static  value_type  crc_update( value_type remainder, unsigned char
 | |
|          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
 | |
|         {
 | |
|             static  array_type const &  table = base_type::get_table();
 | |
| 
 | |
|             while ( new_dividend_byte_count-- )
 | |
|             {
 | |
|                 // Locates the merged partial product based on comparing the
 | |
|                 // leading and incoming bytes
 | |
|                 unsigned char const  index = ( (remainder >> ( Order - CHAR_BIT
 | |
|                  )) & UCHAR_MAX ) ^ *new_dividend_bytes++;
 | |
| 
 | |
|                 // Complete the multi-bit altered modulo-2 polynomial division
 | |
|                 remainder <<= CHAR_BIT;
 | |
|                 remainder ^= table.elems[ index ];
 | |
|             }
 | |
| 
 | |
|             return remainder;
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     /** \brief  A mix-in class that handles reflected byte-fed, table-driven CRC
 | |
|           algorithms
 | |
| 
 | |
|         This class template adds member functions #augmented_crc_update and
 | |
|         #crc_update to update remainders from new input bytes.  The bytes are
 | |
|         reflected before processing.
 | |
| 
 | |
|         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
 | |
|           \::digits
 | |
| 
 | |
|         \tparam Order  The order of the modulo-2 polynomial remainder and one
 | |
|           less than the divisor's order.
 | |
|         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|      */
 | |
|     template < int Order, boost::uintmax_t TruncatedPolynomial >
 | |
|     class reflected_byte_table_driven_crcs
 | |
|         : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true>
 | |
|     {
 | |
|         typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true>
 | |
|           base_type;
 | |
| 
 | |
|     public:
 | |
|         typedef typename base_type::value_type  value_type;
 | |
|         typedef typename base_type::array_type  array_type;
 | |
| 
 | |
|         /** \brief  Compute the updated remainder after reading some bytes
 | |
| 
 | |
|             The implementation reads from a table to speed-up applying
 | |
|             reflecting augmented-CRC updates byte-wise.
 | |
| 
 | |
|             \param remainder  The pre-update remainder; since the bytes are
 | |
|               being reflected, this remainder also has to be reflected
 | |
|             \param new_dividend_bytes  The address where the new bytes start
 | |
|             \param new_dividend_byte_count  The number of new bytes to read
 | |
| 
 | |
|             \return  The updated, reflected remainder
 | |
|          */
 | |
|         static  value_type  augmented_crc_update( value_type remainder, unsigned
 | |
|          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
 | |
|         {
 | |
|             static  array_type const &  table = base_type::get_table();
 | |
| 
 | |
|             while ( new_dividend_byte_count-- )
 | |
|             {
 | |
|                 // Locates the merged partial product based on the leading byte
 | |
|                 // (which is at the low-order end for reflected remainders)
 | |
|                 unsigned char const  index = remainder & UCHAR_MAX;
 | |
| 
 | |
|                 // Complete the multi-bit reflected modulo-2 polynomial division
 | |
|                 remainder >>= CHAR_BIT;
 | |
|                 remainder |= static_cast<value_type>( *new_dividend_bytes++ )
 | |
|                  << ( Order - CHAR_BIT );
 | |
|                 remainder ^= table.elems[ index ];
 | |
|             }
 | |
| 
 | |
|             return remainder;
 | |
|         }
 | |
| 
 | |
|         /** \brief  Compute the updated remainder after reading some bytes
 | |
| 
 | |
|             The implementation reads from a table to speed-up applying
 | |
|             reflected unaugmented-CRC updates byte-wise.
 | |
| 
 | |
|             \param remainder  The pre-update remainder; since the bytes are
 | |
|               being reflected, this remainder also has to be reflected
 | |
|             \param new_dividend_bytes  The address where the new bytes start
 | |
|             \param new_dividend_byte_count  The number of new bytes to read
 | |
| 
 | |
|             \return  The updated, reflected remainder
 | |
|          */
 | |
|         static  value_type  crc_update( value_type remainder, unsigned char
 | |
|          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
 | |
|         {
 | |
|             static  array_type const &  table = base_type::get_table();
 | |
| 
 | |
|             while ( new_dividend_byte_count-- )
 | |
|             {
 | |
|                 // Locates the merged partial product based on comparing the
 | |
|                 // leading and incoming bytes
 | |
|                 unsigned char const  index = ( remainder & UCHAR_MAX ) ^
 | |
|                  *new_dividend_bytes++;
 | |
| 
 | |
|                 // Complete the multi-bit reflected altered modulo-2 polynomial
 | |
|                 // division
 | |
|                 remainder >>= CHAR_BIT;
 | |
|                 remainder ^= table.elems[ index ];
 | |
|             }
 | |
| 
 | |
|             return remainder;
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     /** \brief  Mix-in class for byte-fed, table-driven CRC algorithms with
 | |
|           parameter values at least a byte in width
 | |
| 
 | |
|         This class template adds member functions #augmented_crc_update and
 | |
|         #crc_update to update remainders from new input bytes.  The bytes may be
 | |
|         reflected before processing, controlled by a compile-time parameter.
 | |
| 
 | |
|         \pre  \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
 | |
|           \::digits
 | |
| 
 | |
|         \tparam Order  The order of the modulo-2 polynomial remainder and one
 | |
|           less than the divisor's order.
 | |
|         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|         \tparam Reflect  If \c false, read from the highest-order bit from a new
 | |
|           input byte and go down, as normal.  Otherwise, proceed from the
 | |
|           lowest-order bit and go up.
 | |
|      */
 | |
|     template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect >
 | |
|     class byte_table_driven_crcs
 | |
|         : public boost::conditional< Reflect,
 | |
|           reflected_byte_table_driven_crcs<Order, TruncatedPolynomial>,
 | |
|           direct_byte_table_driven_crcs<Order, TruncatedPolynomial> >::type
 | |
|     { };
 | |
| 
 | |
|     /** \brief  A mix-in class that handles direct (i.e. non-reflected) byte-fed
 | |
|           CRC algorithms for sub-byte parameters
 | |
| 
 | |
|         This class template adds member functions #augmented_crc_update and
 | |
|         #crc_update to update remainders from new input bytes.  The bytes aren't
 | |
|         reflected before processing.
 | |
| 
 | |
|         \pre  0 \< \a Order \< \c CHAR_BIT
 | |
| 
 | |
|         \tparam Order  The order of the modulo-2 polynomial remainder and one
 | |
|           less than the divisor's order.
 | |
|         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|      */
 | |
|     template < int Order, boost::uintmax_t TruncatedPolynomial >
 | |
|     class direct_sub_byte_crcs
 | |
|         : public crc_table_t<Order, Order, TruncatedPolynomial, false>
 | |
|     {
 | |
|         typedef crc_table_t<Order, Order, TruncatedPolynomial, false>
 | |
|           base_type;
 | |
| 
 | |
|     public:
 | |
|         typedef typename base_type::width_c     width_c;
 | |
|         typedef typename base_type::value_type  value_type;
 | |
|         typedef typename base_type::poly_c       poly_c;
 | |
|         typedef typename base_type::array_type  array_type;
 | |
| 
 | |
|         /** \brief  Compute the updated remainder after reading some bytes
 | |
| 
 | |
|             The implementation reads from a table to speed-up applying
 | |
|             augmented-CRC updates byte-wise.
 | |
| 
 | |
|             \param remainder  The pre-update remainder
 | |
|             \param new_dividend_bytes  The address where the new bytes start
 | |
|             \param new_dividend_byte_count  The number of new bytes to read
 | |
| 
 | |
|             \return  The updated remainder
 | |
| 
 | |
|             \todo  Use this function somewhere so I can test it.
 | |
|          */
 | |
|         static  value_type  augmented_crc_update( value_type remainder, unsigned
 | |
|          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
 | |
|         {
 | |
|             //static  array_type const &  table = base_type::get_table();
 | |
| 
 | |
|             while ( new_dividend_byte_count-- )
 | |
|             {
 | |
|                 // Without a table, process each byte explicitly
 | |
|                 augmented_crc_modulo_word_update( width_c::value, remainder,
 | |
|                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, false );
 | |
|             }
 | |
| 
 | |
|             return remainder;
 | |
|         }
 | |
| 
 | |
|         /** \brief  Compute the updated remainder after reading some bytes
 | |
| 
 | |
|             The implementation reads from a table to speed-up applying
 | |
|             unaugmented-CRC updates byte-wise.
 | |
| 
 | |
|             \param remainder  The pre-update remainder
 | |
|             \param new_dividend_bytes  The address where the new bytes start
 | |
|             \param new_dividend_byte_count  The number of new bytes to read
 | |
| 
 | |
|             \return  The updated remainder
 | |
|          */
 | |
|         static  value_type  crc_update( value_type remainder, unsigned char
 | |
|          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
 | |
|         {
 | |
|             //static  array_type const &  table = base_type::get_table();
 | |
| 
 | |
|             while ( new_dividend_byte_count-- )
 | |
|             {
 | |
|                 // Without a table, process each byte explicitly
 | |
|                 crc_modulo_word_update( width_c::value, remainder,
 | |
|                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, false );
 | |
|             }
 | |
| 
 | |
|             return remainder;
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     /** \brief  A mix-in class that handles reflected byte-fed, CRC algorithms
 | |
|           for sub-byte parameters
 | |
| 
 | |
|         This class template adds member functions #augmented_crc_update and
 | |
|         #crc_update to update remainders from new input bytes.  The bytes are
 | |
|         reflected before processing.
 | |
| 
 | |
|         \pre  0 \< \a Order \< \c CHAR_BIT
 | |
| 
 | |
|         \tparam Order  The order of the modulo-2 polynomial remainder and one
 | |
|           less than the divisor's order.
 | |
|         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|      */
 | |
|     template < int Order, boost::uintmax_t TruncatedPolynomial >
 | |
|     class reflected_sub_byte_crcs
 | |
|         : public crc_table_t<Order, Order, TruncatedPolynomial, true>
 | |
|     {
 | |
|         typedef crc_table_t<Order, Order, TruncatedPolynomial, true>
 | |
|           base_type;
 | |
| 
 | |
|     public:
 | |
|         typedef typename base_type::width_c     width_c;
 | |
|         typedef typename base_type::value_type  value_type;
 | |
|         typedef typename base_type::poly_c       poly_c;
 | |
|         typedef typename base_type::array_type  array_type;
 | |
| 
 | |
|         /** \brief  Compute the updated remainder after reading some bytes
 | |
| 
 | |
|             The implementation reads from a table to speed-up applying
 | |
|             reflecting augmented-CRC updates byte-wise.
 | |
| 
 | |
|             \param remainder  The pre-update remainder; since the bytes are
 | |
|               being reflected, this remainder also has to be reflected
 | |
|             \param new_dividend_bytes  The address where the new bytes start
 | |
|             \param new_dividend_byte_count  The number of new bytes to read
 | |
| 
 | |
|             \return  The updated, reflected remainder
 | |
| 
 | |
|             \todo  Use this function somewhere so I can test it.
 | |
|          */
 | |
|         static  value_type  augmented_crc_update( value_type remainder, unsigned
 | |
|          char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
 | |
|         {
 | |
|             //static  array_type const &  table = base_type::get_table();
 | |
| 
 | |
|             remainder = reflect_sub_byte( remainder, width_c::value );
 | |
|             while ( new_dividend_byte_count-- )
 | |
|             {
 | |
|                 // Without a table, process each byte explicitly
 | |
|                 augmented_crc_modulo_word_update( width_c::value, remainder,
 | |
|                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, true );
 | |
|             }
 | |
|             remainder = reflect_sub_byte( remainder, width_c::value );
 | |
| 
 | |
|             return remainder;
 | |
|         }
 | |
| 
 | |
|         /** \brief  Compute the updated remainder after reading some bytes
 | |
| 
 | |
|             The implementation reads from a table to speed-up applying
 | |
|             reflected unaugmented-CRC updates byte-wise.
 | |
| 
 | |
|             \param remainder  The pre-update remainder; since the bytes are
 | |
|               being reflected, this remainder also has to be reflected
 | |
|             \param new_dividend_bytes  The address where the new bytes start
 | |
|             \param new_dividend_byte_count  The number of new bytes to read
 | |
| 
 | |
|             \return  The updated, reflected remainder
 | |
|          */
 | |
|         static  value_type  crc_update( value_type remainder, unsigned char
 | |
|          const *new_dividend_bytes, std::size_t new_dividend_byte_count)
 | |
|         {
 | |
|             //static  array_type const &  table = base_type::get_table();
 | |
| 
 | |
|             remainder = reflect_sub_byte( remainder, width_c::value );
 | |
|             while ( new_dividend_byte_count-- )
 | |
|             {
 | |
|                 // Without a table, process each byte explicitly
 | |
|                 crc_modulo_word_update( width_c::value, remainder,
 | |
|                  *new_dividend_bytes++, poly_c::value, CHAR_BIT, true );
 | |
|             }
 | |
|             remainder = reflect_sub_byte( remainder, width_c::value );
 | |
| 
 | |
|             return remainder;
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     /** \brief  Mix-in class for byte-fed, table-driven CRC algorithms with
 | |
|           sub-byte parameters
 | |
| 
 | |
|         This class template adds member functions #augmented_crc_update and
 | |
|         #crc_update to update remainders from new input bytes.  The bytes may be
 | |
|         reflected before processing, controlled by a compile-time parameter.
 | |
| 
 | |
|         \pre  0 \< \a Order \< \c CHAR_BIT
 | |
| 
 | |
|         \tparam Order  The order of the modulo-2 polynomial remainder and one
 | |
|           less than the divisor's order.
 | |
|         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|         \tparam Reflect  If \c false, read from the highest-order bit from a new
 | |
|           input byte and go down, as normal.  Otherwise, proceed from the
 | |
|           lowest-order bit and go up.
 | |
|      */
 | |
|     template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect >
 | |
|     class sub_byte_crcs
 | |
|         : public boost::conditional< Reflect,
 | |
|           reflected_sub_byte_crcs<Order, TruncatedPolynomial>,
 | |
|           direct_sub_byte_crcs<Order, TruncatedPolynomial> >::type
 | |
|     { };
 | |
| 
 | |
|     /** This class template adds member functions #augmented_crc_update and
 | |
|         #crc_update to update remainders from new input bytes.  The bytes may be
 | |
|         reflected before processing, controlled by a compile-time parameter.
 | |
| 
 | |
|         \pre  0 \< \a Order \<= \c std\::numeric_limits\<uintmax_t\>\::digits
 | |
| 
 | |
|         \tparam Order  The order of the modulo-2 polynomial remainder and one
 | |
|           less than the divisor's order.
 | |
|         \tparam TruncatedPolynomial  The lowest coefficients of the divisor
 | |
|           polynomial.  The highest-order coefficient is omitted and always
 | |
|           assumed to be 1.
 | |
|         \tparam Reflect  If \c false, read from the highest-order bit from a new
 | |
|           input byte and go down, as normal.  Otherwise, proceed from the
 | |
|           lowest-order bit and go up.
 | |
|         \tparam Id  An extra differentiator if multiple copies of this class
 | |
|           template are mixed-in as base classes.  Defaults to 0 if omitted.
 | |
|      */
 | |
|     template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect,
 | |
|      int Id >
 | |
|     class crc_driver
 | |
|         : public boost::conditional< (Order < CHAR_BIT), sub_byte_crcs<Order,
 | |
|           TruncatedPolynomial, Reflect>, byte_table_driven_crcs<Order,
 | |
|           TruncatedPolynomial, Reflect> >::type
 | |
|     {
 | |
|     public:
 | |
|         /** \brief  The type to check for ID
 | |
| 
 | |
|             This is a Boost integral constant indicating what ID number this
 | |
|             instantiation used.
 | |
|          */
 | |
|         typedef boost::integral_constant<int, Id>  id_type;
 | |
|     };
 | |
| 
 | |
| 
 | |
| }  // namespace detail
 | |
| //! \endcond
 | |
| 
 | |
| 
 | |
| //  Simple CRC class function definitions  -----------------------------------//
 | |
| 
 | |
| /** Constructs a \c crc_basic object with at least the required parameters to a
 | |
|     particular CRC formula to be processed upon receiving input.
 | |
| 
 | |
|     \param[in] truncated_polynomial  The lowest coefficients of the divisor
 | |
|       polynomial.  The highest-order coefficient is omitted and always assumed
 | |
|       to be 1.  (\e Poly from the RMCA)
 | |
|     \param[in] initial_remainder  The (unaugmented) initial state of the
 | |
|       polynomial remainder.  Defaults to \c 0 if omitted.  (\e Init from the
 | |
|       RMCA)
 | |
|     \param[in] final_xor_value  The (XOR) bit-mask to be applied to the output
 | |
|       remainder, after possible reflection but before returning.  Defaults to
 | |
|       \c 0 (i.e. no bit changes) if omitted.  (\e XorOut from the RMCA)
 | |
|     \param[in] reflect_input  If \c true, input bytes are read lowest-order bit
 | |
|       first, otherwise highest-order bit first.  Defaults to \c false if
 | |
|       omitted.  (\e RefIn from the RMCA)
 | |
|     \param[in] reflect_remainder  If \c true, the output remainder is reflected
 | |
|       before the XOR-mask.  Defaults to \c false if omitted.  (\e RefOut from
 | |
|       the RMCA)
 | |
| 
 | |
|     \post  <code><var>truncated_polynomial</var> ==
 | |
|       this->get_truncated_polynominal()</code>
 | |
|     \post  <code><var>initial_remainder</var> ==
 | |
|       this->get_initial_remainder()</code>
 | |
|     \post  <code><var>final_xor_value</var> ==
 | |
|       this->get_final_xor_value()</code>
 | |
|     \post  <code><var>reflect_input</var> ==
 | |
|       this->get_reflect_input()</code>
 | |
|     \post  <code><var>reflect_remainder</var> ==
 | |
|       this->get_reflect_remainder()</code>
 | |
|     \post  <code><var>initial_remainder</var> ==
 | |
|       this->get_interim_remainder()</code>
 | |
|     \post  <code>(<var>reflect_remainder</var> ?
 | |
|       REFLECT(<var>initial_remainder</var>) : <var>initial_remainder</var>) ^
 | |
|       <var>final_xor_value</var> == this->checksum()</code>
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| crc_basic<Bits>::crc_basic
 | |
| (
 | |
|     value_type  truncated_polynomial,
 | |
|     value_type  initial_remainder,      // = 0
 | |
|     value_type  final_xor_value,        // = 0
 | |
|     bool        reflect_input,          // = false
 | |
|     bool        reflect_remainder       // = false
 | |
| )
 | |
|     : rem_( initial_remainder ), poly_( truncated_polynomial )
 | |
|     , init_( initial_remainder ), final_( final_xor_value )
 | |
|     , rft_in_( reflect_input ), rft_out_( reflect_remainder )
 | |
| {
 | |
| }
 | |
| 
 | |
| /** Returns a representation of the polynomial divisor.  The value of the
 | |
|     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
 | |
|     x<sup>i</sup> term.  The omitted bit for x<sup>(#bit_count)</sup> term is
 | |
|     always 1.
 | |
| 
 | |
|     \return  The bit-packed list of coefficients.  If the bit-length of
 | |
|       #value_type exceeds #bit_count, the values of higher-placed bits should be
 | |
|       ignored (even any for x<sup>(#bit_count)</sup>) since they're unregulated.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| typename crc_basic<Bits>::value_type
 | |
| crc_basic<Bits>::get_truncated_polynominal
 | |
| (
 | |
| ) const
 | |
| {
 | |
|     return poly_;
 | |
| }
 | |
| 
 | |
| /** Returns a representation of the polynomial remainder before any input has
 | |
|     been submitted.  The value of the 2<sup>i</sup> bit is the value of the
 | |
|     coefficient of the polynomial's x<sup>i</sup> term.
 | |
| 
 | |
|     \return  The bit-packed list of coefficients.  If the bit-length of
 | |
|       #value_type exceeds #bit_count, the values of higher-placed bits should be
 | |
|       ignored since they're unregulated.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| typename crc_basic<Bits>::value_type
 | |
| crc_basic<Bits>::get_initial_remainder
 | |
| (
 | |
| ) const
 | |
| {
 | |
|     return init_;
 | |
| }
 | |
| 
 | |
| /** Returns the mask to be used during creation of a checksum.  The mask is used
 | |
|     for an exclusive-or (XOR) operation applied bit-wise to the interim
 | |
|     remainder representation (after any reflection, if #get_reflect_remainder()
 | |
|     returns \c true).
 | |
| 
 | |
|     \return  The bit-mask.  If the bit-length of #value_type exceeds #bit_count,
 | |
|       the values of higher-placed bits should be ignored since they're
 | |
|       unregulated.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| typename crc_basic<Bits>::value_type
 | |
| crc_basic<Bits>::get_final_xor_value
 | |
| (
 | |
| ) const
 | |
| {
 | |
|     return final_;
 | |
| }
 | |
| 
 | |
| /** Returns a whether or not a submitted byte will be \"reflected\" before it is
 | |
|     used to update the interim remainder.  Only the byte-wise operations
 | |
|     #process_byte, #process_block, and #process_bytes are affected.
 | |
| 
 | |
|     \retval true  Input bytes will be read starting from the lowest-order bit.
 | |
|     \retval false  Input bytes will be read starting from the highest-order bit.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| bool
 | |
| crc_basic<Bits>::get_reflect_input
 | |
| (
 | |
| ) const
 | |
| {
 | |
|     return rft_in_;
 | |
| }
 | |
| 
 | |
| /** Indicates if the interim remainder will be \"reflected\" before it is passed
 | |
|     to the XOR-mask stage when returning a checksum.
 | |
| 
 | |
|     \retval true  The interim remainder is reflected before further work.
 | |
|     \retval false  The interim remainder is applied to the XOR-mask as-is.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| bool
 | |
| crc_basic<Bits>::get_reflect_remainder
 | |
| (
 | |
| ) const
 | |
| {
 | |
|     return rft_out_;
 | |
| }
 | |
| 
 | |
| /** Returns a representation of the polynomial remainder after all the input
 | |
|     submissions since construction or the last #reset call.  The value of the
 | |
|     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
 | |
|     x<sup>i</sup> term.  If CRC processing gets interrupted here, retain the
 | |
|     value returned, and use it to start up the next CRC computer where you left
 | |
|     off (with #reset(value_type) or construction).  The next computer has to
 | |
|     have its other parameters compatible with this computer.
 | |
| 
 | |
|     \return  The bit-packed list of coefficients.  If the bit-length of
 | |
|       #value_type exceeds #bit_count, the values of higher-placed bits should be
 | |
|       ignored since they're unregulated.  No output processing (reflection or
 | |
|       XOR mask) has been applied to the value.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| typename crc_basic<Bits>::value_type
 | |
| crc_basic<Bits>::get_interim_remainder
 | |
| (
 | |
| ) const
 | |
| {
 | |
|     return rem_ & detail::low_bits_mask_c<bit_count>::value;
 | |
| }
 | |
| 
 | |
| /** Changes the interim polynomial remainder to \a new_rem, purging any
 | |
|     influence previously submitted input has had.  The value of the
 | |
|     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
 | |
|     x<sup>i</sup> term.
 | |
| 
 | |
|     \param[in] new_rem  The (unaugmented) state of the polynomial remainder
 | |
|       starting from this point, with no output processing applied.
 | |
| 
 | |
|     \post  <code><var>new_rem</var> == this->get_interim_remainder()</code>
 | |
|     \post  <code>((this->get_reflect_remainder() ?
 | |
|       REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^
 | |
|       this->get_final_xor_value()) == this->checksum()</code>
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| void
 | |
| crc_basic<Bits>::reset
 | |
| (
 | |
|     value_type  new_rem
 | |
| )
 | |
| {
 | |
|     rem_ = new_rem;
 | |
| }
 | |
| 
 | |
| /** Changes the interim polynomial remainder to the initial remainder given
 | |
|     during construction, purging any influence previously submitted input has
 | |
|     had.  The value of the 2<sup>i</sup> bit is the value of the coefficient of
 | |
|     the polynomial's x<sup>i</sup> term.
 | |
| 
 | |
|     \post  <code>this->get_initial_remainder() ==
 | |
|       this->get_interim_remainder()</code>
 | |
|     \post  <code>((this->get_reflect_remainder() ?
 | |
|       REFLECT(this->get_initial_remainder()) :
 | |
|       this->get_initial_remainder()) ^ this->get_final_xor_value())
 | |
|       == this->checksum()</code>
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| void
 | |
| crc_basic<Bits>::reset
 | |
| (
 | |
| )
 | |
| {
 | |
|     this->reset( this->get_initial_remainder() );
 | |
| }
 | |
| 
 | |
| /** Updates the interim remainder with a single altered-CRC-division step.
 | |
| 
 | |
|     \param[in] bit  The new input bit.
 | |
| 
 | |
|     \post  The interim remainder is updated though a modulo-2 polynomial
 | |
|       division, where the division steps are altered for unaugmented CRCs.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| void
 | |
| crc_basic<Bits>::process_bit
 | |
| (
 | |
|     bool  bit
 | |
| )
 | |
| {
 | |
|     detail::crc_modulo_update( bit_count, rem_, bit, poly_ );
 | |
| }
 | |
| 
 | |
| /** Updates the interim remainder with several altered-CRC-division steps.  Each
 | |
|     bit is processed separately, starting from the one at the
 | |
|     2<sup><var>bit_length</var> - 1</sup> place, then proceeding down to the
 | |
|     lowest-placed bit.  Any order imposed by
 | |
|     <code>this->get_reflect_input()</code> is ignored.
 | |
| 
 | |
|     \pre  0 \< \a bit_length \<= \c CHAR_BIT
 | |
| 
 | |
|     \param[in] bits  The byte containing the new input bits.
 | |
|     \param[in] bit_length  The number of bits in the byte to be read.
 | |
| 
 | |
|     \post  The interim remainder is updated though \a bit_length modulo-2
 | |
|       polynomial divisions, where the division steps are altered for unaugmented
 | |
|       CRCs.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| void
 | |
| crc_basic<Bits>::process_bits
 | |
| (
 | |
|     unsigned char  bits,
 | |
|     std::size_t    bit_length
 | |
| )
 | |
| {
 | |
|     // ignore the bits above the ones we want
 | |
|     bits <<= CHAR_BIT - bit_length;
 | |
| 
 | |
|     // 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_length ; i > 0u ; --i, bits <<= 1u )
 | |
|     {
 | |
|         process_bit( static_cast<bool>(bits & high_bit_mask) );
 | |
|     }
 | |
| }
 | |
| 
 | |
| /** Updates the interim remainder with a byte's worth of altered-CRC-division
 | |
|     steps.  The bits within the byte are processed from the highest place down
 | |
|     if <code>this->get_reflect_input()</code> is \c false, and lowest place
 | |
|     up otherwise.
 | |
| 
 | |
|     \param[in] byte  The new input byte.
 | |
| 
 | |
|     \post  The interim remainder is updated though \c CHAR_BIT modulo-2
 | |
|       polynomial divisions, where the division steps are altered for unaugmented
 | |
|       CRCs.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| void
 | |
| crc_basic<Bits>::process_byte
 | |
| (
 | |
|     unsigned char  byte
 | |
| )
 | |
| {
 | |
|     process_bits( (rft_in_ ? detail::reflect_byte( byte ) : byte), CHAR_BIT );
 | |
| }
 | |
| 
 | |
| /** Updates the interim remainder with several bytes' worth of
 | |
|     altered-CRC-division steps.  The bits within each byte are processed from
 | |
|     the highest place down if <code>this->get_reflect_input()</code> is
 | |
|     \c false, and lowest place up otherwise.  The bytes themselves are processed
 | |
|     starting from the one pointed by \a bytes_begin until \a bytes_end is
 | |
|     reached through forward iteration, treating the two pointers as if they
 | |
|     point to <code>unsigned char</code> objects.
 | |
| 
 | |
|     \pre  \a bytes_end has to equal \a bytes_begin if the latter is \c NULL or
 | |
|       otherwise doesn't point to a valid buffer.
 | |
|     \pre  \a bytes_end, if not equal to \a bytes_begin, has to point within or
 | |
|       one-byte-past the same buffer \a bytes_begin points into.
 | |
|     \pre  \a bytes_end has to be reachable from \a bytes_begin through a finite
 | |
|       number of forward byte-pointer increments.
 | |
| 
 | |
|     \param[in] bytes_begin  The address where the memory block begins.
 | |
|     \param[in] bytes_end  Points to one-byte past the address of the memory
 | |
|       block's last byte, or \a bytes_begin if no bytes are to be read.
 | |
| 
 | |
|     \post  The interim remainder is updated though <code>CHAR_BIT * (((unsigned
 | |
|       char const *) bytes_end) - ((unsigned char const *) bytes_begin))</code>
 | |
|       modulo-2 polynomial divisions, where the division steps are altered for
 | |
|       unaugmented CRCs.
 | |
|  */
 | |
| 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 );
 | |
|     }
 | |
| }
 | |
| 
 | |
| /** Updates the interim remainder with several bytes' worth of
 | |
|     altered-CRC-division steps.  The bits within each byte are processed from
 | |
|     the highest place down if <code>this->get_reflect_input()</code> is
 | |
|     \c false, and lowest place up otherwise.  The bytes themselves are processed
 | |
|     starting from the one pointed by \a buffer, forward-iterated (as if the
 | |
|     pointed-to objects were of <code>unsigned char</code>) until \a byte_count
 | |
|     bytes are read.
 | |
| 
 | |
|     \pre  \a byte_count has to equal 0 if \a buffer is \c NULL or otherwise
 | |
|       doesn't point to valid memory.
 | |
|     \pre  If \a buffer points within valid memory, then that block has to have
 | |
|       at least \a byte_count more valid bytes allocated from that point.
 | |
| 
 | |
|     \param[in] buffer  The address where the memory block begins.
 | |
|     \param[in] byte_count  The number of bytes in the memory block.
 | |
| 
 | |
|     \post  The interim remainder is updated though <code>CHAR_BIT *
 | |
|       <var>byte_count</var></code> modulo-2 polynomial divisions, where the
 | |
|       division steps are altered for unaugmented CRCs.
 | |
|  */
 | |
| 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 );
 | |
| }
 | |
| 
 | |
| /** Computes the checksum of all the submitted bits since construction or the
 | |
|     last call to #reset.  The checksum will be the raw checksum, i.e. the
 | |
|     (interim) remainder after all the modulo-2 polynomial division, plus any
 | |
|     output processing.
 | |
| 
 | |
|     \return  <code>(this->get_reflect_remainder() ?
 | |
|       REFLECT(this->get_interim_remainder()) :
 | |
|       this->get_interim_remainder()) ^ this->get_final_xor_value()</code>
 | |
| 
 | |
|     \note  Since checksums are meant to be compared, any higher-placed bits
 | |
|       (when the bit-length of #value_type exceeds #bit_count) will be set to 0.
 | |
|  */
 | |
| template < std::size_t Bits >
 | |
| inline
 | |
| typename crc_basic<Bits>::value_type
 | |
| crc_basic<Bits>::checksum
 | |
| (
 | |
| ) const
 | |
| {
 | |
|     return ( (rft_out_ ? detail::reflect_unsigned( rem_, bit_count ) :
 | |
|      rem_) ^ final_ ) & detail::low_bits_mask_c<bit_count>::value;
 | |
| }
 | |
| 
 | |
| 
 | |
| //  Optimized CRC class function definitions  --------------------------------//
 | |
| 
 | |
| // Macro to compact code
 | |
| #define BOOST_CRC_OPTIMAL_NAME  crc_optimal<Bits, TruncPoly, InitRem, \
 | |
|  FinalXor, ReflectIn, ReflectRem>
 | |
| 
 | |
| /** Constructs a \c crc_optimal object with a particular CRC formula to be
 | |
|     processed upon receiving input.  The initial remainder may be overridden.
 | |
| 
 | |
|     \param[in] init_rem  The (unaugmented) initial state of the polynomial
 | |
|       remainder.  Defaults to #initial_remainder if omitted.
 | |
| 
 | |
|     \post  <code>#truncated_polynominal ==
 | |
|       this->get_truncated_polynominal()</code>
 | |
|     \post  <code>#initial_remainder == this->get_initial_remainder()</code>
 | |
|     \post  <code>#final_xor_value == this->get_final_xor_value()</code>
 | |
|     \post  <code>#reflect_input == this->get_reflect_input()</code>
 | |
|     \post  <code>#reflect_remainder == this->get_reflect_remainder()</code>
 | |
|     \post  <code><var>init_rem</var> == this->get_interim_remainder()</code>
 | |
|     \post  <code>(#reflect_remainder ? REFLECT(<var>init_rem</var>) :
 | |
|       <var>init_rem</var>) ^ #final_xor_value == this->checksum()</code>
 | |
|  */
 | |
| 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
 | |
| (
 | |
|     value_type  init_rem  // = initial_remainder
 | |
| )
 | |
|     : rem_( reflect_i_type::reflect_q(init_rem) )
 | |
| {
 | |
| }
 | |
| 
 | |
| //! \copydetails  boost::crc_basic::get_truncated_polynominal
 | |
| 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 truncated_polynominal;
 | |
| }
 | |
| 
 | |
| //! \copydetails  boost::crc_basic::get_initial_remainder
 | |
| 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 initial_remainder;
 | |
| }
 | |
| 
 | |
| //! \copydetails  boost::crc_basic::get_final_xor_value
 | |
| 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 final_xor_value;
 | |
| }
 | |
| 
 | |
| //! \copydetails  boost::crc_basic::get_reflect_input
 | |
| 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 reflect_input;
 | |
| }
 | |
| 
 | |
| //! \copydetails  boost::crc_basic::get_reflect_remainder
 | |
| 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 reflect_remainder;
 | |
| }
 | |
| 
 | |
| //! \copydetails  boost::crc_basic::get_interim_remainder
 | |
| 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 reflect_i_type::reflect_q( rem_ ) &
 | |
|      detail::low_bits_mask_c<bit_count>::value;
 | |
| }
 | |
| 
 | |
| /** Changes the interim polynomial remainder to \a new_rem, purging any
 | |
|     influence previously submitted input has had.  The value of the
 | |
|     2<sup>i</sup> bit is the value of the coefficient of the polynomial's
 | |
|     x<sup>i</sup> term.
 | |
| 
 | |
|     \param[in] new_rem  The (unaugmented) state of the polynomial remainder
 | |
|       starting from this point, with no output processing applied.  Defaults to
 | |
|       <code>this->get_initial_remainder()</code> if omitted.
 | |
| 
 | |
|     \post  <code><var>new_rem</var> == this->get_interim_remainder()</code>
 | |
|     \post  <code>((this->get_reflect_remainder() ?
 | |
|       REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^
 | |
|       this->get_final_xor_value()) == this->checksum()</code>
 | |
|  */
 | |
| 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
 | |
| (
 | |
|     value_type  new_rem  // = initial_remainder
 | |
| )
 | |
| {
 | |
|     rem_ = reflect_i_type::reflect_q( new_rem );
 | |
| }
 | |
| 
 | |
| /** \copydetails  boost::crc_basic::process_byte
 | |
| 
 | |
|     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
 | |
|       remainder changes (as XOR masks) to speed computation when reading data
 | |
|       byte-wise.
 | |
|  */
 | |
| 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) );
 | |
| }
 | |
| 
 | |
| /** \copydetails  boost::crc_basic::process_block
 | |
| 
 | |
|     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
 | |
|       remainder changes (as XOR masks) to speed computation when reading data
 | |
|       byte-wise.
 | |
|  */
 | |
| 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_block
 | |
| (
 | |
|     void const *  bytes_begin,
 | |
|     void const *  bytes_end
 | |
| )
 | |
| {
 | |
|     process_bytes( bytes_begin, static_cast<unsigned char const *>(bytes_end) -
 | |
|      static_cast<unsigned char const *>(bytes_begin) );
 | |
| }
 | |
| 
 | |
| /** \copydetails  boost::crc_basic::process_bytes
 | |
| 
 | |
|     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
 | |
|       remainder changes (as XOR masks) to speed computation when reading data
 | |
|       byte-wise.
 | |
|  */
 | |
| 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
 | |
| )
 | |
| {
 | |
|     rem_ = crc_table_type::crc_update( rem_, static_cast<unsigned char const
 | |
|      *>(buffer), byte_count );
 | |
| }
 | |
| 
 | |
| //! \copydetails  boost::crc_basic::checksum
 | |
| 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_o_type::reflect_q(rem_) ^ get_final_xor_value() )
 | |
|      & detail::low_bits_mask_c<bit_count>::value;
 | |
| }
 | |
| 
 | |
| /** Updates the interim remainder with a byte's worth of altered-CRC-division
 | |
|     steps.  The bits within the byte are processed from the highest place down
 | |
|     if <code>this->get_reflect_input()</code> is \c false, and lowest place
 | |
|     up otherwise.  This function is meant to present a function-object interface
 | |
|     to code that wants to process a stream of bytes with
 | |
|     <code>std::for_each</code> or similar range-processing algorithms.  Since
 | |
|     some of these algorithms takes their function object by value, make sure to
 | |
|     copy back the result to this object so the updates can be remembered.
 | |
| 
 | |
|     \param[in] byte  The new input byte.
 | |
| 
 | |
|     \post  The interim remainder is updated though \c CHAR_BIT modulo-2
 | |
|       polynomial divisions, where the division steps are altered for unaugmented
 | |
|       CRCs.
 | |
| 
 | |
|     \note  Any modulo-2 polynomial divisions may use a table of pre-computed
 | |
|       remainder changes (as XOR masks) to speed computation when reading data
 | |
|       byte-wise.
 | |
|  */
 | |
| 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 );
 | |
| }
 | |
| 
 | |
| /** Computes the checksum of all the submitted bits since construction or the
 | |
|     last call to #reset.  The checksum will be the raw checksum, i.e. the
 | |
|     (interim) remainder after all the modulo-2 polynomial division, plus any
 | |
|     output processing.  This function is meant to present a function-object
 | |
|     interface to code that wants to receive data like
 | |
|     <code>std::generate_n</code> or similar data-processing algorithms.  Note
 | |
|     that if this object is used as a generator multiple times without an
 | |
|     intervening mutating operation, the same value will always be returned.
 | |
| 
 | |
|     \return  <code>(this->get_reflect_remainder() ?
 | |
|       REFLECT(this->get_interim_remainder()) :
 | |
|       this->get_interim_remainder()) ^ this->get_final_xor_value()</code>
 | |
| 
 | |
|     \note  Since checksums are meant to be compared, any higher-placed bits
 | |
|       (when the bit-length of #value_type exceeds #bit_count) will be set to 0.
 | |
|  */
 | |
| 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  -------------------------------------//
 | |
| 
 | |
| /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and
 | |
|     \a byte_count describe a memory block representing the polynomial dividend.
 | |
|     The division steps are altered so the result directly gives a checksum,
 | |
|     without need to augment the memory block with scratch-space bytes.  The
 | |
|     first byte is considered the highest order, going down for subsequent bytes.
 | |
| 
 | |
|     \pre  0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
 | |
| 
 | |
|     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
 | |
|       the RMCA)
 | |
|     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
 | |
|       highest-order coefficient is omitted and always assumed to be 1.
 | |
|       (\e Poly from the RMCA)
 | |
|     \tparam InitRem  The (unaugmented) initial state of the polynomial
 | |
|       remainder.  (\e Init from the RMCA)
 | |
|     \tparam FinalXor  The (XOR) bit-mask to be applied to the output remainder,
 | |
|       after possible reflection but before returning.  (\e XorOut from the RMCA)
 | |
|     \tparam ReflectIn  If \c True, input bytes are read lowest-order bit first,
 | |
|       otherwise highest-order bit first.  (\e RefIn from the RMCA)
 | |
|     \tparam ReflectRem  If \c True, the output remainder is reflected before the
 | |
|       XOR-mask.  (\e RefOut from the RMCA)
 | |
| 
 | |
|     \param[in] buffer  The address where the memory block begins.
 | |
|     \param[in] byte_count  The number of bytes in the memory block.
 | |
| 
 | |
|     \return  The checksum, which is the last (interim) remainder plus any output
 | |
|       processing.
 | |
| 
 | |
|     \note  Unaugmented-style CRC runs perform modulo-2 polynomial division in
 | |
|       an altered order.  The trailing \a Bits number of zero-valued bits needed
 | |
|       to extracted an (unprocessed) checksum is virtually moved to near the
 | |
|       beginning of the message.  This is OK since the XOR operation is
 | |
|       commutative and associative.  It also means that you can get a checksum
 | |
|       anytime.  Since data is being read byte-wise, a table of pre-computed
 | |
|       remainder changes (as XOR masks) can be used to speed computation.
 | |
| 
 | |
|  */
 | |
| 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_OPTIMAL_NAME  computer;
 | |
|     computer.process_bytes( buffer, byte_count );
 | |
|     return computer.checksum();
 | |
| }
 | |
| 
 | |
| 
 | |
| //  Augmented-message CRC computation function definition  -------------------//
 | |
| 
 | |
| /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and
 | |
|     \a byte_count describe a memory block representing the polynomial dividend.
 | |
|     The first byte is considered the highest order, going down for subsequent
 | |
|     bytes.  Within a byte, the highest-order bit is read first (corresponding to
 | |
|     \e RefIn = \c False in the RMCA).  Check the other parts of this function's
 | |
|     documentation to see how a checksum can be gained and/or used.
 | |
| 
 | |
|     \pre  0 \< \a Bits \<= \c std\::numeric_limit\<uintmax_t\>\::digits
 | |
| 
 | |
|     \tparam Bits  The order of the modulo-2 polynomial divisor.  (\e Width from
 | |
|       the RMCA)
 | |
|     \tparam TruncPoly  The lowest coefficients of the divisor polynomial.  The
 | |
|       highest-order coefficient is omitted and always assumed to be 1.
 | |
|       (\e Poly from the RMCA)
 | |
| 
 | |
|     \param[in] buffer  The address where the memory block begins.
 | |
|     \param[in] byte_count  The number of bytes in the memory block.
 | |
|     \param[in] initial_remainder  The initial state of the polynomial
 | |
|       remainder, defaulting to zero if omitted.  If you are reading a memory
 | |
|       block in multiple runs, put the return value of the previous run here.
 | |
|       (Note that initial-remainders given by RMCA parameter lists, as
 | |
|       \e Init, assume that the initial remainder is in its \b unaugmented state,
 | |
|       so you would need to convert the value to make it suitable for this
 | |
|       function.  I currently don't provide a conversion routine.)
 | |
| 
 | |
|     \return  The interim remainder, if no augmentation is used.  A special value
 | |
|       if augmentation is used (see the notes).  No output processing is done on
 | |
|       the value.  (In RMCA terms, \e RefOut is \c False and \e XorOut is \c 0.)
 | |
| 
 | |
|     \note  Augmented-style CRC runs use straight-up modulo-2 polynomial
 | |
|       division.  Since data is being read byte-wise, a table of pre-computed
 | |
|       remainder changes (as XOR masks) can be used to speed computation.
 | |
|     \note  Reading just a memory block will yield an interim remainder, and not
 | |
|       the final checksum.  To get that checksum, allocate \a Bits / \c CHAR_BIT
 | |
|       bytes directly after the block and fill them with zero values, then extend
 | |
|       \a byte_count to include those extra bytes.  A data block is corrupt if
 | |
|       the return value doesn't equal your separately given checksum.
 | |
|     \note  Another way to perform a check is use the zero-byte extension method,
 | |
|       but replace the zero values with your separately-given checksum.  The
 | |
|       checksum must be loaded in big-endian order.  Here corruption, in either
 | |
|       the data block or the given checksum, is confirmed if the return value is
 | |
|       not zero.
 | |
|     \note  The two checksum techniques assume the CRC-run is performed bit-wise,
 | |
|       while this function works byte-wise.  That means that the techniques can
 | |
|       be used only if \c CHAR_BIT divides \a Bits evenly!
 | |
|  */
 | |
| 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  // = 0u
 | |
| )
 | |
| {
 | |
|     return detail::low_bits_mask_c<Bits>::value &
 | |
|      detail::byte_table_driven_crcs<Bits, TruncPoly, false>::
 | |
|      augmented_crc_update( initial_remainder, static_cast<unsigned char const
 | |
|      *>(buffer), byte_count );
 | |
| }
 | |
| 
 | |
| 
 | |
| }  // namespace boost
 | |
| 
 | |
| 
 | |
| // Undo header-private macros
 | |
| #undef BOOST_CRC_OPTIMAL_NAME
 | |
| #undef BOOST_CRC_PARM_TYPE
 | |
| 
 | |
| 
 | |
| #endif  // BOOST_CRC_HPP
 | |
| 
 |