...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
#include <boost/cstdint.hpp> // for boost::uintmax_t #include <boost/integer.hpp> // for boost::uint_t #include <cstddef> // for std::size_t namespace boost { template < std::size_t Bits, uintmax_t TruncPoly > typename uint_t<Bits>::fast augmented_crc( void const *buffer, std::size_t byte_count, typename uint_t<Bits>::fast initial_remainder = 0u ); }
The boost::augmented_crc
function computes the augmented-style CRC of a data block. Like boost::crc
,
the first two template parameters are the WIDTH and POLY.
However, the INIT has moved to being a function parameter,
after the data block's starting address and byte length, defaulting to zero
if not given.
This function uses modulo-2 division at its most raw, and so forfeits the
REFIN, REFOUT, and XOROUT
attributes, setting them to 0
or
false
. Another difference from
boost::crc
is that a non-zero INIT
has to be skewed when used with this function. (No conversion functions are
currently given.)
The augmented_crc
function
can compute CRCs from distributed data, too:
unsigned combined_acrc_16( int block_count, ... ) { using namespace std; va_list ap; unsigned result = 0u; va_start( ap, block_count ); if ( block_count <= 0 ) goto finish; void const * bs = va_arg( ap, void const * ); size_t bl = va_arg( ap, size_t ); result = boost::augmented_crc<16, 0x1021u>( bs, bl ); while ( --block_count ) { bs = va_arg( ap, void const * ); bl = va_arg( ap, size_t ); result = boost::augmented_crc<16, 0x1021u>( bs, bl, result ); } finish: va_end( ap ); return result; }
No CRC operation throws, so there is no need for extra protection between the varargs macro calls. Feeding the result from the previous run as the initial remainder for the next run works easily because there's no output reflection or XOR mask.
C-style variable-argument routines are or may be macros. |
|
The parameters are based on |
Since augmented_crc
doesn't
know when your data ends, you must supply the augment, either WIDTH
zero bits or the expected checksum. The augment can be either at the end of
last data block or from an extra call. Remember that if an expected checksum
is used as the augment, its bits must be arranged in big-endian order. Because
augmented_crc
reads byte-wise,
while augments assume bit-wise reading, augmentations are valid only when
WIDTH is a multiple of the bits-per-byte ratio (CHAR_BIT
).