1 // Boost CRC library crc.hpp header file -----------------------------------//
3 // (C) Copyright Daryle Walker 2001. Permission to copy, use, modify, sell and
4 // distribute this software is granted provided this copyright notice appears
5 // in all copies. This software is provided "as is" without express or
6 // implied warranty, and with no claim as to its suitability for any purpose.
8 // See http://www.boost.org for updates, documentation, and revision history.
13 #include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc.
14 #include <boost/integer.hpp> // for boost::uint_t
16 #include <climits> // for CHAR_BIT, etc.
17 #include <cstddef> // for std::size_t
19 #include <boost/limits.hpp> // for std::numeric_limits
22 // The type of CRC parameters that can go in a template should be related
23 // on the CRC's bit count. This macro expresses that type in a compact
24 // form, but also allows an alternate type for compilers that don't support
25 // dependent types (in template value-parameters).
26 #ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
27 #define BOOST_CRC_PARM_TYPE typename ::boost::uint_t<Bits>::fast
29 #define BOOST_CRC_PARM_TYPE unsigned long
32 // Some compilers [MS VC++ 6] cannot correctly set up several versions of a
33 // function template unless every template argument can be unambiguously
34 // deduced from the function arguments. (The bug is hidden if only one version
35 // is needed.) Since all of the CRC function templates have this problem, the
36 // workaround is to make up a dummy function argument that encodes the template
37 // arguments. Calls to such template functions need all their template
38 // arguments explicitly specified. At least one compiler that needs this
39 // workaround also needs the default value for the dummy argument to be
40 // specified in the definition.
41 #ifndef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
42 #define BOOST_CRC_DUMMY_PARM_TYPE
43 #define BOOST_CRC_DUMMY_INIT
44 #define BOOST_ACRC_DUMMY_PARM_TYPE
45 #define BOOST_ACRC_DUMMY_INIT
47 namespace boost { namespace detail {
48 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
49 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
50 bool ReflectIn, bool ReflectRem >
51 struct dummy_crc_argument { };
53 #define BOOST_CRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument<Bits, \
54 TruncPoly, InitRem, FinalXor, ReflectIn, ReflectRem> *p_
55 #define BOOST_CRC_DUMMY_INIT BOOST_CRC_DUMMY_PARM_TYPE = 0
56 #define BOOST_ACRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument<Bits, \
57 TruncPoly, 0, 0, false, false> *p_
58 #define BOOST_ACRC_DUMMY_INIT BOOST_ACRC_DUMMY_PARM_TYPE = 0
66 // Forward declarations ----------------------------------------------------//
68 template < std::size_t Bits >
71 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u,
72 BOOST_CRC_PARM_TYPE InitRem = 0u,
73 BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false,
74 bool ReflectRem = false >
77 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
78 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
79 bool ReflectIn, bool ReflectRem >
80 typename uint_t<Bits>::fast crc( void const *buffer,
81 std::size_t byte_count
82 BOOST_CRC_DUMMY_PARM_TYPE );
84 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
85 typename uint_t<Bits>::fast augmented_crc( void const *buffer,
86 std::size_t byte_count, typename uint_t<Bits>::fast initial_remainder
87 BOOST_ACRC_DUMMY_PARM_TYPE );
89 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
90 typename uint_t<Bits>::fast augmented_crc( void const *buffer,
91 std::size_t byte_count
92 BOOST_ACRC_DUMMY_PARM_TYPE );
94 typedef crc_optimal<16, 0x8005, 0, 0, true, true> crc_16_type;
95 typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_type;
96 typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type;
98 typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>
102 // Forward declarations for implementation detail stuff --------------------//
103 // (Just for the stuff that will be needed for the next two sections)
107 template < std::size_t Bits >
111 struct mask_uint_t< std::numeric_limits<unsigned char>::digits >;
113 #if USHRT_MAX > UCHAR_MAX
115 struct mask_uint_t< std::numeric_limits<unsigned short>::digits >;
118 #if UINT_MAX > USHRT_MAX
120 struct mask_uint_t< std::numeric_limits<unsigned int>::digits >;
123 #if ULONG_MAX > UINT_MAX
125 struct mask_uint_t< std::numeric_limits<unsigned long>::digits >;
128 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
131 template < std::size_t Bits, bool DoReflect >
134 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
135 template < std::size_t Bits >
136 class crc_helper< Bits, false >;
139 } // namespace detail
142 // Simple cyclic redundancy code (CRC) class declaration -------------------//
144 template < std::size_t Bits >
147 // Implementation type
148 typedef detail::mask_uint_t<Bits> masking_type;
152 typedef typename masking_type::least value_type;
154 // Constant for the template parameter
155 BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
158 explicit crc_basic( value_type truncated_polynominal,
159 value_type initial_remainder = 0, value_type final_xor_value = 0,
160 bool reflect_input = false, bool reflect_remainder = false );
162 // Internal Operations
163 value_type get_truncated_polynominal() const;
164 value_type get_initial_remainder() const;
165 value_type get_final_xor_value() const;
166 bool get_reflect_input() const;
167 bool get_reflect_remainder() const;
169 value_type get_interim_remainder() const;
170 void reset( value_type new_rem );
173 // External Operations
174 void process_bit( bool bit );
175 void process_bits( unsigned char bits, std::size_t bit_count );
176 void process_byte( unsigned char byte );
177 void process_block( void const *bytes_begin, void const *bytes_end );
178 void process_bytes( void const *buffer, std::size_t byte_count );
180 value_type checksum() const;
185 value_type poly_, init_, final_; // non-const to allow assignability
186 bool rft_in_, rft_out_; // non-const to allow assignability
188 }; // boost::crc_basic
191 // Optimized cyclic redundancy code (CRC) class declaration ----------------//
193 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
194 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
195 bool ReflectIn, bool ReflectRem >
198 // Implementation type
199 typedef detail::mask_uint_t<Bits> masking_type;
203 typedef typename masking_type::fast value_type;
205 // Constants for the template parameters
206 BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
207 BOOST_STATIC_CONSTANT( value_type, truncated_polynominal = TruncPoly );
208 BOOST_STATIC_CONSTANT( value_type, initial_remainder = InitRem );
209 BOOST_STATIC_CONSTANT( value_type, final_xor_value = FinalXor );
210 BOOST_STATIC_CONSTANT( bool, reflect_input = ReflectIn );
211 BOOST_STATIC_CONSTANT( bool, reflect_remainder = ReflectRem );
214 explicit crc_optimal( value_type init_rem = InitRem );
216 // Internal Operations
217 value_type get_truncated_polynominal() const;
218 value_type get_initial_remainder() const;
219 value_type get_final_xor_value() const;
220 bool get_reflect_input() const;
221 bool get_reflect_remainder() const;
223 value_type get_interim_remainder() const;
224 void reset( value_type new_rem = InitRem );
226 // External Operations
227 void process_byte( unsigned char byte );
228 void process_block( void const *bytes_begin, void const *bytes_end );
229 void process_bytes( void const *buffer, std::size_t byte_count );
231 value_type checksum() const;
234 void operator ()( unsigned char byte );
235 value_type operator ()() const;
238 // The implementation of output reflection depends on both reflect states.
239 BOOST_STATIC_CONSTANT( bool, reflect_output = (ReflectRem != ReflectIn) );
242 #define BOOST_CRC_REF_OUT_VAL reflect_output
244 typedef crc_optimal self_type;
245 #define BOOST_CRC_REF_OUT_VAL (self_type::reflect_output)
248 // More implementation types
249 typedef detail::crc_table_t<Bits, TruncPoly, ReflectIn> crc_table_type;
250 typedef detail::crc_helper<Bits, ReflectIn> helper_type;
251 typedef detail::crc_helper<Bits, BOOST_CRC_REF_OUT_VAL> reflect_out_type;
253 #undef BOOST_CRC_REF_OUT_VAL
258 }; // boost::crc_optimal
261 // Implementation detail stuff ---------------------------------------------//
265 // Forward declarations for more implementation details
266 template < std::size_t Bits >
269 template < std::size_t Bits >
273 // Traits class for mask; given the bit number
274 // (1-based), get the mask for that bit by itself.
275 template < std::size_t Bits >
277 : boost::uint_t< Bits >
279 typedef boost::uint_t<Bits> base_type;
280 typedef typename base_type::least least;
281 typedef typename base_type::fast fast;
284 static const least high_bit = 1ul << (Bits - 1u);
285 static const fast high_bit_fast = 1ul << (Bits - 1u);
287 BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << ( Bits
289 BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << ( Bits
293 }; // boost::detail::high_uint_t
296 // Reflection routine class wrapper
297 // (since MS VC++ 6 couldn't handle the unwrapped version)
298 template < std::size_t Bits >
301 typedef typename boost::uint_t<Bits>::fast value_type;
303 static value_type reflect( value_type x );
305 }; // boost::detail::reflector
307 // Function that reflects its argument
308 template < std::size_t Bits >
309 typename reflector<Bits>::value_type
310 reflector<Bits>::reflect
312 typename reflector<Bits>::value_type x
315 value_type reflection = 0;
316 value_type const one = 1;
318 for ( std::size_t i = 0 ; i < Bits ; ++i, x >>= 1 )
322 reflection |= ( one << (Bits - 1u - i) );
330 // Traits class for masks; given the bit number (1-based),
331 // get the mask for that bit and its lower bits.
332 template < std::size_t Bits >
334 : high_uint_t< Bits >
336 typedef high_uint_t<Bits> base_type;
337 typedef typename base_type::least least;
338 typedef typename base_type::fast fast;
341 using base_type::high_bit;
342 using base_type::high_bit_fast;
344 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
345 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
349 static const least sig_bits = (~( ~(0ul) << Bits));
351 BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) );
353 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
355 }; // boost::detail::mask_uint_t
358 struct mask_uint_t< std::numeric_limits<unsigned char>::digits >
359 : high_uint_t< std::numeric_limits<unsigned char>::digits >
361 typedef high_uint_t<std::numeric_limits<unsigned char>::digits>
363 typedef base_type::least least;
364 typedef base_type::fast fast;
367 using base_type::high_bit;
368 using base_type::high_bit_fast;
370 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
371 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
374 BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
375 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
377 }; // boost::detail::mask_uint_t
379 #if USHRT_MAX > UCHAR_MAX
381 struct mask_uint_t< std::numeric_limits<unsigned short>::digits >
382 : high_uint_t< std::numeric_limits<unsigned short>::digits >
384 typedef high_uint_t<std::numeric_limits<unsigned short>::digits>
386 typedef base_type::least least;
387 typedef base_type::fast fast;
390 using base_type::high_bit;
391 using base_type::high_bit_fast;
393 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
394 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
397 BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
398 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
400 }; // boost::detail::mask_uint_t
403 #if UINT_MAX > USHRT_MAX
405 struct mask_uint_t< std::numeric_limits<unsigned int>::digits >
406 : high_uint_t< std::numeric_limits<unsigned int>::digits >
408 typedef high_uint_t<std::numeric_limits<unsigned int>::digits>
410 typedef base_type::least least;
411 typedef base_type::fast fast;
414 using base_type::high_bit;
415 using base_type::high_bit_fast;
417 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
418 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
421 BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
422 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
424 }; // boost::detail::mask_uint_t
427 #if ULONG_MAX > UINT_MAX
429 struct mask_uint_t< std::numeric_limits<unsigned long>::digits >
430 : high_uint_t< std::numeric_limits<unsigned long>::digits >
432 typedef high_uint_t<std::numeric_limits<unsigned long>::digits>
434 typedef base_type::least least;
435 typedef base_type::fast fast;
438 using base_type::high_bit;
439 using base_type::high_bit_fast;
441 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
442 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
445 BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
446 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
448 }; // boost::detail::mask_uint_t
452 // CRC table generator
453 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
456 BOOST_STATIC_CONSTANT( std::size_t, byte_combos = (1ul << CHAR_BIT) );
458 typedef mask_uint_t<Bits> masking_type;
459 typedef typename masking_type::fast value_type;
460 typedef value_type table_type[ byte_combos ];
462 static void init_table();
464 static table_type table_;
466 }; // boost::detail::crc_table_t
468 // CRC table generator static data member definition
469 // (Some compilers [Borland C++] require the initializer to be present.)
470 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
471 typename crc_table_t<Bits, TruncPoly, Reflect>::table_type
472 crc_table_t<Bits, TruncPoly, Reflect>::table_
475 // Populate CRC lookup table
476 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
478 crc_table_t<Bits, TruncPoly, Reflect>::init_table
482 // compute table only on the first run
483 static bool did_init = false;
484 if ( did_init ) return;
486 // factor-out constants to avoid recalculation
487 value_type const fast_hi_bit = masking_type::high_bit_fast;
488 unsigned char const byte_hi_bit = 1u << (CHAR_BIT - 1u);
490 // loop over every possible dividend value
491 unsigned char dividend = 0;
494 value_type remainder = 0;
496 // go through all the dividend's bits
497 for ( unsigned char mask = byte_hi_bit ; mask ; mask >>= 1 )
499 // check if divisor fits
500 if ( dividend & mask )
502 remainder ^= fast_hi_bit;
505 // do polynominal division
506 if ( remainder & fast_hi_bit )
509 remainder ^= TruncPoly;
517 table_[ crc_helper<CHAR_BIT, Reflect>::reflect(dividend) ]
518 = crc_helper<Bits, Reflect>::reflect( remainder );
520 while ( ++dividend );
526 // CRC helper routines
527 template < std::size_t Bits, bool DoReflect >
532 typedef typename uint_t<Bits>::fast value_type;
534 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
535 // Possibly reflect a remainder
536 static value_type reflect( value_type x )
537 { return detail::reflector<Bits>::reflect( x ); }
539 // Compare a byte to the remainder's highest byte
540 static unsigned char index( value_type rem, unsigned char x )
543 // Shift out the remainder's highest byte
544 static value_type shift( value_type rem )
545 { return rem >> CHAR_BIT; }
547 // Possibly reflect a remainder
548 static value_type reflect( value_type x )
549 { return DoReflect ? detail::reflector<Bits>::reflect( x ) : x; }
551 // Compare a byte to the remainder's highest byte
552 static unsigned char index( value_type rem, unsigned char x )
553 { return x ^ ( rem >> (DoReflect ? 0u : Bits - CHAR_BIT) ); }
555 // Shift out the remainder's highest byte
556 static value_type shift( value_type rem )
557 { return DoReflect ? rem >> CHAR_BIT : rem << CHAR_BIT; }
560 }; // boost::detail::crc_helper
562 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
563 template < std::size_t Bits >
564 class crc_helper<Bits, false>
568 typedef typename uint_t<Bits>::fast value_type;
570 // Possibly reflect a remainder
571 static value_type reflect( value_type x )
574 // Compare a byte to the remainder's highest byte
575 static unsigned char index( value_type rem, unsigned char x )
576 { return x ^ ( rem >> (Bits - CHAR_BIT) ); }
578 // Shift out the remainder's highest byte
579 static value_type shift( value_type rem )
580 { return rem << CHAR_BIT; }
582 }; // boost::detail::crc_helper
586 } // namespace detail
589 // Simple CRC class function definitions -----------------------------------//
591 template < std::size_t Bits >
593 crc_basic<Bits>::crc_basic
595 typename crc_basic<Bits>::value_type truncated_polynominal,
596 typename crc_basic<Bits>::value_type initial_remainder, // = 0
597 typename crc_basic<Bits>::value_type final_xor_value, // = 0
598 bool reflect_input, // = false
599 bool reflect_remainder // = false
601 : rem_( initial_remainder ), poly_( truncated_polynominal )
602 , init_( initial_remainder ), final_( final_xor_value )
603 , rft_in_( reflect_input ), rft_out_( reflect_remainder )
607 template < std::size_t Bits >
609 typename crc_basic<Bits>::value_type
610 crc_basic<Bits>::get_truncated_polynominal
617 template < std::size_t Bits >
619 typename crc_basic<Bits>::value_type
620 crc_basic<Bits>::get_initial_remainder
627 template < std::size_t Bits >
629 typename crc_basic<Bits>::value_type
630 crc_basic<Bits>::get_final_xor_value
637 template < std::size_t Bits >
640 crc_basic<Bits>::get_reflect_input
647 template < std::size_t Bits >
650 crc_basic<Bits>::get_reflect_remainder
657 template < std::size_t Bits >
659 typename crc_basic<Bits>::value_type
660 crc_basic<Bits>::get_interim_remainder
664 return rem_ & masking_type::sig_bits;
667 template < std::size_t Bits >
670 crc_basic<Bits>::reset
672 typename crc_basic<Bits>::value_type new_rem
678 template < std::size_t Bits >
681 crc_basic<Bits>::reset
685 this->reset( this->get_initial_remainder() );
688 template < std::size_t Bits >
691 crc_basic<Bits>::process_bit
696 value_type const high_bit_mask = masking_type::high_bit;
698 // compare the new bit with the remainder's highest
699 rem_ ^= ( bit ? high_bit_mask : 0u );
701 // a full polynominal division step is done when the highest bit is one
702 bool const do_poly_div = static_cast<bool>( rem_ & high_bit_mask );
704 // shift out the highest bit
707 // carry out the division, if needed
714 template < std::size_t Bits >
716 crc_basic<Bits>::process_bits
719 std::size_t bit_count
722 // ignore the bits above the ones we want
723 bits <<= CHAR_BIT - bit_count;
725 // compute the CRC for each bit, starting with the upper ones
726 unsigned char const high_bit_mask = 1u << ( CHAR_BIT - 1u );
727 for ( std::size_t i = bit_count ; i > 0u ; --i, bits <<= 1u )
729 process_bit( static_cast<bool>(bits & high_bit_mask) );
733 template < std::size_t Bits >
736 crc_basic<Bits>::process_byte
741 process_bits( (rft_in_ ? detail::reflector<CHAR_BIT>::reflect(byte)
745 template < std::size_t Bits >
747 crc_basic<Bits>::process_block
749 void const * bytes_begin,
750 void const * bytes_end
753 for ( unsigned char const * p
754 = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
760 template < std::size_t Bits >
763 crc_basic<Bits>::process_bytes
766 std::size_t byte_count
769 unsigned char const * const b = static_cast<unsigned char const *>(
772 process_block( b, b + byte_count );
775 template < std::size_t Bits >
777 typename crc_basic<Bits>::value_type
778 crc_basic<Bits>::checksum
782 return ( (rft_out_ ? detail::reflector<Bits>::reflect( rem_ ) : rem_)
783 ^ final_ ) & masking_type::sig_bits;
787 // Optimized CRC class function definitions --------------------------------//
789 // Macro to compact code
790 #define BOOST_CRC_OPTIMAL_NAME crc_optimal<Bits, TruncPoly, InitRem, \
791 FinalXor, ReflectIn, ReflectRem>
793 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
794 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
795 bool ReflectIn, bool ReflectRem >
797 BOOST_CRC_OPTIMAL_NAME::crc_optimal
799 typename BOOST_CRC_OPTIMAL_NAME::value_type init_rem // = InitRem
801 : rem_( helper_type::reflect(init_rem) )
803 crc_table_type::init_table();
806 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
807 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
808 bool ReflectIn, bool ReflectRem >
810 typename BOOST_CRC_OPTIMAL_NAME::value_type
811 BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal
818 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
819 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
820 bool ReflectIn, bool ReflectRem >
822 typename BOOST_CRC_OPTIMAL_NAME::value_type
823 BOOST_CRC_OPTIMAL_NAME::get_initial_remainder
830 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
831 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
832 bool ReflectIn, bool ReflectRem >
834 typename BOOST_CRC_OPTIMAL_NAME::value_type
835 BOOST_CRC_OPTIMAL_NAME::get_final_xor_value
842 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
843 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
844 bool ReflectIn, bool ReflectRem >
847 BOOST_CRC_OPTIMAL_NAME::get_reflect_input
854 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
855 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
856 bool ReflectIn, bool ReflectRem >
859 BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder
866 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
867 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
868 bool ReflectIn, bool ReflectRem >
870 typename BOOST_CRC_OPTIMAL_NAME::value_type
871 BOOST_CRC_OPTIMAL_NAME::get_interim_remainder
875 // Interim remainder should be _un_-reflected, so we have to undo it.
876 return helper_type::reflect( rem_ ) & masking_type::sig_bits_fast;
879 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
880 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
881 bool ReflectIn, bool ReflectRem >
884 BOOST_CRC_OPTIMAL_NAME::reset
886 typename BOOST_CRC_OPTIMAL_NAME::value_type new_rem // = InitRem
889 rem_ = helper_type::reflect( new_rem );
892 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
893 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
894 bool ReflectIn, bool ReflectRem >
897 BOOST_CRC_OPTIMAL_NAME::process_byte
902 process_bytes( &byte, sizeof(byte) );
905 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
906 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
907 bool ReflectIn, bool ReflectRem >
909 BOOST_CRC_OPTIMAL_NAME::process_block
911 void const * bytes_begin,
912 void const * bytes_end
915 // Recompute the CRC for each byte passed
916 for ( unsigned char const * p
917 = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
919 // Compare the new byte with the remainder's higher bits to
920 // get the new bits, shift out the remainder's current higher
921 // bits, and update the remainder with the polynominal division
923 unsigned char const byte_index = helper_type::index( rem_, *p );
924 rem_ = helper_type::shift( rem_ );
925 rem_ ^= crc_table_type::table_[ byte_index ];
929 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
930 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
931 bool ReflectIn, bool ReflectRem >
934 BOOST_CRC_OPTIMAL_NAME::process_bytes
937 std::size_t byte_count
940 unsigned char const * const b = static_cast<unsigned char const *>(
942 process_block( b, b + byte_count );
945 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
946 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
947 bool ReflectIn, bool ReflectRem >
949 typename BOOST_CRC_OPTIMAL_NAME::value_type
950 BOOST_CRC_OPTIMAL_NAME::checksum
954 return ( reflect_out_type::reflect(rem_) ^ get_final_xor_value() )
955 & masking_type::sig_bits_fast;
958 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
959 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
960 bool ReflectIn, bool ReflectRem >
963 BOOST_CRC_OPTIMAL_NAME::operator ()
968 process_byte( byte );
971 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
972 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
973 bool ReflectIn, bool ReflectRem >
975 typename BOOST_CRC_OPTIMAL_NAME::value_type
976 BOOST_CRC_OPTIMAL_NAME::operator ()
984 // CRC computation function definition -------------------------------------//
986 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
987 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
988 bool ReflectIn, bool ReflectRem >
990 typename uint_t<Bits>::fast
994 std::size_t byte_count
998 BOOST_CRC_OPTIMAL_NAME computer;
999 computer.process_bytes( buffer, byte_count );
1000 return computer.checksum();
1004 // Augmented-message CRC computation function definitions ------------------//
1006 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
1007 typename uint_t<Bits>::fast
1010 void const * buffer,
1011 std::size_t byte_count,
1012 typename uint_t<Bits>::fast initial_remainder
1013 BOOST_ACRC_DUMMY_INIT
1016 typedef unsigned char byte_type;
1017 typedef detail::mask_uint_t<Bits> masking_type;
1018 typedef detail::crc_table_t<Bits, TruncPoly, false> crc_table_type;
1020 typename masking_type::fast rem = initial_remainder;
1021 byte_type const * const b = static_cast<byte_type const *>( buffer );
1022 byte_type const * const e = b + byte_count;
1024 crc_table_type::init_table();
1025 for ( byte_type const * p = b ; p < e ; ++p )
1027 // Use the current top byte as the table index to the next
1028 // "partial product." Shift out that top byte, shifting in
1029 // the next augmented-message byte. Complete the division.
1030 byte_type const byte_index = rem >> ( Bits - CHAR_BIT );
1033 rem ^= crc_table_type::table_[ byte_index ];
1036 return rem & masking_type::sig_bits_fast;
1039 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
1041 typename uint_t<Bits>::fast
1044 void const * buffer,
1045 std::size_t byte_count
1046 BOOST_ACRC_DUMMY_INIT
1049 // The last function argument has its type specified so the other version of
1050 // augmented_crc will be called. If the cast wasn't in place, and the
1051 // BOOST_ACRC_DUMMY_INIT added a third argument (for a workaround), the "0"
1052 // would match as that third argument, leading to infinite recursion.
1053 return augmented_crc<Bits, TruncPoly>( buffer, byte_count,
1054 static_cast<typename uint_t<Bits>::fast>(0) );
1058 } // namespace boost
1061 // Undo header-private macros
1062 #undef BOOST_CRC_OPTIMAL_NAME
1063 #undef BOOST_ACRC_DUMMY_INIT
1064 #undef BOOST_ACRC_DUMMY_PARM_TYPE
1065 #undef BOOST_CRC_DUMMY_INIT
1066 #undef BOOST_CRC_DUMMY_PARM_TYPE
1067 #undef BOOST_CRC_PARM_TYPE
1070 #endif // BOOST_CRC_HPP