crc.hpp 93 KB

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