|
||||
File indexing completed on 2024-11-15 09:34:12
0001 // Boost CRC library crc.hpp header file -----------------------------------// 0002 0003 // Copyright 2001, 2004, 2011 Daryle Walker. 0004 // Distributed under the Boost Software License, Version 1.0. (See the 0005 // accompanying file LICENSE_1_0.txt or a copy at 0006 // <http://www.boost.org/LICENSE_1_0.txt>.) 0007 0008 // See <http://www.boost.org/libs/crc/> for the library's home page. 0009 0010 /** \file 0011 \brief A collection of function templates and class templates that compute 0012 various forms of Cyclic Redundancy Codes (CRCs). 0013 0014 \author Daryle Walker 0015 0016 \version 1.5 0017 0018 \copyright Boost Software License, version 1.0 0019 0020 Contains the declarations (and definitions) of various kinds of CRC 0021 computation functions, function object types, and encapsulated policy types. 0022 0023 \warning The sample CRC-computer types were just checked against the 0024 <a href="http://regregex.bbcmicro.net/crc-catalogue.htm">Catalogue of 0025 parametrised CRC algorithms</a>. New type aliases were added where I got 0026 a standard wrong. However, the mistaken <code>typedef</code>s are still 0027 there for backwards compatibility. 0028 \note There are references to the <i>Rocksoft™ Model CRC 0029 Algorithm</i>, as described within \"A Painless Guide to CRC Error 0030 Detection Algorithms,\" linked from \"<a 0031 href="http://www.ross.net/crc/crcpaper.html">CRC: A Paper On CRCs</a>\" by 0032 Ross Williams. It will be abbreviated \"RMCA\" in other documentation 0033 blocks. 0034 */ 0035 0036 #ifndef BOOST_CRC_HPP 0037 #define BOOST_CRC_HPP 0038 0039 #include <boost/array.hpp> // for boost::array 0040 #include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc. 0041 #include <boost/cstdint.hpp> // for UINTMAX_C, boost::uintmax_t 0042 #include <boost/integer.hpp> // for boost::uint_t 0043 #include <boost/type_traits/conditional.hpp> 0044 #include <boost/type_traits/integral_constant.hpp> 0045 #include <boost/config/pragma_message.hpp> 0046 0047 #include <climits> // for CHAR_BIT, etc. 0048 #include <cstddef> // for std::size_t 0049 0050 #include <boost/limits.hpp> // for std::numeric_limits 0051 0052 #if defined(BOOST_NO_CXX11_HDR_ARRAY) || \ 0053 defined(BOOST_NO_CXX11_NOEXCEPT) // BOOST_NO_CXX11_HDR_TYPE_TRAITS is set for GCC 4.8 0054 0055 BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.CRC 1.84 and will be removed in Boost.CRC 1.86.") 0056 0057 #endif 0058 0059 // The type of CRC parameters that can go in a template should be related 0060 // on the CRC's bit count. This macro expresses that type in a compact 0061 // form, but also allows an alternate type for compilers that don't support 0062 // dependent types (in template value-parameters). 0063 #if !(defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS)) 0064 #define BOOST_CRC_PARM_TYPE typename ::boost::uint_t<Bits>::fast 0065 #else 0066 #define BOOST_CRC_PARM_TYPE unsigned long 0067 #endif 0068 0069 namespace boost 0070 { 0071 0072 0073 // Forward declarations ----------------------------------------------------// 0074 0075 //! Bit-wise CRC computer 0076 template < std::size_t Bits > 0077 class crc_basic; 0078 0079 //! Table-driven CRC computer, usable as a function object 0080 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u, 0081 BOOST_CRC_PARM_TYPE InitRem = 0u, 0082 BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false, 0083 bool ReflectRem = false > 0084 class crc_optimal; 0085 0086 //! Compute the (unaugmented) CRC of a memory block 0087 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 0088 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 0089 bool ReflectIn, bool ReflectRem > 0090 typename uint_t<Bits>::fast crc( void const *buffer, 0091 std::size_t byte_count); 0092 0093 //! Compute the CRC of a memory block, with any augmentation provided by user 0094 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > 0095 typename uint_t<Bits>::fast augmented_crc( void const *buffer, 0096 std::size_t byte_count, 0097 typename uint_t<Bits>::fast initial_remainder = 0u); 0098 0099 //! Computation type for ARC|CRC-16|CRC-IBM|CRC-16/ARC|CRC-16/LHA standard 0100 typedef crc_optimal<16, 0x8005, 0, 0, true, true> crc_16_type; 0101 //! Computation type for CRC-16/CCITT-FALSE standard 0102 typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_false_t; 0103 //! Computation type for the CRC mistakenly called the CCITT standard 0104 typedef crc_ccitt_false_t crc_ccitt_type; 0105 //! Computation type for the actual 0106 //! KERMIT|CRC-16/CCITT|CRC-16/CCITT-TRUE|CRC-CCITT standard 0107 typedef crc_optimal<16, 0x1021, 0, 0, true, true> crc_ccitt_true_t; 0108 //! Computation type that I mistakenly called the XMODEM standard; it inverts 0109 //! both reflection parameters and reflects the truncated divisor (Don't use?!) 0110 typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type; 0111 //! Computation type for the actual XMODEM|ZMODEM|CRC-16/ACORN standard 0112 typedef crc_optimal<16, 0x1021, 0, 0, false, false> crc_xmodem_t; 0113 0114 //! Computation type for CRC-32|CRC-32/ADCCP|PKZIP standard 0115 typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> 0116 crc_32_type; 0117 0118 0119 // Forward declarations for implementation detail stuff --------------------// 0120 // (Just for the stuff that will be needed for the next two sections) 0121 0122 //! \cond 0123 namespace detail 0124 { 0125 //! Mix-in class to add a possibly-reflecting member function 0126 template < int BitLength, bool DoIt, int Id = 0 > 0127 class possible_reflector; 0128 0129 //! Mix-in class for byte-fed, table-driven CRC algorithms 0130 template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect, 0131 int Id = 0 > 0132 class crc_driver; 0133 0134 } // namespace detail 0135 //! \endcond 0136 0137 0138 // Simple cyclic redundancy code (CRC) class declaration -------------------// 0139 0140 /** Objects of this type compute the CRC checksum of submitted data, where said 0141 data can be entered piecemeal through several different kinds of groupings. 0142 Modulo-2 polynomial division steps are always performed bit-wise, without 0143 the use of pre-computation tables. Said division uses the altered 0144 algorithm, so any data has to be unaugmented. 0145 0146 \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits 0147 0148 \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from 0149 the RMCA) 0150 */ 0151 template < std::size_t Bits > 0152 class crc_basic 0153 { 0154 public: 0155 // Type 0156 /** \brief The register type used for computations 0157 0158 This type is used for CRC calculations and is the type for any returned 0159 checksums and returned or submitted remainders, (truncated) divisors, or 0160 XOR masks. It is a built-in unsigned integer type. 0161 */ 0162 typedef typename boost::uint_t<Bits>::fast value_type; 0163 0164 // Constant for the template parameter 0165 //! A copy of \a Bits provided for meta-programming purposes 0166 BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); 0167 0168 // Constructor (use the automatic copy-ctr, move-ctr, and dtr) 0169 //! Create a computer, separately listing each needed parameter 0170 explicit crc_basic( value_type truncated_polynomial, 0171 value_type initial_remainder = 0, value_type final_xor_value = 0, 0172 bool reflect_input = false, bool reflect_remainder = false ); 0173 0174 // Internal Operations 0175 //! Return the (truncated) polynomial divisor 0176 value_type get_truncated_polynominal() const; 0177 //! Return what the polynomial remainder was set to during construction 0178 value_type get_initial_remainder() const; 0179 //! Return the XOR-mask used during output processing 0180 value_type get_final_xor_value() const; 0181 //! Check if input-bytes will be reflected before processing 0182 bool get_reflect_input() const; 0183 //! Check if the remainder will be reflected during output processing 0184 bool get_reflect_remainder() const; 0185 0186 //! Return the remainder based from already-processed bits 0187 value_type get_interim_remainder() const; 0188 //! Change the interim remainder to a new value 0189 void reset( value_type new_rem ); 0190 //! Change the interim remainder back to the initial value 0191 void reset(); 0192 0193 // External Operations 0194 //! Submit a single bit for input processing 0195 void process_bit( bool bit ); 0196 //! Submit the lowest \a bit_length bits of a byte for input processing 0197 void process_bits( unsigned char bits, std::size_t bit_length ); 0198 //! Submit a single byte for input processing 0199 void process_byte( unsigned char byte ); 0200 //! Submit a memory block for input processing, iterator-pair style 0201 void process_block( void const *bytes_begin, void const *bytes_end ); 0202 //! Submit a memory block for input processing, pointer-and-size style 0203 void process_bytes( void const *buffer, std::size_t byte_count ); 0204 0205 //! Return the checksum of the already-processed bits 0206 value_type checksum() const; 0207 0208 private: 0209 // Member data 0210 value_type rem_; 0211 value_type poly_, init_, final_; // non-const to allow assignability 0212 bool rft_in_, rft_out_; // non-const to allow assignability 0213 0214 }; // boost::crc_basic 0215 0216 0217 // Optimized cyclic redundancy code (CRC) class declaration ----------------// 0218 0219 /** Objects of this type compute the CRC checksum of submitted data, where said 0220 data can be entered piecemeal through several different kinds of groupings. 0221 Modulo-2 polynomial division steps are performed byte-wise, aided by the use 0222 of pre-computation tables. Said division uses the altered algorithm, so any 0223 data has to be unaugmented. 0224 0225 \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits 0226 0227 \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from 0228 the RMCA) 0229 \tparam TruncPoly The lowest coefficients of the divisor polynomial. The 0230 highest-order coefficient is omitted and always assumed to be 1. Defaults 0231 to \c 0, i.e. the only non-zero term is the implicit one for 0232 x<sup><var>Bits</var></sup>. (\e Poly from the RMCA) 0233 \tparam InitRem The (unaugmented) initial state of the polynomial 0234 remainder. Defaults to \c 0 if omitted. (\e Init from the RMCA) 0235 \tparam FinalXor The (XOR) bit-mask to be applied to the output remainder, 0236 after possible reflection but before returning. Defaults to \c 0 (i.e. no 0237 bit changes) if omitted. (\e XorOut from the RMCA) 0238 \tparam ReflectIn If \c true, input bytes are read lowest-order bit first, 0239 otherwise highest-order bit first. Defaults to \c false if omitted. 0240 (\e RefIn from the RMCA) 0241 \tparam ReflectRem If \c true, the output remainder is reflected before the 0242 XOR-mask. Defaults to \c false if omitted. (\e RefOut from the RMCA) 0243 0244 \todo Get rid of the default value for \a TruncPoly. Choosing a divisor is 0245 an important decision with many factors, so a default is never useful, 0246 especially a bad one. 0247 */ 0248 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 0249 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 0250 bool ReflectIn, bool ReflectRem > 0251 class crc_optimal 0252 { 0253 public: 0254 // Type 0255 //! \copydoc boost::crc_basic::value_type 0256 typedef typename boost::uint_t<Bits>::fast value_type; 0257 0258 // Constants for the template parameters 0259 //! \copydoc boost::crc_basic::bit_count 0260 BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); 0261 //! A copy of \a TruncPoly provided for meta-programming purposes 0262 BOOST_STATIC_CONSTANT( value_type, truncated_polynominal = TruncPoly ); 0263 //! A copy of \a InitRem provided for meta-programming purposes 0264 BOOST_STATIC_CONSTANT( value_type, initial_remainder = InitRem ); 0265 //! A copy of \a FinalXor provided for meta-programming purposes 0266 BOOST_STATIC_CONSTANT( value_type, final_xor_value = FinalXor ); 0267 //! A copy of \a ReflectIn provided for meta-programming purposes 0268 BOOST_STATIC_CONSTANT( bool, reflect_input = ReflectIn ); 0269 //! A copy of \a ReflectRem provided for meta-programming purposes 0270 BOOST_STATIC_CONSTANT( bool, reflect_remainder = ReflectRem ); 0271 0272 // Constructor (use the automatic copy-ctr, move-ctr, and dtr) 0273 //! Create a computer, giving an initial remainder if desired 0274 explicit crc_optimal( value_type init_rem = initial_remainder ); 0275 0276 // Internal Operations 0277 //! \copybrief boost::crc_basic::get_truncated_polynominal 0278 value_type get_truncated_polynominal() const; 0279 //! \copybrief boost::crc_basic::get_initial_remainder 0280 value_type get_initial_remainder() const; 0281 //! \copybrief boost::crc_basic::get_final_xor_value 0282 value_type get_final_xor_value() const; 0283 //! \copybrief boost::crc_basic::get_reflect_input 0284 bool get_reflect_input() const; 0285 //! \copybrief boost::crc_basic::get_reflect_remainder 0286 bool get_reflect_remainder() const; 0287 0288 //! \copybrief boost::crc_basic::get_interim_remainder 0289 value_type get_interim_remainder() const; 0290 //! Change the interim remainder to either a given value or the initial one 0291 void reset( value_type new_rem = initial_remainder ); 0292 0293 // External Operations 0294 //! \copybrief boost::crc_basic::process_byte 0295 void process_byte( unsigned char byte ); 0296 //! \copybrief boost::crc_basic::process_block 0297 void process_block( void const *bytes_begin, void const *bytes_end ); 0298 //! \copybrief boost::crc_basic::process_bytes 0299 void process_bytes( void const *buffer, std::size_t byte_count ); 0300 0301 //! \copybrief boost::crc_basic::checksum 0302 value_type checksum() const; 0303 0304 // Operators 0305 //! Submit a single byte for input processing, suitable for the STL 0306 void operator ()( unsigned char byte ); 0307 //! Return the checksum of the already-processed bits, suitable for the STL 0308 value_type operator ()() const; 0309 0310 private: 0311 // Implementation types 0312 // (Processing for reflected input gives reflected remainders, so you only 0313 // have to apply output-reflection if Reflect-Remainder doesn't match 0314 // Reflect-Input.) 0315 typedef detail::possible_reflector<Bits, ReflectIn> reflect_i_type; 0316 typedef detail::crc_driver<Bits, TruncPoly, ReflectIn> crc_table_type; 0317 typedef detail::possible_reflector<Bits, ReflectRem != ReflectIn> 0318 reflect_o_type; 0319 0320 // Member data 0321 value_type rem_; 0322 0323 }; // boost::crc_optimal 0324 0325 0326 // Implementation detail stuff ---------------------------------------------// 0327 0328 //! \cond 0329 namespace detail 0330 { 0331 /** \brief Meta-programming integral constant for a single-bit bit-mask 0332 0333 Generates a compile-time constant for a bit-mask that affects a single 0334 bit. The \c value will be 2<sup><var>BitIndex</var></sup>. The \c type 0335 will be the smallest built-in unsigned integer type that can contain the 0336 value, unless there's a built-in type that the system can handle easier, 0337 then the \c type will be smallest fast-handled unsigned integer type. 0338 0339 \pre 0 \<= BitIndex \< \c std\::numeric_limits\<uintmax_t\>\::digits 0340 0341 \tparam BitIndex The place of the sole set bit. 0342 */ 0343 template < int BitIndex > 0344 struct high_bit_mask_c 0345 : boost::integral_constant<typename boost::uint_t< BitIndex + 1 >::fast, 0346 ( UINTMAX_C(1) << BitIndex )> 0347 {}; 0348 0349 /** \brief Meta-programming integral constant for a lowest-bits bit-mask 0350 0351 Generates a compile-time constant for a bit-mask that affects the lowest 0352 bits. The \c value will be 2<sup><var>BitCount</var></sup> - 1. The 0353 \c type will be the smallest built-in unsigned integer type that can 0354 contain the value, unless there's a built-in type that the system can 0355 handle easier, then the \c type will be smallest fast-handled unsigned 0356 integer type. 0357 0358 \pre 0 \<= BitCount \<= \c std\::numeric_limits\<uintmax_t\>\::digits 0359 0360 \tparam BitCount The number of lowest-placed bits set. 0361 */ 0362 template < int BitCount > 0363 struct low_bits_mask_c 0364 : boost::integral_constant<typename boost::uint_t< BitCount >::fast, ( 0365 BitCount ? (( (( UINTMAX_C(1) << (BitCount - 1) ) - 1u) << 1 ) | 0366 UINTMAX_C( 1 )) : 0u )> 0367 {}; 0368 0369 /** \brief Reflects the bits of a number 0370 0371 Reverses the order of the given number of bits within a value. For 0372 instance, if the given reflect count is 5, then the bit values for the 0373 16- and 1-place will switch and the 8- and 2-place will switch, leaving 0374 the other bits alone. (The 4-place bit is in the middle, so it wouldn't 0375 change.) 0376 0377 \pre \a Unsigned is a built-in unsigned integer type 0378 \pre 0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits 0379 0380 \tparam Unsigned The type of \a x. 0381 0382 \param x The value to be (partially) reflected. 0383 \param word_length The number of low-order bits to reflect. Defaults 0384 to the total number of value bits in \a Unsigned. 0385 0386 \return The (partially) reflected value. 0387 0388 \todo Check if this is the fastest way. 0389 */ 0390 template < typename Unsigned > 0391 Unsigned reflect_unsigned( Unsigned x, int word_length 0392 = std::numeric_limits<Unsigned>::digits ) 0393 { 0394 for ( Unsigned l = 1u, h = static_cast<Unsigned>(l << (word_length - 1)) ; h > l ; h >>= 1, l 0395 <<= 1 ) 0396 { 0397 Unsigned const m = h | l, t = x & m; 0398 0399 if ( (t == h) || (t == l) ) 0400 x ^= m; 0401 } 0402 0403 return x; 0404 } 0405 0406 /** \brief Make a byte-to-byte-reflection map 0407 0408 Creates a mapping array so the results can be cached. Uses 0409 #reflect_unsigned to generate the element values. 0410 0411 \return An array <var>a</var> such that, for a given byte value 0412 <var>i</var>, <code><var>a</var>[ <var>i</var> ]</code> resolves to 0413 the reflected value of <var>i</var>. 0414 */ 0415 boost::array< unsigned char, (UINTMAX_C( 1 ) << CHAR_BIT) > 0416 inline make_byte_reflection_table() 0417 { 0418 boost::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> result; 0419 unsigned char i = 0u; 0420 0421 do 0422 result[ i ] = reflect_unsigned( i ); 0423 while ( ++i ); 0424 return result; 0425 } 0426 0427 /** \brief Reflects the bits of a single byte 0428 0429 Reverses the order of all the bits within a value. For instance, the 0430 bit values for the 2<sup><code>CHAR_BIT</code> - 1</sup>- and 1-place 0431 will switch and the 2<sup><code>CHAR_BIT</code> - 2</sup>- and 2-place 0432 will switch, etc. 0433 0434 \param x The byte value to be reflected. 0435 0436 \return The reflected value. 0437 0438 \note Since this could be the most common type of reflection, and the 0439 number of states is relatively small, the implementation pre-computes 0440 and uses a table of all the results. 0441 */ 0442 inline unsigned char reflect_byte( unsigned char x ) 0443 { 0444 static boost::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> const 0445 table = make_byte_reflection_table(); 0446 0447 return table[ x ]; 0448 } 0449 0450 /** \brief Reflects some bits within a single byte 0451 0452 Like #reflect_unsigned, except it takes advantage of any (long-term) 0453 speed gains #reflect_byte may bring. 0454 0455 \pre 0 \< \a word_length \<= \c CHAR_BIT 0456 0457 \param x The value to be (partially) reflected. 0458 \param word_length The number of low-order bits to reflect. 0459 0460 \return The (partially) reflected value. 0461 */ 0462 inline unsigned char reflect_sub_byte( unsigned char x, int word_length ) 0463 { return reflect_byte(x) >> (CHAR_BIT - word_length); } 0464 0465 /** \brief Possibly reflects the bits of a number 0466 0467 Reverses the order of the given number of bits within a value. For 0468 instance, if the given reflect count is 5, then the bit values for the 0469 16- and 1-place will switch and the 8- and 2-place will switch, leaving 0470 the other bits alone. (The 4-place bit is in the middle, so it wouldn't 0471 change.) This variant function allows the reflection be controlled by 0472 an extra parameter, in case the decision to use reflection is made at 0473 run-time. 0474 0475 \pre \a Unsigned is a built-in unsigned integer type 0476 \pre 0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits 0477 0478 \tparam Unsigned The type of \a x. 0479 0480 \param x The value to be (partially) reflected. 0481 \param reflect Controls whether \a x is actually reflected (\c true) or 0482 left alone (\c false). 0483 \param word_length The number of low-order bits to reflect. Defaults 0484 to the total number of value bits in \a Unsigned. 0485 0486 \return The possibly (partially) reflected value. 0487 */ 0488 template < typename Unsigned > 0489 inline 0490 Unsigned reflect_optionally( Unsigned x, bool reflect, int word_length 0491 = std::numeric_limits<Unsigned>::digits ) 0492 { return reflect ? reflect_unsigned(x, word_length) : x; } 0493 0494 /** \brief Possibly reflects the bits of a single byte 0495 0496 Uses #reflect_byte (if \a reflect is \c true). 0497 0498 \param x The byte value to be (possibly) reflected. 0499 \param reflect Whether (\c true) or not (\c false) \a x is reflected. 0500 0501 \return <code><var>reflect</var> ? reflect_byte(<var>x</var>) : 0502 <var>x</var></code> 0503 */ 0504 inline 0505 unsigned char reflect_byte_optionally( unsigned char x, bool reflect ) 0506 { return reflect ? reflect_byte(x) : x; } 0507 0508 /** \brief Update a CRC remainder by several bits, assuming a non-augmented 0509 message 0510 0511 Performs several steps of division required by the CRC algorithm, giving 0512 a new remainder polynomial based on the divisor polynomial and the 0513 synthesized dividend polynomial (from the old remainder and the 0514 newly-provided input). The computations assume that the CRC is directly 0515 exposed from the remainder, without any zero-valued bits augmented to 0516 the message bits. 0517 0518 \pre \a Register and \a Word are both built-in unsigned integer types 0519 \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\> 0520 \::digits 0521 \pre 0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits 0522 0523 \tparam Register The type used for representing the remainder and 0524 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0525 is used as the coefficient of <i>x<sup>i</sup></i>. 0526 \tparam Word The type used for storing the incoming terms of the 0527 dividend modulo-2 polynomial. The bit at <code>2<sup>i</sup></code> 0528 is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is 0529 \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 - 0530 i</sup></i> otherwise. 0531 0532 \param[in] register_length The number of significant low-order bits 0533 to be used from \a Register values. It is the order of the modulo-2 0534 polynomial remainder and one less than the divisor's order. 0535 \param[in,out] remainder The upper part of the dividend polynomial 0536 before division, and the remainder polynomial after. 0537 \param[in] new_dividend_bits The coefficients for the next 0538 \a word_length lowest terms of the dividend polynomial. 0539 \param[in] truncated_divisor The lowest coefficients of the divisor 0540 polynomial. The highest-order coefficient is omitted and always 0541 assumed to be 1. 0542 \param[in] word_length The number of lowest-order bits to read from 0543 \a new_dividend_bits. 0544 \param[in] reflect If \c false, read from the highest-order marked 0545 bit from \a new_dividend_bits and go down, as normal. Otherwise, 0546 proceed from the lowest-order bit and go up. 0547 0548 \note This routine performs a modulo-2 polynomial division variant. 0549 The exclusive-or operations are applied in a different order, since 0550 that kind of operation is commutative and associative. It also 0551 assumes that the zero-valued augment string was applied before this 0552 step, which means that the updated remainder can be directly used as 0553 the final CRC. 0554 */ 0555 template < typename Register, typename Word > 0556 void crc_modulo_word_update( int register_length, Register &remainder, Word 0557 new_dividend_bits, Register truncated_divisor, int word_length, bool 0558 reflect ) 0559 { 0560 // Create this masking constant outside the loop. 0561 Register const high_bit_mask = UINTMAX_C(1) << (register_length - 1); 0562 0563 // The natural reading order for division is highest digit/bit first. 0564 // The "reflect" parameter switches this. However, building a bit mask 0565 // for the lowest bit is the easiest.... 0566 new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect, 0567 word_length ); 0568 0569 // Perform modulo-2 division for each new dividend input bit 0570 for ( int i = word_length ; i ; --i, new_dividend_bits >>= 1 ) 0571 { 0572 // compare the new bit with the remainder's highest 0573 remainder ^= ( new_dividend_bits & 1u ) ? high_bit_mask : 0u; 0574 0575 // perform modulo-2 division 0576 bool const quotient = (remainder & high_bit_mask) != 0; 0577 0578 remainder <<= 1; 0579 remainder ^= quotient ? truncated_divisor : 0u; 0580 0581 // The quotient isn't used for anything, so don't keep it. 0582 } 0583 0584 // Clear overflowed bits 0585 remainder &= std::numeric_limits<Register>::max() >> (std::numeric_limits<Register>::digits - register_length); 0586 } 0587 0588 /** \brief Update a CRC remainder by a single bit, assuming a non-augmented 0589 message 0590 0591 Performs the next step of division required by the CRC algorithm, giving 0592 a new remainder polynomial based on the divisor polynomial and the 0593 synthesized dividend polynomial (from the old remainder and the 0594 newly-provided input). The computations assume that the CRC is directly 0595 exposed from the remainder, without any zero-valued bits augmented to 0596 the message bits. 0597 0598 \pre \a Register is a built-in unsigned integer type 0599 \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\> 0600 \::digits 0601 0602 \tparam Register The type used for representing the remainder and 0603 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0604 is used as the coefficient of <i>x<sup>i</sup></i>. 0605 0606 \param[in] register_length The number of significant low-order bits 0607 to be used from \a Register values. It is the order of the modulo-2 0608 polynomial remainder and one less than the divisor's order. 0609 \param[in,out] remainder The upper part of the dividend polynomial 0610 before division, and the remainder polynomial after. 0611 \param[in] new_dividend_bit The coefficient for the constant term 0612 of the dividend polynomial. 0613 \param[in] truncated_divisor The lowest coefficients of the divisor 0614 polynomial. The highest-order coefficient is omitted and always 0615 assumed to be 1. 0616 0617 \note This routine performs a modulo-2 polynomial division variant. 0618 The exclusive-or operations are applied in a different order, since 0619 that kind of operation is commutative and associative. It also 0620 assumes that the zero-valued augment string was applied before this 0621 step, which means that the updated remainder can be directly used as 0622 the final CRC. 0623 */ 0624 template < typename Register > 0625 inline void crc_modulo_update( int register_length, Register &remainder, 0626 bool new_dividend_bit, Register truncated_divisor ) 0627 { 0628 crc_modulo_word_update( register_length, remainder, 0629 static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false ); 0630 } 0631 0632 /** \brief Update a CRC remainder by several bits, assuming an augmented 0633 message 0634 0635 Performs several steps of division required by the CRC algorithm, giving 0636 a new remainder polynomial based on the divisor polynomial and the 0637 synthesized dividend polynomial (from the old remainder and the 0638 newly-provided input). The computations assume that a zero-valued 0639 string of bits will be appended to the message before extracting the 0640 CRC. 0641 0642 \pre \a Register and \a Word are both built-in unsigned integer types 0643 \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\> 0644 \::digits 0645 \pre 0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits 0646 0647 \tparam Register The type used for representing the remainder and 0648 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0649 is used as the coefficient of <i>x<sup>i</sup></i>. 0650 \tparam Word The type used for storing the incoming terms of the 0651 dividend modulo-2 polynomial. The bit at <code>2<sup>i</sup></code> 0652 is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is 0653 \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 - 0654 i</sup></i> otherwise. 0655 0656 \param[in] register_length The number of significant low-order bits 0657 to be used from \a Register values. It is the order of the modulo-2 0658 polynomial remainder and one less than the divisor's order. 0659 \param[in,out] remainder The upper part of the dividend polynomial 0660 before division, and the remainder polynomial after. 0661 \param[in] new_dividend_bits The coefficients for the next 0662 \a word_length lowest terms of the dividend polynomial. 0663 \param[in] truncated_divisor The lowest coefficients of the divisor 0664 polynomial. The highest-order coefficient is omitted and always 0665 assumed to be 1. 0666 \param[in] word_length The number of lowest-order bits to read from 0667 \a new_dividend_bits. 0668 \param[in] reflect If \c false, read from the highest-order marked 0669 bit from \a new_dividend_bits and go down, as normal. Otherwise, 0670 proceed from the lowest-order bit and go up. 0671 0672 \note This routine performs straight-forward modulo-2 polynomial 0673 division. It assumes that an augment string will be processed at the 0674 end of the message bits before doing CRC analysis. 0675 \todo Use this function somewhere so I can test it. 0676 */ 0677 template < typename Register, typename Word > 0678 void augmented_crc_modulo_word_update( int register_length, Register 0679 &remainder, Word new_dividend_bits, Register truncated_divisor, int 0680 word_length, bool reflect ) 0681 { 0682 // Create this masking constant outside the loop. 0683 Register const high_bit_mask = UINTMAX_C(1) << (register_length - 1); 0684 0685 // The natural reading order for division is highest digit/bit first. 0686 // The "reflect" parameter switches this. However, building a bit mask 0687 // for the lowest bit is the easiest.... 0688 new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect, 0689 word_length ); 0690 0691 // Perform modulo-2 division for each new dividend input bit 0692 for ( int i = word_length ; i ; --i, new_dividend_bits >>= 1 ) 0693 { 0694 bool const quotient = (remainder & high_bit_mask) != 0; 0695 0696 remainder <<= 1; 0697 remainder |= new_dividend_bits & 1u; 0698 remainder ^= quotient ? truncated_divisor : 0u; 0699 0700 // The quotient isn't used for anything, so don't keep it. 0701 } 0702 } 0703 0704 /** \brief Update a CRC remainder by a single bit, assuming an augmented 0705 message 0706 0707 Performs the next step of division required by the CRC algorithm, giving 0708 a new remainder polynomial based on the divisor polynomial and the 0709 synthesized dividend polynomial (from the old remainder and the 0710 newly-provided input). The computations assume that a zero-valued 0711 string of bits will be appended to the message before extracting the 0712 CRC. 0713 0714 \pre \a Register is a built-in unsigned integer type 0715 \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\> 0716 \::digits 0717 0718 \tparam Register The type used for representing the remainder and 0719 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0720 is used as the coefficient of <i>x<sup>i</sup></i>. 0721 0722 \param[in] register_length The number of significant low-order bits 0723 to be used from \a Register values. It is the order of the modulo-2 0724 polynomial remainder and one less than the divisor's order. 0725 \param[in,out] remainder The upper part of the dividend polynomial 0726 before division, and the remainder polynomial after. 0727 \param[in] new_dividend_bit The coefficient for the constant term 0728 of the dividend polynomial. 0729 \param[in] truncated_divisor The lowest coefficients of the divisor 0730 polynomial. The highest-order coefficient is omitted and always 0731 assumed to be 1. 0732 0733 \note This routine performs straight-forward modulo-2 polynomial 0734 division. It assumes that an augment string will be processed at the 0735 end of the message bits before doing CRC analysis. 0736 \todo Use this function somewhere so I can test it. 0737 */ 0738 template < typename Register > 0739 inline void augmented_crc_modulo_update( int register_length, Register 0740 &remainder, bool new_dividend_bit, Register truncated_divisor ) 0741 { 0742 augmented_crc_modulo_word_update( register_length, remainder, 0743 static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false ); 0744 } 0745 0746 /** \brief A mix-in class that returns its argument 0747 0748 This class template makes a function object that returns its argument 0749 as-is. It's one case for #possible_reflector. 0750 0751 \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\> 0752 \::digits 0753 0754 \tparam BitLength How many significant bits arguments have. 0755 */ 0756 template < int BitLength > 0757 class non_reflector 0758 { 0759 public: 0760 /** \brief The type to check for specialization 0761 0762 This is a Boost integral constant indicating that this class 0763 does not reflect its input values. 0764 */ 0765 typedef boost::false_type is_reflecting_type; 0766 /** \brief The type to check for register bit length 0767 0768 This is a Boost integral constant indicating how many 0769 significant bits won't actually be reflected. 0770 */ 0771 typedef boost::integral_constant< int, BitLength > width_c; 0772 /** \brief The type of (not-)reflected values 0773 0774 This type is the input and output type for the (possible-) 0775 reflection function, which does nothing here. 0776 */ 0777 typedef typename boost::uint_t< BitLength >::fast value_type; 0778 0779 /** \brief Does nothing 0780 0781 Returns the given value, not reflecting any part of it. 0782 0783 \param x The value to not be reflected. 0784 0785 \return \a x 0786 */ 0787 inline static value_type reflect_q( value_type x ) 0788 { return x; } 0789 }; 0790 0791 /** \brief A mix-in class that reflects (the lower part of) its argument, 0792 generally for types larger than a byte 0793 0794 This class template makes a function object that returns its argument 0795 after reflecting its lower-order bits. It's one sub-case for 0796 #possible_reflector. 0797 0798 \pre \c CHAR_BIT \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t 0799 \>\::digits 0800 0801 \tparam BitLength How many significant bits arguments have. 0802 */ 0803 template < int BitLength > 0804 class super_byte_reflector 0805 { 0806 public: 0807 /** \brief The type to check for specialization 0808 0809 This is a Boost integral constant indicating that this class 0810 does reflect its input values. 0811 */ 0812 typedef boost::true_type is_reflecting_type; 0813 /** \brief The type to check for register bit length 0814 0815 This is a Boost integral constant indicating how many 0816 significant bits will be reflected. 0817 */ 0818 typedef boost::integral_constant< int, BitLength > width_c; 0819 /** \brief The type of reflected values 0820 0821 This is both the input and output type for the reflection function. 0822 */ 0823 typedef typename boost::uint_t< BitLength >::fast value_type; 0824 0825 /** \brief Reflect (part of) the given value 0826 0827 Reverses the order of the given number of bits within a value, 0828 using #reflect_unsigned. 0829 0830 \param x The value to be (partially) reflected. 0831 0832 \return ( <var>x</var> & 0833 ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT( 0834 <var>x</var> & (2<sup><var>width_c</var>\::value</sup> - 0835 1) ) 0836 */ 0837 inline static value_type reflect_q( value_type x ) 0838 { return reflect_unsigned(x, width_c::value); } 0839 }; 0840 0841 /** \brief A mix-in class that reflects (the lower part of) its argument, 0842 generally for bytes 0843 0844 This class template makes a function object that returns its argument 0845 after reflecting its lower-order bits. It's one sub-case for 0846 #possible_reflector. 0847 0848 \pre 0 \< \a BitLength \<= \c CHAR_BIT 0849 0850 \tparam BitLength How many significant bits arguments have. 0851 */ 0852 template < int BitLength > 0853 class sub_type_reflector 0854 { 0855 public: 0856 /** \brief The type to check for specialization 0857 0858 This is a Boost integral constant indicating that this class 0859 does reflect its input values. 0860 */ 0861 typedef boost::true_type is_reflecting_type; 0862 /** \brief The type to check for register bit length 0863 0864 This is a Boost integral constant indicating how many 0865 significant bits will be reflected. 0866 */ 0867 typedef boost::integral_constant< int, BitLength > width_c; 0868 /** \brief The type of reflected values 0869 0870 This is both the input and output type for the reflection function. 0871 */ 0872 typedef unsigned char value_type; 0873 0874 /** \brief Reflect (part of) the given value 0875 0876 Reverses the order of the given number of bits within a value, 0877 using #reflect_sub_byte. 0878 0879 \param x The value to be (partially) reflected. 0880 0881 \return ( <var>x</var> & 0882 ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT( 0883 <var>x</var> & (2<sup><var>width_c</var>\::value</sup> - 0884 1) ) 0885 */ 0886 inline static value_type reflect_q( value_type x ) 0887 { return reflect_sub_byte(x, width_c::value); } 0888 }; 0889 0890 /** \brief A mix-in class that reflects (the lower part of) its argument 0891 0892 This class template makes a function object that returns its argument 0893 after reflecting its lower-order bits. It's one case for 0894 #possible_reflector. 0895 0896 \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\> 0897 \::digits 0898 0899 \tparam BitLength How many significant bits arguments have. 0900 */ 0901 template < int BitLength > 0902 class reflector 0903 : public boost::conditional< (BitLength > CHAR_BIT), 0904 super_byte_reflector<BitLength>, sub_type_reflector<BitLength> >::type 0905 { }; 0906 0907 /** This class template adds a member function #reflect_q that will 0908 conditionally reflect its first argument, controlled by a compile-time 0909 parameter. 0910 0911 \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\> 0912 \::digits 0913 0914 \tparam BitLength How many significant bits arguments have. 0915 \tparam DoIt \c true if #reflect_q will reflect, \c false if it should 0916 return its argument unchanged. 0917 \tparam Id An extra differentiator if multiple copies of this class 0918 template are mixed-in as base classes. Defaults to 0 if omitted. 0919 */ 0920 template < int BitLength, bool DoIt, int Id > 0921 class possible_reflector 0922 : public boost::conditional< DoIt, reflector<BitLength>, 0923 non_reflector<BitLength> >::type 0924 { 0925 public: 0926 /** \brief The type to check for ID 0927 0928 This is a Boost integral constant indicating what ID number this 0929 instantiation used. 0930 */ 0931 typedef boost::integral_constant<int, Id> id_type; 0932 }; 0933 0934 /** \brief Find the composite remainder update effect from a fixed bit 0935 sequence, for each potential sequence combination. 0936 0937 For each value between 0 and 2<sup><var>SubOrder</var></sup> - 1, 0938 computes the XOR mask corresponding to the composite effect they update 0939 the incoming remainder, which is the upper part of the dividend that 0940 gets (partially) pushed out of its register by the incoming value's 0941 bits. The composite value merges the \"partial products\" from each bit 0942 of the value being updated individually. 0943 0944 \pre \a Register is a built-in unsigned integer type 0945 \pre 0 \< \a SubOrder \<= \a register_length \<= 0946 std\::numeric_limits\<\a Register\>\::digits 0947 0948 \tparam SubOrder The number of low-order significant bits of the trial 0949 new dividends. 0950 \tparam Register The type used for representing the remainder and 0951 divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code> 0952 is used as the coefficient of <i>x<sup>i</sup></i>. 0953 0954 \param[in] register_length The number of significant low-order bits 0955 to be used from \a Register values. It is the order of the modulo-2 0956 polynomial remainder and one less than the divisor's order. 0957 \param[in] truncated_divisor The lowest coefficients of the divisor 0958 polynomial. The highest-order coefficient is omitted and always 0959 assumed to be 1. 0960 \param[in] reflect If \c false, read from the highest-order marked 0961 bit from a new dividend's bits and go down, as normal. Otherwise, 0962 proceed from the lowest-order bit and go up. 0963 0964 \return An array such that the element at index <var>i</var> is the 0965 composite effect XOR mask for value <var>i</var>. 0966 0967 \note This routine performs a modulo-2 polynomial division variant. 0968 The exclusive-or operations are applied in a different order, since 0969 that kind of operation is commutative and associative. It also 0970 assumes that the zero-valued augment string was applied before this 0971 step, which means that the updated remainder can be directly used as 0972 the final CRC. 0973 \todo Check that using the unaugmented-CRC division routines give the 0974 same composite mask table as using augmented-CRC routines. 0975 */ 0976 template < int SubOrder, typename Register > 0977 boost::array< Register, (UINTMAX_C( 1 ) << SubOrder) > 0978 make_partial_xor_products_table( int register_length, Register 0979 truncated_divisor, bool reflect ) 0980 { 0981 boost::array<Register, ( UINTMAX_C(1) << SubOrder )> result = { 0 }; 0982 0983 // Loop over every possible dividend value 0984 for ( typename boost::uint_t<SubOrder + 1>::fast dividend = 0u; 0985 dividend < result.size() ; ++dividend ) 0986 { 0987 Register remainder = 0u; 0988 0989 crc_modulo_word_update( register_length, remainder, dividend, 0990 truncated_divisor, SubOrder, false ); 0991 result[ reflect_optionally(dividend, reflect, SubOrder) ] = 0992 reflect_optionally( remainder, reflect, register_length ); 0993 } 0994 return result; 0995 } 0996 0997 /** \brief A mix-in class for the table of table-driven CRC algorithms 0998 0999 Encapsulates the parameters need to make a global (technically, 1000 class-static) table usuable in CRC algorithms, and generates said 1001 table. 1002 1003 \pre 0 \< \a SubOrder \<= Order \<= 1004 std\::numeric_limits\<uintmax_t\>\::digits 1005 1006 \tparam Order The order of the modulo-2 polynomial remainder and one 1007 less than the divisor's order. 1008 \tparam SubOrder The number of low-order significant bits of the trial 1009 new dividends. 1010 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1011 polynomial. The highest-order coefficient is omitted and always 1012 assumed to be 1. 1013 \tparam Reflect If \c false, read from the highest-order marked 1014 bit from a new dividend's bits and go down, as normal. Otherwise, 1015 proceed from the lowest-order bit and go up. 1016 */ 1017 template < int Order, int SubOrder, boost::uintmax_t TruncatedPolynomial, 1018 bool Reflect > 1019 class crc_table_t 1020 { 1021 public: 1022 /** \brief The type to check for register bit length 1023 1024 This is a Boost integral constant indicating how many 1025 significant bits are in the remainder and (truncated) divisor. 1026 */ 1027 typedef boost::integral_constant< int, Order > width_c; 1028 /** \brief The type to check for index-unit bit length 1029 1030 This is a Boost integral constant indicating how many 1031 significant bits are in the trial new dividends. 1032 */ 1033 typedef boost::integral_constant< int, SubOrder > unit_width_c; 1034 /** \brief The type of registers 1035 1036 This is the output type for the partial-product map. 1037 */ 1038 typedef typename boost::uint_t< Order >::fast value_type; 1039 /** \brief The type to check the divisor 1040 1041 This is a Boost integral constant representing the (truncated) 1042 divisor. 1043 */ 1044 typedef boost::integral_constant< value_type, TruncatedPolynomial > 1045 poly_c; 1046 /** \brief The type to check for reflection 1047 1048 This is a Boost integral constant representing whether input 1049 units should be read in reverse order. 1050 */ 1051 typedef boost::integral_constant< bool, Reflect > refin_c; 1052 /** \brief The type to check for map size 1053 1054 This is a Boost integral constant representing the number of 1055 elements in the partial-product map, based on the unit size. 1056 */ 1057 typedef high_bit_mask_c< SubOrder > table_size_c; 1058 /** \brief The type of the unit TO partial-product map 1059 1060 This is the array type that takes units as the index and said unit's 1061 composite partial-product mask as the element. 1062 */ 1063 typedef boost::array<value_type, table_size_c::value> array_type; 1064 /** \brief Create a global array for the mapping table 1065 1066 Creates an instance of a partial-product array with this class's 1067 parameters. 1068 1069 \return A reference to a immutable array giving the partial-product 1070 update XOR map for each potential sub-unit value. 1071 */ 1072 static array_type const & get_table() 1073 { 1074 static array_type const table = 1075 make_partial_xor_products_table<unit_width_c::value>( 1076 width_c::value, poly_c::value, refin_c::value ); 1077 1078 return table; 1079 } 1080 }; 1081 1082 /** \brief A mix-in class that handles direct (i.e. non-reflected) byte-fed 1083 table-driven CRC algorithms 1084 1085 This class template adds member functions #augmented_crc_update and 1086 #crc_update to update remainders from new input bytes. The bytes aren't 1087 reflected before processing. 1088 1089 \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\> 1090 \::digits 1091 1092 \tparam Order The order of the modulo-2 polynomial remainder and one 1093 less than the divisor's order. 1094 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1095 polynomial. The highest-order coefficient is omitted and always 1096 assumed to be 1. 1097 */ 1098 template < int Order, boost::uintmax_t TruncatedPolynomial > 1099 class direct_byte_table_driven_crcs 1100 : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false> 1101 { 1102 typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false> 1103 base_type; 1104 1105 public: 1106 typedef typename base_type::value_type value_type; 1107 typedef typename base_type::array_type array_type; 1108 1109 /** \brief Compute the updated remainder after reading some bytes 1110 1111 The implementation reads from a table to speed-up applying 1112 augmented-CRC updates byte-wise. 1113 1114 \param remainder The pre-update remainder 1115 \param new_dividend_bytes The address where the new bytes start 1116 \param new_dividend_byte_count The number of new bytes to read 1117 1118 \return The updated remainder 1119 */ 1120 static value_type augmented_crc_update( value_type remainder, unsigned 1121 char const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1122 { 1123 static array_type const & table = base_type::get_table(); 1124 1125 while ( new_dividend_byte_count-- ) 1126 { 1127 // Locates the merged partial product based on the leading byte 1128 unsigned char const index = ( remainder >> (Order - CHAR_BIT) ) 1129 & UCHAR_MAX; 1130 1131 // Complete the multi-bit modulo-2 polynomial division 1132 remainder <<= CHAR_BIT; 1133 remainder |= *new_dividend_bytes++; 1134 remainder ^= table.elems[ index ]; 1135 } 1136 1137 return remainder; 1138 } 1139 1140 /** \brief Compute the updated remainder after reading some bytes 1141 1142 The implementation reads from a table to speed-up applying 1143 unaugmented-CRC updates byte-wise. 1144 1145 \param remainder The pre-update remainder 1146 \param new_dividend_bytes The address where the new bytes start 1147 \param new_dividend_byte_count The number of new bytes to read 1148 1149 \return The updated remainder 1150 */ 1151 static value_type crc_update( value_type remainder, unsigned char 1152 const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1153 { 1154 static array_type const & table = base_type::get_table(); 1155 1156 while ( new_dividend_byte_count-- ) 1157 { 1158 // Locates the merged partial product based on comparing the 1159 // leading and incoming bytes 1160 unsigned char const index = ( (remainder >> ( Order - CHAR_BIT 1161 )) & UCHAR_MAX ) ^ *new_dividend_bytes++; 1162 1163 // Complete the multi-bit altered modulo-2 polynomial division 1164 remainder <<= CHAR_BIT; 1165 remainder ^= table.elems[ index ]; 1166 } 1167 1168 return remainder; 1169 } 1170 }; 1171 1172 /** \brief A mix-in class that handles reflected byte-fed, table-driven CRC 1173 algorithms 1174 1175 This class template adds member functions #augmented_crc_update and 1176 #crc_update to update remainders from new input bytes. The bytes are 1177 reflected before processing. 1178 1179 \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\> 1180 \::digits 1181 1182 \tparam Order The order of the modulo-2 polynomial remainder and one 1183 less than the divisor's order. 1184 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1185 polynomial. The highest-order coefficient is omitted and always 1186 assumed to be 1. 1187 */ 1188 template < int Order, boost::uintmax_t TruncatedPolynomial > 1189 class reflected_byte_table_driven_crcs 1190 : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true> 1191 { 1192 typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true> 1193 base_type; 1194 1195 public: 1196 typedef typename base_type::value_type value_type; 1197 typedef typename base_type::array_type array_type; 1198 1199 /** \brief Compute the updated remainder after reading some bytes 1200 1201 The implementation reads from a table to speed-up applying 1202 reflecting augmented-CRC updates byte-wise. 1203 1204 \param remainder The pre-update remainder; since the bytes are 1205 being reflected, this remainder also has to be reflected 1206 \param new_dividend_bytes The address where the new bytes start 1207 \param new_dividend_byte_count The number of new bytes to read 1208 1209 \return The updated, reflected remainder 1210 */ 1211 static value_type augmented_crc_update( value_type remainder, unsigned 1212 char const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1213 { 1214 static array_type const & table = base_type::get_table(); 1215 1216 while ( new_dividend_byte_count-- ) 1217 { 1218 // Locates the merged partial product based on the leading byte 1219 // (which is at the low-order end for reflected remainders) 1220 unsigned char const index = remainder & UCHAR_MAX; 1221 1222 // Complete the multi-bit reflected modulo-2 polynomial division 1223 remainder >>= CHAR_BIT; 1224 remainder |= static_cast<value_type>( *new_dividend_bytes++ ) 1225 << ( Order - CHAR_BIT ); 1226 remainder ^= table.elems[ index ]; 1227 } 1228 1229 return remainder; 1230 } 1231 1232 /** \brief Compute the updated remainder after reading some bytes 1233 1234 The implementation reads from a table to speed-up applying 1235 reflected unaugmented-CRC updates byte-wise. 1236 1237 \param remainder The pre-update remainder; since the bytes are 1238 being reflected, this remainder also has to be reflected 1239 \param new_dividend_bytes The address where the new bytes start 1240 \param new_dividend_byte_count The number of new bytes to read 1241 1242 \return The updated, reflected remainder 1243 */ 1244 static value_type crc_update( value_type remainder, unsigned char 1245 const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1246 { 1247 static array_type const & table = base_type::get_table(); 1248 1249 while ( new_dividend_byte_count-- ) 1250 { 1251 // Locates the merged partial product based on comparing the 1252 // leading and incoming bytes 1253 unsigned char const index = ( remainder & UCHAR_MAX ) ^ 1254 *new_dividend_bytes++; 1255 1256 // Complete the multi-bit reflected altered modulo-2 polynomial 1257 // division 1258 remainder >>= CHAR_BIT; 1259 remainder ^= table.elems[ index ]; 1260 } 1261 1262 return remainder; 1263 } 1264 }; 1265 1266 /** \brief Mix-in class for byte-fed, table-driven CRC algorithms with 1267 parameter values at least a byte in width 1268 1269 This class template adds member functions #augmented_crc_update and 1270 #crc_update to update remainders from new input bytes. The bytes may be 1271 reflected before processing, controlled by a compile-time parameter. 1272 1273 \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\> 1274 \::digits 1275 1276 \tparam Order The order of the modulo-2 polynomial remainder and one 1277 less than the divisor's order. 1278 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1279 polynomial. The highest-order coefficient is omitted and always 1280 assumed to be 1. 1281 \tparam Reflect If \c false, read from the highest-order bit from a new 1282 input byte and go down, as normal. Otherwise, proceed from the 1283 lowest-order bit and go up. 1284 */ 1285 template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect > 1286 class byte_table_driven_crcs 1287 : public boost::conditional< Reflect, 1288 reflected_byte_table_driven_crcs<Order, TruncatedPolynomial>, 1289 direct_byte_table_driven_crcs<Order, TruncatedPolynomial> >::type 1290 { }; 1291 1292 /** \brief A mix-in class that handles direct (i.e. non-reflected) byte-fed 1293 CRC algorithms for sub-byte parameters 1294 1295 This class template adds member functions #augmented_crc_update and 1296 #crc_update to update remainders from new input bytes. The bytes aren't 1297 reflected before processing. 1298 1299 \pre 0 \< \a Order \< \c CHAR_BIT 1300 1301 \tparam Order The order of the modulo-2 polynomial remainder and one 1302 less than the divisor's order. 1303 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1304 polynomial. The highest-order coefficient is omitted and always 1305 assumed to be 1. 1306 */ 1307 template < int Order, boost::uintmax_t TruncatedPolynomial > 1308 class direct_sub_byte_crcs 1309 : public crc_table_t<Order, Order, TruncatedPolynomial, false> 1310 { 1311 typedef crc_table_t<Order, Order, TruncatedPolynomial, false> 1312 base_type; 1313 1314 public: 1315 typedef typename base_type::width_c width_c; 1316 typedef typename base_type::value_type value_type; 1317 typedef typename base_type::poly_c poly_c; 1318 typedef typename base_type::array_type array_type; 1319 1320 /** \brief Compute the updated remainder after reading some bytes 1321 1322 The implementation reads from a table to speed-up applying 1323 augmented-CRC updates byte-wise. 1324 1325 \param remainder The pre-update remainder 1326 \param new_dividend_bytes The address where the new bytes start 1327 \param new_dividend_byte_count The number of new bytes to read 1328 1329 \return The updated remainder 1330 1331 \todo Use this function somewhere so I can test it. 1332 */ 1333 static value_type augmented_crc_update( value_type remainder, unsigned 1334 char const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1335 { 1336 //static array_type const & table = base_type::get_table(); 1337 1338 while ( new_dividend_byte_count-- ) 1339 { 1340 // Without a table, process each byte explicitly 1341 augmented_crc_modulo_word_update( width_c::value, remainder, 1342 *new_dividend_bytes++, poly_c::value, CHAR_BIT, false ); 1343 } 1344 1345 return remainder; 1346 } 1347 1348 /** \brief Compute the updated remainder after reading some bytes 1349 1350 The implementation reads from a table to speed-up applying 1351 unaugmented-CRC updates byte-wise. 1352 1353 \param remainder The pre-update remainder 1354 \param new_dividend_bytes The address where the new bytes start 1355 \param new_dividend_byte_count The number of new bytes to read 1356 1357 \return The updated remainder 1358 */ 1359 static value_type crc_update( value_type remainder, unsigned char 1360 const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1361 { 1362 //static array_type const & table = base_type::get_table(); 1363 1364 while ( new_dividend_byte_count-- ) 1365 { 1366 // Without a table, process each byte explicitly 1367 crc_modulo_word_update( width_c::value, remainder, 1368 *new_dividend_bytes++, poly_c::value, CHAR_BIT, false ); 1369 } 1370 1371 return remainder; 1372 } 1373 }; 1374 1375 /** \brief A mix-in class that handles reflected byte-fed, CRC algorithms 1376 for sub-byte parameters 1377 1378 This class template adds member functions #augmented_crc_update and 1379 #crc_update to update remainders from new input bytes. The bytes are 1380 reflected before processing. 1381 1382 \pre 0 \< \a Order \< \c CHAR_BIT 1383 1384 \tparam Order The order of the modulo-2 polynomial remainder and one 1385 less than the divisor's order. 1386 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1387 polynomial. The highest-order coefficient is omitted and always 1388 assumed to be 1. 1389 */ 1390 template < int Order, boost::uintmax_t TruncatedPolynomial > 1391 class reflected_sub_byte_crcs 1392 : public crc_table_t<Order, Order, TruncatedPolynomial, true> 1393 { 1394 typedef crc_table_t<Order, Order, TruncatedPolynomial, true> 1395 base_type; 1396 1397 public: 1398 typedef typename base_type::width_c width_c; 1399 typedef typename base_type::value_type value_type; 1400 typedef typename base_type::poly_c poly_c; 1401 typedef typename base_type::array_type array_type; 1402 1403 /** \brief Compute the updated remainder after reading some bytes 1404 1405 The implementation reads from a table to speed-up applying 1406 reflecting augmented-CRC updates byte-wise. 1407 1408 \param remainder The pre-update remainder; since the bytes are 1409 being reflected, this remainder also has to be reflected 1410 \param new_dividend_bytes The address where the new bytes start 1411 \param new_dividend_byte_count The number of new bytes to read 1412 1413 \return The updated, reflected remainder 1414 1415 \todo Use this function somewhere so I can test it. 1416 */ 1417 static value_type augmented_crc_update( value_type remainder, unsigned 1418 char const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1419 { 1420 //static array_type const & table = base_type::get_table(); 1421 1422 remainder = reflect_sub_byte( remainder, width_c::value ); 1423 while ( new_dividend_byte_count-- ) 1424 { 1425 // Without a table, process each byte explicitly 1426 augmented_crc_modulo_word_update( width_c::value, remainder, 1427 *new_dividend_bytes++, poly_c::value, CHAR_BIT, true ); 1428 } 1429 remainder = reflect_sub_byte( remainder, width_c::value ); 1430 1431 return remainder; 1432 } 1433 1434 /** \brief Compute the updated remainder after reading some bytes 1435 1436 The implementation reads from a table to speed-up applying 1437 reflected unaugmented-CRC updates byte-wise. 1438 1439 \param remainder The pre-update remainder; since the bytes are 1440 being reflected, this remainder also has to be reflected 1441 \param new_dividend_bytes The address where the new bytes start 1442 \param new_dividend_byte_count The number of new bytes to read 1443 1444 \return The updated, reflected remainder 1445 */ 1446 static value_type crc_update( value_type remainder, unsigned char 1447 const *new_dividend_bytes, std::size_t new_dividend_byte_count) 1448 { 1449 //static array_type const & table = base_type::get_table(); 1450 1451 remainder = reflect_sub_byte( remainder, width_c::value ); 1452 while ( new_dividend_byte_count-- ) 1453 { 1454 // Without a table, process each byte explicitly 1455 crc_modulo_word_update( width_c::value, remainder, 1456 *new_dividend_bytes++, poly_c::value, CHAR_BIT, true ); 1457 } 1458 remainder = reflect_sub_byte( remainder, width_c::value ); 1459 1460 return remainder; 1461 } 1462 }; 1463 1464 /** \brief Mix-in class for byte-fed, table-driven CRC algorithms with 1465 sub-byte parameters 1466 1467 This class template adds member functions #augmented_crc_update and 1468 #crc_update to update remainders from new input bytes. The bytes may be 1469 reflected before processing, controlled by a compile-time parameter. 1470 1471 \pre 0 \< \a Order \< \c CHAR_BIT 1472 1473 \tparam Order The order of the modulo-2 polynomial remainder and one 1474 less than the divisor's order. 1475 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1476 polynomial. The highest-order coefficient is omitted and always 1477 assumed to be 1. 1478 \tparam Reflect If \c false, read from the highest-order bit from a new 1479 input byte and go down, as normal. Otherwise, proceed from the 1480 lowest-order bit and go up. 1481 */ 1482 template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect > 1483 class sub_byte_crcs 1484 : public boost::conditional< Reflect, 1485 reflected_sub_byte_crcs<Order, TruncatedPolynomial>, 1486 direct_sub_byte_crcs<Order, TruncatedPolynomial> >::type 1487 { }; 1488 1489 /** This class template adds member functions #augmented_crc_update and 1490 #crc_update to update remainders from new input bytes. The bytes may be 1491 reflected before processing, controlled by a compile-time parameter. 1492 1493 \pre 0 \< \a Order \<= \c std\::numeric_limits\<uintmax_t\>\::digits 1494 1495 \tparam Order The order of the modulo-2 polynomial remainder and one 1496 less than the divisor's order. 1497 \tparam TruncatedPolynomial The lowest coefficients of the divisor 1498 polynomial. The highest-order coefficient is omitted and always 1499 assumed to be 1. 1500 \tparam Reflect If \c false, read from the highest-order bit from a new 1501 input byte and go down, as normal. Otherwise, proceed from the 1502 lowest-order bit and go up. 1503 \tparam Id An extra differentiator if multiple copies of this class 1504 template are mixed-in as base classes. Defaults to 0 if omitted. 1505 */ 1506 template < int Order, boost::uintmax_t TruncatedPolynomial, bool Reflect, 1507 int Id > 1508 class crc_driver 1509 : public boost::conditional< (Order < CHAR_BIT), sub_byte_crcs<Order, 1510 TruncatedPolynomial, Reflect>, byte_table_driven_crcs<Order, 1511 TruncatedPolynomial, Reflect> >::type 1512 { 1513 public: 1514 /** \brief The type to check for ID 1515 1516 This is a Boost integral constant indicating what ID number this 1517 instantiation used. 1518 */ 1519 typedef boost::integral_constant<int, Id> id_type; 1520 }; 1521 1522 1523 } // namespace detail 1524 //! \endcond 1525 1526 1527 // Simple CRC class function definitions -----------------------------------// 1528 1529 /** Constructs a \c crc_basic object with at least the required parameters to a 1530 particular CRC formula to be processed upon receiving input. 1531 1532 \param[in] truncated_polynomial The lowest coefficients of the divisor 1533 polynomial. The highest-order coefficient is omitted and always assumed 1534 to be 1. (\e Poly from the RMCA) 1535 \param[in] initial_remainder The (unaugmented) initial state of the 1536 polynomial remainder. Defaults to \c 0 if omitted. (\e Init from the 1537 RMCA) 1538 \param[in] final_xor_value The (XOR) bit-mask to be applied to the output 1539 remainder, after possible reflection but before returning. Defaults to 1540 \c 0 (i.e. no bit changes) if omitted. (\e XorOut from the RMCA) 1541 \param[in] reflect_input If \c true, input bytes are read lowest-order bit 1542 first, otherwise highest-order bit first. Defaults to \c false if 1543 omitted. (\e RefIn from the RMCA) 1544 \param[in] reflect_remainder If \c true, the output remainder is reflected 1545 before the XOR-mask. Defaults to \c false if omitted. (\e RefOut from 1546 the RMCA) 1547 1548 \post <code><var>truncated_polynomial</var> == 1549 this->get_truncated_polynominal()</code> 1550 \post <code><var>initial_remainder</var> == 1551 this->get_initial_remainder()</code> 1552 \post <code><var>final_xor_value</var> == 1553 this->get_final_xor_value()</code> 1554 \post <code><var>reflect_input</var> == 1555 this->get_reflect_input()</code> 1556 \post <code><var>reflect_remainder</var> == 1557 this->get_reflect_remainder()</code> 1558 \post <code><var>initial_remainder</var> == 1559 this->get_interim_remainder()</code> 1560 \post <code>(<var>reflect_remainder</var> ? 1561 REFLECT(<var>initial_remainder</var>) : <var>initial_remainder</var>) ^ 1562 <var>final_xor_value</var> == this->checksum()</code> 1563 */ 1564 template < std::size_t Bits > 1565 inline 1566 crc_basic<Bits>::crc_basic 1567 ( 1568 value_type truncated_polynomial, 1569 value_type initial_remainder, // = 0 1570 value_type final_xor_value, // = 0 1571 bool reflect_input, // = false 1572 bool reflect_remainder // = false 1573 ) 1574 : rem_( initial_remainder ), poly_( truncated_polynomial ) 1575 , init_( initial_remainder ), final_( final_xor_value ) 1576 , rft_in_( reflect_input ), rft_out_( reflect_remainder ) 1577 { 1578 } 1579 1580 /** Returns a representation of the polynomial divisor. The value of the 1581 2<sup>i</sup> bit is the value of the coefficient of the polynomial's 1582 x<sup>i</sup> term. The omitted bit for x<sup>(#bit_count)</sup> term is 1583 always 1. 1584 1585 \return The bit-packed list of coefficients. If the bit-length of 1586 #value_type exceeds #bit_count, the values of higher-placed bits should be 1587 ignored (even any for x<sup>(#bit_count)</sup>) since they're unregulated. 1588 */ 1589 template < std::size_t Bits > 1590 inline 1591 typename crc_basic<Bits>::value_type 1592 crc_basic<Bits>::get_truncated_polynominal 1593 ( 1594 ) const 1595 { 1596 return poly_; 1597 } 1598 1599 /** Returns a representation of the polynomial remainder before any input has 1600 been submitted. The value of the 2<sup>i</sup> bit is the value of the 1601 coefficient of the polynomial's x<sup>i</sup> term. 1602 1603 \return The bit-packed list of coefficients. If the bit-length of 1604 #value_type exceeds #bit_count, the values of higher-placed bits should be 1605 ignored since they're unregulated. 1606 */ 1607 template < std::size_t Bits > 1608 inline 1609 typename crc_basic<Bits>::value_type 1610 crc_basic<Bits>::get_initial_remainder 1611 ( 1612 ) const 1613 { 1614 return init_; 1615 } 1616 1617 /** Returns the mask to be used during creation of a checksum. The mask is used 1618 for an exclusive-or (XOR) operation applied bit-wise to the interim 1619 remainder representation (after any reflection, if #get_reflect_remainder() 1620 returns \c true). 1621 1622 \return The bit-mask. If the bit-length of #value_type exceeds #bit_count, 1623 the values of higher-placed bits should be ignored since they're 1624 unregulated. 1625 */ 1626 template < std::size_t Bits > 1627 inline 1628 typename crc_basic<Bits>::value_type 1629 crc_basic<Bits>::get_final_xor_value 1630 ( 1631 ) const 1632 { 1633 return final_; 1634 } 1635 1636 /** Returns a whether or not a submitted byte will be \"reflected\" before it is 1637 used to update the interim remainder. Only the byte-wise operations 1638 #process_byte, #process_block, and #process_bytes are affected. 1639 1640 \retval true Input bytes will be read starting from the lowest-order bit. 1641 \retval false Input bytes will be read starting from the highest-order bit. 1642 */ 1643 template < std::size_t Bits > 1644 inline 1645 bool 1646 crc_basic<Bits>::get_reflect_input 1647 ( 1648 ) const 1649 { 1650 return rft_in_; 1651 } 1652 1653 /** Indicates if the interim remainder will be \"reflected\" before it is passed 1654 to the XOR-mask stage when returning a checksum. 1655 1656 \retval true The interim remainder is reflected before further work. 1657 \retval false The interim remainder is applied to the XOR-mask as-is. 1658 */ 1659 template < std::size_t Bits > 1660 inline 1661 bool 1662 crc_basic<Bits>::get_reflect_remainder 1663 ( 1664 ) const 1665 { 1666 return rft_out_; 1667 } 1668 1669 /** Returns a representation of the polynomial remainder after all the input 1670 submissions since construction or the last #reset call. The value of the 1671 2<sup>i</sup> bit is the value of the coefficient of the polynomial's 1672 x<sup>i</sup> term. If CRC processing gets interrupted here, retain the 1673 value returned, and use it to start up the next CRC computer where you left 1674 off (with #reset(value_type) or construction). The next computer has to 1675 have its other parameters compatible with this computer. 1676 1677 \return The bit-packed list of coefficients. If the bit-length of 1678 #value_type exceeds #bit_count, the values of higher-placed bits should be 1679 ignored since they're unregulated. No output processing (reflection or 1680 XOR mask) has been applied to the value. 1681 */ 1682 template < std::size_t Bits > 1683 inline 1684 typename crc_basic<Bits>::value_type 1685 crc_basic<Bits>::get_interim_remainder 1686 ( 1687 ) const 1688 { 1689 return rem_ & detail::low_bits_mask_c<bit_count>::value; 1690 } 1691 1692 /** Changes the interim polynomial remainder to \a new_rem, purging any 1693 influence previously submitted input has had. The value of the 1694 2<sup>i</sup> bit is the value of the coefficient of the polynomial's 1695 x<sup>i</sup> term. 1696 1697 \param[in] new_rem The (unaugmented) state of the polynomial remainder 1698 starting from this point, with no output processing applied. 1699 1700 \post <code><var>new_rem</var> == this->get_interim_remainder()</code> 1701 \post <code>((this->get_reflect_remainder() ? 1702 REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^ 1703 this->get_final_xor_value()) == this->checksum()</code> 1704 */ 1705 template < std::size_t Bits > 1706 inline 1707 void 1708 crc_basic<Bits>::reset 1709 ( 1710 value_type new_rem 1711 ) 1712 { 1713 rem_ = new_rem; 1714 } 1715 1716 /** Changes the interim polynomial remainder to the initial remainder given 1717 during construction, purging any influence previously submitted input has 1718 had. The value of the 2<sup>i</sup> bit is the value of the coefficient of 1719 the polynomial's x<sup>i</sup> term. 1720 1721 \post <code>this->get_initial_remainder() == 1722 this->get_interim_remainder()</code> 1723 \post <code>((this->get_reflect_remainder() ? 1724 REFLECT(this->get_initial_remainder()) : 1725 this->get_initial_remainder()) ^ this->get_final_xor_value()) 1726 == this->checksum()</code> 1727 */ 1728 template < std::size_t Bits > 1729 inline 1730 void 1731 crc_basic<Bits>::reset 1732 ( 1733 ) 1734 { 1735 this->reset( this->get_initial_remainder() ); 1736 } 1737 1738 /** Updates the interim remainder with a single altered-CRC-division step. 1739 1740 \param[in] bit The new input bit. 1741 1742 \post The interim remainder is updated though a modulo-2 polynomial 1743 division, where the division steps are altered for unaugmented CRCs. 1744 */ 1745 template < std::size_t Bits > 1746 inline 1747 void 1748 crc_basic<Bits>::process_bit 1749 ( 1750 bool bit 1751 ) 1752 { 1753 detail::crc_modulo_update( bit_count, rem_, bit, poly_ ); 1754 } 1755 1756 /** Updates the interim remainder with several altered-CRC-division steps. Each 1757 bit is processed separately, starting from the one at the 1758 2<sup><var>bit_length</var> - 1</sup> place, then proceeding down to the 1759 lowest-placed bit. Any order imposed by 1760 <code>this->get_reflect_input()</code> is ignored. 1761 1762 \pre 0 \< \a bit_length \<= \c CHAR_BIT 1763 1764 \param[in] bits The byte containing the new input bits. 1765 \param[in] bit_length The number of bits in the byte to be read. 1766 1767 \post The interim remainder is updated though \a bit_length modulo-2 1768 polynomial divisions, where the division steps are altered for unaugmented 1769 CRCs. 1770 */ 1771 template < std::size_t Bits > 1772 void 1773 crc_basic<Bits>::process_bits 1774 ( 1775 unsigned char bits, 1776 std::size_t bit_length 1777 ) 1778 { 1779 // ignore the bits above the ones we want 1780 bits <<= CHAR_BIT - bit_length; 1781 1782 // compute the CRC for each bit, starting with the upper ones 1783 unsigned char const high_bit_mask = 1u << ( CHAR_BIT - 1u ); 1784 for ( std::size_t i = bit_length ; i > 0u ; --i, bits <<= 1u ) 1785 { 1786 process_bit( (bits & high_bit_mask) != 0 ); 1787 } 1788 } 1789 1790 /** Updates the interim remainder with a byte's worth of altered-CRC-division 1791 steps. The bits within the byte are processed from the highest place down 1792 if <code>this->get_reflect_input()</code> is \c false, and lowest place 1793 up otherwise. 1794 1795 \param[in] byte The new input byte. 1796 1797 \post The interim remainder is updated though \c CHAR_BIT modulo-2 1798 polynomial divisions, where the division steps are altered for unaugmented 1799 CRCs. 1800 */ 1801 template < std::size_t Bits > 1802 inline 1803 void 1804 crc_basic<Bits>::process_byte 1805 ( 1806 unsigned char byte 1807 ) 1808 { 1809 process_bits( (rft_in_ ? detail::reflect_byte( byte ) : byte), CHAR_BIT ); 1810 } 1811 1812 /** Updates the interim remainder with several bytes' worth of 1813 altered-CRC-division steps. The bits within each byte are processed from 1814 the highest place down if <code>this->get_reflect_input()</code> is 1815 \c false, and lowest place up otherwise. The bytes themselves are processed 1816 starting from the one pointed by \a bytes_begin until \a bytes_end is 1817 reached through forward iteration, treating the two pointers as if they 1818 point to <code>unsigned char</code> objects. 1819 1820 \pre \a bytes_end has to equal \a bytes_begin if the latter is \c NULL or 1821 otherwise doesn't point to a valid buffer. 1822 \pre \a bytes_end, if not equal to \a bytes_begin, has to point within or 1823 one-byte-past the same buffer \a bytes_begin points into. 1824 \pre \a bytes_end has to be reachable from \a bytes_begin through a finite 1825 number of forward byte-pointer increments. 1826 1827 \param[in] bytes_begin The address where the memory block begins. 1828 \param[in] bytes_end Points to one-byte past the address of the memory 1829 block's last byte, or \a bytes_begin if no bytes are to be read. 1830 1831 \post The interim remainder is updated though <code>CHAR_BIT * (((unsigned 1832 char const *) bytes_end) - ((unsigned char const *) bytes_begin))</code> 1833 modulo-2 polynomial divisions, where the division steps are altered for 1834 unaugmented CRCs. 1835 */ 1836 template < std::size_t Bits > 1837 void 1838 crc_basic<Bits>::process_block 1839 ( 1840 void const * bytes_begin, 1841 void const * bytes_end 1842 ) 1843 { 1844 for ( unsigned char const * p 1845 = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p ) 1846 { 1847 process_byte( *p ); 1848 } 1849 } 1850 1851 /** Updates the interim remainder with several bytes' worth of 1852 altered-CRC-division steps. The bits within each byte are processed from 1853 the highest place down if <code>this->get_reflect_input()</code> is 1854 \c false, and lowest place up otherwise. The bytes themselves are processed 1855 starting from the one pointed by \a buffer, forward-iterated (as if the 1856 pointed-to objects were of <code>unsigned char</code>) until \a byte_count 1857 bytes are read. 1858 1859 \pre \a byte_count has to equal 0 if \a buffer is \c NULL or otherwise 1860 doesn't point to valid memory. 1861 \pre If \a buffer points within valid memory, then that block has to have 1862 at least \a byte_count more valid bytes allocated from that point. 1863 1864 \param[in] buffer The address where the memory block begins. 1865 \param[in] byte_count The number of bytes in the memory block. 1866 1867 \post The interim remainder is updated though <code>CHAR_BIT * 1868 <var>byte_count</var></code> modulo-2 polynomial divisions, where the 1869 division steps are altered for unaugmented CRCs. 1870 */ 1871 template < std::size_t Bits > 1872 inline 1873 void 1874 crc_basic<Bits>::process_bytes 1875 ( 1876 void const * buffer, 1877 std::size_t byte_count 1878 ) 1879 { 1880 unsigned char const * const b = static_cast<unsigned char const *>( 1881 buffer ); 1882 1883 process_block( b, b + byte_count ); 1884 } 1885 1886 /** Computes the checksum of all the submitted bits since construction or the 1887 last call to #reset. The checksum will be the raw checksum, i.e. the 1888 (interim) remainder after all the modulo-2 polynomial division, plus any 1889 output processing. 1890 1891 \return <code>(this->get_reflect_remainder() ? 1892 REFLECT(this->get_interim_remainder()) : 1893 this->get_interim_remainder()) ^ this->get_final_xor_value()</code> 1894 1895 \note Since checksums are meant to be compared, any higher-placed bits 1896 (when the bit-length of #value_type exceeds #bit_count) will be set to 0. 1897 */ 1898 template < std::size_t Bits > 1899 inline 1900 typename crc_basic<Bits>::value_type 1901 crc_basic<Bits>::checksum 1902 ( 1903 ) const 1904 { 1905 return ( (rft_out_ ? detail::reflect_unsigned( rem_, bit_count ) : 1906 rem_) ^ final_ ) & detail::low_bits_mask_c<bit_count>::value; 1907 } 1908 1909 1910 // Optimized CRC class function definitions --------------------------------// 1911 1912 // Macro to compact code 1913 #define BOOST_CRC_OPTIMAL_NAME crc_optimal<Bits, TruncPoly, InitRem, \ 1914 FinalXor, ReflectIn, ReflectRem> 1915 1916 /** Constructs a \c crc_optimal object with a particular CRC formula to be 1917 processed upon receiving input. The initial remainder may be overridden. 1918 1919 \param[in] init_rem The (unaugmented) initial state of the polynomial 1920 remainder. Defaults to #initial_remainder if omitted. 1921 1922 \post <code>#truncated_polynominal == 1923 this->get_truncated_polynominal()</code> 1924 \post <code>#initial_remainder == this->get_initial_remainder()</code> 1925 \post <code>#final_xor_value == this->get_final_xor_value()</code> 1926 \post <code>#reflect_input == this->get_reflect_input()</code> 1927 \post <code>#reflect_remainder == this->get_reflect_remainder()</code> 1928 \post <code><var>init_rem</var> == this->get_interim_remainder()</code> 1929 \post <code>(#reflect_remainder ? REFLECT(<var>init_rem</var>) : 1930 <var>init_rem</var>) ^ #final_xor_value == this->checksum()</code> 1931 */ 1932 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1933 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1934 bool ReflectIn, bool ReflectRem > 1935 inline 1936 BOOST_CRC_OPTIMAL_NAME::crc_optimal 1937 ( 1938 value_type init_rem // = initial_remainder 1939 ) 1940 : rem_( reflect_i_type::reflect_q(init_rem) ) 1941 { 1942 } 1943 1944 //! \copydetails boost::crc_basic::get_truncated_polynominal 1945 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1946 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1947 bool ReflectIn, bool ReflectRem > 1948 inline 1949 typename BOOST_CRC_OPTIMAL_NAME::value_type 1950 BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal 1951 ( 1952 ) const 1953 { 1954 return truncated_polynominal; 1955 } 1956 1957 //! \copydetails boost::crc_basic::get_initial_remainder 1958 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1959 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1960 bool ReflectIn, bool ReflectRem > 1961 inline 1962 typename BOOST_CRC_OPTIMAL_NAME::value_type 1963 BOOST_CRC_OPTIMAL_NAME::get_initial_remainder 1964 ( 1965 ) const 1966 { 1967 return initial_remainder; 1968 } 1969 1970 //! \copydetails boost::crc_basic::get_final_xor_value 1971 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1972 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1973 bool ReflectIn, bool ReflectRem > 1974 inline 1975 typename BOOST_CRC_OPTIMAL_NAME::value_type 1976 BOOST_CRC_OPTIMAL_NAME::get_final_xor_value 1977 ( 1978 ) const 1979 { 1980 return final_xor_value; 1981 } 1982 1983 //! \copydetails boost::crc_basic::get_reflect_input 1984 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1985 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1986 bool ReflectIn, bool ReflectRem > 1987 inline 1988 bool 1989 BOOST_CRC_OPTIMAL_NAME::get_reflect_input 1990 ( 1991 ) const 1992 { 1993 return reflect_input; 1994 } 1995 1996 //! \copydetails boost::crc_basic::get_reflect_remainder 1997 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 1998 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 1999 bool ReflectIn, bool ReflectRem > 2000 inline 2001 bool 2002 BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder 2003 ( 2004 ) const 2005 { 2006 return reflect_remainder; 2007 } 2008 2009 //! \copydetails boost::crc_basic::get_interim_remainder 2010 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2011 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2012 bool ReflectIn, bool ReflectRem > 2013 inline 2014 typename BOOST_CRC_OPTIMAL_NAME::value_type 2015 BOOST_CRC_OPTIMAL_NAME::get_interim_remainder 2016 ( 2017 ) const 2018 { 2019 // Interim remainder should be _un_-reflected, so we have to undo it. 2020 return reflect_i_type::reflect_q( rem_ ) & 2021 detail::low_bits_mask_c<bit_count>::value; 2022 } 2023 2024 /** Changes the interim polynomial remainder to \a new_rem, purging any 2025 influence previously submitted input has had. The value of the 2026 2<sup>i</sup> bit is the value of the coefficient of the polynomial's 2027 x<sup>i</sup> term. 2028 2029 \param[in] new_rem The (unaugmented) state of the polynomial remainder 2030 starting from this point, with no output processing applied. Defaults to 2031 <code>this->get_initial_remainder()</code> if omitted. 2032 2033 \post <code><var>new_rem</var> == this->get_interim_remainder()</code> 2034 \post <code>((this->get_reflect_remainder() ? 2035 REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^ 2036 this->get_final_xor_value()) == this->checksum()</code> 2037 */ 2038 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2039 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2040 bool ReflectIn, bool ReflectRem > 2041 inline 2042 void 2043 BOOST_CRC_OPTIMAL_NAME::reset 2044 ( 2045 value_type new_rem // = initial_remainder 2046 ) 2047 { 2048 rem_ = reflect_i_type::reflect_q( new_rem ); 2049 } 2050 2051 /** \copydetails boost::crc_basic::process_byte 2052 2053 \note Any modulo-2 polynomial divisions may use a table of pre-computed 2054 remainder changes (as XOR masks) to speed computation when reading data 2055 byte-wise. 2056 */ 2057 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2058 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2059 bool ReflectIn, bool ReflectRem > 2060 inline 2061 void 2062 BOOST_CRC_OPTIMAL_NAME::process_byte 2063 ( 2064 unsigned char byte 2065 ) 2066 { 2067 process_bytes( &byte, sizeof(byte) ); 2068 } 2069 2070 /** \copydetails boost::crc_basic::process_block 2071 2072 \note Any modulo-2 polynomial divisions may use a table of pre-computed 2073 remainder changes (as XOR masks) to speed computation when reading data 2074 byte-wise. 2075 */ 2076 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2077 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2078 bool ReflectIn, bool ReflectRem > 2079 inline 2080 void 2081 BOOST_CRC_OPTIMAL_NAME::process_block 2082 ( 2083 void const * bytes_begin, 2084 void const * bytes_end 2085 ) 2086 { 2087 process_bytes( bytes_begin, static_cast<unsigned char const *>(bytes_end) - 2088 static_cast<unsigned char const *>(bytes_begin) ); 2089 } 2090 2091 /** \copydetails boost::crc_basic::process_bytes 2092 2093 \note Any modulo-2 polynomial divisions may use a table of pre-computed 2094 remainder changes (as XOR masks) to speed computation when reading data 2095 byte-wise. 2096 */ 2097 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2098 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2099 bool ReflectIn, bool ReflectRem > 2100 inline 2101 void 2102 BOOST_CRC_OPTIMAL_NAME::process_bytes 2103 ( 2104 void const * buffer, 2105 std::size_t byte_count 2106 ) 2107 { 2108 rem_ = crc_table_type::crc_update( rem_, static_cast<unsigned char const 2109 *>(buffer), byte_count ); 2110 } 2111 2112 //! \copydetails boost::crc_basic::checksum 2113 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2114 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2115 bool ReflectIn, bool ReflectRem > 2116 inline 2117 typename BOOST_CRC_OPTIMAL_NAME::value_type 2118 BOOST_CRC_OPTIMAL_NAME::checksum 2119 ( 2120 ) const 2121 { 2122 return ( reflect_o_type::reflect_q(rem_) ^ get_final_xor_value() ) 2123 & detail::low_bits_mask_c<bit_count>::value; 2124 } 2125 2126 /** Updates the interim remainder with a byte's worth of altered-CRC-division 2127 steps. The bits within the byte are processed from the highest place down 2128 if <code>this->get_reflect_input()</code> is \c false, and lowest place 2129 up otherwise. This function is meant to present a function-object interface 2130 to code that wants to process a stream of bytes with 2131 <code>std::for_each</code> or similar range-processing algorithms. Since 2132 some of these algorithms takes their function object by value, make sure to 2133 copy back the result to this object so the updates can be remembered. 2134 2135 \param[in] byte The new input byte. 2136 2137 \post The interim remainder is updated though \c CHAR_BIT modulo-2 2138 polynomial divisions, where the division steps are altered for unaugmented 2139 CRCs. 2140 2141 \note Any modulo-2 polynomial divisions may use a table of pre-computed 2142 remainder changes (as XOR masks) to speed computation when reading data 2143 byte-wise. 2144 */ 2145 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2146 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2147 bool ReflectIn, bool ReflectRem > 2148 inline 2149 void 2150 BOOST_CRC_OPTIMAL_NAME::operator () 2151 ( 2152 unsigned char byte 2153 ) 2154 { 2155 process_byte( byte ); 2156 } 2157 2158 /** Computes the checksum of all the submitted bits since construction or the 2159 last call to #reset. The checksum will be the raw checksum, i.e. the 2160 (interim) remainder after all the modulo-2 polynomial division, plus any 2161 output processing. This function is meant to present a function-object 2162 interface to code that wants to receive data like 2163 <code>std::generate_n</code> or similar data-processing algorithms. Note 2164 that if this object is used as a generator multiple times without an 2165 intervening mutating operation, the same value will always be returned. 2166 2167 \return <code>(this->get_reflect_remainder() ? 2168 REFLECT(this->get_interim_remainder()) : 2169 this->get_interim_remainder()) ^ this->get_final_xor_value()</code> 2170 2171 \note Since checksums are meant to be compared, any higher-placed bits 2172 (when the bit-length of #value_type exceeds #bit_count) will be set to 0. 2173 */ 2174 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2175 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2176 bool ReflectIn, bool ReflectRem > 2177 inline 2178 typename BOOST_CRC_OPTIMAL_NAME::value_type 2179 BOOST_CRC_OPTIMAL_NAME::operator () 2180 ( 2181 ) const 2182 { 2183 return checksum(); 2184 } 2185 2186 2187 // CRC computation function definition -------------------------------------// 2188 2189 /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and 2190 \a byte_count describe a memory block representing the polynomial dividend. 2191 The division steps are altered so the result directly gives a checksum, 2192 without need to augment the memory block with scratch-space bytes. The 2193 first byte is considered the highest order, going down for subsequent bytes. 2194 2195 \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits 2196 2197 \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from 2198 the RMCA) 2199 \tparam TruncPoly The lowest coefficients of the divisor polynomial. The 2200 highest-order coefficient is omitted and always assumed to be 1. 2201 (\e Poly from the RMCA) 2202 \tparam InitRem The (unaugmented) initial state of the polynomial 2203 remainder. (\e Init from the RMCA) 2204 \tparam FinalXor The (XOR) bit-mask to be applied to the output remainder, 2205 after possible reflection but before returning. (\e XorOut from the RMCA) 2206 \tparam ReflectIn If \c True, input bytes are read lowest-order bit first, 2207 otherwise highest-order bit first. (\e RefIn from the RMCA) 2208 \tparam ReflectRem If \c True, the output remainder is reflected before the 2209 XOR-mask. (\e RefOut from the RMCA) 2210 2211 \param[in] buffer The address where the memory block begins. 2212 \param[in] byte_count The number of bytes in the memory block. 2213 2214 \return The checksum, which is the last (interim) remainder plus any output 2215 processing. 2216 2217 \note Unaugmented-style CRC runs perform modulo-2 polynomial division in 2218 an altered order. The trailing \a Bits number of zero-valued bits needed 2219 to extracted an (unprocessed) checksum is virtually moved to near the 2220 beginning of the message. This is OK since the XOR operation is 2221 commutative and associative. It also means that you can get a checksum 2222 anytime. Since data is being read byte-wise, a table of pre-computed 2223 remainder changes (as XOR masks) can be used to speed computation. 2224 2225 */ 2226 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, 2227 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor, 2228 bool ReflectIn, bool ReflectRem > 2229 inline 2230 typename uint_t<Bits>::fast 2231 crc 2232 ( 2233 void const * buffer, 2234 std::size_t byte_count 2235 ) 2236 { 2237 BOOST_CRC_OPTIMAL_NAME computer; 2238 computer.process_bytes( buffer, byte_count ); 2239 return computer.checksum(); 2240 } 2241 2242 2243 // Augmented-message CRC computation function definition -------------------// 2244 2245 /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and 2246 \a byte_count describe a memory block representing the polynomial dividend. 2247 The first byte is considered the highest order, going down for subsequent 2248 bytes. Within a byte, the highest-order bit is read first (corresponding to 2249 \e RefIn = \c False in the RMCA). Check the other parts of this function's 2250 documentation to see how a checksum can be gained and/or used. 2251 2252 \pre 0 \< \a Bits \<= \c std\::numeric_limit\<uintmax_t\>\::digits 2253 2254 \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from 2255 the RMCA) 2256 \tparam TruncPoly The lowest coefficients of the divisor polynomial. The 2257 highest-order coefficient is omitted and always assumed to be 1. 2258 (\e Poly from the RMCA) 2259 2260 \param[in] buffer The address where the memory block begins. 2261 \param[in] byte_count The number of bytes in the memory block. 2262 \param[in] initial_remainder The initial state of the polynomial 2263 remainder, defaulting to zero if omitted. If you are reading a memory 2264 block in multiple runs, put the return value of the previous run here. 2265 (Note that initial-remainders given by RMCA parameter lists, as 2266 \e Init, assume that the initial remainder is in its \b unaugmented state, 2267 so you would need to convert the value to make it suitable for this 2268 function. I currently don't provide a conversion routine.) 2269 2270 \return The interim remainder, if no augmentation is used. A special value 2271 if augmentation is used (see the notes). No output processing is done on 2272 the value. (In RMCA terms, \e RefOut is \c False and \e XorOut is \c 0.) 2273 2274 \note Augmented-style CRC runs use straight-up modulo-2 polynomial 2275 division. Since data is being read byte-wise, a table of pre-computed 2276 remainder changes (as XOR masks) can be used to speed computation. 2277 \note Reading just a memory block will yield an interim remainder, and not 2278 the final checksum. To get that checksum, allocate \a Bits / \c CHAR_BIT 2279 bytes directly after the block and fill them with zero values, then extend 2280 \a byte_count to include those extra bytes. A data block is corrupt if 2281 the return value doesn't equal your separately given checksum. 2282 \note Another way to perform a check is use the zero-byte extension method, 2283 but replace the zero values with your separately-given checksum. The 2284 checksum must be loaded in big-endian order. Here corruption, in either 2285 the data block or the given checksum, is confirmed if the return value is 2286 not zero. 2287 \note The two checksum techniques assume the CRC-run is performed bit-wise, 2288 while this function works byte-wise. That means that the techniques can 2289 be used only if \c CHAR_BIT divides \a Bits evenly! 2290 */ 2291 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly > 2292 typename uint_t<Bits>::fast 2293 augmented_crc 2294 ( 2295 void const * buffer, 2296 std::size_t byte_count, 2297 typename uint_t<Bits>::fast initial_remainder // = 0u 2298 ) 2299 { 2300 return detail::low_bits_mask_c<Bits>::value & 2301 detail::byte_table_driven_crcs<Bits, TruncPoly, false>:: 2302 augmented_crc_update( initial_remainder, static_cast<unsigned char const 2303 *>(buffer), byte_count ); 2304 } 2305 2306 2307 } // namespace boost 2308 2309 2310 // Undo header-private macros 2311 #undef BOOST_CRC_OPTIMAL_NAME 2312 #undef BOOST_CRC_PARM_TYPE 2313 2314 2315 #endif // BOOST_CRC_HPP 2316
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |