crc.hpp 93 KB

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