Chris@16
|
1 // Boost CRC library crc.hpp header file -----------------------------------//
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright 2001, 2004 Daryle Walker. Use, modification, and distribution are
|
Chris@16
|
4 // subject to the Boost Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
Chris@16
|
6
|
Chris@16
|
7 // See <http://www.boost.org/libs/crc/> for the library's home page.
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_CRC_HPP
|
Chris@16
|
10 #define BOOST_CRC_HPP
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc.
|
Chris@16
|
13 #include <boost/integer.hpp> // for boost::uint_t
|
Chris@16
|
14
|
Chris@16
|
15 #include <climits> // for CHAR_BIT, etc.
|
Chris@16
|
16 #include <cstddef> // for std::size_t
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/limits.hpp> // for std::numeric_limits
|
Chris@16
|
19
|
Chris@16
|
20
|
Chris@16
|
21 // The type of CRC parameters that can go in a template should be related
|
Chris@16
|
22 // on the CRC's bit count. This macro expresses that type in a compact
|
Chris@16
|
23 // form, but also allows an alternate type for compilers that don't support
|
Chris@16
|
24 // dependent types (in template value-parameters).
|
Chris@16
|
25 #if !(defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) || (defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)))
|
Chris@16
|
26 #define BOOST_CRC_PARM_TYPE typename ::boost::uint_t<Bits>::fast
|
Chris@16
|
27 #else
|
Chris@16
|
28 #define BOOST_CRC_PARM_TYPE unsigned long
|
Chris@16
|
29 #endif
|
Chris@16
|
30
|
Chris@16
|
31 // Some compilers [MS VC++ 6] cannot correctly set up several versions of a
|
Chris@16
|
32 // function template unless every template argument can be unambiguously
|
Chris@16
|
33 // deduced from the function arguments. (The bug is hidden if only one version
|
Chris@16
|
34 // is needed.) Since all of the CRC function templates have this problem, the
|
Chris@16
|
35 // workaround is to make up a dummy function argument that encodes the template
|
Chris@16
|
36 // arguments. Calls to such template functions need all their template
|
Chris@16
|
37 // arguments explicitly specified. At least one compiler that needs this
|
Chris@16
|
38 // workaround also needs the default value for the dummy argument to be
|
Chris@16
|
39 // specified in the definition.
|
Chris@16
|
40 #if defined(__GNUC__) || !defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
|
Chris@16
|
41 #define BOOST_CRC_DUMMY_PARM_TYPE
|
Chris@16
|
42 #define BOOST_CRC_DUMMY_INIT
|
Chris@16
|
43 #define BOOST_ACRC_DUMMY_PARM_TYPE
|
Chris@16
|
44 #define BOOST_ACRC_DUMMY_INIT
|
Chris@16
|
45 #else
|
Chris@16
|
46 namespace boost { namespace detail {
|
Chris@16
|
47 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
48 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
49 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
50 struct dummy_crc_argument { };
|
Chris@16
|
51 } }
|
Chris@16
|
52 #define BOOST_CRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument<Bits, \
|
Chris@16
|
53 TruncPoly, InitRem, FinalXor, ReflectIn, ReflectRem> *p_
|
Chris@16
|
54 #define BOOST_CRC_DUMMY_INIT BOOST_CRC_DUMMY_PARM_TYPE = 0
|
Chris@16
|
55 #define BOOST_ACRC_DUMMY_PARM_TYPE , detail::dummy_crc_argument<Bits, \
|
Chris@16
|
56 TruncPoly, 0, 0, false, false> *p_
|
Chris@16
|
57 #define BOOST_ACRC_DUMMY_INIT BOOST_ACRC_DUMMY_PARM_TYPE = 0
|
Chris@16
|
58 #endif
|
Chris@16
|
59
|
Chris@16
|
60
|
Chris@16
|
61 namespace boost
|
Chris@16
|
62 {
|
Chris@16
|
63
|
Chris@16
|
64
|
Chris@16
|
65 // Forward declarations ----------------------------------------------------//
|
Chris@16
|
66
|
Chris@16
|
67 template < std::size_t Bits >
|
Chris@16
|
68 class crc_basic;
|
Chris@16
|
69
|
Chris@16
|
70 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u,
|
Chris@16
|
71 BOOST_CRC_PARM_TYPE InitRem = 0u,
|
Chris@16
|
72 BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false,
|
Chris@16
|
73 bool ReflectRem = false >
|
Chris@16
|
74 class crc_optimal;
|
Chris@16
|
75
|
Chris@16
|
76 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
77 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
78 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
79 typename uint_t<Bits>::fast crc( void const *buffer,
|
Chris@16
|
80 std::size_t byte_count
|
Chris@16
|
81 BOOST_CRC_DUMMY_PARM_TYPE );
|
Chris@16
|
82
|
Chris@16
|
83 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
|
Chris@16
|
84 typename uint_t<Bits>::fast augmented_crc( void const *buffer,
|
Chris@16
|
85 std::size_t byte_count, typename uint_t<Bits>::fast initial_remainder
|
Chris@16
|
86 BOOST_ACRC_DUMMY_PARM_TYPE );
|
Chris@16
|
87
|
Chris@16
|
88 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
|
Chris@16
|
89 typename uint_t<Bits>::fast augmented_crc( void const *buffer,
|
Chris@16
|
90 std::size_t byte_count
|
Chris@16
|
91 BOOST_ACRC_DUMMY_PARM_TYPE );
|
Chris@16
|
92
|
Chris@16
|
93 typedef crc_optimal<16, 0x8005, 0, 0, true, true> crc_16_type;
|
Chris@16
|
94 typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_type;
|
Chris@16
|
95 typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type;
|
Chris@16
|
96
|
Chris@16
|
97 typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>
|
Chris@16
|
98 crc_32_type;
|
Chris@16
|
99
|
Chris@16
|
100
|
Chris@16
|
101 // Forward declarations for implementation detail stuff --------------------//
|
Chris@16
|
102 // (Just for the stuff that will be needed for the next two sections)
|
Chris@16
|
103
|
Chris@16
|
104 namespace detail
|
Chris@16
|
105 {
|
Chris@16
|
106 template < std::size_t Bits >
|
Chris@16
|
107 struct mask_uint_t;
|
Chris@16
|
108
|
Chris@16
|
109 template < >
|
Chris@16
|
110 struct mask_uint_t< std::numeric_limits<unsigned char>::digits >;
|
Chris@16
|
111
|
Chris@16
|
112 #if USHRT_MAX > UCHAR_MAX
|
Chris@16
|
113 template < >
|
Chris@16
|
114 struct mask_uint_t< std::numeric_limits<unsigned short>::digits >;
|
Chris@16
|
115 #endif
|
Chris@16
|
116
|
Chris@16
|
117 #if UINT_MAX > USHRT_MAX
|
Chris@16
|
118 template < >
|
Chris@16
|
119 struct mask_uint_t< std::numeric_limits<unsigned int>::digits >;
|
Chris@16
|
120 #endif
|
Chris@16
|
121
|
Chris@16
|
122 #if ULONG_MAX > UINT_MAX
|
Chris@16
|
123 template < >
|
Chris@16
|
124 struct mask_uint_t< std::numeric_limits<unsigned long>::digits >;
|
Chris@16
|
125 #endif
|
Chris@16
|
126
|
Chris@16
|
127 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
|
Chris@16
|
128 struct crc_table_t;
|
Chris@16
|
129
|
Chris@16
|
130 template < std::size_t Bits, bool DoReflect >
|
Chris@16
|
131 class crc_helper;
|
Chris@16
|
132
|
Chris@16
|
133 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
Chris@16
|
134 template < std::size_t Bits >
|
Chris@16
|
135 class crc_helper< Bits, false >;
|
Chris@16
|
136 #endif
|
Chris@16
|
137
|
Chris@16
|
138 } // namespace detail
|
Chris@16
|
139
|
Chris@16
|
140
|
Chris@16
|
141 // Simple cyclic redundancy code (CRC) class declaration -------------------//
|
Chris@16
|
142
|
Chris@16
|
143 template < std::size_t Bits >
|
Chris@16
|
144 class crc_basic
|
Chris@16
|
145 {
|
Chris@16
|
146 // Implementation type
|
Chris@16
|
147 typedef detail::mask_uint_t<Bits> masking_type;
|
Chris@16
|
148
|
Chris@16
|
149 public:
|
Chris@16
|
150 // Type
|
Chris@16
|
151 typedef typename masking_type::least value_type;
|
Chris@16
|
152
|
Chris@16
|
153 // Constant for the template parameter
|
Chris@16
|
154 BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
|
Chris@16
|
155
|
Chris@16
|
156 // Constructor
|
Chris@16
|
157 explicit crc_basic( value_type truncated_polynominal,
|
Chris@16
|
158 value_type initial_remainder = 0, value_type final_xor_value = 0,
|
Chris@16
|
159 bool reflect_input = false, bool reflect_remainder = false );
|
Chris@16
|
160
|
Chris@16
|
161 // Internal Operations
|
Chris@16
|
162 value_type get_truncated_polynominal() const;
|
Chris@16
|
163 value_type get_initial_remainder() const;
|
Chris@16
|
164 value_type get_final_xor_value() const;
|
Chris@16
|
165 bool get_reflect_input() const;
|
Chris@16
|
166 bool get_reflect_remainder() const;
|
Chris@16
|
167
|
Chris@16
|
168 value_type get_interim_remainder() const;
|
Chris@16
|
169 void reset( value_type new_rem );
|
Chris@16
|
170 void reset();
|
Chris@16
|
171
|
Chris@16
|
172 // External Operations
|
Chris@16
|
173 void process_bit( bool bit );
|
Chris@16
|
174 void process_bits( unsigned char bits, std::size_t bit_count );
|
Chris@16
|
175 void process_byte( unsigned char byte );
|
Chris@16
|
176 void process_block( void const *bytes_begin, void const *bytes_end );
|
Chris@16
|
177 void process_bytes( void const *buffer, std::size_t byte_count );
|
Chris@16
|
178
|
Chris@16
|
179 value_type checksum() const;
|
Chris@16
|
180
|
Chris@16
|
181 private:
|
Chris@16
|
182 // Member data
|
Chris@16
|
183 value_type rem_;
|
Chris@16
|
184 value_type poly_, init_, final_; // non-const to allow assignability
|
Chris@16
|
185 bool rft_in_, rft_out_; // non-const to allow assignability
|
Chris@16
|
186
|
Chris@16
|
187 }; // boost::crc_basic
|
Chris@16
|
188
|
Chris@16
|
189
|
Chris@16
|
190 // Optimized cyclic redundancy code (CRC) class declaration ----------------//
|
Chris@16
|
191
|
Chris@16
|
192 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
193 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
194 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
195 class crc_optimal
|
Chris@16
|
196 {
|
Chris@16
|
197 // Implementation type
|
Chris@16
|
198 typedef detail::mask_uint_t<Bits> masking_type;
|
Chris@16
|
199
|
Chris@16
|
200 public:
|
Chris@16
|
201 // Type
|
Chris@16
|
202 typedef typename masking_type::fast value_type;
|
Chris@16
|
203
|
Chris@16
|
204 // Constants for the template parameters
|
Chris@16
|
205 BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
|
Chris@16
|
206 BOOST_STATIC_CONSTANT( value_type, truncated_polynominal = TruncPoly );
|
Chris@16
|
207 BOOST_STATIC_CONSTANT( value_type, initial_remainder = InitRem );
|
Chris@16
|
208 BOOST_STATIC_CONSTANT( value_type, final_xor_value = FinalXor );
|
Chris@16
|
209 BOOST_STATIC_CONSTANT( bool, reflect_input = ReflectIn );
|
Chris@16
|
210 BOOST_STATIC_CONSTANT( bool, reflect_remainder = ReflectRem );
|
Chris@16
|
211
|
Chris@16
|
212 // Constructor
|
Chris@16
|
213 explicit crc_optimal( value_type init_rem = InitRem );
|
Chris@16
|
214
|
Chris@16
|
215 // Internal Operations
|
Chris@16
|
216 value_type get_truncated_polynominal() const;
|
Chris@16
|
217 value_type get_initial_remainder() const;
|
Chris@16
|
218 value_type get_final_xor_value() const;
|
Chris@16
|
219 bool get_reflect_input() const;
|
Chris@16
|
220 bool get_reflect_remainder() const;
|
Chris@16
|
221
|
Chris@16
|
222 value_type get_interim_remainder() const;
|
Chris@16
|
223 void reset( value_type new_rem = InitRem );
|
Chris@16
|
224
|
Chris@16
|
225 // External Operations
|
Chris@16
|
226 void process_byte( unsigned char byte );
|
Chris@16
|
227 void process_block( void const *bytes_begin, void const *bytes_end );
|
Chris@16
|
228 void process_bytes( void const *buffer, std::size_t byte_count );
|
Chris@16
|
229
|
Chris@16
|
230 value_type checksum() const;
|
Chris@16
|
231
|
Chris@16
|
232 // Operators
|
Chris@16
|
233 void operator ()( unsigned char byte );
|
Chris@16
|
234 value_type operator ()() const;
|
Chris@16
|
235
|
Chris@16
|
236 private:
|
Chris@16
|
237 // The implementation of output reflection depends on both reflect states.
|
Chris@16
|
238 BOOST_STATIC_CONSTANT( bool, reflect_output = (ReflectRem != ReflectIn) );
|
Chris@16
|
239
|
Chris@16
|
240 #ifndef __BORLANDC__
|
Chris@16
|
241 #define BOOST_CRC_REF_OUT_VAL reflect_output
|
Chris@16
|
242 #else
|
Chris@16
|
243 typedef crc_optimal self_type;
|
Chris@16
|
244 #define BOOST_CRC_REF_OUT_VAL (self_type::reflect_output)
|
Chris@16
|
245 #endif
|
Chris@16
|
246
|
Chris@16
|
247 // More implementation types
|
Chris@16
|
248 typedef detail::crc_table_t<Bits, TruncPoly, ReflectIn> crc_table_type;
|
Chris@16
|
249 typedef detail::crc_helper<Bits, ReflectIn> helper_type;
|
Chris@16
|
250 typedef detail::crc_helper<Bits, BOOST_CRC_REF_OUT_VAL> reflect_out_type;
|
Chris@16
|
251
|
Chris@16
|
252 #undef BOOST_CRC_REF_OUT_VAL
|
Chris@16
|
253
|
Chris@16
|
254 // Member data
|
Chris@16
|
255 value_type rem_;
|
Chris@16
|
256
|
Chris@16
|
257 }; // boost::crc_optimal
|
Chris@16
|
258
|
Chris@16
|
259
|
Chris@16
|
260 // Implementation detail stuff ---------------------------------------------//
|
Chris@16
|
261
|
Chris@16
|
262 namespace detail
|
Chris@16
|
263 {
|
Chris@16
|
264 // Forward declarations for more implementation details
|
Chris@16
|
265 template < std::size_t Bits >
|
Chris@16
|
266 struct high_uint_t;
|
Chris@16
|
267
|
Chris@16
|
268 template < std::size_t Bits >
|
Chris@16
|
269 struct reflector;
|
Chris@16
|
270
|
Chris@16
|
271
|
Chris@16
|
272 // Traits class for mask; given the bit number
|
Chris@16
|
273 // (1-based), get the mask for that bit by itself.
|
Chris@16
|
274 template < std::size_t Bits >
|
Chris@16
|
275 struct high_uint_t
|
Chris@16
|
276 : boost::uint_t< Bits >
|
Chris@16
|
277 {
|
Chris@16
|
278 typedef boost::uint_t<Bits> base_type;
|
Chris@16
|
279 typedef typename base_type::least least;
|
Chris@16
|
280 typedef typename base_type::fast fast;
|
Chris@16
|
281
|
Chris@16
|
282 #if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
|
Chris@16
|
283 static const least high_bit = 1ul << ( Bits - 1u );
|
Chris@16
|
284 static const fast high_bit_fast = 1ul << ( Bits - 1u );
|
Chris@16
|
285 #else
|
Chris@16
|
286 BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << ( Bits
|
Chris@16
|
287 - 1u )) );
|
Chris@16
|
288 BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << ( Bits
|
Chris@16
|
289 - 1u )) );
|
Chris@16
|
290 #endif
|
Chris@16
|
291
|
Chris@16
|
292 }; // boost::detail::high_uint_t
|
Chris@16
|
293
|
Chris@16
|
294
|
Chris@16
|
295 // Reflection routine class wrapper
|
Chris@16
|
296 // (since MS VC++ 6 couldn't handle the unwrapped version)
|
Chris@16
|
297 template < std::size_t Bits >
|
Chris@16
|
298 struct reflector
|
Chris@16
|
299 {
|
Chris@16
|
300 typedef typename boost::uint_t<Bits>::fast value_type;
|
Chris@16
|
301
|
Chris@16
|
302 static value_type reflect( value_type x );
|
Chris@16
|
303
|
Chris@16
|
304 }; // boost::detail::reflector
|
Chris@16
|
305
|
Chris@16
|
306 // Function that reflects its argument
|
Chris@16
|
307 template < std::size_t Bits >
|
Chris@16
|
308 typename reflector<Bits>::value_type
|
Chris@16
|
309 reflector<Bits>::reflect
|
Chris@16
|
310 (
|
Chris@16
|
311 typename reflector<Bits>::value_type x
|
Chris@16
|
312 )
|
Chris@16
|
313 {
|
Chris@16
|
314 value_type reflection = 0;
|
Chris@16
|
315 value_type const one = 1;
|
Chris@16
|
316
|
Chris@16
|
317 for ( std::size_t i = 0 ; i < Bits ; ++i, x >>= 1 )
|
Chris@16
|
318 {
|
Chris@16
|
319 if ( x & one )
|
Chris@16
|
320 {
|
Chris@16
|
321 reflection |= ( one << (Bits - 1u - i) );
|
Chris@16
|
322 }
|
Chris@16
|
323 }
|
Chris@16
|
324
|
Chris@16
|
325 return reflection;
|
Chris@16
|
326 }
|
Chris@16
|
327
|
Chris@16
|
328
|
Chris@16
|
329 // Traits class for masks; given the bit number (1-based),
|
Chris@16
|
330 // get the mask for that bit and its lower bits.
|
Chris@16
|
331 template < std::size_t Bits >
|
Chris@16
|
332 struct mask_uint_t
|
Chris@16
|
333 : high_uint_t< Bits >
|
Chris@16
|
334 {
|
Chris@16
|
335 typedef high_uint_t<Bits> base_type;
|
Chris@16
|
336 typedef typename base_type::least least;
|
Chris@16
|
337 typedef typename base_type::fast fast;
|
Chris@16
|
338
|
Chris@16
|
339 #ifndef __BORLANDC__
|
Chris@16
|
340 using base_type::high_bit;
|
Chris@16
|
341 using base_type::high_bit_fast;
|
Chris@16
|
342 #else
|
Chris@16
|
343 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
|
Chris@16
|
344 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
|
Chris@16
|
345 #endif
|
Chris@16
|
346
|
Chris@16
|
347 #if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
|
Chris@16
|
348 static const least sig_bits = (~( ~( 0ul ) << Bits )) ;
|
Chris@16
|
349 #else
|
Chris@16
|
350 BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) );
|
Chris@16
|
351 #endif
|
Chris@16
|
352 #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
|
Chris@16
|
353 // Work around a weird bug that ICEs the compiler in build_c_cast
|
Chris@16
|
354 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = static_cast<fast>(sig_bits) );
|
Chris@16
|
355 #else
|
Chris@16
|
356 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
|
Chris@16
|
357 #endif
|
Chris@16
|
358 }; // boost::detail::mask_uint_t
|
Chris@16
|
359
|
Chris@16
|
360 template < >
|
Chris@16
|
361 struct mask_uint_t< std::numeric_limits<unsigned char>::digits >
|
Chris@16
|
362 : high_uint_t< std::numeric_limits<unsigned char>::digits >
|
Chris@16
|
363 {
|
Chris@16
|
364 typedef high_uint_t<std::numeric_limits<unsigned char>::digits>
|
Chris@16
|
365 base_type;
|
Chris@16
|
366 typedef base_type::least least;
|
Chris@16
|
367 typedef base_type::fast fast;
|
Chris@16
|
368
|
Chris@16
|
369 #ifndef __BORLANDC__
|
Chris@16
|
370 using base_type::high_bit;
|
Chris@16
|
371 using base_type::high_bit_fast;
|
Chris@16
|
372 #else
|
Chris@16
|
373 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
|
Chris@16
|
374 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
|
Chris@16
|
375 #endif
|
Chris@16
|
376
|
Chris@16
|
377 BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
|
Chris@16
|
378 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
|
Chris@16
|
379
|
Chris@16
|
380 }; // boost::detail::mask_uint_t
|
Chris@16
|
381
|
Chris@16
|
382 #if USHRT_MAX > UCHAR_MAX
|
Chris@16
|
383 template < >
|
Chris@16
|
384 struct mask_uint_t< std::numeric_limits<unsigned short>::digits >
|
Chris@16
|
385 : high_uint_t< std::numeric_limits<unsigned short>::digits >
|
Chris@16
|
386 {
|
Chris@16
|
387 typedef high_uint_t<std::numeric_limits<unsigned short>::digits>
|
Chris@16
|
388 base_type;
|
Chris@16
|
389 typedef base_type::least least;
|
Chris@16
|
390 typedef base_type::fast fast;
|
Chris@16
|
391
|
Chris@16
|
392 #ifndef __BORLANDC__
|
Chris@16
|
393 using base_type::high_bit;
|
Chris@16
|
394 using base_type::high_bit_fast;
|
Chris@16
|
395 #else
|
Chris@16
|
396 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
|
Chris@16
|
397 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
|
Chris@16
|
398 #endif
|
Chris@16
|
399
|
Chris@16
|
400 BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
|
Chris@16
|
401 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
|
Chris@16
|
402
|
Chris@16
|
403 }; // boost::detail::mask_uint_t
|
Chris@16
|
404 #endif
|
Chris@16
|
405
|
Chris@16
|
406 #if UINT_MAX > USHRT_MAX
|
Chris@16
|
407 template < >
|
Chris@16
|
408 struct mask_uint_t< std::numeric_limits<unsigned int>::digits >
|
Chris@16
|
409 : high_uint_t< std::numeric_limits<unsigned int>::digits >
|
Chris@16
|
410 {
|
Chris@16
|
411 typedef high_uint_t<std::numeric_limits<unsigned int>::digits>
|
Chris@16
|
412 base_type;
|
Chris@16
|
413 typedef base_type::least least;
|
Chris@16
|
414 typedef base_type::fast fast;
|
Chris@16
|
415
|
Chris@16
|
416 #ifndef __BORLANDC__
|
Chris@16
|
417 using base_type::high_bit;
|
Chris@16
|
418 using base_type::high_bit_fast;
|
Chris@16
|
419 #else
|
Chris@16
|
420 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
|
Chris@16
|
421 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
|
Chris@16
|
422 #endif
|
Chris@16
|
423
|
Chris@16
|
424 BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
|
Chris@16
|
425 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
|
Chris@16
|
426
|
Chris@16
|
427 }; // boost::detail::mask_uint_t
|
Chris@16
|
428 #endif
|
Chris@16
|
429
|
Chris@16
|
430 #if ULONG_MAX > UINT_MAX
|
Chris@16
|
431 template < >
|
Chris@16
|
432 struct mask_uint_t< std::numeric_limits<unsigned long>::digits >
|
Chris@16
|
433 : high_uint_t< std::numeric_limits<unsigned long>::digits >
|
Chris@16
|
434 {
|
Chris@16
|
435 typedef high_uint_t<std::numeric_limits<unsigned long>::digits>
|
Chris@16
|
436 base_type;
|
Chris@16
|
437 typedef base_type::least least;
|
Chris@16
|
438 typedef base_type::fast fast;
|
Chris@16
|
439
|
Chris@16
|
440 #ifndef __BORLANDC__
|
Chris@16
|
441 using base_type::high_bit;
|
Chris@16
|
442 using base_type::high_bit_fast;
|
Chris@16
|
443 #else
|
Chris@16
|
444 BOOST_STATIC_CONSTANT( least, high_bit = base_type::high_bit );
|
Chris@16
|
445 BOOST_STATIC_CONSTANT( fast, high_bit_fast = base_type::high_bit_fast );
|
Chris@16
|
446 #endif
|
Chris@16
|
447
|
Chris@16
|
448 BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) );
|
Chris@16
|
449 BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
|
Chris@16
|
450
|
Chris@16
|
451 }; // boost::detail::mask_uint_t
|
Chris@16
|
452 #endif
|
Chris@16
|
453
|
Chris@16
|
454
|
Chris@16
|
455 // CRC table generator
|
Chris@16
|
456 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
|
Chris@16
|
457 struct crc_table_t
|
Chris@16
|
458 {
|
Chris@16
|
459 BOOST_STATIC_CONSTANT( std::size_t, byte_combos = (1ul << CHAR_BIT) );
|
Chris@16
|
460
|
Chris@16
|
461 typedef mask_uint_t<Bits> masking_type;
|
Chris@16
|
462 typedef typename masking_type::fast value_type;
|
Chris@16
|
463 #if defined(__BORLANDC__) && defined(_M_IX86) && (__BORLANDC__ == 0x560)
|
Chris@16
|
464 // for some reason Borland's command line compiler (version 0x560)
|
Chris@16
|
465 // chokes over this unless we do the calculation for it:
|
Chris@16
|
466 typedef value_type table_type[ 0x100 ];
|
Chris@16
|
467 #elif defined(__GNUC__)
|
Chris@16
|
468 // old versions of GCC (before 4.0.2) choke on using byte_combos
|
Chris@16
|
469 // as a constant expression when compiling with -pedantic.
|
Chris@16
|
470 typedef value_type table_type[1ul << CHAR_BIT];
|
Chris@16
|
471 #else
|
Chris@16
|
472 typedef value_type table_type[ byte_combos ];
|
Chris@16
|
473 #endif
|
Chris@16
|
474
|
Chris@16
|
475 static void init_table();
|
Chris@16
|
476
|
Chris@16
|
477 static table_type table_;
|
Chris@16
|
478
|
Chris@16
|
479 }; // boost::detail::crc_table_t
|
Chris@16
|
480
|
Chris@16
|
481 // CRC table generator static data member definition
|
Chris@16
|
482 // (Some compilers [Borland C++] require the initializer to be present.)
|
Chris@16
|
483 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
|
Chris@16
|
484 typename crc_table_t<Bits, TruncPoly, Reflect>::table_type
|
Chris@16
|
485 crc_table_t<Bits, TruncPoly, Reflect>::table_
|
Chris@16
|
486 = { 0 };
|
Chris@16
|
487
|
Chris@16
|
488 // Populate CRC lookup table
|
Chris@16
|
489 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool Reflect >
|
Chris@16
|
490 void
|
Chris@16
|
491 crc_table_t<Bits, TruncPoly, Reflect>::init_table
|
Chris@16
|
492 (
|
Chris@16
|
493 )
|
Chris@16
|
494 {
|
Chris@16
|
495 // compute table only on the first run
|
Chris@16
|
496 static bool did_init = false;
|
Chris@16
|
497 if ( did_init ) return;
|
Chris@16
|
498
|
Chris@16
|
499 // factor-out constants to avoid recalculation
|
Chris@16
|
500 value_type const fast_hi_bit = masking_type::high_bit_fast;
|
Chris@16
|
501 unsigned char const byte_hi_bit = 1u << (CHAR_BIT - 1u);
|
Chris@16
|
502
|
Chris@16
|
503 // loop over every possible dividend value
|
Chris@16
|
504 unsigned char dividend = 0;
|
Chris@16
|
505 do
|
Chris@16
|
506 {
|
Chris@16
|
507 value_type remainder = 0;
|
Chris@16
|
508
|
Chris@16
|
509 // go through all the dividend's bits
|
Chris@16
|
510 for ( unsigned char mask = byte_hi_bit ; mask ; mask >>= 1 )
|
Chris@16
|
511 {
|
Chris@16
|
512 // check if divisor fits
|
Chris@16
|
513 if ( dividend & mask )
|
Chris@16
|
514 {
|
Chris@16
|
515 remainder ^= fast_hi_bit;
|
Chris@16
|
516 }
|
Chris@16
|
517
|
Chris@16
|
518 // do polynominal division
|
Chris@16
|
519 if ( remainder & fast_hi_bit )
|
Chris@16
|
520 {
|
Chris@16
|
521 remainder <<= 1;
|
Chris@16
|
522 remainder ^= TruncPoly;
|
Chris@16
|
523 }
|
Chris@16
|
524 else
|
Chris@16
|
525 {
|
Chris@16
|
526 remainder <<= 1;
|
Chris@16
|
527 }
|
Chris@16
|
528 }
|
Chris@16
|
529
|
Chris@16
|
530 table_[ crc_helper<CHAR_BIT, Reflect>::reflect(dividend) ]
|
Chris@16
|
531 = crc_helper<Bits, Reflect>::reflect( remainder );
|
Chris@16
|
532 }
|
Chris@16
|
533 while ( ++dividend );
|
Chris@16
|
534
|
Chris@16
|
535 did_init = true;
|
Chris@16
|
536 }
|
Chris@16
|
537
|
Chris@16
|
538 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
Chris@16
|
539 // Align the msb of the remainder to a byte
|
Chris@16
|
540 template < std::size_t Bits, bool RightShift >
|
Chris@16
|
541 class remainder
|
Chris@16
|
542 {
|
Chris@16
|
543 public:
|
Chris@16
|
544 typedef typename uint_t<Bits>::fast value_type;
|
Chris@16
|
545
|
Chris@16
|
546 static unsigned char align_msb( value_type rem )
|
Chris@16
|
547 { return rem >> (Bits - CHAR_BIT); }
|
Chris@16
|
548 };
|
Chris@16
|
549
|
Chris@16
|
550 // Specialization for the case that the remainder has less
|
Chris@16
|
551 // bits than a byte: align the remainder msb to the byte msb
|
Chris@16
|
552 template < std::size_t Bits >
|
Chris@16
|
553 class remainder< Bits, false >
|
Chris@16
|
554 {
|
Chris@16
|
555 public:
|
Chris@16
|
556 typedef typename uint_t<Bits>::fast value_type;
|
Chris@16
|
557
|
Chris@16
|
558 static unsigned char align_msb( value_type rem )
|
Chris@16
|
559 { return rem << (CHAR_BIT - Bits); }
|
Chris@16
|
560 };
|
Chris@16
|
561 #endif
|
Chris@16
|
562
|
Chris@16
|
563 // CRC helper routines
|
Chris@16
|
564 template < std::size_t Bits, bool DoReflect >
|
Chris@16
|
565 class crc_helper
|
Chris@16
|
566 {
|
Chris@16
|
567 public:
|
Chris@16
|
568 // Type
|
Chris@16
|
569 typedef typename uint_t<Bits>::fast value_type;
|
Chris@16
|
570
|
Chris@16
|
571 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
Chris@16
|
572 // Possibly reflect a remainder
|
Chris@16
|
573 static value_type reflect( value_type x )
|
Chris@16
|
574 { return detail::reflector<Bits>::reflect( x ); }
|
Chris@16
|
575
|
Chris@16
|
576 // Compare a byte to the remainder's highest byte
|
Chris@16
|
577 static unsigned char index( value_type rem, unsigned char x )
|
Chris@16
|
578 { return x ^ rem; }
|
Chris@16
|
579
|
Chris@16
|
580 // Shift out the remainder's highest byte
|
Chris@16
|
581 static value_type shift( value_type rem )
|
Chris@16
|
582 { return rem >> CHAR_BIT; }
|
Chris@16
|
583 #else
|
Chris@16
|
584 // Possibly reflect a remainder
|
Chris@16
|
585 static value_type reflect( value_type x )
|
Chris@16
|
586 { return DoReflect ? detail::reflector<Bits>::reflect( x ) : x; }
|
Chris@16
|
587
|
Chris@16
|
588 // Compare a byte to the remainder's highest byte
|
Chris@16
|
589 static unsigned char index( value_type rem, unsigned char x )
|
Chris@16
|
590 { return x ^ ( DoReflect ? rem :
|
Chris@16
|
591 ((Bits>CHAR_BIT)?( rem >> (Bits - CHAR_BIT) ) :
|
Chris@16
|
592 ( rem << (CHAR_BIT - Bits) ))); }
|
Chris@16
|
593
|
Chris@16
|
594 // Shift out the remainder's highest byte
|
Chris@16
|
595 static value_type shift( value_type rem )
|
Chris@16
|
596 { return DoReflect ? rem >> CHAR_BIT : rem << CHAR_BIT; }
|
Chris@16
|
597 #endif
|
Chris@16
|
598
|
Chris@16
|
599 }; // boost::detail::crc_helper
|
Chris@16
|
600
|
Chris@16
|
601 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
Chris@16
|
602 template < std::size_t Bits >
|
Chris@16
|
603 class crc_helper<Bits, false>
|
Chris@16
|
604 {
|
Chris@16
|
605 public:
|
Chris@16
|
606 // Type
|
Chris@16
|
607 typedef typename uint_t<Bits>::fast value_type;
|
Chris@16
|
608
|
Chris@16
|
609 // Possibly reflect a remainder
|
Chris@16
|
610 static value_type reflect( value_type x )
|
Chris@16
|
611 { return x; }
|
Chris@16
|
612
|
Chris@16
|
613 // Compare a byte to the remainder's highest byte
|
Chris@16
|
614 static unsigned char index( value_type rem, unsigned char x )
|
Chris@16
|
615 { return x ^ remainder<Bits,(Bits>CHAR_BIT)>::align_msb( rem ); }
|
Chris@16
|
616
|
Chris@16
|
617 // Shift out the remainder's highest byte
|
Chris@16
|
618 static value_type shift( value_type rem )
|
Chris@16
|
619 { return rem << CHAR_BIT; }
|
Chris@16
|
620
|
Chris@16
|
621 }; // boost::detail::crc_helper
|
Chris@16
|
622 #endif
|
Chris@16
|
623
|
Chris@16
|
624
|
Chris@16
|
625 } // namespace detail
|
Chris@16
|
626
|
Chris@16
|
627
|
Chris@16
|
628 // Simple CRC class function definitions -----------------------------------//
|
Chris@16
|
629
|
Chris@16
|
630 template < std::size_t Bits >
|
Chris@16
|
631 inline
|
Chris@16
|
632 crc_basic<Bits>::crc_basic
|
Chris@16
|
633 (
|
Chris@16
|
634 typename crc_basic<Bits>::value_type truncated_polynominal,
|
Chris@16
|
635 typename crc_basic<Bits>::value_type initial_remainder, // = 0
|
Chris@16
|
636 typename crc_basic<Bits>::value_type final_xor_value, // = 0
|
Chris@16
|
637 bool reflect_input, // = false
|
Chris@16
|
638 bool reflect_remainder // = false
|
Chris@16
|
639 )
|
Chris@16
|
640 : rem_( initial_remainder ), poly_( truncated_polynominal )
|
Chris@16
|
641 , init_( initial_remainder ), final_( final_xor_value )
|
Chris@16
|
642 , rft_in_( reflect_input ), rft_out_( reflect_remainder )
|
Chris@16
|
643 {
|
Chris@16
|
644 }
|
Chris@16
|
645
|
Chris@16
|
646 template < std::size_t Bits >
|
Chris@16
|
647 inline
|
Chris@16
|
648 typename crc_basic<Bits>::value_type
|
Chris@16
|
649 crc_basic<Bits>::get_truncated_polynominal
|
Chris@16
|
650 (
|
Chris@16
|
651 ) const
|
Chris@16
|
652 {
|
Chris@16
|
653 return poly_;
|
Chris@16
|
654 }
|
Chris@16
|
655
|
Chris@16
|
656 template < std::size_t Bits >
|
Chris@16
|
657 inline
|
Chris@16
|
658 typename crc_basic<Bits>::value_type
|
Chris@16
|
659 crc_basic<Bits>::get_initial_remainder
|
Chris@16
|
660 (
|
Chris@16
|
661 ) const
|
Chris@16
|
662 {
|
Chris@16
|
663 return init_;
|
Chris@16
|
664 }
|
Chris@16
|
665
|
Chris@16
|
666 template < std::size_t Bits >
|
Chris@16
|
667 inline
|
Chris@16
|
668 typename crc_basic<Bits>::value_type
|
Chris@16
|
669 crc_basic<Bits>::get_final_xor_value
|
Chris@16
|
670 (
|
Chris@16
|
671 ) const
|
Chris@16
|
672 {
|
Chris@16
|
673 return final_;
|
Chris@16
|
674 }
|
Chris@16
|
675
|
Chris@16
|
676 template < std::size_t Bits >
|
Chris@16
|
677 inline
|
Chris@16
|
678 bool
|
Chris@16
|
679 crc_basic<Bits>::get_reflect_input
|
Chris@16
|
680 (
|
Chris@16
|
681 ) const
|
Chris@16
|
682 {
|
Chris@16
|
683 return rft_in_;
|
Chris@16
|
684 }
|
Chris@16
|
685
|
Chris@16
|
686 template < std::size_t Bits >
|
Chris@16
|
687 inline
|
Chris@16
|
688 bool
|
Chris@16
|
689 crc_basic<Bits>::get_reflect_remainder
|
Chris@16
|
690 (
|
Chris@16
|
691 ) const
|
Chris@16
|
692 {
|
Chris@16
|
693 return rft_out_;
|
Chris@16
|
694 }
|
Chris@16
|
695
|
Chris@16
|
696 template < std::size_t Bits >
|
Chris@16
|
697 inline
|
Chris@16
|
698 typename crc_basic<Bits>::value_type
|
Chris@16
|
699 crc_basic<Bits>::get_interim_remainder
|
Chris@16
|
700 (
|
Chris@16
|
701 ) const
|
Chris@16
|
702 {
|
Chris@16
|
703 return rem_ & masking_type::sig_bits;
|
Chris@16
|
704 }
|
Chris@16
|
705
|
Chris@16
|
706 template < std::size_t Bits >
|
Chris@16
|
707 inline
|
Chris@16
|
708 void
|
Chris@16
|
709 crc_basic<Bits>::reset
|
Chris@16
|
710 (
|
Chris@16
|
711 typename crc_basic<Bits>::value_type new_rem
|
Chris@16
|
712 )
|
Chris@16
|
713 {
|
Chris@16
|
714 rem_ = new_rem;
|
Chris@16
|
715 }
|
Chris@16
|
716
|
Chris@16
|
717 template < std::size_t Bits >
|
Chris@16
|
718 inline
|
Chris@16
|
719 void
|
Chris@16
|
720 crc_basic<Bits>::reset
|
Chris@16
|
721 (
|
Chris@16
|
722 )
|
Chris@16
|
723 {
|
Chris@16
|
724 this->reset( this->get_initial_remainder() );
|
Chris@16
|
725 }
|
Chris@16
|
726
|
Chris@16
|
727 template < std::size_t Bits >
|
Chris@16
|
728 inline
|
Chris@16
|
729 void
|
Chris@16
|
730 crc_basic<Bits>::process_bit
|
Chris@16
|
731 (
|
Chris@16
|
732 bool bit
|
Chris@16
|
733 )
|
Chris@16
|
734 {
|
Chris@16
|
735 value_type const high_bit_mask = masking_type::high_bit;
|
Chris@16
|
736
|
Chris@16
|
737 // compare the new bit with the remainder's highest
|
Chris@16
|
738 rem_ ^= ( bit ? high_bit_mask : 0u );
|
Chris@16
|
739
|
Chris@16
|
740 // a full polynominal division step is done when the highest bit is one
|
Chris@16
|
741 bool const do_poly_div = static_cast<bool>( rem_ & high_bit_mask );
|
Chris@16
|
742
|
Chris@16
|
743 // shift out the highest bit
|
Chris@16
|
744 rem_ <<= 1;
|
Chris@16
|
745
|
Chris@16
|
746 // carry out the division, if needed
|
Chris@16
|
747 if ( do_poly_div )
|
Chris@16
|
748 {
|
Chris@16
|
749 rem_ ^= poly_;
|
Chris@16
|
750 }
|
Chris@16
|
751 }
|
Chris@16
|
752
|
Chris@16
|
753 template < std::size_t Bits >
|
Chris@16
|
754 void
|
Chris@16
|
755 crc_basic<Bits>::process_bits
|
Chris@16
|
756 (
|
Chris@16
|
757 unsigned char bits,
|
Chris@16
|
758 std::size_t bit_count
|
Chris@16
|
759 )
|
Chris@16
|
760 {
|
Chris@16
|
761 // ignore the bits above the ones we want
|
Chris@16
|
762 bits <<= CHAR_BIT - bit_count;
|
Chris@16
|
763
|
Chris@16
|
764 // compute the CRC for each bit, starting with the upper ones
|
Chris@16
|
765 unsigned char const high_bit_mask = 1u << ( CHAR_BIT - 1u );
|
Chris@16
|
766 for ( std::size_t i = bit_count ; i > 0u ; --i, bits <<= 1u )
|
Chris@16
|
767 {
|
Chris@16
|
768 process_bit( static_cast<bool>(bits & high_bit_mask) );
|
Chris@16
|
769 }
|
Chris@16
|
770 }
|
Chris@16
|
771
|
Chris@16
|
772 template < std::size_t Bits >
|
Chris@16
|
773 inline
|
Chris@16
|
774 void
|
Chris@16
|
775 crc_basic<Bits>::process_byte
|
Chris@16
|
776 (
|
Chris@16
|
777 unsigned char byte
|
Chris@16
|
778 )
|
Chris@16
|
779 {
|
Chris@16
|
780 process_bits( (rft_in_ ? detail::reflector<CHAR_BIT>::reflect(byte)
|
Chris@16
|
781 : byte), CHAR_BIT );
|
Chris@16
|
782 }
|
Chris@16
|
783
|
Chris@16
|
784 template < std::size_t Bits >
|
Chris@16
|
785 void
|
Chris@16
|
786 crc_basic<Bits>::process_block
|
Chris@16
|
787 (
|
Chris@16
|
788 void const * bytes_begin,
|
Chris@16
|
789 void const * bytes_end
|
Chris@16
|
790 )
|
Chris@16
|
791 {
|
Chris@16
|
792 for ( unsigned char const * p
|
Chris@16
|
793 = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
|
Chris@16
|
794 {
|
Chris@16
|
795 process_byte( *p );
|
Chris@16
|
796 }
|
Chris@16
|
797 }
|
Chris@16
|
798
|
Chris@16
|
799 template < std::size_t Bits >
|
Chris@16
|
800 inline
|
Chris@16
|
801 void
|
Chris@16
|
802 crc_basic<Bits>::process_bytes
|
Chris@16
|
803 (
|
Chris@16
|
804 void const * buffer,
|
Chris@16
|
805 std::size_t byte_count
|
Chris@16
|
806 )
|
Chris@16
|
807 {
|
Chris@16
|
808 unsigned char const * const b = static_cast<unsigned char const *>(
|
Chris@16
|
809 buffer );
|
Chris@16
|
810
|
Chris@16
|
811 process_block( b, b + byte_count );
|
Chris@16
|
812 }
|
Chris@16
|
813
|
Chris@16
|
814 template < std::size_t Bits >
|
Chris@16
|
815 inline
|
Chris@16
|
816 typename crc_basic<Bits>::value_type
|
Chris@16
|
817 crc_basic<Bits>::checksum
|
Chris@16
|
818 (
|
Chris@16
|
819 ) const
|
Chris@16
|
820 {
|
Chris@16
|
821 return ( (rft_out_ ? detail::reflector<Bits>::reflect( rem_ ) : rem_)
|
Chris@16
|
822 ^ final_ ) & masking_type::sig_bits;
|
Chris@16
|
823 }
|
Chris@16
|
824
|
Chris@16
|
825
|
Chris@16
|
826 // Optimized CRC class function definitions --------------------------------//
|
Chris@16
|
827
|
Chris@16
|
828 // Macro to compact code
|
Chris@16
|
829 #define BOOST_CRC_OPTIMAL_NAME crc_optimal<Bits, TruncPoly, InitRem, \
|
Chris@16
|
830 FinalXor, ReflectIn, ReflectRem>
|
Chris@16
|
831
|
Chris@16
|
832 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
833 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
834 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
835 inline
|
Chris@16
|
836 BOOST_CRC_OPTIMAL_NAME::crc_optimal
|
Chris@16
|
837 (
|
Chris@16
|
838 typename BOOST_CRC_OPTIMAL_NAME::value_type init_rem // = InitRem
|
Chris@16
|
839 )
|
Chris@16
|
840 : rem_( helper_type::reflect(init_rem) )
|
Chris@16
|
841 {
|
Chris@16
|
842 crc_table_type::init_table();
|
Chris@16
|
843 }
|
Chris@16
|
844
|
Chris@16
|
845 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
846 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
847 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
848 inline
|
Chris@16
|
849 typename BOOST_CRC_OPTIMAL_NAME::value_type
|
Chris@16
|
850 BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal
|
Chris@16
|
851 (
|
Chris@16
|
852 ) const
|
Chris@16
|
853 {
|
Chris@16
|
854 return TruncPoly;
|
Chris@16
|
855 }
|
Chris@16
|
856
|
Chris@16
|
857 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
858 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
859 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
860 inline
|
Chris@16
|
861 typename BOOST_CRC_OPTIMAL_NAME::value_type
|
Chris@16
|
862 BOOST_CRC_OPTIMAL_NAME::get_initial_remainder
|
Chris@16
|
863 (
|
Chris@16
|
864 ) const
|
Chris@16
|
865 {
|
Chris@16
|
866 return InitRem;
|
Chris@16
|
867 }
|
Chris@16
|
868
|
Chris@16
|
869 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
870 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
871 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
872 inline
|
Chris@16
|
873 typename BOOST_CRC_OPTIMAL_NAME::value_type
|
Chris@16
|
874 BOOST_CRC_OPTIMAL_NAME::get_final_xor_value
|
Chris@16
|
875 (
|
Chris@16
|
876 ) const
|
Chris@16
|
877 {
|
Chris@16
|
878 return FinalXor;
|
Chris@16
|
879 }
|
Chris@16
|
880
|
Chris@16
|
881 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
882 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
883 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
884 inline
|
Chris@16
|
885 bool
|
Chris@16
|
886 BOOST_CRC_OPTIMAL_NAME::get_reflect_input
|
Chris@16
|
887 (
|
Chris@16
|
888 ) const
|
Chris@16
|
889 {
|
Chris@16
|
890 return ReflectIn;
|
Chris@16
|
891 }
|
Chris@16
|
892
|
Chris@16
|
893 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
894 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
895 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
896 inline
|
Chris@16
|
897 bool
|
Chris@16
|
898 BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder
|
Chris@16
|
899 (
|
Chris@16
|
900 ) const
|
Chris@16
|
901 {
|
Chris@16
|
902 return ReflectRem;
|
Chris@16
|
903 }
|
Chris@16
|
904
|
Chris@16
|
905 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
906 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
907 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
908 inline
|
Chris@16
|
909 typename BOOST_CRC_OPTIMAL_NAME::value_type
|
Chris@16
|
910 BOOST_CRC_OPTIMAL_NAME::get_interim_remainder
|
Chris@16
|
911 (
|
Chris@16
|
912 ) const
|
Chris@16
|
913 {
|
Chris@16
|
914 // Interim remainder should be _un_-reflected, so we have to undo it.
|
Chris@16
|
915 return helper_type::reflect( rem_ ) & masking_type::sig_bits_fast;
|
Chris@16
|
916 }
|
Chris@16
|
917
|
Chris@16
|
918 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
919 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
920 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
921 inline
|
Chris@16
|
922 void
|
Chris@16
|
923 BOOST_CRC_OPTIMAL_NAME::reset
|
Chris@16
|
924 (
|
Chris@16
|
925 typename BOOST_CRC_OPTIMAL_NAME::value_type new_rem // = InitRem
|
Chris@16
|
926 )
|
Chris@16
|
927 {
|
Chris@16
|
928 rem_ = helper_type::reflect( new_rem );
|
Chris@16
|
929 }
|
Chris@16
|
930
|
Chris@16
|
931 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
932 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
933 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
934 inline
|
Chris@16
|
935 void
|
Chris@16
|
936 BOOST_CRC_OPTIMAL_NAME::process_byte
|
Chris@16
|
937 (
|
Chris@16
|
938 unsigned char byte
|
Chris@16
|
939 )
|
Chris@16
|
940 {
|
Chris@16
|
941 process_bytes( &byte, sizeof(byte) );
|
Chris@16
|
942 }
|
Chris@16
|
943
|
Chris@16
|
944 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
945 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
946 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
947 void
|
Chris@16
|
948 BOOST_CRC_OPTIMAL_NAME::process_block
|
Chris@16
|
949 (
|
Chris@16
|
950 void const * bytes_begin,
|
Chris@16
|
951 void const * bytes_end
|
Chris@16
|
952 )
|
Chris@16
|
953 {
|
Chris@16
|
954 // Recompute the CRC for each byte passed
|
Chris@16
|
955 for ( unsigned char const * p
|
Chris@16
|
956 = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
|
Chris@16
|
957 {
|
Chris@16
|
958 // Compare the new byte with the remainder's higher bits to
|
Chris@16
|
959 // get the new bits, shift out the remainder's current higher
|
Chris@16
|
960 // bits, and update the remainder with the polynominal division
|
Chris@16
|
961 // of the new bits.
|
Chris@16
|
962 unsigned char const byte_index = helper_type::index( rem_, *p );
|
Chris@16
|
963 rem_ = helper_type::shift( rem_ );
|
Chris@16
|
964 rem_ ^= crc_table_type::table_[ byte_index ];
|
Chris@16
|
965 }
|
Chris@16
|
966 }
|
Chris@16
|
967
|
Chris@16
|
968 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
969 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
970 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
971 inline
|
Chris@16
|
972 void
|
Chris@16
|
973 BOOST_CRC_OPTIMAL_NAME::process_bytes
|
Chris@16
|
974 (
|
Chris@16
|
975 void const * buffer,
|
Chris@16
|
976 std::size_t byte_count
|
Chris@16
|
977 )
|
Chris@16
|
978 {
|
Chris@16
|
979 unsigned char const * const b = static_cast<unsigned char const *>(
|
Chris@16
|
980 buffer );
|
Chris@16
|
981 process_block( b, b + byte_count );
|
Chris@16
|
982 }
|
Chris@16
|
983
|
Chris@16
|
984 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
985 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
986 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
987 inline
|
Chris@16
|
988 typename BOOST_CRC_OPTIMAL_NAME::value_type
|
Chris@16
|
989 BOOST_CRC_OPTIMAL_NAME::checksum
|
Chris@16
|
990 (
|
Chris@16
|
991 ) const
|
Chris@16
|
992 {
|
Chris@16
|
993 return ( reflect_out_type::reflect(rem_) ^ get_final_xor_value() )
|
Chris@16
|
994 & masking_type::sig_bits_fast;
|
Chris@16
|
995 }
|
Chris@16
|
996
|
Chris@16
|
997 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
998 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
999 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
1000 inline
|
Chris@16
|
1001 void
|
Chris@16
|
1002 BOOST_CRC_OPTIMAL_NAME::operator ()
|
Chris@16
|
1003 (
|
Chris@16
|
1004 unsigned char byte
|
Chris@16
|
1005 )
|
Chris@16
|
1006 {
|
Chris@16
|
1007 process_byte( byte );
|
Chris@16
|
1008 }
|
Chris@16
|
1009
|
Chris@16
|
1010 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
1011 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
1012 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
1013 inline
|
Chris@16
|
1014 typename BOOST_CRC_OPTIMAL_NAME::value_type
|
Chris@16
|
1015 BOOST_CRC_OPTIMAL_NAME::operator ()
|
Chris@16
|
1016 (
|
Chris@16
|
1017 ) const
|
Chris@16
|
1018 {
|
Chris@16
|
1019 return checksum();
|
Chris@16
|
1020 }
|
Chris@16
|
1021
|
Chris@16
|
1022
|
Chris@16
|
1023 // CRC computation function definition -------------------------------------//
|
Chris@16
|
1024
|
Chris@16
|
1025 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
|
Chris@16
|
1026 BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
|
Chris@16
|
1027 bool ReflectIn, bool ReflectRem >
|
Chris@16
|
1028 inline
|
Chris@16
|
1029 typename uint_t<Bits>::fast
|
Chris@16
|
1030 crc
|
Chris@16
|
1031 (
|
Chris@16
|
1032 void const * buffer,
|
Chris@16
|
1033 std::size_t byte_count
|
Chris@16
|
1034 BOOST_CRC_DUMMY_INIT
|
Chris@16
|
1035 )
|
Chris@16
|
1036 {
|
Chris@16
|
1037 BOOST_CRC_OPTIMAL_NAME computer;
|
Chris@16
|
1038 computer.process_bytes( buffer, byte_count );
|
Chris@16
|
1039 return computer.checksum();
|
Chris@16
|
1040 }
|
Chris@16
|
1041
|
Chris@16
|
1042
|
Chris@16
|
1043 // Augmented-message CRC computation function definitions ------------------//
|
Chris@16
|
1044
|
Chris@16
|
1045 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
|
Chris@16
|
1046 typename uint_t<Bits>::fast
|
Chris@16
|
1047 augmented_crc
|
Chris@16
|
1048 (
|
Chris@16
|
1049 void const * buffer,
|
Chris@16
|
1050 std::size_t byte_count,
|
Chris@16
|
1051 typename uint_t<Bits>::fast initial_remainder
|
Chris@16
|
1052 BOOST_ACRC_DUMMY_INIT
|
Chris@16
|
1053 )
|
Chris@16
|
1054 {
|
Chris@16
|
1055 typedef unsigned char byte_type;
|
Chris@16
|
1056 typedef detail::mask_uint_t<Bits> masking_type;
|
Chris@16
|
1057 typedef detail::crc_table_t<Bits, TruncPoly, false> crc_table_type;
|
Chris@16
|
1058
|
Chris@16
|
1059 typename masking_type::fast rem = initial_remainder;
|
Chris@16
|
1060 byte_type const * const b = static_cast<byte_type const *>( buffer );
|
Chris@16
|
1061 byte_type const * const e = b + byte_count;
|
Chris@16
|
1062
|
Chris@16
|
1063 crc_table_type::init_table();
|
Chris@16
|
1064 for ( byte_type const * p = b ; p < e ; ++p )
|
Chris@16
|
1065 {
|
Chris@16
|
1066 // Use the current top byte as the table index to the next
|
Chris@16
|
1067 // "partial product." Shift out that top byte, shifting in
|
Chris@16
|
1068 // the next augmented-message byte. Complete the division.
|
Chris@16
|
1069 byte_type const byte_index = rem >> ( Bits - CHAR_BIT );
|
Chris@16
|
1070 rem <<= CHAR_BIT;
|
Chris@16
|
1071 rem |= *p;
|
Chris@16
|
1072 rem ^= crc_table_type::table_[ byte_index ];
|
Chris@16
|
1073 }
|
Chris@16
|
1074
|
Chris@16
|
1075 return rem & masking_type::sig_bits_fast;
|
Chris@16
|
1076 }
|
Chris@16
|
1077
|
Chris@16
|
1078 template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
|
Chris@16
|
1079 inline
|
Chris@16
|
1080 typename uint_t<Bits>::fast
|
Chris@16
|
1081 augmented_crc
|
Chris@16
|
1082 (
|
Chris@16
|
1083 void const * buffer,
|
Chris@16
|
1084 std::size_t byte_count
|
Chris@16
|
1085 BOOST_ACRC_DUMMY_INIT
|
Chris@16
|
1086 )
|
Chris@16
|
1087 {
|
Chris@16
|
1088 // The last function argument has its type specified so the other version of
|
Chris@16
|
1089 // augmented_crc will be called. If the cast wasn't in place, and the
|
Chris@16
|
1090 // BOOST_ACRC_DUMMY_INIT added a third argument (for a workaround), the "0"
|
Chris@16
|
1091 // would match as that third argument, leading to infinite recursion.
|
Chris@16
|
1092 return augmented_crc<Bits, TruncPoly>( buffer, byte_count,
|
Chris@16
|
1093 static_cast<typename uint_t<Bits>::fast>(0) );
|
Chris@16
|
1094 }
|
Chris@16
|
1095
|
Chris@16
|
1096
|
Chris@16
|
1097 } // namespace boost
|
Chris@16
|
1098
|
Chris@16
|
1099
|
Chris@16
|
1100 // Undo header-private macros
|
Chris@16
|
1101 #undef BOOST_CRC_OPTIMAL_NAME
|
Chris@16
|
1102 #undef BOOST_ACRC_DUMMY_INIT
|
Chris@16
|
1103 #undef BOOST_ACRC_DUMMY_PARM_TYPE
|
Chris@16
|
1104 #undef BOOST_CRC_DUMMY_INIT
|
Chris@16
|
1105 #undef BOOST_CRC_DUMMY_PARM_TYPE
|
Chris@16
|
1106 #undef BOOST_CRC_PARM_TYPE
|
Chris@16
|
1107
|
Chris@16
|
1108
|
Chris@16
|
1109 #endif // BOOST_CRC_HPP
|
Chris@16
|
1110
|