1 //  Boost CRC library documentation examples file  ---------------------------//
2 
3 //  Copyright 2012 Daryle Walker.
4 //  Distributed under the Boost Software License, Version 1.0.  (See the
5 //  accompanying file LICENSE_1_0.txt or a copy at
6 //  <http://www.boost.org/LICENSE_1_0.txt>.)
7 
8 //  See <http://www.boost.org/libs/crc/> for the library's home page.
9 
10 #include "boost/crc.hpp"
11 #include <cstdarg>
12 #include <cstddef>
13 #include <utility>
14 
15 //[ crc_basic_reuse
16 //` Here's an example of reuse:
crc_16_and_xmodem(void const * b,std::size_t l)17 std::pair<unsigned, unsigned> crc_16_and_xmodem( void const *b, std::size_t l )
18 {
19     std::pair<unsigned, unsigned>  result;
20     /*<< The parameters are based on `boost::crc_16_type`. >>*/
21     boost::crc_basic<16>           crc1( 0x8005u, 0u, 0u, true, true );
22 
23     crc1.process_bytes( b, l );
24     result.first = crc1.checksum();
25     /*<< Change the parameters to match `boost::crc_xmodem_type`. >>*/
26     crc1 = boost::crc_basic<16>( 0x8408u, crc1.get_initial_remainder(),
27      crc1.get_final_xor_value(), crc1.get_reflect_input(),
28      crc1.get_reflect_remainder() );
29     crc1.process_bytes( b, l );
30     result.second = crc1.checksum();
31 
32     return result;
33 }
34 /*`
35 For now, most __RMCA__ parameters can only be changed through assignment to the
36 entire object.
37 */
38 //]
39 
40 //[ crc_piecemeal_run
41 //` Persistent objects mean that the data doesn't have to be in one block:
combined_crc_16(unsigned block_count,...)42 unsigned  combined_crc_16( unsigned block_count, ... )
43 {
44     /*<< C-style variable-argument routines are or may be macros. >>*/
45     using namespace std;
46 
47     /*<< The parameters are based on `boost::crc_16_type`. >>*/
48     boost::crc_basic<16>  crc1( 0x8005u, 0u, 0u, true, true );
49     va_list               ap;
50 
51     va_start( ap, block_count );
52     while ( block_count-- )
53     {
54         void const * const  bs = va_arg( ap, void const * );
55         size_t const        bl = va_arg( ap, size_t );
56 
57         /*<< The `va_arg` calls were within the `process_bytes` call, but I
58          remembered that calling order is not guaranteed among function
59          arguments, so I need explicit object declarations to enforce the
60          extraction order. >>*/
61         crc1.process_bytes( bs, bl );
62     }
63     va_end( ap );
64 
65     return crc1.checksum();
66 }
67 /*` No CRC operation throws, so there is no need for extra protection between
68     the varargs macro calls.
69 */
70 //]
71 
72 //[ acrc_piecemeal_run
73 //` The `augmented_crc` function can compute CRCs from distributed data, too:
combined_acrc_16(int block_count,...)74 unsigned  combined_acrc_16( int block_count, ... )
75 {
76     /*<< C-style variable-argument routines are or may be macros. >>*/
77     using namespace std;
78 
79     va_list   ap;
80     unsigned  result = 0u;
81 
82     va_start( ap, block_count );
83     if ( block_count <= 0 )
84         goto finish;
85 
86     void const *  bs = va_arg( ap, void const * );
87     size_t        bl = va_arg( ap, size_t );
88 
89     /*<< The parameters are based on `boost::crc_xmodem_t`. >>*/
90     result = boost::augmented_crc<16, 0x1021u>( bs, bl );
91     while ( --block_count )
92     {
93         bs = va_arg( ap, void const * );
94         bl = va_arg( ap, size_t );
95         result = boost::augmented_crc<16, 0x1021u>( bs, bl, result );
96     }
97 
98 finish:
99     va_end( ap );
100     return result;
101 }
102 /*` No CRC operation throws, so there is no need for extra protection between
103     the varargs macro calls.  Feeding the result from the previous run as the
104     initial remainder for the next run works easily because there's no output
105     reflection or XOR mask.
106 */
107 //]
108 
main()109 /*<-*/ int  main()  {} /*->*/
110