crc.hpp 93 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343
  1. // Boost CRC library crc.hpp header file -----------------------------------//
  2. // Copyright 2001, 2004, 2011 Daryle Walker.
  3. // Distributed under the Boost Software License, Version 1.0. (See the
  4. // accompanying file LICENSE_1_0.txt or a copy at
  5. // <http://www.boost.org/LICENSE_1_0.txt>.)
  6. // See <http://www.boost.org/libs/crc/> for the library's home page.
  7. /** \file
  8. \brief A collection of function templates and class templates that compute
  9. various forms of Cyclic Redundancy Codes (CRCs).
  10. \author Daryle Walker
  11. \version 1.5
  12. \copyright Boost Software License, version 1.0
  13. Contains the declarations (and definitions) of various kinds of CRC
  14. computation functions, function object types, and encapsulated policy types.
  15. \warning The sample CRC-computer types were just checked against the
  16. <a href="http://regregex.bbcmicro.net/crc-catalogue.htm">Catalogue of
  17. parametrised CRC algorithms</a>. New type aliases were added where I got
  18. a standard wrong. However, the mistaken <code>typedef</code>s are still
  19. there for backwards compatibility.
  20. \note There are references to the <i>Rocksoft&trade; Model CRC
  21. Algorithm</i>, as described within \"A Painless Guide to CRC Error
  22. Detection Algorithms,\" linked from \"<a
  23. href="http://www.ross.net/crc/crcpaper.html">CRC: A Paper On CRCs</a>\" by
  24. Ross Williams. It will be abbreviated \"RMCA\" in other documentation
  25. blocks.
  26. */
  27. #ifndef BOOST_CRC_HPP
  28. #define BOOST_CRC_HPP
  29. #include <array> // for std::array
  30. #include <climits> // for CHAR_BIT, etc.
  31. #include <cstddef> // for std::size_t
  32. #include <cstdint> // for UINTMAX_C, std::uintmax_t
  33. #include <limits> // for std::numeric_limits
  34. #include <type_traits> // for std::conditional, std::integral_constant
  35. // Local reimplementation of boost::uint_t, to avoid dependency on Integer
  36. namespace boost {
  37. namespace crc_detail {
  38. struct uint_t_8
  39. {
  40. typedef std::uint_least8_t least;
  41. typedef std::uint_fast8_t fast;
  42. };
  43. struct uint_t_16
  44. {
  45. typedef std::uint_least16_t least;
  46. typedef std::uint_fast16_t fast;
  47. };
  48. struct uint_t_32
  49. {
  50. typedef std::uint_least32_t least;
  51. typedef std::uint_fast32_t fast;
  52. };
  53. struct uint_t_64
  54. {
  55. typedef std::uint_least64_t least;
  56. typedef std::uint_fast64_t fast;
  57. };
  58. struct uint_t_none
  59. {
  60. };
  61. template<int Bits> struct uint_t:
  62. std::conditional< (Bits <= 8), uint_t_8,
  63. typename std::conditional< (Bits <= 16), uint_t_16,
  64. typename std::conditional< (Bits <= 32), uint_t_32,
  65. typename std::conditional< (Bits <= 64), uint_t_64,
  66. uint_t_none>::type>::type>::type>::type
  67. {
  68. };
  69. } // namespace crc_detail
  70. } // namespace boost
  71. // The type of CRC parameters that can go in a template should be related
  72. // on the CRC's bit count. This macro expresses that type in a compact
  73. // form.
  74. #define BOOST_CRC_PARM_TYPE typename ::boost::crc_detail::uint_t<Bits>::fast
  75. namespace boost
  76. {
  77. // Forward declarations ----------------------------------------------------//
  78. //! Bit-wise CRC computer
  79. template < std::size_t Bits >
  80. class crc_basic;
  81. //! Table-driven CRC computer, usable as a function object
  82. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u,
  83. BOOST_CRC_PARM_TYPE InitRem = 0u,
  84. BOOST_CRC_PARM_TYPE FinalXor = 0u, bool ReflectIn = false,
  85. bool ReflectRem = false >
  86. class crc_optimal;
  87. //! Compute the (unaugmented) CRC of a memory block
  88. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  89. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  90. bool ReflectIn, bool ReflectRem >
  91. typename crc_detail::uint_t<Bits>::fast crc( void const *buffer,
  92. std::size_t byte_count);
  93. //! Compute the CRC of a memory block, with any augmentation provided by user
  94. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
  95. typename crc_detail::uint_t<Bits>::fast augmented_crc( void const *buffer,
  96. std::size_t byte_count,
  97. typename crc_detail::uint_t<Bits>::fast initial_remainder = 0u);
  98. //! Computation type for ARC|CRC-16|CRC-IBM|CRC-16/ARC|CRC-16/LHA standard
  99. typedef crc_optimal<16, 0x8005, 0, 0, true, true> crc_16_type;
  100. //! Computation type for CRC-16/CCITT-FALSE standard
  101. typedef crc_optimal<16, 0x1021, 0xFFFF, 0, false, false> crc_ccitt_false_t;
  102. //! Computation type for the CRC mistakenly called the CCITT standard
  103. typedef crc_ccitt_false_t crc_ccitt_type;
  104. //! Computation type for the actual
  105. //! KERMIT|CRC-16/CCITT|CRC-16/CCITT-TRUE|CRC-CCITT standard
  106. typedef crc_optimal<16, 0x1021, 0, 0, true, true> crc_ccitt_true_t;
  107. //! Computation type that I mistakenly called the XMODEM standard; it inverts
  108. //! both reflection parameters and reflects the truncated divisor (Don't use?!)
  109. typedef crc_optimal<16, 0x8408, 0, 0, true, true> crc_xmodem_type;
  110. //! Computation type for the actual XMODEM|ZMODEM|CRC-16/ACORN standard
  111. typedef crc_optimal<16, 0x1021, 0, 0, false, false> crc_xmodem_t;
  112. //! Computation type for CRC-32|CRC-32/ADCCP|PKZIP standard
  113. typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true>
  114. crc_32_type;
  115. // Forward declarations for implementation detail stuff --------------------//
  116. // (Just for the stuff that will be needed for the next two sections)
  117. //! \cond
  118. namespace detail
  119. {
  120. //! Mix-in class to add a possibly-reflecting member function
  121. template < int BitLength, bool DoIt, int Id = 0 >
  122. class possible_reflector;
  123. //! Mix-in class for byte-fed, table-driven CRC algorithms
  124. template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect,
  125. int Id = 0 >
  126. class crc_driver;
  127. } // namespace detail
  128. //! \endcond
  129. // Simple cyclic redundancy code (CRC) class declaration -------------------//
  130. /** Objects of this type compute the CRC checksum of submitted data, where said
  131. data can be entered piecemeal through several different kinds of groupings.
  132. Modulo-2 polynomial division steps are always performed bit-wise, without
  133. the use of pre-computation tables. Said division uses the altered
  134. algorithm, so any data has to be unaugmented.
  135. \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
  136. \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from
  137. the RMCA)
  138. */
  139. template < std::size_t Bits >
  140. class crc_basic
  141. {
  142. public:
  143. // Type
  144. /** \brief The register type used for computations
  145. This type is used for CRC calculations and is the type for any returned
  146. checksums and returned or submitted remainders, (truncated) divisors, or
  147. XOR masks. It is a built-in unsigned integer type.
  148. */
  149. typedef typename boost::crc_detail::uint_t<Bits>::fast value_type;
  150. // Constant for the template parameter
  151. //! A copy of \a Bits provided for meta-programming purposes
  152. static const std::size_t bit_count = Bits;
  153. // Constructor (use the automatic copy-ctr, move-ctr, and dtr)
  154. //! Create a computer, separately listing each needed parameter
  155. explicit crc_basic( value_type truncated_polynomial,
  156. value_type initial_remainder = 0, value_type final_xor_value = 0,
  157. bool reflect_input = false, bool reflect_remainder = false );
  158. // Internal Operations
  159. //! Return the (truncated) polynomial divisor
  160. value_type get_truncated_polynominal() const;
  161. //! Return what the polynomial remainder was set to during construction
  162. value_type get_initial_remainder() const;
  163. //! Return the XOR-mask used during output processing
  164. value_type get_final_xor_value() const;
  165. //! Check if input-bytes will be reflected before processing
  166. bool get_reflect_input() const;
  167. //! Check if the remainder will be reflected during output processing
  168. bool get_reflect_remainder() const;
  169. //! Return the remainder based from already-processed bits
  170. value_type get_interim_remainder() const;
  171. //! Change the interim remainder to a new value
  172. void reset( value_type new_rem );
  173. //! Change the interim remainder back to the initial value
  174. void reset();
  175. // External Operations
  176. //! Submit a single bit for input processing
  177. void process_bit( bool bit );
  178. //! Submit the lowest \a bit_length bits of a byte for input processing
  179. void process_bits( unsigned char bits, std::size_t bit_length );
  180. //! Submit a single byte for input processing
  181. void process_byte( unsigned char byte );
  182. //! Submit a memory block for input processing, iterator-pair style
  183. void process_block( void const *bytes_begin, void const *bytes_end );
  184. //! Submit a memory block for input processing, pointer-and-size style
  185. void process_bytes( void const *buffer, std::size_t byte_count );
  186. //! Return the checksum of the already-processed bits
  187. value_type checksum() const;
  188. private:
  189. // Member data
  190. value_type rem_;
  191. value_type poly_, init_, final_; // non-const to allow assignability
  192. bool rft_in_, rft_out_; // non-const to allow assignability
  193. }; // boost::crc_basic
  194. // Optimized cyclic redundancy code (CRC) class declaration ----------------//
  195. /** Objects of this type compute the CRC checksum of submitted data, where said
  196. data can be entered piecemeal through several different kinds of groupings.
  197. Modulo-2 polynomial division steps are performed byte-wise, aided by the use
  198. of pre-computation tables. Said division uses the altered algorithm, so any
  199. data has to be unaugmented.
  200. \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
  201. \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from
  202. the RMCA)
  203. \tparam TruncPoly The lowest coefficients of the divisor polynomial. The
  204. highest-order coefficient is omitted and always assumed to be 1. Defaults
  205. to \c 0, i.e. the only non-zero term is the implicit one for
  206. x<sup><var>Bits</var></sup>. (\e Poly from the RMCA)
  207. \tparam InitRem The (unaugmented) initial state of the polynomial
  208. remainder. Defaults to \c 0 if omitted. (\e Init from the RMCA)
  209. \tparam FinalXor The (XOR) bit-mask to be applied to the output remainder,
  210. after possible reflection but before returning. Defaults to \c 0 (i.e. no
  211. bit changes) if omitted. (\e XorOut from the RMCA)
  212. \tparam ReflectIn If \c true, input bytes are read lowest-order bit first,
  213. otherwise highest-order bit first. Defaults to \c false if omitted.
  214. (\e RefIn from the RMCA)
  215. \tparam ReflectRem If \c true, the output remainder is reflected before the
  216. XOR-mask. Defaults to \c false if omitted. (\e RefOut from the RMCA)
  217. \todo Get rid of the default value for \a TruncPoly. Choosing a divisor is
  218. an important decision with many factors, so a default is never useful,
  219. especially a bad one.
  220. */
  221. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  222. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  223. bool ReflectIn, bool ReflectRem >
  224. class crc_optimal
  225. {
  226. public:
  227. // Type
  228. //! \copydoc boost::crc_basic::value_type
  229. typedef typename boost::crc_detail::uint_t<Bits>::fast value_type;
  230. // Constants for the template parameters
  231. //! \copydoc boost::crc_basic::bit_count
  232. static const std::size_t bit_count = Bits;
  233. //! A copy of \a TruncPoly provided for meta-programming purposes
  234. static const value_type truncated_polynominal = TruncPoly;
  235. //! A copy of \a InitRem provided for meta-programming purposes
  236. static const value_type initial_remainder = InitRem;
  237. //! A copy of \a FinalXor provided for meta-programming purposes
  238. static const value_type final_xor_value = FinalXor;
  239. //! A copy of \a ReflectIn provided for meta-programming purposes
  240. static const bool reflect_input = ReflectIn;
  241. //! A copy of \a ReflectRem provided for meta-programming purposes
  242. static const bool reflect_remainder = ReflectRem;
  243. // Constructor (use the automatic copy-ctr, move-ctr, and dtr)
  244. //! Create a computer, giving an initial remainder if desired
  245. explicit crc_optimal( value_type init_rem = initial_remainder );
  246. // Internal Operations
  247. //! \copybrief boost::crc_basic::get_truncated_polynominal
  248. value_type get_truncated_polynominal() const;
  249. //! \copybrief boost::crc_basic::get_initial_remainder
  250. value_type get_initial_remainder() const;
  251. //! \copybrief boost::crc_basic::get_final_xor_value
  252. value_type get_final_xor_value() const;
  253. //! \copybrief boost::crc_basic::get_reflect_input
  254. bool get_reflect_input() const;
  255. //! \copybrief boost::crc_basic::get_reflect_remainder
  256. bool get_reflect_remainder() const;
  257. //! \copybrief boost::crc_basic::get_interim_remainder
  258. value_type get_interim_remainder() const;
  259. //! Change the interim remainder to either a given value or the initial one
  260. void reset( value_type new_rem = initial_remainder );
  261. // External Operations
  262. //! \copybrief boost::crc_basic::process_byte
  263. void process_byte( unsigned char byte );
  264. //! \copybrief boost::crc_basic::process_block
  265. void process_block( void const *bytes_begin, void const *bytes_end );
  266. //! \copybrief boost::crc_basic::process_bytes
  267. void process_bytes( void const *buffer, std::size_t byte_count );
  268. //! \copybrief boost::crc_basic::checksum
  269. value_type checksum() const;
  270. // Operators
  271. //! Submit a single byte for input processing, suitable for the STL
  272. void operator ()( unsigned char byte );
  273. //! Return the checksum of the already-processed bits, suitable for the STL
  274. value_type operator ()() const;
  275. private:
  276. // Implementation types
  277. // (Processing for reflected input gives reflected remainders, so you only
  278. // have to apply output-reflection if Reflect-Remainder doesn't match
  279. // Reflect-Input.)
  280. typedef detail::possible_reflector<Bits, ReflectIn> reflect_i_type;
  281. typedef detail::crc_driver<Bits, TruncPoly, ReflectIn> crc_table_type;
  282. typedef detail::possible_reflector<Bits, ReflectRem != ReflectIn>
  283. reflect_o_type;
  284. // Member data
  285. value_type rem_;
  286. }; // boost::crc_optimal
  287. // Implementation detail stuff ---------------------------------------------//
  288. //! \cond
  289. namespace detail
  290. {
  291. /** \brief Meta-programming integral constant for a single-bit bit-mask
  292. Generates a compile-time constant for a bit-mask that affects a single
  293. bit. The \c value will be 2<sup><var>BitIndex</var></sup>. The \c type
  294. will be the smallest built-in unsigned integer type that can contain the
  295. value, unless there's a built-in type that the system can handle easier,
  296. then the \c type will be smallest fast-handled unsigned integer type.
  297. \pre 0 \<= BitIndex \< \c std\::numeric_limits\<uintmax_t\>\::digits
  298. \tparam BitIndex The place of the sole set bit.
  299. */
  300. template < int BitIndex >
  301. struct high_bit_mask_c
  302. : std::integral_constant<typename boost::crc_detail::uint_t< BitIndex + 1 >::fast,
  303. ( UINTMAX_C(1) << BitIndex )>
  304. {};
  305. /** \brief Meta-programming integral constant for a lowest-bits bit-mask
  306. Generates a compile-time constant for a bit-mask that affects the lowest
  307. bits. The \c value will be 2<sup><var>BitCount</var></sup> - 1. The
  308. \c type will be the smallest built-in unsigned integer type that can
  309. contain the value, unless there's a built-in type that the system can
  310. handle easier, then the \c type will be smallest fast-handled unsigned
  311. integer type.
  312. \pre 0 \<= BitCount \<= \c std\::numeric_limits\<uintmax_t\>\::digits
  313. \tparam BitCount The number of lowest-placed bits set.
  314. */
  315. template < int BitCount >
  316. struct low_bits_mask_c
  317. : std::integral_constant<typename boost::crc_detail::uint_t< BitCount >::fast, (
  318. BitCount ? (( (( UINTMAX_C(1) << (BitCount - 1) ) - 1u) << 1 ) |
  319. UINTMAX_C( 1 )) : 0u )>
  320. {};
  321. /** \brief Reflects the bits of a number
  322. Reverses the order of the given number of bits within a value. For
  323. instance, if the given reflect count is 5, then the bit values for the
  324. 16- and 1-place will switch and the 8- and 2-place will switch, leaving
  325. the other bits alone. (The 4-place bit is in the middle, so it wouldn't
  326. change.)
  327. \pre \a Unsigned is a built-in unsigned integer type
  328. \pre 0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits
  329. \tparam Unsigned The type of \a x.
  330. \param x The value to be (partially) reflected.
  331. \param word_length The number of low-order bits to reflect. Defaults
  332. to the total number of value bits in \a Unsigned.
  333. \return The (partially) reflected value.
  334. \todo Check if this is the fastest way.
  335. */
  336. template < typename Unsigned >
  337. Unsigned reflect_unsigned( Unsigned x, int word_length
  338. = std::numeric_limits<Unsigned>::digits )
  339. {
  340. for ( Unsigned l = 1u, h = static_cast<Unsigned>(l << (word_length - 1)) ; h > l ; h >>= 1, l
  341. <<= 1 )
  342. {
  343. Unsigned const m = h | l, t = x & m;
  344. if ( (t == h) || (t == l) )
  345. x ^= m;
  346. }
  347. return x;
  348. }
  349. /** \brief Make a byte-to-byte-reflection map
  350. Creates a mapping array so the results can be cached. Uses
  351. #reflect_unsigned to generate the element values.
  352. \return An array <var>a</var> such that, for a given byte value
  353. <var>i</var>, <code><var>a</var>[ <var>i</var> ]</code> resolves to
  354. the reflected value of <var>i</var>.
  355. */
  356. std::array< unsigned char, (UINTMAX_C( 1 ) << CHAR_BIT) >
  357. inline make_byte_reflection_table()
  358. {
  359. std::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> result;
  360. unsigned char i = 0u;
  361. do
  362. result[ i ] = reflect_unsigned( i );
  363. while ( ++i );
  364. return result;
  365. }
  366. /** \brief Reflects the bits of a single byte
  367. Reverses the order of all the bits within a value. For instance, the
  368. bit values for the 2<sup><code>CHAR_BIT</code> - 1</sup>- and 1-place
  369. will switch and the 2<sup><code>CHAR_BIT</code> - 2</sup>- and 2-place
  370. will switch, etc.
  371. \param x The byte value to be reflected.
  372. \return The reflected value.
  373. \note Since this could be the most common type of reflection, and the
  374. number of states is relatively small, the implementation pre-computes
  375. and uses a table of all the results.
  376. */
  377. inline unsigned char reflect_byte( unsigned char x )
  378. {
  379. static std::array<unsigned char, ( UINTMAX_C(1) << CHAR_BIT )> const
  380. table = make_byte_reflection_table();
  381. return table[ x ];
  382. }
  383. /** \brief Reflects some bits within a single byte
  384. Like #reflect_unsigned, except it takes advantage of any (long-term)
  385. speed gains #reflect_byte may bring.
  386. \pre 0 \< \a word_length \<= \c CHAR_BIT
  387. \param x The value to be (partially) reflected.
  388. \param word_length The number of low-order bits to reflect.
  389. \return The (partially) reflected value.
  390. */
  391. inline unsigned char reflect_sub_byte( unsigned char x, int word_length )
  392. { return reflect_byte(x) >> (CHAR_BIT - word_length); }
  393. /** \brief Possibly reflects the bits of a number
  394. Reverses the order of the given number of bits within a value. For
  395. instance, if the given reflect count is 5, then the bit values for the
  396. 16- and 1-place will switch and the 8- and 2-place will switch, leaving
  397. the other bits alone. (The 4-place bit is in the middle, so it wouldn't
  398. change.) This variant function allows the reflection be controlled by
  399. an extra parameter, in case the decision to use reflection is made at
  400. run-time.
  401. \pre \a Unsigned is a built-in unsigned integer type
  402. \pre 0 \< word_length \<= \c std\::numeric_limits\<Unsigned\>\::digits
  403. \tparam Unsigned The type of \a x.
  404. \param x The value to be (partially) reflected.
  405. \param reflect Controls whether \a x is actually reflected (\c true) or
  406. left alone (\c false).
  407. \param word_length The number of low-order bits to reflect. Defaults
  408. to the total number of value bits in \a Unsigned.
  409. \return The possibly (partially) reflected value.
  410. */
  411. template < typename Unsigned >
  412. inline
  413. Unsigned reflect_optionally( Unsigned x, bool reflect, int word_length
  414. = std::numeric_limits<Unsigned>::digits )
  415. { return reflect ? reflect_unsigned(x, word_length) : x; }
  416. /** \brief Possibly reflects the bits of a single byte
  417. Uses #reflect_byte (if \a reflect is \c true).
  418. \param x The byte value to be (possibly) reflected.
  419. \param reflect Whether (\c true) or not (\c false) \a x is reflected.
  420. \return <code><var>reflect</var> ? reflect_byte(<var>x</var>) :
  421. <var>x</var></code>
  422. */
  423. inline
  424. unsigned char reflect_byte_optionally( unsigned char x, bool reflect )
  425. { return reflect ? reflect_byte(x) : x; }
  426. /** \brief Update a CRC remainder by several bits, assuming a non-augmented
  427. message
  428. Performs several steps of division required by the CRC algorithm, giving
  429. a new remainder polynomial based on the divisor polynomial and the
  430. synthesized dividend polynomial (from the old remainder and the
  431. newly-provided input). The computations assume that the CRC is directly
  432. exposed from the remainder, without any zero-valued bits augmented to
  433. the message bits.
  434. \pre \a Register and \a Word are both built-in unsigned integer types
  435. \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
  436. \::digits
  437. \pre 0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits
  438. \tparam Register The type used for representing the remainder and
  439. divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code>
  440. is used as the coefficient of <i>x<sup>i</sup></i>.
  441. \tparam Word The type used for storing the incoming terms of the
  442. dividend modulo-2 polynomial. The bit at <code>2<sup>i</sup></code>
  443. is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is
  444. \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 -
  445. i</sup></i> otherwise.
  446. \param[in] register_length The number of significant low-order bits
  447. to be used from \a Register values. It is the order of the modulo-2
  448. polynomial remainder and one less than the divisor's order.
  449. \param[in,out] remainder The upper part of the dividend polynomial
  450. before division, and the remainder polynomial after.
  451. \param[in] new_dividend_bits The coefficients for the next
  452. \a word_length lowest terms of the dividend polynomial.
  453. \param[in] truncated_divisor The lowest coefficients of the divisor
  454. polynomial. The highest-order coefficient is omitted and always
  455. assumed to be 1.
  456. \param[in] word_length The number of lowest-order bits to read from
  457. \a new_dividend_bits.
  458. \param[in] reflect If \c false, read from the highest-order marked
  459. bit from \a new_dividend_bits and go down, as normal. Otherwise,
  460. proceed from the lowest-order bit and go up.
  461. \note This routine performs a modulo-2 polynomial division variant.
  462. The exclusive-or operations are applied in a different order, since
  463. that kind of operation is commutative and associative. It also
  464. assumes that the zero-valued augment string was applied before this
  465. step, which means that the updated remainder can be directly used as
  466. the final CRC.
  467. */
  468. template < typename Register, typename Word >
  469. void crc_modulo_word_update( int register_length, Register &remainder, Word
  470. new_dividend_bits, Register truncated_divisor, int word_length, bool
  471. reflect )
  472. {
  473. // Create this masking constant outside the loop.
  474. Register const high_bit_mask = UINTMAX_C(1) << (register_length - 1);
  475. // The natural reading order for division is highest digit/bit first.
  476. // The "reflect" parameter switches this. However, building a bit mask
  477. // for the lowest bit is the easiest....
  478. new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect,
  479. word_length );
  480. // Perform modulo-2 division for each new dividend input bit
  481. for ( int i = word_length ; i ; --i, new_dividend_bits >>= 1 )
  482. {
  483. // compare the new bit with the remainder's highest
  484. remainder ^= ( new_dividend_bits & 1u ) ? high_bit_mask : 0u;
  485. // perform modulo-2 division
  486. bool const quotient = (remainder & high_bit_mask) != 0;
  487. remainder <<= 1;
  488. remainder ^= quotient ? truncated_divisor : 0u;
  489. // The quotient isn't used for anything, so don't keep it.
  490. }
  491. // Clear overflowed bits
  492. remainder &= (std::numeric_limits<Register>::max)() >> (std::numeric_limits<Register>::digits - register_length);
  493. }
  494. /** \brief Update a CRC remainder by a single bit, assuming a non-augmented
  495. message
  496. Performs the next step of division required by the CRC algorithm, giving
  497. a new remainder polynomial based on the divisor polynomial and the
  498. synthesized dividend polynomial (from the old remainder and the
  499. newly-provided input). The computations assume that the CRC is directly
  500. exposed from the remainder, without any zero-valued bits augmented to
  501. the message bits.
  502. \pre \a Register is a built-in unsigned integer type
  503. \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
  504. \::digits
  505. \tparam Register The type used for representing the remainder and
  506. divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code>
  507. is used as the coefficient of <i>x<sup>i</sup></i>.
  508. \param[in] register_length The number of significant low-order bits
  509. to be used from \a Register values. It is the order of the modulo-2
  510. polynomial remainder and one less than the divisor's order.
  511. \param[in,out] remainder The upper part of the dividend polynomial
  512. before division, and the remainder polynomial after.
  513. \param[in] new_dividend_bit The coefficient for the constant term
  514. of the dividend polynomial.
  515. \param[in] truncated_divisor The lowest coefficients of the divisor
  516. polynomial. The highest-order coefficient is omitted and always
  517. assumed to be 1.
  518. \note This routine performs a modulo-2 polynomial division variant.
  519. The exclusive-or operations are applied in a different order, since
  520. that kind of operation is commutative and associative. It also
  521. assumes that the zero-valued augment string was applied before this
  522. step, which means that the updated remainder can be directly used as
  523. the final CRC.
  524. */
  525. template < typename Register >
  526. inline void crc_modulo_update( int register_length, Register &remainder,
  527. bool new_dividend_bit, Register truncated_divisor )
  528. {
  529. crc_modulo_word_update( register_length, remainder,
  530. static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false );
  531. }
  532. /** \brief Update a CRC remainder by several bits, assuming an augmented
  533. message
  534. Performs several steps of division required by the CRC algorithm, giving
  535. a new remainder polynomial based on the divisor polynomial and the
  536. synthesized dividend polynomial (from the old remainder and the
  537. newly-provided input). The computations assume that a zero-valued
  538. string of bits will be appended to the message before extracting the
  539. CRC.
  540. \pre \a Register and \a Word are both built-in unsigned integer types
  541. \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
  542. \::digits
  543. \pre 0 \< \a word_length \<= std\::numeric_limits\<\a Word\>\::digits
  544. \tparam Register The type used for representing the remainder and
  545. divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code>
  546. is used as the coefficient of <i>x<sup>i</sup></i>.
  547. \tparam Word The type used for storing the incoming terms of the
  548. dividend modulo-2 polynomial. The bit at <code>2<sup>i</sup></code>
  549. is used as the coefficient of <i>x<sup>i</sup></i> when \a reflect is
  550. \c false, and the coefficient of <i>x<sup><var>word_length</var> - 1 -
  551. i</sup></i> otherwise.
  552. \param[in] register_length The number of significant low-order bits
  553. to be used from \a Register values. It is the order of the modulo-2
  554. polynomial remainder and one less than the divisor's order.
  555. \param[in,out] remainder The upper part of the dividend polynomial
  556. before division, and the remainder polynomial after.
  557. \param[in] new_dividend_bits The coefficients for the next
  558. \a word_length lowest terms of the dividend polynomial.
  559. \param[in] truncated_divisor The lowest coefficients of the divisor
  560. polynomial. The highest-order coefficient is omitted and always
  561. assumed to be 1.
  562. \param[in] word_length The number of lowest-order bits to read from
  563. \a new_dividend_bits.
  564. \param[in] reflect If \c false, read from the highest-order marked
  565. bit from \a new_dividend_bits and go down, as normal. Otherwise,
  566. proceed from the lowest-order bit and go up.
  567. \note This routine performs straight-forward modulo-2 polynomial
  568. division. It assumes that an augment string will be processed at the
  569. end of the message bits before doing CRC analysis.
  570. \todo Use this function somewhere so I can test it.
  571. */
  572. template < typename Register, typename Word >
  573. void augmented_crc_modulo_word_update( int register_length, Register
  574. &remainder, Word new_dividend_bits, Register truncated_divisor, int
  575. word_length, bool reflect )
  576. {
  577. // Create this masking constant outside the loop.
  578. Register const high_bit_mask = UINTMAX_C(1) << (register_length - 1);
  579. // The natural reading order for division is highest digit/bit first.
  580. // The "reflect" parameter switches this. However, building a bit mask
  581. // for the lowest bit is the easiest....
  582. new_dividend_bits = reflect_optionally( new_dividend_bits, !reflect,
  583. word_length );
  584. // Perform modulo-2 division for each new dividend input bit
  585. for ( int i = word_length ; i ; --i, new_dividend_bits >>= 1 )
  586. {
  587. bool const quotient = (remainder & high_bit_mask) != 0;
  588. remainder <<= 1;
  589. remainder |= new_dividend_bits & 1u;
  590. remainder ^= quotient ? truncated_divisor : 0u;
  591. // The quotient isn't used for anything, so don't keep it.
  592. }
  593. }
  594. /** \brief Update a CRC remainder by a single bit, assuming an augmented
  595. message
  596. Performs the next step of division required by the CRC algorithm, giving
  597. a new remainder polynomial based on the divisor polynomial and the
  598. synthesized dividend polynomial (from the old remainder and the
  599. newly-provided input). The computations assume that a zero-valued
  600. string of bits will be appended to the message before extracting the
  601. CRC.
  602. \pre \a Register is a built-in unsigned integer type
  603. \pre 0 \< \a register_length \<= std\::numeric_limits\<\a Register\>
  604. \::digits
  605. \tparam Register The type used for representing the remainder and
  606. divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code>
  607. is used as the coefficient of <i>x<sup>i</sup></i>.
  608. \param[in] register_length The number of significant low-order bits
  609. to be used from \a Register values. It is the order of the modulo-2
  610. polynomial remainder and one less than the divisor's order.
  611. \param[in,out] remainder The upper part of the dividend polynomial
  612. before division, and the remainder polynomial after.
  613. \param[in] new_dividend_bit The coefficient for the constant term
  614. of the dividend polynomial.
  615. \param[in] truncated_divisor The lowest coefficients of the divisor
  616. polynomial. The highest-order coefficient is omitted and always
  617. assumed to be 1.
  618. \note This routine performs straight-forward modulo-2 polynomial
  619. division. It assumes that an augment string will be processed at the
  620. end of the message bits before doing CRC analysis.
  621. \todo Use this function somewhere so I can test it.
  622. */
  623. template < typename Register >
  624. inline void augmented_crc_modulo_update( int register_length, Register
  625. &remainder, bool new_dividend_bit, Register truncated_divisor )
  626. {
  627. augmented_crc_modulo_word_update( register_length, remainder,
  628. static_cast<unsigned>(new_dividend_bit), truncated_divisor, 1, false );
  629. }
  630. /** \brief A mix-in class that returns its argument
  631. This class template makes a function object that returns its argument
  632. as-is. It's one case for #possible_reflector.
  633. \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
  634. \::digits
  635. \tparam BitLength How many significant bits arguments have.
  636. */
  637. template < int BitLength >
  638. class non_reflector
  639. {
  640. public:
  641. /** \brief The type to check for specialization
  642. This is a Boost integral constant indicating that this class
  643. does not reflect its input values.
  644. */
  645. typedef std::false_type is_reflecting_type;
  646. /** \brief The type to check for register bit length
  647. This is a Boost integral constant indicating how many
  648. significant bits won't actually be reflected.
  649. */
  650. typedef std::integral_constant< int, BitLength > width_c;
  651. /** \brief The type of (not-)reflected values
  652. This type is the input and output type for the (possible-)
  653. reflection function, which does nothing here.
  654. */
  655. typedef typename boost::crc_detail::uint_t< BitLength >::fast value_type;
  656. /** \brief Does nothing
  657. Returns the given value, not reflecting any part of it.
  658. \param x The value to not be reflected.
  659. \return \a x
  660. */
  661. inline static value_type reflect_q( value_type x )
  662. { return x; }
  663. };
  664. /** \brief A mix-in class that reflects (the lower part of) its argument,
  665. generally for types larger than a byte
  666. This class template makes a function object that returns its argument
  667. after reflecting its lower-order bits. It's one sub-case for
  668. #possible_reflector.
  669. \pre \c CHAR_BIT \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t
  670. \>\::digits
  671. \tparam BitLength How many significant bits arguments have.
  672. */
  673. template < int BitLength >
  674. class super_byte_reflector
  675. {
  676. public:
  677. /** \brief The type to check for specialization
  678. This is a Boost integral constant indicating that this class
  679. does reflect its input values.
  680. */
  681. typedef std::true_type is_reflecting_type;
  682. /** \brief The type to check for register bit length
  683. This is a Boost integral constant indicating how many
  684. significant bits will be reflected.
  685. */
  686. typedef std::integral_constant< int, BitLength > width_c;
  687. /** \brief The type of reflected values
  688. This is both the input and output type for the reflection function.
  689. */
  690. typedef typename boost::crc_detail::uint_t< BitLength >::fast value_type;
  691. /** \brief Reflect (part of) the given value
  692. Reverses the order of the given number of bits within a value,
  693. using #reflect_unsigned.
  694. \param x The value to be (partially) reflected.
  695. \return ( <var>x</var> &amp;
  696. ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT(
  697. <var>x</var> &amp; (2<sup><var>width_c</var>\::value</sup> -
  698. 1) )
  699. */
  700. inline static value_type reflect_q( value_type x )
  701. { return reflect_unsigned(x, width_c::value); }
  702. };
  703. /** \brief A mix-in class that reflects (the lower part of) its argument,
  704. generally for bytes
  705. This class template makes a function object that returns its argument
  706. after reflecting its lower-order bits. It's one sub-case for
  707. #possible_reflector.
  708. \pre 0 \< \a BitLength \<= \c CHAR_BIT
  709. \tparam BitLength How many significant bits arguments have.
  710. */
  711. template < int BitLength >
  712. class sub_type_reflector
  713. {
  714. public:
  715. /** \brief The type to check for specialization
  716. This is a Boost integral constant indicating that this class
  717. does reflect its input values.
  718. */
  719. typedef std::true_type is_reflecting_type;
  720. /** \brief The type to check for register bit length
  721. This is a Boost integral constant indicating how many
  722. significant bits will be reflected.
  723. */
  724. typedef std::integral_constant< int, BitLength > width_c;
  725. /** \brief The type of reflected values
  726. This is both the input and output type for the reflection function.
  727. */
  728. typedef unsigned char value_type;
  729. /** \brief Reflect (part of) the given value
  730. Reverses the order of the given number of bits within a value,
  731. using #reflect_sub_byte.
  732. \param x The value to be (partially) reflected.
  733. \return ( <var>x</var> &amp;
  734. ~(2<sup><var>width_c</var>\::value</sup> - 1) ) | REFLECT(
  735. <var>x</var> &amp; (2<sup><var>width_c</var>\::value</sup> -
  736. 1) )
  737. */
  738. inline static value_type reflect_q( value_type x )
  739. { return reflect_sub_byte(x, width_c::value); }
  740. };
  741. /** \brief A mix-in class that reflects (the lower part of) its argument
  742. This class template makes a function object that returns its argument
  743. after reflecting its lower-order bits. It's one case for
  744. #possible_reflector.
  745. \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
  746. \::digits
  747. \tparam BitLength How many significant bits arguments have.
  748. */
  749. template < int BitLength >
  750. class reflector
  751. : public std::conditional< (BitLength > CHAR_BIT),
  752. super_byte_reflector<BitLength>, sub_type_reflector<BitLength> >::type
  753. { };
  754. /** This class template adds a member function #reflect_q that will
  755. conditionally reflect its first argument, controlled by a compile-time
  756. parameter.
  757. \pre 0 \< \a BitLength \<= \c std\::numeric_limits\<uintmax_t\>
  758. \::digits
  759. \tparam BitLength How many significant bits arguments have.
  760. \tparam DoIt \c true if #reflect_q will reflect, \c false if it should
  761. return its argument unchanged.
  762. \tparam Id An extra differentiator if multiple copies of this class
  763. template are mixed-in as base classes. Defaults to 0 if omitted.
  764. */
  765. template < int BitLength, bool DoIt, int Id >
  766. class possible_reflector
  767. : public std::conditional< DoIt, reflector<BitLength>,
  768. non_reflector<BitLength> >::type
  769. {
  770. public:
  771. /** \brief The type to check for ID
  772. This is a Boost integral constant indicating what ID number this
  773. instantiation used.
  774. */
  775. typedef std::integral_constant<int, Id> id_type;
  776. };
  777. /** \brief Find the composite remainder update effect from a fixed bit
  778. sequence, for each potential sequence combination.
  779. For each value between 0 and 2<sup><var>SubOrder</var></sup> - 1,
  780. computes the XOR mask corresponding to the composite effect they update
  781. the incoming remainder, which is the upper part of the dividend that
  782. gets (partially) pushed out of its register by the incoming value's
  783. bits. The composite value merges the \"partial products\" from each bit
  784. of the value being updated individually.
  785. \pre \a Register is a built-in unsigned integer type
  786. \pre 0 \< \a SubOrder \<= \a register_length \<=
  787. std\::numeric_limits\<\a Register\>\::digits
  788. \tparam SubOrder The number of low-order significant bits of the trial
  789. new dividends.
  790. \tparam Register The type used for representing the remainder and
  791. divisor modulo-2 polynomials. The bit at <code>2<sup>i</sup></code>
  792. is used as the coefficient of <i>x<sup>i</sup></i>.
  793. \param[in] register_length The number of significant low-order bits
  794. to be used from \a Register values. It is the order of the modulo-2
  795. polynomial remainder and one less than the divisor's order.
  796. \param[in] truncated_divisor The lowest coefficients of the divisor
  797. polynomial. The highest-order coefficient is omitted and always
  798. assumed to be 1.
  799. \param[in] reflect If \c false, read from the highest-order marked
  800. bit from a new dividend's bits and go down, as normal. Otherwise,
  801. proceed from the lowest-order bit and go up.
  802. \return An array such that the element at index <var>i</var> is the
  803. composite effect XOR mask for value <var>i</var>.
  804. \note This routine performs a modulo-2 polynomial division variant.
  805. The exclusive-or operations are applied in a different order, since
  806. that kind of operation is commutative and associative. It also
  807. assumes that the zero-valued augment string was applied before this
  808. step, which means that the updated remainder can be directly used as
  809. the final CRC.
  810. \todo Check that using the unaugmented-CRC division routines give the
  811. same composite mask table as using augmented-CRC routines.
  812. */
  813. template < int SubOrder, typename Register >
  814. std::array< Register, (UINTMAX_C( 1 ) << SubOrder) >
  815. make_partial_xor_products_table( int register_length, Register
  816. truncated_divisor, bool reflect )
  817. {
  818. std::array<Register, ( UINTMAX_C(1) << SubOrder )> result = { 0 };
  819. // Loop over every possible dividend value
  820. for ( typename boost::crc_detail::uint_t<SubOrder + 1>::fast dividend = 0u;
  821. dividend < result.size() ; ++dividend )
  822. {
  823. Register remainder = 0u;
  824. crc_modulo_word_update( register_length, remainder, dividend,
  825. truncated_divisor, SubOrder, false );
  826. result[ reflect_optionally(dividend, reflect, SubOrder) ] =
  827. reflect_optionally( remainder, reflect, register_length );
  828. }
  829. return result;
  830. }
  831. /** \brief A mix-in class for the table of table-driven CRC algorithms
  832. Encapsulates the parameters need to make a global (technically,
  833. class-static) table usuable in CRC algorithms, and generates said
  834. table.
  835. \pre 0 \< \a SubOrder \<= Order \<=
  836. std\::numeric_limits\<uintmax_t\>\::digits
  837. \tparam Order The order of the modulo-2 polynomial remainder and one
  838. less than the divisor's order.
  839. \tparam SubOrder The number of low-order significant bits of the trial
  840. new dividends.
  841. \tparam TruncatedPolynomial The lowest coefficients of the divisor
  842. polynomial. The highest-order coefficient is omitted and always
  843. assumed to be 1.
  844. \tparam Reflect If \c false, read from the highest-order marked
  845. bit from a new dividend's bits and go down, as normal. Otherwise,
  846. proceed from the lowest-order bit and go up.
  847. */
  848. template < int Order, int SubOrder, std::uintmax_t TruncatedPolynomial,
  849. bool Reflect >
  850. class crc_table_t
  851. {
  852. public:
  853. /** \brief The type to check for register bit length
  854. This is a Boost integral constant indicating how many
  855. significant bits are in the remainder and (truncated) divisor.
  856. */
  857. typedef std::integral_constant< int, Order > width_c;
  858. /** \brief The type to check for index-unit bit length
  859. This is a Boost integral constant indicating how many
  860. significant bits are in the trial new dividends.
  861. */
  862. typedef std::integral_constant< int, SubOrder > unit_width_c;
  863. /** \brief The type of registers
  864. This is the output type for the partial-product map.
  865. */
  866. typedef typename boost::crc_detail::uint_t< Order >::fast value_type;
  867. /** \brief The type to check the divisor
  868. This is a Boost integral constant representing the (truncated)
  869. divisor.
  870. */
  871. typedef std::integral_constant< value_type, TruncatedPolynomial >
  872. poly_c;
  873. /** \brief The type to check for reflection
  874. This is a Boost integral constant representing whether input
  875. units should be read in reverse order.
  876. */
  877. typedef std::integral_constant< bool, Reflect > refin_c;
  878. /** \brief The type to check for map size
  879. This is a Boost integral constant representing the number of
  880. elements in the partial-product map, based on the unit size.
  881. */
  882. typedef high_bit_mask_c< SubOrder > table_size_c;
  883. /** \brief The type of the unit TO partial-product map
  884. This is the array type that takes units as the index and said unit's
  885. composite partial-product mask as the element.
  886. */
  887. typedef std::array<value_type, table_size_c::value> array_type;
  888. /** \brief Create a global array for the mapping table
  889. Creates an instance of a partial-product array with this class's
  890. parameters.
  891. \return A reference to a immutable array giving the partial-product
  892. update XOR map for each potential sub-unit value.
  893. */
  894. static array_type const & get_table()
  895. {
  896. static array_type const table =
  897. make_partial_xor_products_table<unit_width_c::value>(
  898. width_c::value, poly_c::value, refin_c::value );
  899. return table;
  900. }
  901. };
  902. /** \brief A mix-in class that handles direct (i.e. non-reflected) byte-fed
  903. table-driven CRC algorithms
  904. This class template adds member functions #augmented_crc_update and
  905. #crc_update to update remainders from new input bytes. The bytes aren't
  906. reflected before processing.
  907. \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
  908. \::digits
  909. \tparam Order The order of the modulo-2 polynomial remainder and one
  910. less than the divisor's order.
  911. \tparam TruncatedPolynomial The lowest coefficients of the divisor
  912. polynomial. The highest-order coefficient is omitted and always
  913. assumed to be 1.
  914. */
  915. template < int Order, std::uintmax_t TruncatedPolynomial >
  916. class direct_byte_table_driven_crcs
  917. : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false>
  918. {
  919. typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, false>
  920. base_type;
  921. public:
  922. typedef typename base_type::value_type value_type;
  923. typedef typename base_type::array_type array_type;
  924. /** \brief Compute the updated remainder after reading some bytes
  925. The implementation reads from a table to speed-up applying
  926. augmented-CRC updates byte-wise.
  927. \param remainder The pre-update remainder
  928. \param new_dividend_bytes The address where the new bytes start
  929. \param new_dividend_byte_count The number of new bytes to read
  930. \return The updated remainder
  931. */
  932. static value_type augmented_crc_update( value_type remainder, unsigned
  933. char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
  934. {
  935. static array_type const & table = base_type::get_table();
  936. while ( new_dividend_byte_count-- )
  937. {
  938. // Locates the merged partial product based on the leading byte
  939. unsigned char const index = ( remainder >> (Order - CHAR_BIT) )
  940. & UCHAR_MAX;
  941. // Complete the multi-bit modulo-2 polynomial division
  942. remainder <<= CHAR_BIT;
  943. remainder |= *new_dividend_bytes++;
  944. remainder ^= table[ index ];
  945. }
  946. return remainder;
  947. }
  948. /** \brief Compute the updated remainder after reading some bytes
  949. The implementation reads from a table to speed-up applying
  950. unaugmented-CRC updates byte-wise.
  951. \param remainder The pre-update remainder
  952. \param new_dividend_bytes The address where the new bytes start
  953. \param new_dividend_byte_count The number of new bytes to read
  954. \return The updated remainder
  955. */
  956. static value_type crc_update( value_type remainder, unsigned char
  957. const *new_dividend_bytes, std::size_t new_dividend_byte_count)
  958. {
  959. static array_type const & table = base_type::get_table();
  960. while ( new_dividend_byte_count-- )
  961. {
  962. // Locates the merged partial product based on comparing the
  963. // leading and incoming bytes
  964. unsigned char const index = ( (remainder >> ( Order - CHAR_BIT
  965. )) & UCHAR_MAX ) ^ *new_dividend_bytes++;
  966. // Complete the multi-bit altered modulo-2 polynomial division
  967. remainder <<= CHAR_BIT;
  968. remainder ^= table[ index ];
  969. }
  970. return remainder;
  971. }
  972. };
  973. /** \brief A mix-in class that handles reflected byte-fed, table-driven CRC
  974. algorithms
  975. This class template adds member functions #augmented_crc_update and
  976. #crc_update to update remainders from new input bytes. The bytes are
  977. reflected before processing.
  978. \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
  979. \::digits
  980. \tparam Order The order of the modulo-2 polynomial remainder and one
  981. less than the divisor's order.
  982. \tparam TruncatedPolynomial The lowest coefficients of the divisor
  983. polynomial. The highest-order coefficient is omitted and always
  984. assumed to be 1.
  985. */
  986. template < int Order, std::uintmax_t TruncatedPolynomial >
  987. class reflected_byte_table_driven_crcs
  988. : public crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true>
  989. {
  990. typedef crc_table_t<Order, CHAR_BIT, TruncatedPolynomial, true>
  991. base_type;
  992. public:
  993. typedef typename base_type::value_type value_type;
  994. typedef typename base_type::array_type array_type;
  995. /** \brief Compute the updated remainder after reading some bytes
  996. The implementation reads from a table to speed-up applying
  997. reflecting augmented-CRC updates byte-wise.
  998. \param remainder The pre-update remainder; since the bytes are
  999. being reflected, this remainder also has to be reflected
  1000. \param new_dividend_bytes The address where the new bytes start
  1001. \param new_dividend_byte_count The number of new bytes to read
  1002. \return The updated, reflected remainder
  1003. */
  1004. static value_type augmented_crc_update( value_type remainder, unsigned
  1005. char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
  1006. {
  1007. static array_type const & table = base_type::get_table();
  1008. while ( new_dividend_byte_count-- )
  1009. {
  1010. // Locates the merged partial product based on the leading byte
  1011. // (which is at the low-order end for reflected remainders)
  1012. unsigned char const index = remainder & UCHAR_MAX;
  1013. // Complete the multi-bit reflected modulo-2 polynomial division
  1014. remainder >>= CHAR_BIT;
  1015. remainder |= static_cast<value_type>( *new_dividend_bytes++ )
  1016. << ( Order - CHAR_BIT );
  1017. remainder ^= table[ index ];
  1018. }
  1019. return remainder;
  1020. }
  1021. /** \brief Compute the updated remainder after reading some bytes
  1022. The implementation reads from a table to speed-up applying
  1023. reflected unaugmented-CRC updates byte-wise.
  1024. \param remainder The pre-update remainder; since the bytes are
  1025. being reflected, this remainder also has to be reflected
  1026. \param new_dividend_bytes The address where the new bytes start
  1027. \param new_dividend_byte_count The number of new bytes to read
  1028. \return The updated, reflected remainder
  1029. */
  1030. static value_type crc_update( value_type remainder, unsigned char
  1031. const *new_dividend_bytes, std::size_t new_dividend_byte_count)
  1032. {
  1033. static array_type const & table = base_type::get_table();
  1034. while ( new_dividend_byte_count-- )
  1035. {
  1036. // Locates the merged partial product based on comparing the
  1037. // leading and incoming bytes
  1038. unsigned char const index = ( remainder & UCHAR_MAX ) ^
  1039. *new_dividend_bytes++;
  1040. // Complete the multi-bit reflected altered modulo-2 polynomial
  1041. // division
  1042. remainder >>= CHAR_BIT;
  1043. remainder ^= table[ index ];
  1044. }
  1045. return remainder;
  1046. }
  1047. };
  1048. /** \brief Mix-in class for byte-fed, table-driven CRC algorithms with
  1049. parameter values at least a byte in width
  1050. This class template adds member functions #augmented_crc_update and
  1051. #crc_update to update remainders from new input bytes. The bytes may be
  1052. reflected before processing, controlled by a compile-time parameter.
  1053. \pre \c CHAR_BIT \<= \a Order \<= \c std\::numeric_limits\<uintmax_t\>
  1054. \::digits
  1055. \tparam Order The order of the modulo-2 polynomial remainder and one
  1056. less than the divisor's order.
  1057. \tparam TruncatedPolynomial The lowest coefficients of the divisor
  1058. polynomial. The highest-order coefficient is omitted and always
  1059. assumed to be 1.
  1060. \tparam Reflect If \c false, read from the highest-order bit from a new
  1061. input byte and go down, as normal. Otherwise, proceed from the
  1062. lowest-order bit and go up.
  1063. */
  1064. template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect >
  1065. class byte_table_driven_crcs
  1066. : public std::conditional< Reflect,
  1067. reflected_byte_table_driven_crcs<Order, TruncatedPolynomial>,
  1068. direct_byte_table_driven_crcs<Order, TruncatedPolynomial> >::type
  1069. { };
  1070. /** \brief A mix-in class that handles direct (i.e. non-reflected) byte-fed
  1071. CRC algorithms for sub-byte parameters
  1072. This class template adds member functions #augmented_crc_update and
  1073. #crc_update to update remainders from new input bytes. The bytes aren't
  1074. reflected before processing.
  1075. \pre 0 \< \a Order \< \c CHAR_BIT
  1076. \tparam Order The order of the modulo-2 polynomial remainder and one
  1077. less than the divisor's order.
  1078. \tparam TruncatedPolynomial The lowest coefficients of the divisor
  1079. polynomial. The highest-order coefficient is omitted and always
  1080. assumed to be 1.
  1081. */
  1082. template < int Order, std::uintmax_t TruncatedPolynomial >
  1083. class direct_sub_byte_crcs
  1084. : public crc_table_t<Order, Order, TruncatedPolynomial, false>
  1085. {
  1086. typedef crc_table_t<Order, Order, TruncatedPolynomial, false>
  1087. base_type;
  1088. public:
  1089. typedef typename base_type::width_c width_c;
  1090. typedef typename base_type::value_type value_type;
  1091. typedef typename base_type::poly_c poly_c;
  1092. typedef typename base_type::array_type array_type;
  1093. /** \brief Compute the updated remainder after reading some bytes
  1094. The implementation reads from a table to speed-up applying
  1095. augmented-CRC updates byte-wise.
  1096. \param remainder The pre-update remainder
  1097. \param new_dividend_bytes The address where the new bytes start
  1098. \param new_dividend_byte_count The number of new bytes to read
  1099. \return The updated remainder
  1100. \todo Use this function somewhere so I can test it.
  1101. */
  1102. static value_type augmented_crc_update( value_type remainder, unsigned
  1103. char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
  1104. {
  1105. //static array_type const & table = base_type::get_table();
  1106. while ( new_dividend_byte_count-- )
  1107. {
  1108. // Without a table, process each byte explicitly
  1109. augmented_crc_modulo_word_update( width_c::value, remainder,
  1110. *new_dividend_bytes++, poly_c::value, CHAR_BIT, false );
  1111. }
  1112. return remainder;
  1113. }
  1114. /** \brief Compute the updated remainder after reading some bytes
  1115. The implementation reads from a table to speed-up applying
  1116. unaugmented-CRC updates byte-wise.
  1117. \param remainder The pre-update remainder
  1118. \param new_dividend_bytes The address where the new bytes start
  1119. \param new_dividend_byte_count The number of new bytes to read
  1120. \return The updated remainder
  1121. */
  1122. static value_type crc_update( value_type remainder, unsigned char
  1123. const *new_dividend_bytes, std::size_t new_dividend_byte_count)
  1124. {
  1125. //static array_type const & table = base_type::get_table();
  1126. while ( new_dividend_byte_count-- )
  1127. {
  1128. // Without a table, process each byte explicitly
  1129. crc_modulo_word_update( width_c::value, remainder,
  1130. *new_dividend_bytes++, poly_c::value, CHAR_BIT, false );
  1131. }
  1132. return remainder;
  1133. }
  1134. };
  1135. /** \brief A mix-in class that handles reflected byte-fed, CRC algorithms
  1136. for sub-byte parameters
  1137. This class template adds member functions #augmented_crc_update and
  1138. #crc_update to update remainders from new input bytes. The bytes are
  1139. reflected before processing.
  1140. \pre 0 \< \a Order \< \c CHAR_BIT
  1141. \tparam Order The order of the modulo-2 polynomial remainder and one
  1142. less than the divisor's order.
  1143. \tparam TruncatedPolynomial The lowest coefficients of the divisor
  1144. polynomial. The highest-order coefficient is omitted and always
  1145. assumed to be 1.
  1146. */
  1147. template < int Order, std::uintmax_t TruncatedPolynomial >
  1148. class reflected_sub_byte_crcs
  1149. : public crc_table_t<Order, Order, TruncatedPolynomial, true>
  1150. {
  1151. typedef crc_table_t<Order, Order, TruncatedPolynomial, true>
  1152. base_type;
  1153. public:
  1154. typedef typename base_type::width_c width_c;
  1155. typedef typename base_type::value_type value_type;
  1156. typedef typename base_type::poly_c poly_c;
  1157. typedef typename base_type::array_type array_type;
  1158. /** \brief Compute the updated remainder after reading some bytes
  1159. The implementation reads from a table to speed-up applying
  1160. reflecting augmented-CRC updates byte-wise.
  1161. \param remainder The pre-update remainder; since the bytes are
  1162. being reflected, this remainder also has to be reflected
  1163. \param new_dividend_bytes The address where the new bytes start
  1164. \param new_dividend_byte_count The number of new bytes to read
  1165. \return The updated, reflected remainder
  1166. \todo Use this function somewhere so I can test it.
  1167. */
  1168. static value_type augmented_crc_update( value_type remainder, unsigned
  1169. char const *new_dividend_bytes, std::size_t new_dividend_byte_count)
  1170. {
  1171. //static array_type const & table = base_type::get_table();
  1172. remainder = reflect_sub_byte( remainder, width_c::value );
  1173. while ( new_dividend_byte_count-- )
  1174. {
  1175. // Without a table, process each byte explicitly
  1176. augmented_crc_modulo_word_update( width_c::value, remainder,
  1177. *new_dividend_bytes++, poly_c::value, CHAR_BIT, true );
  1178. }
  1179. remainder = reflect_sub_byte( remainder, width_c::value );
  1180. return remainder;
  1181. }
  1182. /** \brief Compute the updated remainder after reading some bytes
  1183. The implementation reads from a table to speed-up applying
  1184. reflected unaugmented-CRC updates byte-wise.
  1185. \param remainder The pre-update remainder; since the bytes are
  1186. being reflected, this remainder also has to be reflected
  1187. \param new_dividend_bytes The address where the new bytes start
  1188. \param new_dividend_byte_count The number of new bytes to read
  1189. \return The updated, reflected remainder
  1190. */
  1191. static value_type crc_update( value_type remainder, unsigned char
  1192. const *new_dividend_bytes, std::size_t new_dividend_byte_count)
  1193. {
  1194. //static array_type const & table = base_type::get_table();
  1195. remainder = reflect_sub_byte( remainder, width_c::value );
  1196. while ( new_dividend_byte_count-- )
  1197. {
  1198. // Without a table, process each byte explicitly
  1199. crc_modulo_word_update( width_c::value, remainder,
  1200. *new_dividend_bytes++, poly_c::value, CHAR_BIT, true );
  1201. }
  1202. remainder = reflect_sub_byte( remainder, width_c::value );
  1203. return remainder;
  1204. }
  1205. };
  1206. /** \brief Mix-in class for byte-fed, table-driven CRC algorithms with
  1207. sub-byte parameters
  1208. This class template adds member functions #augmented_crc_update and
  1209. #crc_update to update remainders from new input bytes. The bytes may be
  1210. reflected before processing, controlled by a compile-time parameter.
  1211. \pre 0 \< \a Order \< \c CHAR_BIT
  1212. \tparam Order The order of the modulo-2 polynomial remainder and one
  1213. less than the divisor's order.
  1214. \tparam TruncatedPolynomial The lowest coefficients of the divisor
  1215. polynomial. The highest-order coefficient is omitted and always
  1216. assumed to be 1.
  1217. \tparam Reflect If \c false, read from the highest-order bit from a new
  1218. input byte and go down, as normal. Otherwise, proceed from the
  1219. lowest-order bit and go up.
  1220. */
  1221. template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect >
  1222. class sub_byte_crcs
  1223. : public std::conditional< Reflect,
  1224. reflected_sub_byte_crcs<Order, TruncatedPolynomial>,
  1225. direct_sub_byte_crcs<Order, TruncatedPolynomial> >::type
  1226. { };
  1227. /** This class template adds member functions #augmented_crc_update and
  1228. #crc_update to update remainders from new input bytes. The bytes may be
  1229. reflected before processing, controlled by a compile-time parameter.
  1230. \pre 0 \< \a Order \<= \c std\::numeric_limits\<uintmax_t\>\::digits
  1231. \tparam Order The order of the modulo-2 polynomial remainder and one
  1232. less than the divisor's order.
  1233. \tparam TruncatedPolynomial The lowest coefficients of the divisor
  1234. polynomial. The highest-order coefficient is omitted and always
  1235. assumed to be 1.
  1236. \tparam Reflect If \c false, read from the highest-order bit from a new
  1237. input byte and go down, as normal. Otherwise, proceed from the
  1238. lowest-order bit and go up.
  1239. \tparam Id An extra differentiator if multiple copies of this class
  1240. template are mixed-in as base classes. Defaults to 0 if omitted.
  1241. */
  1242. template < int Order, std::uintmax_t TruncatedPolynomial, bool Reflect,
  1243. int Id >
  1244. class crc_driver
  1245. : public std::conditional< (Order < CHAR_BIT), sub_byte_crcs<Order,
  1246. TruncatedPolynomial, Reflect>, byte_table_driven_crcs<Order,
  1247. TruncatedPolynomial, Reflect> >::type
  1248. {
  1249. public:
  1250. /** \brief The type to check for ID
  1251. This is a Boost integral constant indicating what ID number this
  1252. instantiation used.
  1253. */
  1254. typedef std::integral_constant<int, Id> id_type;
  1255. };
  1256. } // namespace detail
  1257. //! \endcond
  1258. // Simple CRC class function definitions -----------------------------------//
  1259. /** Constructs a \c crc_basic object with at least the required parameters to a
  1260. particular CRC formula to be processed upon receiving input.
  1261. \param[in] truncated_polynomial The lowest coefficients of the divisor
  1262. polynomial. The highest-order coefficient is omitted and always assumed
  1263. to be 1. (\e Poly from the RMCA)
  1264. \param[in] initial_remainder The (unaugmented) initial state of the
  1265. polynomial remainder. Defaults to \c 0 if omitted. (\e Init from the
  1266. RMCA)
  1267. \param[in] final_xor_value The (XOR) bit-mask to be applied to the output
  1268. remainder, after possible reflection but before returning. Defaults to
  1269. \c 0 (i.e. no bit changes) if omitted. (\e XorOut from the RMCA)
  1270. \param[in] reflect_input If \c true, input bytes are read lowest-order bit
  1271. first, otherwise highest-order bit first. Defaults to \c false if
  1272. omitted. (\e RefIn from the RMCA)
  1273. \param[in] reflect_remainder If \c true, the output remainder is reflected
  1274. before the XOR-mask. Defaults to \c false if omitted. (\e RefOut from
  1275. the RMCA)
  1276. \post <code><var>truncated_polynomial</var> ==
  1277. this-&gt;get_truncated_polynominal()</code>
  1278. \post <code><var>initial_remainder</var> ==
  1279. this-&gt;get_initial_remainder()</code>
  1280. \post <code><var>final_xor_value</var> ==
  1281. this-&gt;get_final_xor_value()</code>
  1282. \post <code><var>reflect_input</var> ==
  1283. this-&gt;get_reflect_input()</code>
  1284. \post <code><var>reflect_remainder</var> ==
  1285. this-&gt;get_reflect_remainder()</code>
  1286. \post <code><var>initial_remainder</var> ==
  1287. this-&gt;get_interim_remainder()</code>
  1288. \post <code>(<var>reflect_remainder</var> ?
  1289. REFLECT(<var>initial_remainder</var>) : <var>initial_remainder</var>) ^
  1290. <var>final_xor_value</var> == this-&gt;checksum()</code>
  1291. */
  1292. template < std::size_t Bits >
  1293. inline
  1294. crc_basic<Bits>::crc_basic
  1295. (
  1296. value_type truncated_polynomial,
  1297. value_type initial_remainder, // = 0
  1298. value_type final_xor_value, // = 0
  1299. bool reflect_input, // = false
  1300. bool reflect_remainder // = false
  1301. )
  1302. : rem_( initial_remainder ), poly_( truncated_polynomial )
  1303. , init_( initial_remainder ), final_( final_xor_value )
  1304. , rft_in_( reflect_input ), rft_out_( reflect_remainder )
  1305. {
  1306. }
  1307. /** Returns a representation of the polynomial divisor. The value of the
  1308. 2<sup>i</sup> bit is the value of the coefficient of the polynomial's
  1309. x<sup>i</sup> term. The omitted bit for x<sup>(#bit_count)</sup> term is
  1310. always 1.
  1311. \return The bit-packed list of coefficients. If the bit-length of
  1312. #value_type exceeds #bit_count, the values of higher-placed bits should be
  1313. ignored (even any for x<sup>(#bit_count)</sup>) since they're unregulated.
  1314. */
  1315. template < std::size_t Bits >
  1316. inline
  1317. typename crc_basic<Bits>::value_type
  1318. crc_basic<Bits>::get_truncated_polynominal
  1319. (
  1320. ) const
  1321. {
  1322. return poly_;
  1323. }
  1324. /** Returns a representation of the polynomial remainder before any input has
  1325. been submitted. The value of the 2<sup>i</sup> bit is the value of the
  1326. coefficient of the polynomial's x<sup>i</sup> term.
  1327. \return The bit-packed list of coefficients. If the bit-length of
  1328. #value_type exceeds #bit_count, the values of higher-placed bits should be
  1329. ignored since they're unregulated.
  1330. */
  1331. template < std::size_t Bits >
  1332. inline
  1333. typename crc_basic<Bits>::value_type
  1334. crc_basic<Bits>::get_initial_remainder
  1335. (
  1336. ) const
  1337. {
  1338. return init_;
  1339. }
  1340. /** Returns the mask to be used during creation of a checksum. The mask is used
  1341. for an exclusive-or (XOR) operation applied bit-wise to the interim
  1342. remainder representation (after any reflection, if #get_reflect_remainder()
  1343. returns \c true).
  1344. \return The bit-mask. If the bit-length of #value_type exceeds #bit_count,
  1345. the values of higher-placed bits should be ignored since they're
  1346. unregulated.
  1347. */
  1348. template < std::size_t Bits >
  1349. inline
  1350. typename crc_basic<Bits>::value_type
  1351. crc_basic<Bits>::get_final_xor_value
  1352. (
  1353. ) const
  1354. {
  1355. return final_;
  1356. }
  1357. /** Returns a whether or not a submitted byte will be \"reflected\" before it is
  1358. used to update the interim remainder. Only the byte-wise operations
  1359. #process_byte, #process_block, and #process_bytes are affected.
  1360. \retval true Input bytes will be read starting from the lowest-order bit.
  1361. \retval false Input bytes will be read starting from the highest-order bit.
  1362. */
  1363. template < std::size_t Bits >
  1364. inline
  1365. bool
  1366. crc_basic<Bits>::get_reflect_input
  1367. (
  1368. ) const
  1369. {
  1370. return rft_in_;
  1371. }
  1372. /** Indicates if the interim remainder will be \"reflected\" before it is passed
  1373. to the XOR-mask stage when returning a checksum.
  1374. \retval true The interim remainder is reflected before further work.
  1375. \retval false The interim remainder is applied to the XOR-mask as-is.
  1376. */
  1377. template < std::size_t Bits >
  1378. inline
  1379. bool
  1380. crc_basic<Bits>::get_reflect_remainder
  1381. (
  1382. ) const
  1383. {
  1384. return rft_out_;
  1385. }
  1386. /** Returns a representation of the polynomial remainder after all the input
  1387. submissions since construction or the last #reset call. The value of the
  1388. 2<sup>i</sup> bit is the value of the coefficient of the polynomial's
  1389. x<sup>i</sup> term. If CRC processing gets interrupted here, retain the
  1390. value returned, and use it to start up the next CRC computer where you left
  1391. off (with #reset(value_type) or construction). The next computer has to
  1392. have its other parameters compatible with this computer.
  1393. \return The bit-packed list of coefficients. If the bit-length of
  1394. #value_type exceeds #bit_count, the values of higher-placed bits should be
  1395. ignored since they're unregulated. No output processing (reflection or
  1396. XOR mask) has been applied to the value.
  1397. */
  1398. template < std::size_t Bits >
  1399. inline
  1400. typename crc_basic<Bits>::value_type
  1401. crc_basic<Bits>::get_interim_remainder
  1402. (
  1403. ) const
  1404. {
  1405. return rem_ & detail::low_bits_mask_c<bit_count>::value;
  1406. }
  1407. /** Changes the interim polynomial remainder to \a new_rem, purging any
  1408. influence previously submitted input has had. The value of the
  1409. 2<sup>i</sup> bit is the value of the coefficient of the polynomial's
  1410. x<sup>i</sup> term.
  1411. \param[in] new_rem The (unaugmented) state of the polynomial remainder
  1412. starting from this point, with no output processing applied.
  1413. \post <code><var>new_rem</var> == this-&gt;get_interim_remainder()</code>
  1414. \post <code>((this-&gt;get_reflect_remainder() ?
  1415. REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^
  1416. this-&gt;get_final_xor_value()) == this-&gt;checksum()</code>
  1417. */
  1418. template < std::size_t Bits >
  1419. inline
  1420. void
  1421. crc_basic<Bits>::reset
  1422. (
  1423. value_type new_rem
  1424. )
  1425. {
  1426. rem_ = new_rem;
  1427. }
  1428. /** Changes the interim polynomial remainder to the initial remainder given
  1429. during construction, purging any influence previously submitted input has
  1430. had. The value of the 2<sup>i</sup> bit is the value of the coefficient of
  1431. the polynomial's x<sup>i</sup> term.
  1432. \post <code>this-&gt;get_initial_remainder() ==
  1433. this-&gt;get_interim_remainder()</code>
  1434. \post <code>((this-&gt;get_reflect_remainder() ?
  1435. REFLECT(this-&gt;get_initial_remainder()) :
  1436. this-&gt;get_initial_remainder()) ^ this-&gt;get_final_xor_value())
  1437. == this-&gt;checksum()</code>
  1438. */
  1439. template < std::size_t Bits >
  1440. inline
  1441. void
  1442. crc_basic<Bits>::reset
  1443. (
  1444. )
  1445. {
  1446. this->reset( this->get_initial_remainder() );
  1447. }
  1448. /** Updates the interim remainder with a single altered-CRC-division step.
  1449. \param[in] bit The new input bit.
  1450. \post The interim remainder is updated though a modulo-2 polynomial
  1451. division, where the division steps are altered for unaugmented CRCs.
  1452. */
  1453. template < std::size_t Bits >
  1454. inline
  1455. void
  1456. crc_basic<Bits>::process_bit
  1457. (
  1458. bool bit
  1459. )
  1460. {
  1461. detail::crc_modulo_update( bit_count, rem_, bit, poly_ );
  1462. }
  1463. /** Updates the interim remainder with several altered-CRC-division steps. Each
  1464. bit is processed separately, starting from the one at the
  1465. 2<sup><var>bit_length</var> - 1</sup> place, then proceeding down to the
  1466. lowest-placed bit. Any order imposed by
  1467. <code>this-&gt;get_reflect_input()</code> is ignored.
  1468. \pre 0 \< \a bit_length \<= \c CHAR_BIT
  1469. \param[in] bits The byte containing the new input bits.
  1470. \param[in] bit_length The number of bits in the byte to be read.
  1471. \post The interim remainder is updated though \a bit_length modulo-2
  1472. polynomial divisions, where the division steps are altered for unaugmented
  1473. CRCs.
  1474. */
  1475. template < std::size_t Bits >
  1476. void
  1477. crc_basic<Bits>::process_bits
  1478. (
  1479. unsigned char bits,
  1480. std::size_t bit_length
  1481. )
  1482. {
  1483. // ignore the bits above the ones we want
  1484. bits <<= CHAR_BIT - bit_length;
  1485. // compute the CRC for each bit, starting with the upper ones
  1486. unsigned char const high_bit_mask = 1u << ( CHAR_BIT - 1u );
  1487. for ( std::size_t i = bit_length ; i > 0u ; --i, bits <<= 1u )
  1488. {
  1489. process_bit( (bits & high_bit_mask) != 0 );
  1490. }
  1491. }
  1492. /** Updates the interim remainder with a byte's worth of altered-CRC-division
  1493. steps. The bits within the byte are processed from the highest place down
  1494. if <code>this-&gt;get_reflect_input()</code> is \c false, and lowest place
  1495. up otherwise.
  1496. \param[in] byte The new input byte.
  1497. \post The interim remainder is updated though \c CHAR_BIT modulo-2
  1498. polynomial divisions, where the division steps are altered for unaugmented
  1499. CRCs.
  1500. */
  1501. template < std::size_t Bits >
  1502. inline
  1503. void
  1504. crc_basic<Bits>::process_byte
  1505. (
  1506. unsigned char byte
  1507. )
  1508. {
  1509. process_bits( (rft_in_ ? detail::reflect_byte( byte ) : byte), CHAR_BIT );
  1510. }
  1511. /** Updates the interim remainder with several bytes' worth of
  1512. altered-CRC-division steps. The bits within each byte are processed from
  1513. the highest place down if <code>this-&gt;get_reflect_input()</code> is
  1514. \c false, and lowest place up otherwise. The bytes themselves are processed
  1515. starting from the one pointed by \a bytes_begin until \a bytes_end is
  1516. reached through forward iteration, treating the two pointers as if they
  1517. point to <code>unsigned char</code> objects.
  1518. \pre \a bytes_end has to equal \a bytes_begin if the latter is \c NULL or
  1519. otherwise doesn't point to a valid buffer.
  1520. \pre \a bytes_end, if not equal to \a bytes_begin, has to point within or
  1521. one-byte-past the same buffer \a bytes_begin points into.
  1522. \pre \a bytes_end has to be reachable from \a bytes_begin through a finite
  1523. number of forward byte-pointer increments.
  1524. \param[in] bytes_begin The address where the memory block begins.
  1525. \param[in] bytes_end Points to one-byte past the address of the memory
  1526. block's last byte, or \a bytes_begin if no bytes are to be read.
  1527. \post The interim remainder is updated though <code>CHAR_BIT * (((unsigned
  1528. char const *) bytes_end) - ((unsigned char const *) bytes_begin))</code>
  1529. modulo-2 polynomial divisions, where the division steps are altered for
  1530. unaugmented CRCs.
  1531. */
  1532. template < std::size_t Bits >
  1533. void
  1534. crc_basic<Bits>::process_block
  1535. (
  1536. void const * bytes_begin,
  1537. void const * bytes_end
  1538. )
  1539. {
  1540. for ( unsigned char const * p
  1541. = static_cast<unsigned char const *>(bytes_begin) ; p < bytes_end ; ++p )
  1542. {
  1543. process_byte( *p );
  1544. }
  1545. }
  1546. /** Updates the interim remainder with several bytes' worth of
  1547. altered-CRC-division steps. The bits within each byte are processed from
  1548. the highest place down if <code>this-&gt;get_reflect_input()</code> is
  1549. \c false, and lowest place up otherwise. The bytes themselves are processed
  1550. starting from the one pointed by \a buffer, forward-iterated (as if the
  1551. pointed-to objects were of <code>unsigned char</code>) until \a byte_count
  1552. bytes are read.
  1553. \pre \a byte_count has to equal 0 if \a buffer is \c NULL or otherwise
  1554. doesn't point to valid memory.
  1555. \pre If \a buffer points within valid memory, then that block has to have
  1556. at least \a byte_count more valid bytes allocated from that point.
  1557. \param[in] buffer The address where the memory block begins.
  1558. \param[in] byte_count The number of bytes in the memory block.
  1559. \post The interim remainder is updated though <code>CHAR_BIT *
  1560. <var>byte_count</var></code> modulo-2 polynomial divisions, where the
  1561. division steps are altered for unaugmented CRCs.
  1562. */
  1563. template < std::size_t Bits >
  1564. inline
  1565. void
  1566. crc_basic<Bits>::process_bytes
  1567. (
  1568. void const * buffer,
  1569. std::size_t byte_count
  1570. )
  1571. {
  1572. unsigned char const * const b = static_cast<unsigned char const *>(
  1573. buffer );
  1574. process_block( b, b + byte_count );
  1575. }
  1576. /** Computes the checksum of all the submitted bits since construction or the
  1577. last call to #reset. The checksum will be the raw checksum, i.e. the
  1578. (interim) remainder after all the modulo-2 polynomial division, plus any
  1579. output processing.
  1580. \return <code>(this-&gt;get_reflect_remainder() ?
  1581. REFLECT(this-&gt;get_interim_remainder()) :
  1582. this-&gt;get_interim_remainder()) ^ this-&gt;get_final_xor_value()</code>
  1583. \note Since checksums are meant to be compared, any higher-placed bits
  1584. (when the bit-length of #value_type exceeds #bit_count) will be set to 0.
  1585. */
  1586. template < std::size_t Bits >
  1587. inline
  1588. typename crc_basic<Bits>::value_type
  1589. crc_basic<Bits>::checksum
  1590. (
  1591. ) const
  1592. {
  1593. return ( (rft_out_ ? detail::reflect_unsigned( rem_, bit_count ) :
  1594. rem_) ^ final_ ) & detail::low_bits_mask_c<bit_count>::value;
  1595. }
  1596. // Optimized CRC class function definitions --------------------------------//
  1597. // Macro to compact code
  1598. #define BOOST_CRC_OPTIMAL_NAME crc_optimal<Bits, TruncPoly, InitRem, \
  1599. FinalXor, ReflectIn, ReflectRem>
  1600. /** Constructs a \c crc_optimal object with a particular CRC formula to be
  1601. processed upon receiving input. The initial remainder may be overridden.
  1602. \param[in] init_rem The (unaugmented) initial state of the polynomial
  1603. remainder. Defaults to #initial_remainder if omitted.
  1604. \post <code>#truncated_polynominal ==
  1605. this-&gt;get_truncated_polynominal()</code>
  1606. \post <code>#initial_remainder == this-&gt;get_initial_remainder()</code>
  1607. \post <code>#final_xor_value == this-&gt;get_final_xor_value()</code>
  1608. \post <code>#reflect_input == this-&gt;get_reflect_input()</code>
  1609. \post <code>#reflect_remainder == this-&gt;get_reflect_remainder()</code>
  1610. \post <code><var>init_rem</var> == this-&gt;get_interim_remainder()</code>
  1611. \post <code>(#reflect_remainder ? REFLECT(<var>init_rem</var>) :
  1612. <var>init_rem</var>) ^ #final_xor_value == this-&gt;checksum()</code>
  1613. */
  1614. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1615. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1616. bool ReflectIn, bool ReflectRem >
  1617. inline
  1618. BOOST_CRC_OPTIMAL_NAME::crc_optimal
  1619. (
  1620. value_type init_rem // = initial_remainder
  1621. )
  1622. : rem_( reflect_i_type::reflect_q(init_rem) )
  1623. {
  1624. }
  1625. //! \copydetails boost::crc_basic::get_truncated_polynominal
  1626. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1627. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1628. bool ReflectIn, bool ReflectRem >
  1629. inline
  1630. typename BOOST_CRC_OPTIMAL_NAME::value_type
  1631. BOOST_CRC_OPTIMAL_NAME::get_truncated_polynominal
  1632. (
  1633. ) const
  1634. {
  1635. return truncated_polynominal;
  1636. }
  1637. //! \copydetails boost::crc_basic::get_initial_remainder
  1638. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1639. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1640. bool ReflectIn, bool ReflectRem >
  1641. inline
  1642. typename BOOST_CRC_OPTIMAL_NAME::value_type
  1643. BOOST_CRC_OPTIMAL_NAME::get_initial_remainder
  1644. (
  1645. ) const
  1646. {
  1647. return initial_remainder;
  1648. }
  1649. //! \copydetails boost::crc_basic::get_final_xor_value
  1650. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1651. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1652. bool ReflectIn, bool ReflectRem >
  1653. inline
  1654. typename BOOST_CRC_OPTIMAL_NAME::value_type
  1655. BOOST_CRC_OPTIMAL_NAME::get_final_xor_value
  1656. (
  1657. ) const
  1658. {
  1659. return final_xor_value;
  1660. }
  1661. //! \copydetails boost::crc_basic::get_reflect_input
  1662. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1663. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1664. bool ReflectIn, bool ReflectRem >
  1665. inline
  1666. bool
  1667. BOOST_CRC_OPTIMAL_NAME::get_reflect_input
  1668. (
  1669. ) const
  1670. {
  1671. return reflect_input;
  1672. }
  1673. //! \copydetails boost::crc_basic::get_reflect_remainder
  1674. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1675. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1676. bool ReflectIn, bool ReflectRem >
  1677. inline
  1678. bool
  1679. BOOST_CRC_OPTIMAL_NAME::get_reflect_remainder
  1680. (
  1681. ) const
  1682. {
  1683. return reflect_remainder;
  1684. }
  1685. //! \copydetails boost::crc_basic::get_interim_remainder
  1686. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1687. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1688. bool ReflectIn, bool ReflectRem >
  1689. inline
  1690. typename BOOST_CRC_OPTIMAL_NAME::value_type
  1691. BOOST_CRC_OPTIMAL_NAME::get_interim_remainder
  1692. (
  1693. ) const
  1694. {
  1695. // Interim remainder should be _un_-reflected, so we have to undo it.
  1696. return reflect_i_type::reflect_q( rem_ ) &
  1697. detail::low_bits_mask_c<bit_count>::value;
  1698. }
  1699. /** Changes the interim polynomial remainder to \a new_rem, purging any
  1700. influence previously submitted input has had. The value of the
  1701. 2<sup>i</sup> bit is the value of the coefficient of the polynomial's
  1702. x<sup>i</sup> term.
  1703. \param[in] new_rem The (unaugmented) state of the polynomial remainder
  1704. starting from this point, with no output processing applied. Defaults to
  1705. <code>this-&gt;get_initial_remainder()</code> if omitted.
  1706. \post <code><var>new_rem</var> == this-&gt;get_interim_remainder()</code>
  1707. \post <code>((this-&gt;get_reflect_remainder() ?
  1708. REFLECT(<var>new_rem</var>) : <var>new_rem</var>) ^
  1709. this-&gt;get_final_xor_value()) == this-&gt;checksum()</code>
  1710. */
  1711. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1712. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1713. bool ReflectIn, bool ReflectRem >
  1714. inline
  1715. void
  1716. BOOST_CRC_OPTIMAL_NAME::reset
  1717. (
  1718. value_type new_rem // = initial_remainder
  1719. )
  1720. {
  1721. rem_ = reflect_i_type::reflect_q( new_rem );
  1722. }
  1723. /** \copydetails boost::crc_basic::process_byte
  1724. \note Any modulo-2 polynomial divisions may use a table of pre-computed
  1725. remainder changes (as XOR masks) to speed computation when reading data
  1726. byte-wise.
  1727. */
  1728. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1729. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1730. bool ReflectIn, bool ReflectRem >
  1731. inline
  1732. void
  1733. BOOST_CRC_OPTIMAL_NAME::process_byte
  1734. (
  1735. unsigned char byte
  1736. )
  1737. {
  1738. process_bytes( &byte, sizeof(byte) );
  1739. }
  1740. /** \copydetails boost::crc_basic::process_block
  1741. \note Any modulo-2 polynomial divisions may use a table of pre-computed
  1742. remainder changes (as XOR masks) to speed computation when reading data
  1743. byte-wise.
  1744. */
  1745. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1746. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1747. bool ReflectIn, bool ReflectRem >
  1748. inline
  1749. void
  1750. BOOST_CRC_OPTIMAL_NAME::process_block
  1751. (
  1752. void const * bytes_begin,
  1753. void const * bytes_end
  1754. )
  1755. {
  1756. process_bytes( bytes_begin, static_cast<unsigned char const *>(bytes_end) -
  1757. static_cast<unsigned char const *>(bytes_begin) );
  1758. }
  1759. /** \copydetails boost::crc_basic::process_bytes
  1760. \note Any modulo-2 polynomial divisions may use a table of pre-computed
  1761. remainder changes (as XOR masks) to speed computation when reading data
  1762. byte-wise.
  1763. */
  1764. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1765. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1766. bool ReflectIn, bool ReflectRem >
  1767. inline
  1768. void
  1769. BOOST_CRC_OPTIMAL_NAME::process_bytes
  1770. (
  1771. void const * buffer,
  1772. std::size_t byte_count
  1773. )
  1774. {
  1775. rem_ = crc_table_type::crc_update( rem_, static_cast<unsigned char const
  1776. *>(buffer), byte_count );
  1777. }
  1778. //! \copydetails boost::crc_basic::checksum
  1779. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1780. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1781. bool ReflectIn, bool ReflectRem >
  1782. inline
  1783. typename BOOST_CRC_OPTIMAL_NAME::value_type
  1784. BOOST_CRC_OPTIMAL_NAME::checksum
  1785. (
  1786. ) const
  1787. {
  1788. return ( reflect_o_type::reflect_q(rem_) ^ get_final_xor_value() )
  1789. & detail::low_bits_mask_c<bit_count>::value;
  1790. }
  1791. /** Updates the interim remainder with a byte's worth of altered-CRC-division
  1792. steps. The bits within the byte are processed from the highest place down
  1793. if <code>this-&gt;get_reflect_input()</code> is \c false, and lowest place
  1794. up otherwise. This function is meant to present a function-object interface
  1795. to code that wants to process a stream of bytes with
  1796. <code>std::for_each</code> or similar range-processing algorithms. Since
  1797. some of these algorithms takes their function object by value, make sure to
  1798. copy back the result to this object so the updates can be remembered.
  1799. \param[in] byte The new input byte.
  1800. \post The interim remainder is updated though \c CHAR_BIT modulo-2
  1801. polynomial divisions, where the division steps are altered for unaugmented
  1802. CRCs.
  1803. \note Any modulo-2 polynomial divisions may use a table of pre-computed
  1804. remainder changes (as XOR masks) to speed computation when reading data
  1805. byte-wise.
  1806. */
  1807. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1808. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1809. bool ReflectIn, bool ReflectRem >
  1810. inline
  1811. void
  1812. BOOST_CRC_OPTIMAL_NAME::operator ()
  1813. (
  1814. unsigned char byte
  1815. )
  1816. {
  1817. process_byte( byte );
  1818. }
  1819. /** Computes the checksum of all the submitted bits since construction or the
  1820. last call to #reset. The checksum will be the raw checksum, i.e. the
  1821. (interim) remainder after all the modulo-2 polynomial division, plus any
  1822. output processing. This function is meant to present a function-object
  1823. interface to code that wants to receive data like
  1824. <code>std::generate_n</code> or similar data-processing algorithms. Note
  1825. that if this object is used as a generator multiple times without an
  1826. intervening mutating operation, the same value will always be returned.
  1827. \return <code>(this-&gt;get_reflect_remainder() ?
  1828. REFLECT(this-&gt;get_interim_remainder()) :
  1829. this-&gt;get_interim_remainder()) ^ this-&gt;get_final_xor_value()</code>
  1830. \note Since checksums are meant to be compared, any higher-placed bits
  1831. (when the bit-length of #value_type exceeds #bit_count) will be set to 0.
  1832. */
  1833. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1834. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1835. bool ReflectIn, bool ReflectRem >
  1836. inline
  1837. typename BOOST_CRC_OPTIMAL_NAME::value_type
  1838. BOOST_CRC_OPTIMAL_NAME::operator ()
  1839. (
  1840. ) const
  1841. {
  1842. return checksum();
  1843. }
  1844. // CRC computation function definition -------------------------------------//
  1845. /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and
  1846. \a byte_count describe a memory block representing the polynomial dividend.
  1847. The division steps are altered so the result directly gives a checksum,
  1848. without need to augment the memory block with scratch-space bytes. The
  1849. first byte is considered the highest order, going down for subsequent bytes.
  1850. \pre 0 \< \a Bits \<= \c std\::numeric_limits\<uintmax_t\>\::digits
  1851. \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from
  1852. the RMCA)
  1853. \tparam TruncPoly The lowest coefficients of the divisor polynomial. The
  1854. highest-order coefficient is omitted and always assumed to be 1.
  1855. (\e Poly from the RMCA)
  1856. \tparam InitRem The (unaugmented) initial state of the polynomial
  1857. remainder. (\e Init from the RMCA)
  1858. \tparam FinalXor The (XOR) bit-mask to be applied to the output remainder,
  1859. after possible reflection but before returning. (\e XorOut from the RMCA)
  1860. \tparam ReflectIn If \c True, input bytes are read lowest-order bit first,
  1861. otherwise highest-order bit first. (\e RefIn from the RMCA)
  1862. \tparam ReflectRem If \c True, the output remainder is reflected before the
  1863. XOR-mask. (\e RefOut from the RMCA)
  1864. \param[in] buffer The address where the memory block begins.
  1865. \param[in] byte_count The number of bytes in the memory block.
  1866. \return The checksum, which is the last (interim) remainder plus any output
  1867. processing.
  1868. \note Unaugmented-style CRC runs perform modulo-2 polynomial division in
  1869. an altered order. The trailing \a Bits number of zero-valued bits needed
  1870. to extracted an (unprocessed) checksum is virtually moved to near the
  1871. beginning of the message. This is OK since the XOR operation is
  1872. commutative and associative. It also means that you can get a checksum
  1873. anytime. Since data is being read byte-wise, a table of pre-computed
  1874. remainder changes (as XOR masks) can be used to speed computation.
  1875. */
  1876. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
  1877. BOOST_CRC_PARM_TYPE InitRem, BOOST_CRC_PARM_TYPE FinalXor,
  1878. bool ReflectIn, bool ReflectRem >
  1879. inline
  1880. typename crc_detail::uint_t<Bits>::fast
  1881. crc
  1882. (
  1883. void const * buffer,
  1884. std::size_t byte_count
  1885. )
  1886. {
  1887. BOOST_CRC_OPTIMAL_NAME computer;
  1888. computer.process_bytes( buffer, byte_count );
  1889. return computer.checksum();
  1890. }
  1891. // Augmented-message CRC computation function definition -------------------//
  1892. /** Computes the polynomial remainder of a CRC run, assuming that \a buffer and
  1893. \a byte_count describe a memory block representing the polynomial dividend.
  1894. The first byte is considered the highest order, going down for subsequent
  1895. bytes. Within a byte, the highest-order bit is read first (corresponding to
  1896. \e RefIn = \c False in the RMCA). Check the other parts of this function's
  1897. documentation to see how a checksum can be gained and/or used.
  1898. \pre 0 \< \a Bits \<= \c std\::numeric_limit\<uintmax_t\>\::digits
  1899. \tparam Bits The order of the modulo-2 polynomial divisor. (\e Width from
  1900. the RMCA)
  1901. \tparam TruncPoly The lowest coefficients of the divisor polynomial. The
  1902. highest-order coefficient is omitted and always assumed to be 1.
  1903. (\e Poly from the RMCA)
  1904. \param[in] buffer The address where the memory block begins.
  1905. \param[in] byte_count The number of bytes in the memory block.
  1906. \param[in] initial_remainder The initial state of the polynomial
  1907. remainder, defaulting to zero if omitted. If you are reading a memory
  1908. block in multiple runs, put the return value of the previous run here.
  1909. (Note that initial-remainders given by RMCA parameter lists, as
  1910. \e Init, assume that the initial remainder is in its \b unaugmented state,
  1911. so you would need to convert the value to make it suitable for this
  1912. function. I currently don't provide a conversion routine.)
  1913. \return The interim remainder, if no augmentation is used. A special value
  1914. if augmentation is used (see the notes). No output processing is done on
  1915. the value. (In RMCA terms, \e RefOut is \c False and \e XorOut is \c 0.)
  1916. \note Augmented-style CRC runs use straight-up modulo-2 polynomial
  1917. division. Since data is being read byte-wise, a table of pre-computed
  1918. remainder changes (as XOR masks) can be used to speed computation.
  1919. \note Reading just a memory block will yield an interim remainder, and not
  1920. the final checksum. To get that checksum, allocate \a Bits / \c CHAR_BIT
  1921. bytes directly after the block and fill them with zero values, then extend
  1922. \a byte_count to include those extra bytes. A data block is corrupt if
  1923. the return value doesn't equal your separately given checksum.
  1924. \note Another way to perform a check is use the zero-byte extension method,
  1925. but replace the zero values with your separately-given checksum. The
  1926. checksum must be loaded in big-endian order. Here corruption, in either
  1927. the data block or the given checksum, is confirmed if the return value is
  1928. not zero.
  1929. \note The two checksum techniques assume the CRC-run is performed bit-wise,
  1930. while this function works byte-wise. That means that the techniques can
  1931. be used only if \c CHAR_BIT divides \a Bits evenly!
  1932. */
  1933. template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly >
  1934. typename crc_detail::uint_t<Bits>::fast
  1935. augmented_crc
  1936. (
  1937. void const * buffer,
  1938. std::size_t byte_count,
  1939. typename crc_detail::uint_t<Bits>::fast initial_remainder // = 0u
  1940. )
  1941. {
  1942. return detail::low_bits_mask_c<Bits>::value &
  1943. detail::byte_table_driven_crcs<Bits, TruncPoly, false>::
  1944. augmented_crc_update( initial_remainder, static_cast<unsigned char const
  1945. *>(buffer), byte_count );
  1946. }
  1947. } // namespace boost
  1948. // Undo header-private macros
  1949. #undef BOOST_CRC_OPTIMAL_NAME
  1950. #undef BOOST_CRC_PARM_TYPE
  1951. #endif // BOOST_CRC_HPP