1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/crc.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1106 @@
1.4 +// Boost CRC library crc.hpp header file -----------------------------------//
1.5 +
1.6 +// Copyright 2001, 2004 Daryle Walker. Use, modification, and distribution are
1.7 +// subject to the Boost Software License, Version 1.0. (See accompanying file
1.8 +// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
1.9 +
1.10 +// See <http://www.boost.org/libs/crc/> for the library's home page.
1.11 +
1.12 +#ifndef BOOST_CRC_HPP
1.13 +#define BOOST_CRC_HPP
1.14 +
1.15 +#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc.
1.16 +#include <boost/integer.hpp> // for boost::uint_t
1.17 +
1.18 +#include <climits> // for CHAR_BIT, etc.
1.19 +#include <cstddef> // for std::size_t
1.20 +
1.21 +#include <boost/limits.hpp> // for std::numeric_limits
1.22 +
1.23 +
1.24 +// The type of CRC parameters that can go in a template should be related
1.25 +// on the CRC's bit count. This macro expresses that type in a compact
1.26 +// form, but also allows an alternate type for compilers that don't support
1.27 +// dependent types (in template value-parameters).
1.28 +#if !(defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) || (defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)))
1.29 +#define BOOST_CRC_PARM_TYPE typename ::boost::uint_t<Bits>::fast
1.30 +#else
1.31 +#define BOOST_CRC_PARM_TYPE unsigned long
1.32 +#endif
1.33 +
1.34 +// Some compilers [MS VC++ 6] cannot correctly set up several versions of a
1.35 +// function template unless every template argument can be unambiguously
1.36 +// deduced from the function arguments. (The bug is hidden if only one version
1.37 +// is needed.) Since all of the CRC function templates have this problem, the
1.38 +// workaround is to make up a dummy function argument that encodes the template
1.39 +// arguments. Calls to such template functions need all their template
1.40 +// arguments explicitly specified. At least one compiler that needs this
1.41 +// workaround also needs the default value for the dummy argument to be
1.42 +// specified in the definition.
1.43 +#if defined(__GNUC__) || !defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
1.44 +#define BOOST_CRC_DUMMY_PARM_TYPE
1.45 +#define BOOST_CRC_DUMMY_INIT
1.46 +#define BOOST_ACRC_DUMMY_PARM_TYPE
1.47 +#define BOOST_ACRC_DUMMY_INIT
1.48 +#else
1.49 +namespace boost { namespace detail {
1.50 + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.51 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.52 + bool ReflectIn, bool ReflectRem >
1.53 + struct dummy_crc_argument { };
1.54 +} }
1.55 +#define BOOST_CRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument<Bits, \
1.56 + TruncPoly, InitRem, FinalXor, ReflectIn, ReflectRem> *p_
1.57 +#define BOOST_CRC_DUMMY_INIT BOOST_CRC_DUMMY_PARM_TYPE = 0
1.58 +#define BOOST_ACRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument<Bits, \
1.59 + TruncPoly, 0, 0, false, false> *p_
1.60 +#define BOOST_ACRC_DUMMY_INIT BOOST_ACRC_DUMMY_PARM_TYPE = 0
1.61 +#endif
1.62 +
1.63 +
1.64 +namespace boost
1.65 +{
1.66 +
1.67 +
1.68 +// Forward declarations ----------------------------------------------------//
1.69 +
1.70 +template < std::size_t Bits >
1.71 + class crc_basic;
1.72 +
1.73 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u,
1.74 + BOOST_CRC_PARM_TYPE InitRem = 0u,
1.75 + BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false,
1.76 + bool ReflectRem = false >
1.77 + class crc_optimal;
1.78 +
1.79 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.80 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.81 + bool ReflectIn, bool ReflectRem >
1.82 + typename uint_t<Bits>::fast crc( void const *buffer,
1.83 + std::size_t byte_count
1.84 + BOOST_CRC_DUMMY_PARM_TYPE );
1.85 +
1.86 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
1.87 + typename uint_t<Bits>::fast augmented_crc( void const *buffer,
1.88 + std::size_t byte_count, typename uint_t<Bits>::fast initial_remainder
1.89 + BOOST_ACRC_DUMMY_PARM_TYPE );
1.90 +
1.91 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
1.92 + typename uint_t<Bits>::fast augmented_crc( void const *buffer,
1.93 + std::size_t byte_count
1.94 + BOOST_ACRC_DUMMY_PARM_TYPE );
1.95 +
1.96 +typedef crc_optimal<16, 0x8005, 0, 0, true, true> crc_16_type;
1.97 +typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_type;
1.98 +typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type;
1.99 +
1.100 +typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>
1.101 + crc_32_type;
1.102 +
1.103 +
1.104 +// Forward declarations for implementation detail stuff --------------------//
1.105 +// (Just for the stuff that will be needed for the next two sections)
1.106 +
1.107 +namespace detail
1.108 +{
1.109 + template < std::size_t Bits >
1.110 + struct mask_uint_t;
1.111 +
1.112 + template < >
1.113 + struct mask_uint_t< std::numeric_limits<unsigned char>::digits >;
1.114 +
1.115 + #if USHRT_MAX > UCHAR_MAX
1.116 + template < >
1.117 + struct mask_uint_t< std::numeric_limits<unsigned short>::digits >;
1.118 + #endif
1.119 +
1.120 + #if UINT_MAX > USHRT_MAX
1.121 + template < >
1.122 + struct mask_uint_t< std::numeric_limits<unsigned int>::digits >;
1.123 + #endif
1.124 +
1.125 + #if ULONG_MAX > UINT_MAX
1.126 + template < >
1.127 + struct mask_uint_t< std::numeric_limits<unsigned long>::digits >;
1.128 + #endif
1.129 +
1.130 + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
1.131 + struct crc_table_t;
1.132 +
1.133 + template < std::size_t Bits, bool DoReflect >
1.134 + class crc_helper;
1.135 +
1.136 + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.137 + template < std::size_t Bits >
1.138 + class crc_helper< Bits, false >;
1.139 + #endif
1.140 +
1.141 +} // namespace detail
1.142 +
1.143 +
1.144 +// Simple cyclic redundancy code (CRC) class declaration -------------------//
1.145 +
1.146 +template < std::size_t Bits >
1.147 +class crc_basic
1.148 +{
1.149 + // Implementation type
1.150 + typedef detail::mask_uint_t<Bits> masking_type;
1.151 +
1.152 +public:
1.153 + // Type
1.154 + typedef typename masking_type::least value_type;
1.155 +
1.156 + // Constant for the template parameter
1.157 + BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
1.158 +
1.159 + // Constructor
1.160 + explicit crc_basic( value_type truncated_polynominal,
1.161 + value_type initial_remainder = 0, value_type final_xor_value = 0,
1.162 + bool reflect_input = false, bool reflect_remainder = false );
1.163 +
1.164 + // Internal Operations
1.165 + value_type get_truncated_polynominal() const;
1.166 + value_type get_initial_remainder() const;
1.167 + value_type get_final_xor_value() const;
1.168 + bool get_reflect_input() const;
1.169 + bool get_reflect_remainder() const;
1.170 +
1.171 + value_type get_interim_remainder() const;
1.172 + void reset( value_type new_rem );
1.173 + void reset();
1.174 +
1.175 + // External Operations
1.176 + void process_bit( bool bit );
1.177 + void process_bits( unsigned char bits, std::size_t bit_count );
1.178 + void process_byte( unsigned char byte );
1.179 + void process_block( void const *bytes_begin, void const *bytes_end );
1.180 + void process_bytes( void const *buffer, std::size_t byte_count );
1.181 +
1.182 + value_type checksum() const;
1.183 +
1.184 +private:
1.185 + // Member data
1.186 + value_type rem_;
1.187 + value_type poly_, init_, final_; // non-const to allow assignability
1.188 + bool rft_in_, rft_out_; // non-const to allow assignability
1.189 +
1.190 +}; // boost::crc_basic
1.191 +
1.192 +
1.193 +// Optimized cyclic redundancy code (CRC) class declaration ----------------//
1.194 +
1.195 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.196 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.197 + bool ReflectIn, bool ReflectRem >
1.198 +class crc_optimal
1.199 +{
1.200 + // Implementation type
1.201 + typedef detail::mask_uint_t<Bits> masking_type;
1.202 +
1.203 +public:
1.204 + // Type
1.205 + typedef typename masking_type::fast value_type;
1.206 +
1.207 + // Constants for the template parameters
1.208 + BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
1.209 + BOOST_STATIC_CONSTANT( value_type, truncated_polynominal = TruncPoly );
1.210 + BOOST_STATIC_CONSTANT( value_type, initial_remainder = InitRem );
1.211 + BOOST_STATIC_CONSTANT( value_type, final_xor_value = FinalXor );
1.212 + BOOST_STATIC_CONSTANT( bool, reflect_input = ReflectIn );
1.213 + BOOST_STATIC_CONSTANT( bool, reflect_remainder = ReflectRem );
1.214 +
1.215 + // Constructor
1.216 + explicit crc_optimal( value_type init_rem = InitRem );
1.217 +
1.218 + // Internal Operations
1.219 + value_type get_truncated_polynominal() const;
1.220 + value_type get_initial_remainder() const;
1.221 + value_type get_final_xor_value() const;
1.222 + bool get_reflect_input() const;
1.223 + bool get_reflect_remainder() const;
1.224 +
1.225 + value_type get_interim_remainder() const;
1.226 + void reset( value_type new_rem = InitRem );
1.227 +
1.228 + // External Operations
1.229 + void process_byte( unsigned char byte );
1.230 + void process_block( void const *bytes_begin, void const *bytes_end );
1.231 + void process_bytes( void const *buffer, std::size_t byte_count );
1.232 +
1.233 + value_type checksum() const;
1.234 +
1.235 + // Operators
1.236 + void operator ()( unsigned char byte );
1.237 + value_type operator ()() const;
1.238 +
1.239 +private:
1.240 + // The implementation of output reflection depends on both reflect states.
1.241 + BOOST_STATIC_CONSTANT( bool, reflect_output = (ReflectRem != ReflectIn) );
1.242 +
1.243 + #ifndef __BORLANDC__
1.244 + #define BOOST_CRC_REF_OUT_VAL reflect_output
1.245 + #else
1.246 + typedef crc_optimal self_type;
1.247 + #define BOOST_CRC_REF_OUT_VAL (self_type::reflect_output)
1.248 + #endif
1.249 +
1.250 + // More implementation types
1.251 + typedef detail::crc_table_t<Bits, TruncPoly, ReflectIn> crc_table_type;
1.252 + typedef detail::crc_helper<Bits, ReflectIn> helper_type;
1.253 + typedef detail::crc_helper<Bits, BOOST_CRC_REF_OUT_VAL> reflect_out_type;
1.254 +
1.255 + #undef BOOST_CRC_REF_OUT_VAL
1.256 +
1.257 + // Member data
1.258 + value_type rem_;
1.259 +
1.260 +}; // boost::crc_optimal
1.261 +
1.262 +
1.263 +// Implementation detail stuff ---------------------------------------------//
1.264 +
1.265 +namespace detail
1.266 +{
1.267 + // Forward declarations for more implementation details
1.268 + template < std::size_t Bits >
1.269 + struct high_uint_t;
1.270 +
1.271 + template < std::size_t Bits >
1.272 + struct reflector;
1.273 +
1.274 +
1.275 + // Traits class for mask; given the bit number
1.276 + // (1-based), get the mask for that bit by itself.
1.277 + template < std::size_t Bits >
1.278 + struct high_uint_t
1.279 + : boost::uint_t< Bits >
1.280 + {
1.281 + typedef boost::uint_t<Bits> base_type;
1.282 + typedef typename base_type::least least;
1.283 + typedef typename base_type::fast fast;
1.284 +
1.285 +#if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
1.286 + static const least high_bit = 1ul << ( Bits - 1u );
1.287 + static const fast high_bit_fast = 1ul << ( Bits - 1u );
1.288 +#else
1.289 + BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << ( Bits
1.290 + - 1u )) );
1.291 + BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << ( Bits
1.292 + - 1u )) );
1.293 +#endif
1.294 +
1.295 + }; // boost::detail::high_uint_t
1.296 +
1.297 +
1.298 + // Reflection routine class wrapper
1.299 + // (since MS VC++ 6 couldn't handle the unwrapped version)
1.300 + template < std::size_t Bits >
1.301 + struct reflector
1.302 + {
1.303 + typedef typename boost::uint_t<Bits>::fast value_type;
1.304 +
1.305 + static value_type reflect( value_type x );
1.306 +
1.307 + }; // boost::detail::reflector
1.308 +
1.309 + // Function that reflects its argument
1.310 + template < std::size_t Bits >
1.311 + typename reflector<Bits>::value_type
1.312 + reflector<Bits>::reflect
1.313 + (
1.314 + typename reflector<Bits>::value_type x
1.315 + )
1.316 + {
1.317 + value_type reflection = 0;
1.318 + value_type const one = 1;
1.319 +
1.320 + for ( std::size_t i = 0 ; i < Bits ; ++i, x >>= 1 )
1.321 + {
1.322 + if ( x & one )
1.323 + {
1.324 + reflection |= ( one << (Bits - 1u - i) );
1.325 + }
1.326 + }
1.327 +
1.328 + return reflection;
1.329 + }
1.330 +
1.331 +
1.332 + // Traits class for masks; given the bit number (1-based),
1.333 + // get the mask for that bit and its lower bits.
1.334 + template < std::size_t Bits >
1.335 + struct mask_uint_t
1.336 + : high_uint_t< Bits >
1.337 + {
1.338 + typedef high_uint_t<Bits> base_type;
1.339 + typedef typename base_type::least least;
1.340 + typedef typename base_type::fast fast;
1.341 +
1.342 + #ifndef __BORLANDC__
1.343 + using base_type::high_bit;
1.344 + using base_type::high_bit_fast;
1.345 + #else
1.346 + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
1.347 + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
1.348 + #endif
1.349 +
1.350 +#if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
1.351 + static const least sig_bits = (~( ~( 0ul ) << Bits )) ;
1.352 +#else
1.353 + BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) );
1.354 +#endif
1.355 +#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
1.356 + // Work around a weird bug that ICEs the compiler in build_c_cast
1.357 + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = static_cast<fast>(sig_bits) );
1.358 +#else
1.359 + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
1.360 +#endif
1.361 + }; // boost::detail::mask_uint_t
1.362 +
1.363 + template < >
1.364 + struct mask_uint_t< std::numeric_limits<unsigned char>::digits >
1.365 + : high_uint_t< std::numeric_limits<unsigned char>::digits >
1.366 + {
1.367 + typedef high_uint_t<std::numeric_limits<unsigned char>::digits>
1.368 + base_type;
1.369 + typedef base_type::least least;
1.370 + typedef base_type::fast fast;
1.371 +
1.372 + #ifndef __BORLANDC__
1.373 + using base_type::high_bit;
1.374 + using base_type::high_bit_fast;
1.375 + #else
1.376 + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
1.377 + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
1.378 + #endif
1.379 +
1.380 + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
1.381 + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
1.382 +
1.383 + }; // boost::detail::mask_uint_t
1.384 +
1.385 + #if USHRT_MAX > UCHAR_MAX
1.386 + template < >
1.387 + struct mask_uint_t< std::numeric_limits<unsigned short>::digits >
1.388 + : high_uint_t< std::numeric_limits<unsigned short>::digits >
1.389 + {
1.390 + typedef high_uint_t<std::numeric_limits<unsigned short>::digits>
1.391 + base_type;
1.392 + typedef base_type::least least;
1.393 + typedef base_type::fast fast;
1.394 +
1.395 + #ifndef __BORLANDC__
1.396 + using base_type::high_bit;
1.397 + using base_type::high_bit_fast;
1.398 + #else
1.399 + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
1.400 + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
1.401 + #endif
1.402 +
1.403 + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
1.404 + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
1.405 +
1.406 + }; // boost::detail::mask_uint_t
1.407 + #endif
1.408 +
1.409 + #if UINT_MAX > USHRT_MAX
1.410 + template < >
1.411 + struct mask_uint_t< std::numeric_limits<unsigned int>::digits >
1.412 + : high_uint_t< std::numeric_limits<unsigned int>::digits >
1.413 + {
1.414 + typedef high_uint_t<std::numeric_limits<unsigned int>::digits>
1.415 + base_type;
1.416 + typedef base_type::least least;
1.417 + typedef base_type::fast fast;
1.418 +
1.419 + #ifndef __BORLANDC__
1.420 + using base_type::high_bit;
1.421 + using base_type::high_bit_fast;
1.422 + #else
1.423 + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
1.424 + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
1.425 + #endif
1.426 +
1.427 + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
1.428 + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
1.429 +
1.430 + }; // boost::detail::mask_uint_t
1.431 + #endif
1.432 +
1.433 + #if ULONG_MAX > UINT_MAX
1.434 + template < >
1.435 + struct mask_uint_t< std::numeric_limits<unsigned long>::digits >
1.436 + : high_uint_t< std::numeric_limits<unsigned long>::digits >
1.437 + {
1.438 + typedef high_uint_t<std::numeric_limits<unsigned long>::digits>
1.439 + base_type;
1.440 + typedef base_type::least least;
1.441 + typedef base_type::fast fast;
1.442 +
1.443 + #ifndef __BORLANDC__
1.444 + using base_type::high_bit;
1.445 + using base_type::high_bit_fast;
1.446 + #else
1.447 + BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
1.448 + BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
1.449 + #endif
1.450 +
1.451 + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
1.452 + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
1.453 +
1.454 + }; // boost::detail::mask_uint_t
1.455 + #endif
1.456 +
1.457 +
1.458 + // CRC table generator
1.459 + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
1.460 + struct crc_table_t
1.461 + {
1.462 + BOOST_STATIC_CONSTANT( std::size_t, byte_combos = (1ul << CHAR_BIT) );
1.463 +
1.464 + typedef mask_uint_t<Bits> masking_type;
1.465 + typedef typename masking_type::fast value_type;
1.466 +#if defined(__BORLANDC__) && defined(_M_IX86) && (__BORLANDC__ == 0x560)
1.467 + // for some reason Borland's command line compiler (version 0x560)
1.468 + // chokes over this unless we do the calculation for it:
1.469 + typedef value_type table_type[ 0x100 ];
1.470 +#else
1.471 + typedef value_type table_type[ byte_combos ];
1.472 +#endif
1.473 +
1.474 + static void init_table();
1.475 +
1.476 + static table_type table_;
1.477 +
1.478 + }; // boost::detail::crc_table_t
1.479 +
1.480 + // CRC table generator static data member definition
1.481 + // (Some compilers [Borland C++] require the initializer to be present.)
1.482 + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
1.483 + typename crc_table_t<Bits, TruncPoly, Reflect>::table_type
1.484 + crc_table_t<Bits, TruncPoly, Reflect>::table_
1.485 + = { 0 };
1.486 +
1.487 + // Populate CRC lookup table
1.488 + template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
1.489 + void
1.490 + crc_table_t<Bits, TruncPoly, Reflect>::init_table
1.491 + (
1.492 + )
1.493 + {
1.494 + // compute table only on the first run
1.495 + static bool did_init = false;
1.496 + if ( did_init ) return;
1.497 +
1.498 + // factor-out constants to avoid recalculation
1.499 + value_type const fast_hi_bit = masking_type::high_bit_fast;
1.500 + unsigned char const byte_hi_bit = 1u << (CHAR_BIT - 1u);
1.501 +
1.502 + // loop over every possible dividend value
1.503 + unsigned char dividend = 0;
1.504 + do
1.505 + {
1.506 + value_type remainder = 0;
1.507 +
1.508 + // go through all the dividend's bits
1.509 + for ( unsigned char mask = byte_hi_bit ; mask ; mask >>= 1 )
1.510 + {
1.511 + // check if divisor fits
1.512 + if ( dividend & mask )
1.513 + {
1.514 + remainder ^= fast_hi_bit;
1.515 + }
1.516 +
1.517 + // do polynominal division
1.518 + if ( remainder & fast_hi_bit )
1.519 + {
1.520 + remainder <<= 1;
1.521 + remainder ^= TruncPoly;
1.522 + }
1.523 + else
1.524 + {
1.525 + remainder <<= 1;
1.526 + }
1.527 + }
1.528 +
1.529 + table_[ crc_helper<CHAR_BIT, Reflect>::reflect(dividend) ]
1.530 + = crc_helper<Bits, Reflect>::reflect( remainder );
1.531 + }
1.532 + while ( ++dividend );
1.533 +
1.534 + did_init = true;
1.535 + }
1.536 +
1.537 + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.538 + // Align the msb of the remainder to a byte
1.539 + template < std::size_t Bits, bool RightShift >
1.540 + class remainder
1.541 + {
1.542 + public:
1.543 + typedef typename uint_t<Bits>::fast value_type;
1.544 +
1.545 + static unsigned char align_msb( value_type rem )
1.546 + { return rem >> (Bits - CHAR_BIT); }
1.547 + };
1.548 +
1.549 + // Specialization for the case that the remainder has less
1.550 + // bits than a byte: align the remainder msb to the byte msb
1.551 + template < std::size_t Bits >
1.552 + class remainder< Bits, false >
1.553 + {
1.554 + public:
1.555 + typedef typename uint_t<Bits>::fast value_type;
1.556 +
1.557 + static unsigned char align_msb( value_type rem )
1.558 + { return rem << (CHAR_BIT - Bits); }
1.559 + };
1.560 + #endif
1.561 +
1.562 + // CRC helper routines
1.563 + template < std::size_t Bits, bool DoReflect >
1.564 + class crc_helper
1.565 + {
1.566 + public:
1.567 + // Type
1.568 + typedef typename uint_t<Bits>::fast value_type;
1.569 +
1.570 + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.571 + // Possibly reflect a remainder
1.572 + static value_type reflect( value_type x )
1.573 + { return detail::reflector<Bits>::reflect( x ); }
1.574 +
1.575 + // Compare a byte to the remainder's highest byte
1.576 + static unsigned char index( value_type rem, unsigned char x )
1.577 + { return x ^ rem; }
1.578 +
1.579 + // Shift out the remainder's highest byte
1.580 + static value_type shift( value_type rem )
1.581 + { return rem >> CHAR_BIT; }
1.582 + #else
1.583 + // Possibly reflect a remainder
1.584 + static value_type reflect( value_type x )
1.585 + { return DoReflect ? detail::reflector<Bits>::reflect( x ) : x; }
1.586 +
1.587 + // Compare a byte to the remainder's highest byte
1.588 + static unsigned char index( value_type rem, unsigned char x )
1.589 + { return x ^ ( DoReflect ? rem :
1.590 + ((Bits>CHAR_BIT)?( rem >> (Bits - CHAR_BIT) ) :
1.591 + ( rem << (CHAR_BIT - Bits) ))); }
1.592 +
1.593 + // Shift out the remainder's highest byte
1.594 + static value_type shift( value_type rem )
1.595 + { return DoReflect ? rem >> CHAR_BIT : rem << CHAR_BIT; }
1.596 + #endif
1.597 +
1.598 + }; // boost::detail::crc_helper
1.599 +
1.600 + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.601 + template < std::size_t Bits >
1.602 + class crc_helper<Bits, false>
1.603 + {
1.604 + public:
1.605 + // Type
1.606 + typedef typename uint_t<Bits>::fast value_type;
1.607 +
1.608 + // Possibly reflect a remainder
1.609 + static value_type reflect( value_type x )
1.610 + { return x; }
1.611 +
1.612 + // Compare a byte to the remainder's highest byte
1.613 + static unsigned char index( value_type rem, unsigned char x )
1.614 + { return x ^ remainder<Bits,(Bits>CHAR_BIT)>::align_msb( rem ); }
1.615 +
1.616 + // Shift out the remainder's highest byte
1.617 + static value_type shift( value_type rem )
1.618 + { return rem << CHAR_BIT; }
1.619 +
1.620 + }; // boost::detail::crc_helper
1.621 + #endif
1.622 +
1.623 +
1.624 +} // namespace detail
1.625 +
1.626 +
1.627 +// Simple CRC class function definitions -----------------------------------//
1.628 +
1.629 +template < std::size_t Bits >
1.630 +inline
1.631 +crc_basic<Bits>::crc_basic
1.632 +(
1.633 + typename crc_basic<Bits>::value_type truncated_polynominal,
1.634 + typename crc_basic<Bits>::value_type initial_remainder, // = 0
1.635 + typename crc_basic<Bits>::value_type final_xor_value, // = 0
1.636 + bool reflect_input, // = false
1.637 + bool reflect_remainder // = false
1.638 +)
1.639 + : rem_( initial_remainder ), poly_( truncated_polynominal )
1.640 + , init_( initial_remainder ), final_( final_xor_value )
1.641 + , rft_in_( reflect_input ), rft_out_( reflect_remainder )
1.642 +{
1.643 +}
1.644 +
1.645 +template < std::size_t Bits >
1.646 +inline
1.647 +typename crc_basic<Bits>::value_type
1.648 +crc_basic<Bits>::get_truncated_polynominal
1.649 +(
1.650 +) const
1.651 +{
1.652 + return poly_;
1.653 +}
1.654 +
1.655 +template < std::size_t Bits >
1.656 +inline
1.657 +typename crc_basic<Bits>::value_type
1.658 +crc_basic<Bits>::get_initial_remainder
1.659 +(
1.660 +) const
1.661 +{
1.662 + return init_;
1.663 +}
1.664 +
1.665 +template < std::size_t Bits >
1.666 +inline
1.667 +typename crc_basic<Bits>::value_type
1.668 +crc_basic<Bits>::get_final_xor_value
1.669 +(
1.670 +) const
1.671 +{
1.672 + return final_;
1.673 +}
1.674 +
1.675 +template < std::size_t Bits >
1.676 +inline
1.677 +bool
1.678 +crc_basic<Bits>::get_reflect_input
1.679 +(
1.680 +) const
1.681 +{
1.682 + return rft_in_;
1.683 +}
1.684 +
1.685 +template < std::size_t Bits >
1.686 +inline
1.687 +bool
1.688 +crc_basic<Bits>::get_reflect_remainder
1.689 +(
1.690 +) const
1.691 +{
1.692 + return rft_out_;
1.693 +}
1.694 +
1.695 +template < std::size_t Bits >
1.696 +inline
1.697 +typename crc_basic<Bits>::value_type
1.698 +crc_basic<Bits>::get_interim_remainder
1.699 +(
1.700 +) const
1.701 +{
1.702 + return rem_ & masking_type::sig_bits;
1.703 +}
1.704 +
1.705 +template < std::size_t Bits >
1.706 +inline
1.707 +void
1.708 +crc_basic<Bits>::reset
1.709 +(
1.710 + typename crc_basic<Bits>::value_type new_rem
1.711 +)
1.712 +{
1.713 + rem_ = new_rem;
1.714 +}
1.715 +
1.716 +template < std::size_t Bits >
1.717 +inline
1.718 +void
1.719 +crc_basic<Bits>::reset
1.720 +(
1.721 +)
1.722 +{
1.723 + this->reset( this->get_initial_remainder() );
1.724 +}
1.725 +
1.726 +template < std::size_t Bits >
1.727 +inline
1.728 +void
1.729 +crc_basic<Bits>::process_bit
1.730 +(
1.731 + bool bit
1.732 +)
1.733 +{
1.734 + value_type const high_bit_mask = masking_type::high_bit;
1.735 +
1.736 + // compare the new bit with the remainder's highest
1.737 + rem_ ^= ( bit ? high_bit_mask : 0u );
1.738 +
1.739 + // a full polynominal division step is done when the highest bit is one
1.740 + bool const do_poly_div = static_cast<bool>( rem_ & high_bit_mask );
1.741 +
1.742 + // shift out the highest bit
1.743 + rem_ <<= 1;
1.744 +
1.745 + // carry out the division, if needed
1.746 + if ( do_poly_div )
1.747 + {
1.748 + rem_ ^= poly_;
1.749 + }
1.750 +}
1.751 +
1.752 +template < std::size_t Bits >
1.753 +void
1.754 +crc_basic<Bits>::process_bits
1.755 +(
1.756 + unsigned char bits,
1.757 + std::size_t bit_count
1.758 +)
1.759 +{
1.760 + // ignore the bits above the ones we want
1.761 + bits <<= CHAR_BIT - bit_count;
1.762 +
1.763 + // compute the CRC for each bit, starting with the upper ones
1.764 + unsigned char const high_bit_mask = 1u << ( CHAR_BIT - 1u );
1.765 + for ( std::size_t i = bit_count ; i > 0u ; --i, bits <<= 1u )
1.766 + {
1.767 + process_bit( static_cast<bool>(bits & high_bit_mask) );
1.768 + }
1.769 +}
1.770 +
1.771 +template < std::size_t Bits >
1.772 +inline
1.773 +void
1.774 +crc_basic<Bits>::process_byte
1.775 +(
1.776 + unsigned char byte
1.777 +)
1.778 +{
1.779 + process_bits( (rft_in_ ? detail::reflector<CHAR_BIT>::reflect(byte)
1.780 + : byte), CHAR_BIT );
1.781 +}
1.782 +
1.783 +template < std::size_t Bits >
1.784 +void
1.785 +crc_basic<Bits>::process_block
1.786 +(
1.787 + void const * bytes_begin,
1.788 + void const * bytes_end
1.789 +)
1.790 +{
1.791 + for ( unsigned char const * p
1.792 + = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
1.793 + {
1.794 + process_byte( *p );
1.795 + }
1.796 +}
1.797 +
1.798 +template < std::size_t Bits >
1.799 +inline
1.800 +void
1.801 +crc_basic<Bits>::process_bytes
1.802 +(
1.803 + void const * buffer,
1.804 + std::size_t byte_count
1.805 +)
1.806 +{
1.807 + unsigned char const * const b = static_cast<unsigned char const *>(
1.808 + buffer );
1.809 +
1.810 + process_block( b, b + byte_count );
1.811 +}
1.812 +
1.813 +template < std::size_t Bits >
1.814 +inline
1.815 +typename crc_basic<Bits>::value_type
1.816 +crc_basic<Bits>::checksum
1.817 +(
1.818 +) const
1.819 +{
1.820 + return ( (rft_out_ ? detail::reflector<Bits>::reflect( rem_ ) : rem_)
1.821 + ^ final_ ) & masking_type::sig_bits;
1.822 +}
1.823 +
1.824 +
1.825 +// Optimized CRC class function definitions --------------------------------//
1.826 +
1.827 +// Macro to compact code
1.828 +#define BOOST_CRC_OPTIMAL_NAME crc_optimal<Bits, TruncPoly, InitRem, \
1.829 + FinalXor, ReflectIn, ReflectRem>
1.830 +
1.831 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.832 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.833 + bool ReflectIn, bool ReflectRem >
1.834 +inline
1.835 +BOOST_CRC_OPTIMAL_NAME::crc_optimal
1.836 +(
1.837 + typename BOOST_CRC_OPTIMAL_NAME::value_type init_rem // = InitRem
1.838 +)
1.839 + : rem_( helper_type::reflect(init_rem) )
1.840 +{
1.841 + crc_table_type::init_table();
1.842 +}
1.843 +
1.844 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.845 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.846 + bool ReflectIn, bool ReflectRem >
1.847 +inline
1.848 +typename BOOST_CRC_OPTIMAL_NAME::value_type
1.849 +BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal
1.850 +(
1.851 +) const
1.852 +{
1.853 + return TruncPoly;
1.854 +}
1.855 +
1.856 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.857 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.858 + bool ReflectIn, bool ReflectRem >
1.859 +inline
1.860 +typename BOOST_CRC_OPTIMAL_NAME::value_type
1.861 +BOOST_CRC_OPTIMAL_NAME::get_initial_remainder
1.862 +(
1.863 +) const
1.864 +{
1.865 + return InitRem;
1.866 +}
1.867 +
1.868 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.869 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.870 + bool ReflectIn, bool ReflectRem >
1.871 +inline
1.872 +typename BOOST_CRC_OPTIMAL_NAME::value_type
1.873 +BOOST_CRC_OPTIMAL_NAME::get_final_xor_value
1.874 +(
1.875 +) const
1.876 +{
1.877 + return FinalXor;
1.878 +}
1.879 +
1.880 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.881 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.882 + bool ReflectIn, bool ReflectRem >
1.883 +inline
1.884 +bool
1.885 +BOOST_CRC_OPTIMAL_NAME::get_reflect_input
1.886 +(
1.887 +) const
1.888 +{
1.889 + return ReflectIn;
1.890 +}
1.891 +
1.892 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.893 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.894 + bool ReflectIn, bool ReflectRem >
1.895 +inline
1.896 +bool
1.897 +BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder
1.898 +(
1.899 +) const
1.900 +{
1.901 + return ReflectRem;
1.902 +}
1.903 +
1.904 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.905 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.906 + bool ReflectIn, bool ReflectRem >
1.907 +inline
1.908 +typename BOOST_CRC_OPTIMAL_NAME::value_type
1.909 +BOOST_CRC_OPTIMAL_NAME::get_interim_remainder
1.910 +(
1.911 +) const
1.912 +{
1.913 + // Interim remainder should be _un_-reflected, so we have to undo it.
1.914 + return helper_type::reflect( rem_ ) & masking_type::sig_bits_fast;
1.915 +}
1.916 +
1.917 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.918 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.919 + bool ReflectIn, bool ReflectRem >
1.920 +inline
1.921 +void
1.922 +BOOST_CRC_OPTIMAL_NAME::reset
1.923 +(
1.924 + typename BOOST_CRC_OPTIMAL_NAME::value_type new_rem // = InitRem
1.925 +)
1.926 +{
1.927 + rem_ = helper_type::reflect( new_rem );
1.928 +}
1.929 +
1.930 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.931 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.932 + bool ReflectIn, bool ReflectRem >
1.933 +inline
1.934 +void
1.935 +BOOST_CRC_OPTIMAL_NAME::process_byte
1.936 +(
1.937 + unsigned char byte
1.938 +)
1.939 +{
1.940 + process_bytes( &byte, sizeof(byte) );
1.941 +}
1.942 +
1.943 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.944 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.945 + bool ReflectIn, bool ReflectRem >
1.946 +void
1.947 +BOOST_CRC_OPTIMAL_NAME::process_block
1.948 +(
1.949 + void const * bytes_begin,
1.950 + void const * bytes_end
1.951 +)
1.952 +{
1.953 + // Recompute the CRC for each byte passed
1.954 + for ( unsigned char const * p
1.955 + = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
1.956 + {
1.957 + // Compare the new byte with the remainder's higher bits to
1.958 + // get the new bits, shift out the remainder's current higher
1.959 + // bits, and update the remainder with the polynominal division
1.960 + // of the new bits.
1.961 + unsigned char const byte_index = helper_type::index( rem_, *p );
1.962 + rem_ = helper_type::shift( rem_ );
1.963 + rem_ ^= crc_table_type::table_[ byte_index ];
1.964 + }
1.965 +}
1.966 +
1.967 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.968 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.969 + bool ReflectIn, bool ReflectRem >
1.970 +inline
1.971 +void
1.972 +BOOST_CRC_OPTIMAL_NAME::process_bytes
1.973 +(
1.974 + void const * buffer,
1.975 + std::size_t byte_count
1.976 +)
1.977 +{
1.978 + unsigned char const * const b = static_cast<unsigned char const *>(
1.979 + buffer );
1.980 + process_block( b, b + byte_count );
1.981 +}
1.982 +
1.983 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.984 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.985 + bool ReflectIn, bool ReflectRem >
1.986 +inline
1.987 +typename BOOST_CRC_OPTIMAL_NAME::value_type
1.988 +BOOST_CRC_OPTIMAL_NAME::checksum
1.989 +(
1.990 +) const
1.991 +{
1.992 + return ( reflect_out_type::reflect(rem_) ^ get_final_xor_value() )
1.993 + & masking_type::sig_bits_fast;
1.994 +}
1.995 +
1.996 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.997 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.998 + bool ReflectIn, bool ReflectRem >
1.999 +inline
1.1000 +void
1.1001 +BOOST_CRC_OPTIMAL_NAME::operator ()
1.1002 +(
1.1003 + unsigned char byte
1.1004 +)
1.1005 +{
1.1006 + process_byte( byte );
1.1007 +}
1.1008 +
1.1009 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.1010 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.1011 + bool ReflectIn, bool ReflectRem >
1.1012 +inline
1.1013 +typename BOOST_CRC_OPTIMAL_NAME::value_type
1.1014 +BOOST_CRC_OPTIMAL_NAME::operator ()
1.1015 +(
1.1016 +) const
1.1017 +{
1.1018 + return checksum();
1.1019 +}
1.1020 +
1.1021 +
1.1022 +// CRC computation function definition -------------------------------------//
1.1023 +
1.1024 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
1.1025 + BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
1.1026 + bool ReflectIn, bool ReflectRem >
1.1027 +inline
1.1028 +typename uint_t<Bits>::fast
1.1029 +crc
1.1030 +(
1.1031 + void const * buffer,
1.1032 + std::size_t byte_count
1.1033 + BOOST_CRC_DUMMY_INIT
1.1034 +)
1.1035 +{
1.1036 + BOOST_CRC_OPTIMAL_NAME computer;
1.1037 + computer.process_bytes( buffer, byte_count );
1.1038 + return computer.checksum();
1.1039 +}
1.1040 +
1.1041 +
1.1042 +// Augmented-message CRC computation function definitions ------------------//
1.1043 +
1.1044 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
1.1045 +typename uint_t<Bits>::fast
1.1046 +augmented_crc
1.1047 +(
1.1048 + void const * buffer,
1.1049 + std::size_t byte_count,
1.1050 + typename uint_t<Bits>::fast initial_remainder
1.1051 + BOOST_ACRC_DUMMY_INIT
1.1052 +)
1.1053 +{
1.1054 + typedef unsigned char byte_type;
1.1055 + typedef detail::mask_uint_t<Bits> masking_type;
1.1056 + typedef detail::crc_table_t<Bits, TruncPoly, false> crc_table_type;
1.1057 +
1.1058 + typename masking_type::fast rem = initial_remainder;
1.1059 + byte_type const * const b = static_cast<byte_type const *>( buffer );
1.1060 + byte_type const * const e = b + byte_count;
1.1061 +
1.1062 + crc_table_type::init_table();
1.1063 + for ( byte_type const * p = b ; p < e ; ++p )
1.1064 + {
1.1065 + // Use the current top byte as the table index to the next
1.1066 + // "partial product." Shift out that top byte, shifting in
1.1067 + // the next augmented-message byte. Complete the division.
1.1068 + byte_type const byte_index = rem >> ( Bits - CHAR_BIT );
1.1069 + rem <<= CHAR_BIT;
1.1070 + rem |= *p;
1.1071 + rem ^= crc_table_type::table_[ byte_index ];
1.1072 + }
1.1073 +
1.1074 + return rem & masking_type::sig_bits_fast;
1.1075 +}
1.1076 +
1.1077 +template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
1.1078 +inline
1.1079 +typename uint_t<Bits>::fast
1.1080 +augmented_crc
1.1081 +(
1.1082 + void const * buffer,
1.1083 + std::size_t byte_count
1.1084 + BOOST_ACRC_DUMMY_INIT
1.1085 +)
1.1086 +{
1.1087 + // The last function argument has its type specified so the other version of
1.1088 + // augmented_crc will be called. If the cast wasn't in place, and the
1.1089 + // BOOST_ACRC_DUMMY_INIT added a third argument (for a workaround), the "0"
1.1090 + // would match as that third argument, leading to infinite recursion.
1.1091 + return augmented_crc<Bits, TruncPoly>( buffer, byte_count,
1.1092 + static_cast<typename uint_t<Bits>::fast>(0) );
1.1093 +}
1.1094 +
1.1095 +
1.1096 +} // namespace boost
1.1097 +
1.1098 +
1.1099 +// Undo header-private macros
1.1100 +#undef BOOST_CRC_OPTIMAL_NAME
1.1101 +#undef BOOST_ACRC_DUMMY_INIT
1.1102 +#undef BOOST_ACRC_DUMMY_PARM_TYPE
1.1103 +#undef BOOST_CRC_DUMMY_INIT
1.1104 +#undef BOOST_CRC_DUMMY_PARM_TYPE
1.1105 +#undef BOOST_CRC_PARM_TYPE
1.1106 +
1.1107 +
1.1108 +#endif // BOOST_CRC_HPP
1.1109 +