|
Boost-Commit : |
From: dwalker07_at_[hidden]
Date: 2008-08-02 16:12:09
Author: dlwalker
Date: 2008-08-02 16:12:09 EDT (Sat, 02 Aug 2008)
New Revision: 47947
URL: http://svn.boost.org/trac/boost/changeset/47947
Log:
Fixed comment spelling; duplicated or moved code around within headers and between classes; changed class-static numeric constants to integral meta-constant types; made bit-coding shell publicly derive from byte-coding shell; added explanations to some comments; used newer integer size & mask types
Text files modified:
sandbox/md5/boost/coding/coding_shell.hpp | 628 ++++++++++++++++++---------------------
sandbox/md5/boost/coding/md5.hpp | 200 ++++++++++--
sandbox/md5/libs/coding/src/md5.cpp | 117 ++++++-
3 files changed, 551 insertions(+), 394 deletions(-)
Modified: sandbox/md5/boost/coding/coding_shell.hpp
==============================================================================
--- sandbox/md5/boost/coding/coding_shell.hpp (original)
+++ sandbox/md5/boost/coding/coding_shell.hpp 2008-08-02 16:12:09 EDT (Sat, 02 Aug 2008)
@@ -19,7 +19,8 @@
#include <boost/coding_fwd.hpp>
#include <boost/assert.hpp> // for BOOST_ASSERT
-#include <boost/mpl/if.hpp> // for boost::mpl::if_c
+#include <boost/mpl/bool.hpp> // for boost::mpl::bool_
+#include <boost/mpl/if.hpp> // for boost::mpl::if_
#include <boost/mpl/int.hpp> // for boost::mpl::int_
#include <boost/serialization/access.hpp> // for boost::serialization::access
#include <boost/typeof/typeof.hpp> // for BOOST_AUTO
@@ -52,7 +53,7 @@
support:
- copying (either through assignment operator or
constructor); default construction recommended.
- - a memeber type \c consumed_type that compatible
+ - a member type \c consumed_type that compatible
with a byte, like <code>unsigned char</code>.
- a member type \c product_type (that's "normal")
- a (non-<code>const</code>) member <code>operator
@@ -162,7 +163,182 @@
}; // byte_coding_shell
-// Bit-processing coding shell class template declarations -----------------//
+// Byte-processing coding shell class template member definitions ----------//
+
+/** Constructs a byte-processor shell set to a given engine.
+
+ \param p The byte-processor engine to copy as the initial state. If not
+ given, a default-constructed engine is used.
+
+ \post \c #bytes uses a copy of \p p and refers to \c *this.
+ */
+template < class ByteProcessor >
+inline
+byte_coding_shell<ByteProcessor>::byte_coding_shell
+(
+ processor_type const & p // = processor_type()
+)
+ : bytes( p )
+{}
+
+/** Provides non-mutable access to the byte-processor engine.
+
+ \return A \c const reference to the internal engine.
+ */
+template < class ByteProcessor >
+inline typename byte_coding_shell<ByteProcessor>::processor_type const &
+byte_coding_shell<ByteProcessor>::context() const
+{ return this->bytes.source; }
+
+/** Provides mutable access to the byte-processor engine.
+
+ \post None, besides what tinkering with the result may do.
+
+ \return A non-<code>const</code> reference to the internal engine.
+ */
+template < class ByteProcessor >
+inline typename byte_coding_shell<ByteProcessor>::processor_type &
+byte_coding_shell<ByteProcessor>::context()
+{ return this->bytes.source; }
+
+/** Submits a byte for processing.
+
+ \param byte The byte value to be submitted.
+
+ \post Calls <code>this->bytes( <var>byte</var> )</code>.
+ */
+template < class ByteProcessor >
+inline void
+byte_coding_shell<ByteProcessor>::process_byte( unsigned char byte )
+{ this->bytes( byte ); }
+
+/** Submits multiple copies of a single byte value for processing.
+
+ \param value The byte value to be submitted.
+ \param byte_count The number of bytes to submit.
+
+ \post Calls <code>this->bytes( <var>value</var> )</code> \p byte_count
+ times.
+ */
+template < class ByteProcessor >
+inline void
+byte_coding_shell<ByteProcessor>::process_byte_copies
+(
+ unsigned char value,
+ size_type byte_count
+)
+{
+ while ( byte_count-- )
+ this->bytes( value );
+}
+
+/** Submits bytes, delimited by a pointer range, for processing.
+
+ \pre If \p bytes_begin is not \c NULL, then \p bytes_end has to be
+ reachable from \p bytes_begin via forward iterations of their
+ equivalent <code>unsigned char const *</code> values, otherwise
+ \p bytes_end has to be \c NULL too.
+
+ \param bytes_begin The start of the byte range to be submitted.
+ \param bytes_end One-past-the-end of the byte range in \p bytes_begin.
+
+ \post Calls <code>this->bytes( <var>x</var> )</code> for each byte \p x
+ in the given range, starting from the one at the address
+ \p bytes_begin to the byte just before the \p bytes_end mark. (If
+ the parameters are identical, then nothing is done.)
+ */
+template < class ByteProcessor >
+inline void
+byte_coding_shell<ByteProcessor>::process_block
+(
+ void const * bytes_begin,
+ void const * bytes_end
+)
+{
+ BOOST_ASSERT( !bytes_begin == !bytes_end ); // Can't test for reachable!
+
+ for ( BOOST_AUTO(p, static_cast<unsigned char const *>( bytes_begin )) ;
+ p != bytes_end ; ++p )
+ this->bytes( *p );
+}
+
+/** Submits bytes, bounded by a pointer and length, for processing.
+
+ \pre If \p buffer is \c NULL, then \p byte_count must be zero.
+
+ \param buffer The start of the byte range to be submitted.
+ \param byte_count Number of (leading) bytes to use from the range.
+
+ \post Calls <code>this->bytes( <var>x</var> )</code> for each byte \p x
+ in the given range, starting from the one at the address \p buffer,
+ going forward for \p byte_count bytes total.
+ */
+template < class ByteProcessor >
+inline void
+byte_coding_shell<ByteProcessor>::process_bytes
+(
+ void const * buffer,
+ size_type byte_count
+)
+{
+ BOOST_ASSERT( buffer || !byte_count );
+
+ for ( BOOST_AUTO(p, static_cast<unsigned char const *>( buffer )) ;
+ byte_count-- ; ++p )
+ this->bytes( *p );
+}
+
+/** Provides the computed check-sum of all the submitted values. Since this is
+ a \c const member function, the engine must act as if value-submission is
+ complete whenever this function is called.
+
+ \return The check-sum.
+ */
+template < class ByteProcessor >
+inline typename byte_coding_shell<ByteProcessor>::value_type
+byte_coding_shell<ByteProcessor>::checksum() const
+{ return this->context()(); }
+
+/** Compares byte-processor shells for equivalence. Such shells are equal if
+ their internal engines are equal.
+
+ \param o The right-side operand to be compared.
+
+ \retval true \c *this and \p o are equivalent.
+ \retval false \c *this and \p o are not equivalent.
+ */
+template < class ByteProcessor >
+inline bool
+byte_coding_shell<ByteProcessor>::operator ==( self_type const &o ) const
+{ return this->bytes == o.bytes; }
+
+/** Compares byte-processor shells for non-equivalence. Such shells are unequal
+ if their internal engines are unequal.
+
+ \param o The right-side operand to be compared.
+
+ \retval true \c *this and \p o are not equivalent.
+ \retval false \c *this and \p o are equivalent.
+ */
+template < class ByteProcessor >
+inline bool
+byte_coding_shell<ByteProcessor>::operator !=( self_type const &o ) const
+{ return !this->operator ==( o ); }
+
+/** Computes the check-sum of the submitted data, through a standard generator
+ interface.
+
+ \return The generated check-sum.
+
+ \see #checksum()const
+ */
+template < class ByteProcessor >
+inline typename byte_coding_shell<ByteProcessor>::value_type
+byte_coding_shell<ByteProcessor>::operator ()() const
+{ return this->checksum(); }
+
+
+// Byte-processing bit-processor wrapper class template declaration --------//
/** \brief A conversion layer: a byte-processor from a bit-processor.
@@ -179,7 +355,7 @@
support:
- copying (either through assignment operator or
constructor); default construction recommended.
- - a memeber type \c consumed_type that compatible
+ - a member type \c consumed_type that compatible
with a Boolean, like <code>bool</code>.
- a member type \c product_type (that's "normal")
- a (non-<code>const</code>) member <code>operator
@@ -221,9 +397,11 @@
*/
typedef unsigned char consumed_type;
- // Constants
- //! The bit-wise endian setting
- static bool const reads_start_highest = BigEndian;
+ /** \brief The bit-wise endian setting
+
+ Represents which way the bits within a submitted byte are processed.
+ */
+ typedef mpl::bool_<BigEndian> read_from_highest;
// Member data
/** \brief The wrapped bit-processing engine
@@ -261,13 +439,13 @@
// Bit-loop implementation
void consume_bits( unsigned char byte, int amount )
{
- typedef boost::mpl::int_<+1> one_type;
- typedef boost::mpl::int_< 0> zero_type;
- typedef boost::mpl::int_<-1> one_ntype;
+ typedef mpl::int_<+1> one_type;
+ typedef mpl::int_< 0> zero_type;
+ typedef mpl::int_<-1> one_ntype;
- typedef typename boost::mpl::if_c<BigEndian, one_type, zero_type>::type
+ typedef typename mpl::if_<read_from_highest, one_type, zero_type>::type
starting_type;
- typedef typename boost::mpl::if_c<BigEndian, one_ntype, one_type>::type
+ typedef typename mpl::if_<read_from_highest, one_ntype, one_type>::type
direction_type;
BOOST_ASSERT( (amount >= 0) && (amount <= CHAR_BIT) );
@@ -282,6 +460,82 @@
}; // bit_to_byte_processor
+
+// Byte-processing bit-processor wrapper class template member definitions -//
+
+/** Constructs a byte-processor engine from to a given bit-processor engine.
+
+ \param p The bit-processor engine to copy as the initial state. If not
+ given, a default-constructed engine is used.
+
+ \post <code>#inner == <var>p</var></code>.
+ */
+template < class BitProcessor, bool BigEndian >
+inline
+bit_to_byte_processor<BitProcessor, BigEndian>::bit_to_byte_processor
+(
+ processor_type const & p // = processor_type()
+)
+ : inner( p )
+{}
+
+/** Submits a byte for processing, bit-wise in the initialized endian order.
+
+ \param byte The byte value to be submitted.
+
+ \post Calls <code>this->inner( <var>x</var> )</code> \c CHAR_BIT times,
+ with \p x iterating from either the highest-order bit (if
+ \c #reads_start_highest is \c true) or lowest-order bit (if \c false)
+ towards, and including, the opposite-order bit.
+ */
+template < class BitProcessor, bool BigEndian >
+inline void
+bit_to_byte_processor<BitProcessor, BigEndian>::operator ()(consumed_type byte)
+{ this->consume_bits( byte, CHAR_BIT ); }
+
+/** Compares byte-processors for equivalence. Such engines are equal if their
+ internal bit-processors are equal.
+
+ \param o The right-side operand to be compared.
+
+ \retval true \c *this and \p o are equivalent.
+ \retval false \c *this and \p o are not equivalent.
+ */
+template < class BitProcessor, bool BigEndian >
+inline bool
+bit_to_byte_processor<BitProcessor, BigEndian>::operator ==
+( self_type const &o ) const
+{ return this->inner == o.inner; }
+
+/** Compares byte-processors for non-equivalence. Such engines are unequal if
+ their internal bit-processors are unequal.
+
+ \param o The right-side operand to be compared.
+
+ \retval true \c *this and \p o are not equivalent.
+ \retval false \c *this and \p o are equivalent.
+ */
+template < class BitProcessor, bool BigEndian >
+inline bool
+bit_to_byte_processor<BitProcessor, BigEndian>::operator !=
+( self_type const &o ) const
+{ return !this->operator ==( o ); }
+
+/** Provides the computed check-sum of all the submitted bytes, through a
+ standard generator interface. Since this is a \c const member function, the
+ engine must act as if bit-submission is complete whenever this function is
+ called.
+
+ \return The check-sum.
+ */
+template < class BitProcessor, bool BigEndian >
+inline typename bit_to_byte_processor<BitProcessor, BigEndian>::product_type
+bit_to_byte_processor<BitProcessor, BigEndian>::operator ()() const
+{ return this->inner(); }
+
+
+// Bit-processing coding shell class template declaration ------------------//
+
/** \brief A presentation layer for encapsulating bit-processing.
This class template can wrap a bit-computation class type. This template
@@ -301,7 +555,7 @@
support:
- copying (either through assignment operator or
constructor); default construction recommended.
- - a memeber type \c consumed_type that compatible
+ - a member type \c consumed_type that compatible
with a Boolean, like <code>bool</code>.
- a member type \c product_type (that's "normal")
- a (non-<code>const</code>) member <code>operator
@@ -324,7 +578,7 @@
*/
template < class BitProcessor, bool BigEndian >
class bit_coding_shell
- : private byte_coding_shell<bit_to_byte_processor<BitProcessor, BigEndian> >
+ : public byte_coding_shell<bit_to_byte_processor<BitProcessor, BigEndian> >
{
typedef byte_coding_shell< bit_to_byte_processor<BitProcessor, BigEndian> >
base_type;
@@ -368,13 +622,13 @@
*/
typedef typename BitProcessor::product_type value_type;
- // Constants
- //! The bit-wise endian setting
- static bool const reads_start_highest = BigEndian;
+ /** \brief The bit-wise endian setting (as a integral meta-constant)
- // Member data
- using base_type::bytes;
+ Represents which way the bits within a submitted byte are processed.
+ */
+ typedef mpl::bool_<BigEndian> read_from_highest;
+ // Member data
/** \brief Proxy for bit-oriented application interface
Accesses an interface where <code>this->bits</code> can be used as a
@@ -387,7 +641,7 @@
\c #bytes' wrapped engine, but copies of this sub-object will
allocate (with regular <code>operator new</code>) independent
copies of that engine. This will cause throws/crashes in
- situtations when default memory allocation is full or disabled.
+ situations when default memory allocation is full or disabled.
(And there's no choice for an alternate allocation scheme.)
Maybe a <code>boost::variant< BitProcessor *, BitProcessor
></code> can be used, but it has its own complicated storage
@@ -410,34 +664,17 @@
/*! \name Input reading */ //@{
// Processors
- using base_type::process_byte;
- using base_type::process_byte_copies;
- using base_type::process_block;
- using base_type::process_bytes;
-
//! Enters one bit for hashing
void process_bit( bool bit );
- //! Enters lowest-signficant part of a byte
+ //! Enters lowest-significant part of a byte
void process_bits( unsigned char bits, size_type bit_count );
//! Enters several bits, all of the same value
- void process_bit_copies( bool value, size_type bit_count );
-
- //! Enters an octet
- void process_octet( uint_least8_t octet );//@}
-
- // Finishers
- using base_type::checksum;
+ void process_bit_copies( bool value, size_type bit_count );//@}
/*! \name Operators */ //@{
// Operators
//! Copy-assignment
self_type & operator =( self_type const &c );
- //! Equals
- bool operator ==( self_type const &o ) const;
- //! Not-equals
- bool operator !=( self_type const &o ) const;
-
- using base_type::operator ();//@} // remove?
private:
/*! \name Persistence */ //@{
@@ -451,262 +688,7 @@
}; // bit_coding_shell
-// Byte-processing coding shell class template member definitions ----------//
-
-/** Constructs a byte-processor shell set to a given engine.
-
- \param p The byte-processor engine to copy as the initial state. If not
- given, a default-constructed engine is used.
-
- \post \c #bytes uses a copy of \p p and refers to \c *this.
- */
-template < class ByteProcessor >
-inline
-byte_coding_shell<ByteProcessor>::byte_coding_shell
-(
- processor_type const & p // = processor_type()
-)
- : bytes( p )
-{}
-
-/** Provides non-mutable access to the byte-processor engine.
-
- \return A \c const reference to the internal engine.
- */
-template < class ByteProcessor >
-inline typename byte_coding_shell<ByteProcessor>::processor_type const &
-byte_coding_shell<ByteProcessor>::context() const
-{ return this->bytes.source; }
-
-/** Provides mutable access to the byte-processor engine.
-
- \post None, besides what tinkering with the result may do.
-
- \return A non-<code>const</code> reference to the internal engine.
- */
-template < class ByteProcessor >
-inline typename byte_coding_shell<ByteProcessor>::processor_type &
-byte_coding_shell<ByteProcessor>::context()
-{ return this->bytes.source; }
-
-/** Submits a byte for processing.
-
- \param byte The byte value to be submitted.
-
- \post Calls <code>this->bytes( <var>byte</var> )</code>.
- */
-template < class ByteProcessor >
-inline void
-byte_coding_shell<ByteProcessor>::process_byte( unsigned char byte )
-{ this->bytes( byte ); }
-
-/** Submits multiple copies of a single byte value for processing.
-
- \param value The byte value to be submitted.
- \param byte_count The number of bytes to submit.
-
- \post Calls <code>this->bytes( <var>value</var> )</code> \p byte_count
- times.
- */
-template < class ByteProcessor >
-inline void
-byte_coding_shell<ByteProcessor>::process_byte_copies
-(
- unsigned char value,
- size_type byte_count
-)
-{
- while ( byte_count-- )
- this->bytes( value );
-}
-
-/** Submits bytes, delimited by a pointer range, for processing.
-
- \pre If \p bytes_begin is not \c NULL, then \p bytes_end has to be
- reachable from \p bytes_begin via forward iterations of their
- equivalent <code>unsigned char const *</code> values, otherwise
- \p bytes_end has to be \c NULL too.
-
- \param bytes_begin The start of the byte range to be submitted.
- \param bytes_end One-past-the-end of the byte range in \p bytes_begin.
-
- \post Calls <code>this->bytes( <var>x</var> )</code> for each byte \p x
- in the given range, starting from the one at the address
- \p bytes_begin to the byte just before the \p bytes_end mark. (If
- the parameters are identical, then nothing is done.)
- */
-template < class ByteProcessor >
-inline void
-byte_coding_shell<ByteProcessor>::process_block
-(
- void const * bytes_begin,
- void const * bytes_end
-)
-{
- BOOST_ASSERT( !bytes_begin == !bytes_end ); // Can't test reachability!
-
- for ( BOOST_AUTO(p, static_cast<unsigned char const *>( bytes_begin )) ;
- p != bytes_end ; ++p )
- this->bytes( *p );
-}
-
-/** Submits bytes, bounded by a pointer and length, for processing.
-
- \pre If \p buffer is \c NULL, then \p byte_count must be zero.
-
- \param buffer The start of the byte range to be submitted.
- \param byte_count Number of (leading) bytes to use from the range.
-
- \post Calls <code>this->bytes( <var>x</var> )</code> for each byte \p x
- in the given range, starting from the one at the address \p buffer,
- going forward for \p byte_count bytes total.
- */
-template < class ByteProcessor >
-inline void
-byte_coding_shell<ByteProcessor>::process_bytes
-(
- void const * buffer,
- size_type byte_count
-)
-{
- BOOST_ASSERT( buffer || !byte_count );
-
- for ( BOOST_AUTO(p, static_cast<unsigned char const *>( buffer )) ;
- byte_count-- ; ++p )
- this->bytes( *p );
-}
-
-/** Provides the computed check-sum of all the submitted values. Since this is
- a \c const member function, the engine must act as if value-submission is
- complete whenever this function is called.
-
- \return The check-sum.
- */
-template < class ByteProcessor >
-inline typename byte_coding_shell<ByteProcessor>::value_type
-byte_coding_shell<ByteProcessor>::checksum() const
-{ return this->context()(); }
-
-/** Compares byte-processor shells for equivalence. Such shells are equal if
- their internal engines are equal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are equivalent.
- \retval false \c *this and \p o are not equivalent.
- */
-template < class ByteProcessor >
-inline bool
-byte_coding_shell<ByteProcessor>::operator ==( self_type const &o ) const
-{ return this->bytes == o.bytes; }
-
-/** Compares byte-processor shells for non-equivalence. Such shells are unequal
- if their internal engines are unequal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are not equivalent.
- \retval false \c *this and \p o are equivalent.
- */
-template < class ByteProcessor >
-inline bool
-byte_coding_shell<ByteProcessor>::operator !=( self_type const &o ) const
-{ return !this->operator ==( o ); }
-
-/** Computes the check-sum of the submitted data, through a standard generator
- interface.
-
- \return The generated check-sum.
-
- \see #checksum()const
- */
-template < class ByteProcessor >
-inline typename byte_coding_shell<ByteProcessor>::value_type
-byte_coding_shell<ByteProcessor>::operator ()() const
-{ return this->checksum(); }
-
-
-// Bit-processing coding shell class templates member defintions -----------//
-
-/** Represents which way the bits within a submitted byte are processed.
- */
-template < class BitProcessor, bool BigEndian >
-bool const bit_to_byte_processor<BitProcessor, BigEndian>::reads_start_highest;
-
-/** Constructs a byte-processor engine from to a given bit-processor engine.
-
- \param p The bit-processor engine to copy as the initial state. If not
- given, a default-constructed engine is used.
-
- \post <code>#inner == <var>p</var></code>.
- */
-template < class BitProcessor, bool BigEndian >
-inline
-bit_to_byte_processor<BitProcessor, BigEndian>::bit_to_byte_processor
-(
- processor_type const & p // = processor_type()
-)
- : inner( p )
-{}
-
-/** Submits a byte for processing, bit-wise in the initialized endian order.
-
- \param byte The byte value to be submitted.
-
- \post Calls <code>this->inner( <var>x</var> )</code> \c CHAR_BIT times,
- with \p x iterating from either the highest-order bit (if
- \c #reads_start_highest is \c true) or lowest-order bit (if \c false)
- towards, and including, the opposite-order bit.
- */
-template < class BitProcessor, bool BigEndian >
-inline void
-bit_to_byte_processor<BitProcessor, BigEndian>::operator ()(consumed_type byte)
-{ this->consume_bits( byte, CHAR_BIT ); }
-
-/** Compares byte-processors for equivalence. Such engines are equal if their
- internal bit-processors are equal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are equivalent.
- \retval false \c *this and \p o are not equivalent.
- */
-template < class BitProcessor, bool BigEndian >
-inline bool
-bit_to_byte_processor<BitProcessor, BigEndian>::operator ==
-( self_type const &o ) const
-{ return this->inner == o.inner; }
-
-/** Compares byte-processors for non-equivalence. Such engines are unequal if
- their internal bit-processors are unequal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are not equivalent.
- \retval false \c *this and \p o are equivalent.
- */
-template < class BitProcessor, bool BigEndian >
-inline bool
-bit_to_byte_processor<BitProcessor, BigEndian>::operator !=
-( self_type const &o ) const
-{ return !this->operator ==( o ); }
-
-/** Provides the computed check-sum of all the submitted bytes, through a
- standard generator interface. Since this is a \c const member function, the
- engine must act as if bit-submission is complete whenever this function is
- called.
-
- \return The check-sum.
- */
-template < class BitProcessor, bool BigEndian >
-inline typename bit_to_byte_processor<BitProcessor, BigEndian>::product_type
-bit_to_byte_processor<BitProcessor, BigEndian>::operator ()() const
-{ return this->inner(); }
-
-/** Represents which way the bits within a submitted byte are processed.
- */
-template < class BitProcessor, bool BigEndian >
-bool const bit_coding_shell<BitProcessor, BigEndian>::reads_start_highest;
+// Bit-processing coding shell class template member definitions -----------//
/** Constructs a bit-processor shell set to a given engine.
@@ -740,7 +722,9 @@
, bits( &this->base_type::context().inner )
{}
-/** Provides non-mutable access to the bit-processor engine.
+/** Provides non-mutable access to the bit-processor engine. This overload
+ exists to give direct access to the bit-processor engine, since the base
+ class's version will return access to the wrapping byte-processing engine.
\return A \c const reference to the internal engine.
*/
@@ -749,7 +733,9 @@
bit_coding_shell<BitProcessor, BigEndian>::context() const
{ return *this->bits.source; }
-/** Provides mutable access to the bit-processor engine.
+/** Provides mutable access to the bit-processor engine. This overload exists
+ to give direct access to the bit-processor engine, since the base class's
+ version will return access to the wrapping byte-processing engine.
\post None, besides what tinkering with the result may do.
@@ -814,21 +800,9 @@
this->bits( value );
}
-/** Submits an octet for processing, bit-wise in the initialized endian order.
-
- \param octet The octet value to be submitted.
-
- \post Calls <code>this->process_bits( <var>octet</var>, 8 )</code>.
-
- \see #process_bits(unsigned char,#size_type)
- */
-template < class BitProcessor, bool BigEndian >
-inline void
-bit_coding_shell<BitProcessor, BigEndian>::process_octet( uint_least8_t octet )
-{ this->process_bits( octet, 8 ); }
-
/** Changes a bit-processing shell to have the same observable state as a given
- shell. (No function object proxies are reseated, however.)
+ shell. (No function object proxies are reseated, however.) This overload
+ exists because the default action would perform an unnecessary extra copy.
\param c The source object with the new state.
@@ -841,36 +815,14 @@
bit_coding_shell<BitProcessor, BigEndian>::operator =( self_type const &c )
{
static_cast<base_type &>( *this ) = static_cast<base_type const &>( c );
- // "bits" is NOT reseated
+ // "bits" can't be reseated; but if it got assigned, it would ultimately
+ // perform a copy of the core bit-processing engine, which was already done
+ // in the base class's version of the copy-assignment operator. (This would
+ // be bad of the engine's assignment took a lot of time or resources.) So
+ // we can skip it.
return *this;
}
-/** Compares bit-processor shells for equivalence. Such shells are equal if
- their internal engines are equal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are equivalent.
- \retval false \c *this and \p o are not equivalent.
- */
-template < class BitProcessor, bool BigEndian >
-inline bool
-bit_coding_shell<BitProcessor, BigEndian>::operator ==(self_type const &o) const
-{ return this->bits == o.bits; }
-
-/** Compares bit-processor shells for non-equivalence. Such shells are unequal
- if their internal engines are unequal.
-
- \param o The right-side operand to be compared.
-
- \retval true \c *this and \p o are not equivalent.
- \retval false \c *this and \p o are equivalent.
- */
-template < class BitProcessor, bool BigEndian >
-inline bool
-bit_coding_shell<BitProcessor, BigEndian>::operator !=(self_type const &o) const
-{ return !this->operator ==( o ); }
-
} // namespace coding
} // namespace boost
Modified: sandbox/md5/boost/coding/md5.hpp
==============================================================================
--- sandbox/md5/boost/coding/md5.hpp (original)
+++ sandbox/md5/boost/coding/md5.hpp 2008-08-02 16:12:09 EDT (Sat, 02 Aug 2008)
@@ -23,7 +23,11 @@
#include <boost/assert.hpp> // for BOOST_ASSERT
#include <boost/coding/coding_shell.hpp> // for b:c:bit_coding_shell
#include <boost/coding/operations.hpp> // for b:c:queued_bit_processing_base
-#include <boost/integer.hpp> // for boost::sized_integral
+#include <boost/cstdint.hpp> // for boost::uint_least8_t, etc.
+#include <boost/integer.hpp> // for boost::sized_integral, etc.
+#include <boost/mpl/arithmetic.hpp> // for boost::mpl::times
+#include <boost/mpl/int.hpp> // for boost::mpl::int_
+#include <boost/mpl/size_t.hpp> // for boost::mpl::size_t
#include <boost/serialization/access.hpp> // for boost::serialization::access
#include <boost/static_assert.hpp> // for BOOST_STATIC_ASSERT
#include <boost/typeof/typeof.hpp> // for BOOST_AUTO
@@ -65,25 +69,31 @@
class md5_digest
{
public:
- //! Number of bits for word-sized quantities
- static int const bits_per_word = 32;
+ // Types
+ /** \brief Number of bits for word-sized quantities
+ Represents the number of bits per word as given in RFC 1321, section 2.
+ */
+ typedef mpl::int_<32> bits_per_word;
/** \brief Type of MD register
Represents the type of each register of the MD buffer.
*/
- typedef boost::sized_integral<bits_per_word, unsigned>::type word_type;
+ typedef sized_integral<bits_per_word::value, unsigned>::type word_type;
+ /** \brief Length of MD buffer
- //! Length of MD buffer
- static std::size_t const words_per_digest = 4u;
+ Represents the number of registers in a MD buffer.
+ */
+ typedef mpl::size_t<4u> words_per_digest;
+ // Member data
/** \brief The MD5 message digest checksum
Represents the checksum from a MD5 hashing, mirroring for format of the
MD buffer (see RFC 1321, section 3.3). The zero-index corresponds to
the "A" register, up to index 3 representing the "D" register.
*/
- word_type hash[ words_per_digest ];
+ word_type hash[ words_per_digest::value ];
}; // md5_digest
@@ -119,18 +129,18 @@
*/
class md5_computerX
: protected queued_bit_processing_base<md5_computerX, uint_fast64_t, 16u *
- md5_digest::bits_per_word>
+ md5_digest::bits_per_word::value>
{
typedef queued_bit_processing_base<md5_computerX, uint_fast64_t, 16u *
- md5_digest::bits_per_word> base_type;
+ md5_digest::bits_per_word::value> base_type;
friend void base_type::process_bit( bool ); // needs "update_hash" access
// Implementation constants, followed by sanity checks
static std::size_t const words_per_block = base_type::queue_length /
- md5_digest::bits_per_word;
+ md5_digest::bits_per_word::value;
- BOOST_STATIC_ASSERT( (base_type::queue_length % md5_digest::bits_per_word)
+ BOOST_STATIC_ASSERT( (base_type::queue_length % md5_digest::bits_per_word::value)
== 0u );
BOOST_STATIC_ASSERT( words_per_block == 16u ); // RFC 1321, section 3.4
@@ -142,7 +152,7 @@
// Constants
//! Number of bits for length quantities
static int const significant_bits_per_length = 2 *
- md5_digest::bits_per_word;
+ md5_digest::bits_per_word::value;
//! Number of bits in hash queue
static std::size_t const bits_per_block = base_type::queue_length;
@@ -174,7 +184,7 @@
prior \e completed hashed blocks. The zero-index corresponds to the "A"
register, up to index 3 representing the "D" register.
*/
- typedef array<md5_digest::word_type, md5_digest::words_per_digest>
+ typedef array<md5_digest::word_type, md5_digest::words_per_digest::value>
buffer_type;
// Lifetime management (use automatic destructor)
@@ -263,14 +273,16 @@
// Implementation types
typedef md5_computerX self_type;
- typedef uint_t<md5_digest::bits_per_word>::fast iword_type;
- typedef array<iword_type, md5_digest::words_per_digest> ibuffer_type;
+ typedef uint_t<md5_digest::bits_per_word::value>::fast iword_type;
+ typedef array<iword_type, md5_digest::words_per_digest::value> ibuffer_type;
// (Computation) member data
ibuffer_type buffer_;
static ibuffer_type const initial_buffer_;
+ friend class md5_context;
+
}; // md5_computerX
/** \brief A computer that produces MD5 message digests from consuming bits.
@@ -285,27 +297,134 @@
{
typedef md5_context self_type;
- friend class md5_computer;
-
public:
+ // Types
+ /** \brief Type of the produced output
+
+ Represents the result type, the checksums from hashing.
+ */
typedef md5_digest product_type;
- typedef bool consumed_type;
+ /** \brief Type of the consumed input
+
+ Represents the argument type, the data to hash.
+ */
+ typedef bool consumed_type;
+
+ // Lifetime management (use automatic copy constructor and destructor)
+ //! Default construction
+ md5_context() : worker(), length(), buffer( initial_buffer ), queue() {}
- void operator ()( consumed_type bit ) { this->worker.process_bit(bit); }
+ /*! \name Operators */ //@{
+ // Operators (use automatic copy-assignment)
+ //! Application, consumer
+ void operator ()( consumed_type bit )
+ {
+ this->worker.process_bit(bit);
+ this->consume_bit( bit );
+ }
+ //! Equals
bool operator ==( self_type const &o ) const
- { return this->worker == o.worker; }
+ {
+ bool const result1( this->worker == o.worker );
+ bool const result2( (this->length == o.length) && (this->buffer ==
+ o.buffer) && std::equal(this->queue.begin(), this->queue.begin() +
+ this->length % bits_per_block::value, o.queue.begin()) );
+ BOOST_ASSERT( result1 == result2 );
+ return result1;
+ }
+ //! Not-equals
bool operator !=( self_type const &o ) const
{ return !this->operator ==( o ); }
- product_type operator ()() const { return this->worker.checksum(); }
+ //! Application, producer
+ product_type operator ()() const
+ {
+ product_type const result1( this->worker.checksum() );
+ product_type result2;
+ {
+ self_type c( *this );
+ c.finish();
+ std::copy( c.buffer.begin(), c.buffer.end(), result2.hash );
+ }
+ BOOST_ASSERT( std::equal(result1.hash, result1.hash+4, result2.hash) );
+ return result1;
+ }//@}
private:
+ friend class md5_computer;
+
+ // Implementation types and meta-constants
+ typedef md5_digest::bits_per_word bits_per_word;
+ typedef md5_digest::word_type word_type;
+ typedef md5_digest::words_per_digest words_per_digest;
+
+ typedef mpl::int_<2> words_per_length;
+ typedef mpl::times<words_per_length, bits_per_word> bits_per_length;
+ typedef mpl::int_<16> words_per_block;
+ typedef mpl::times<words_per_block, bits_per_word> bits_per_block;
+
+ typedef sized_integral<bits_per_length::value, unsigned>::type length_type;
+ typedef fast_integral<length_type>::type length_ftype;
+ typedef fast_integral<word_type>::type word_ftype;
+ typedef array<word_ftype, words_per_digest::value> buffer_type;
+ typedef array<consumed_type, bits_per_block::value> queue_type;
+ typedef array<word_ftype, 64> hash_table_type;
+
+ // Implementation constants
+ static buffer_type const initial_buffer;
+ static hash_table_type const hashing_table;
+
+ // Member data
md5_computerX worker;
+ length_ftype length;
+ buffer_type buffer;
+ queue_type queue;
+
+ // Implementation
+ void update_hash();
+ void consume_bit( bool bit )
+ {
+ this->queue[ this->length++ % bits_per_block::value ] = bit;
+ if ( this->length % bits_per_block::value == 0u )
+ this->update_hash();
+ }
+ void consume_octet( uint_fast8_t octet )
+ {
+ for ( int i = 0 ; i < 8 ; ++i, octet <<= 1 ) // high bit going down
+ this->consume_bit( octet & 0x80u );
+ }
+ void consume_word( word_ftype word )
+ {
+ for ( int i = 0 ; i < 4 ; ++i, word >>= 8 ) // low octet going up
+ this->consume_octet( word & 0xFFu );
+ }
+ void consume_dword( length_ftype dword )
+ {
+ for ( int i = 0 ; i < 2 ; ++i, dword >>= 32 ) // low word going up
+ this->consume_word( dword & 0xFFFFFFFFul );
+ }
+ void finish()
+ {
+ // Save the current length before we mutate it.
+ length_ftype const original_length = length;
+
+ // Enter a One, then enough Zeros so the length would fill the queue.
+ this->consume_bit( true );
+ for ( int i = bits_per_block::value - (this->length +
+ bits_per_length::value) % bits_per_block::value ; i > 0 ; --i )
+ this->consume_bit( false );
+
+ this->consume_dword( original_length );
+ BOOST_ASSERT( !(this->length % bits_per_block::value) );
+
+ // Now a finished checksum in this->buffer is ready to read.
+ }
+ /*! \name Persistence */ //@{
// Serialization
friend class boost::serialization::access;
template < class Archive >
- void serialize( Archive &ar, const unsigned int version ); // not defined yet
+ void serialize( Archive &ar, const unsigned int version );//@} // not defined yet
}; // md5_context
@@ -343,7 +462,7 @@
// Types
typedef uint_least64_t length_type;
- typedef array<md5_digest::word_type, md5_digest::words_per_digest>
+ typedef array<md5_digest::word_type, md5_digest::words_per_digest::value>
buffer_type;
// Assignment
@@ -371,18 +490,24 @@
{ return this->context().worker.copy_unbuffered( o ); }
// Input processing
+ //! Enters an octet
+ void process_octet( uint_least8_t octet )
+ {
+ this->context().worker.process_octet( octet );
+ this->context().consume_octet( octet );
+ }
//! Enters a word for hashing
void process_word( md5_digest::word_type word )
- { this->context().worker.process_word( word ); }
+ {
+ this->context().worker.process_word( word );
+ this->context().consume_word( word );
+ }
//! Enters a double-word for hashing
void process_double_word( length_type dword )
- { this->context().worker.process_double_word( dword ); }
-
- // Operators
- bool operator ==( self_type const &o ) const
- { return this->base_type::operator ==( o ); }
- bool operator !=( self_type const &o ) const
- { return !this->operator ==( o ); }
+ {
+ this->context().worker.process_double_word( dword );
+ this->context().consume_dword( dword );
+ }
// Extras
static array<md5_digest::word_type, 64> generate_hashing_table()
@@ -417,13 +542,13 @@
static char const hex_digits_uc[ number_of_hexadecimal_digits + 1 ];
// MD words
- static std::size_t const nybbles_per_word = md5_digest::bits_per_word /
- bits_per_nybble;
+ static std::size_t const nybbles_per_word =
+ md5_digest::bits_per_word::value / bits_per_nybble;
// MD strings
- static std::size_t const characters_per_digest = md5_digest::bits_per_word
- * md5_digest::words_per_digest / ( nybbles_per_hexadecimal_digit *
- bits_per_nybble );
+ static std::size_t const characters_per_digest =
+ md5_digest::bits_per_word::value * md5_digest::words_per_digest::value /
+ ( nybbles_per_hexadecimal_digit * bits_per_nybble );
}; // md5_constants
@@ -450,7 +575,8 @@
bool
operator ==( md5_digest const &l, md5_digest const &r )
{
- return std::equal( l.hash, l.hash + md5_digest::words_per_digest, r.hash );
+ return std::equal( l.hash, l.hash + md5_digest::words_per_digest::value,
+ r.hash );
}
/** \brief Not-equals
Modified: sandbox/md5/libs/coding/src/md5.cpp
==============================================================================
--- sandbox/md5/libs/coding/src/md5.cpp (original)
+++ sandbox/md5/libs/coding/src/md5.cpp 2008-08-02 16:12:09 EDT (Sat, 02 Aug 2008)
@@ -18,7 +18,7 @@
#include <boost/array.hpp> // for boost::array
#include <boost/assert.hpp> // for BOOST_ASSERT
-#include <boost/integer/integer_mask.hpp> // for boost::low_bits_mask_t
+#include <boost/integer/integer_mask.hpp> // for boost::integer_lo_mask
#include <boost/math/common_factor_rt.hpp> // for boost::math::gcd
#include <boost/static_assert.hpp> // for BOOST_STATIC_ASSERT
@@ -185,16 +185,6 @@
{
-// MD5 message-digest class-static member definitions ----------------------//
-
-/** Represents the number of bits per word as given in RFC 1321, section 2.
- */
-int const md5_digest::bits_per_word;
-/** Represents the number of registers in a MD buffer.
- */
-std::size_t const md5_digest::words_per_digest;
-
-
//! \cond
// Implementation detail object definitions --------------------------------//
@@ -311,12 +301,18 @@
0xEB86D391ul
} };
+md5_context::hash_table_type const md5_context::hashing_table =
+ md5_computerX::hashing_table;
+
// Initial values of the MD buffer, taken from RFC 1321, section 3.3. (Note
// that the RFC lists each number low-order byte first, while numbers need to be
// written high-order byte first in C++.)
md5_computerX::ibuffer_type const md5_computerX::initial_buffer_ = {
{0x67452301ul, 0xEFCDAB89ul, 0x98BADCFEul, 0x10325476ul} };
+md5_context::buffer_type const md5_context::initial_buffer =
+ md5_computerX::initial_buffer_;
+
// MD5 message-digest computer class-static member function definitions ----//
@@ -350,6 +346,89 @@
// Hash an entire block into the running checksum, using RFC 1321, section 3.4
void
+md5_context::update_hash()
+{
+ using std::size_t;
+
+ // Convert the queued bit block to a word block
+ std::valarray<word_ftype> words( words_per_block::value ),
+ scratch( words_per_block::value ); // for later
+
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ // Use the default inner-product; since "queue" has "bool" elements,
+ // which convert to 0 or 1, multiplication acts as AND; since
+ // "order_in_word" has distinct single-bit values, addition acts as OR.
+ words[ i ] = std::inner_product( order_in_word.begin(),
+ order_in_word.end(), this->queue.begin() + i * bits_per_word::value,
+ word_ftype(0u) );
+ }
+
+ // Set up rounds
+ buffer_type buffer = this->buffer;
+
+ // Round 1
+ {
+ md5_special_op<md5_f, word_ftype, bits_per_word::value> ff;
+
+ scratch = words[ skipped_indices(words_per_block::value, 0, 1) ];
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ ff( buffer[( 16u - i ) % 4u], buffer[( 17u - i ) % 4u],
+ buffer[( 18u - i ) % 4u], buffer[( 19u - i ) % 4u], scratch[i],
+ md5_s[0][i % 4u], hashing_table[i] );
+ }
+ }
+
+ // Round 2
+ {
+ md5_special_op<md5_g, word_ftype, bits_per_word::value> gg;
+
+ scratch = words[ skipped_indices(words_per_block::value, 1, 5) ];
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ gg( buffer[( 16u - i ) % 4u], buffer[( 17u - i ) % 4u],
+ buffer[( 18u - i ) % 4u], buffer[( 19u - i ) % 4u], scratch[i],
+ md5_s[1][i % 4u], hashing_table[16 + i] );
+ }
+ }
+
+ // Round 3
+ {
+ md5_special_op<md5_h, word_ftype, bits_per_word::value> hh;
+
+ scratch = words[ skipped_indices(words_per_block::value, 5, 3) ];
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ hh( buffer[( 16u - i ) % 4u], buffer[( 17u - i ) % 4u],
+ buffer[( 18u - i ) % 4u], buffer[( 19u - i ) % 4u], scratch[i],
+ md5_s[2][i % 4u], hashing_table[32 + i] );
+ }
+ }
+
+ // Round 4
+ {
+ md5_special_op<md5_i, word_ftype, bits_per_word::value> ii;
+
+ scratch = words[ skipped_indices(words_per_block::value, 0, 7) ];
+ for ( size_t i = 0u ; i < words_per_block::value ; ++i )
+ {
+ ii( buffer[( 16u - i ) % 4u], buffer[( 17u - i ) % 4u],
+ buffer[( 18u - i ) % 4u], buffer[( 19u - i ) % 4u], scratch[i],
+ md5_s[3][i % 4u], hashing_table[48 + i] );
+ }
+ }
+
+ // Update buffer
+ for ( size_t i = 0u ; i < words_per_digest::value ; ++i )
+ {
+ this->buffer[ i ] += buffer[ i ];
+ this->buffer[ i ] &= integer_lo_mask<bits_per_word::value>::value;
+ }
+}
+
+// Hash an entire block into the running checksum, using RFC 1321, section 3.4
+void
md5_computerX::update_hash( bool const *queue_b, bool const *queue_e )
{
using std::size_t;
@@ -366,7 +445,7 @@
// elements, which convert to 0 or 1, multiplication acts as AND; since
// "order_in_word" has distinct single-bit values, addition acts as OR
words[ i ] = std::inner_product( order_in_word.begin(),
- order_in_word.end(), &scratch[ i * md5_digest::bits_per_word ],
+ order_in_word.end(), &scratch[ i * md5_digest::bits_per_word::value ],
iword_type(0u) );
}
@@ -377,7 +456,7 @@
// Round 1
{
- md5_special_op<md5_f, iword_type, md5_digest::bits_per_word> ff;
+ md5_special_op<md5_f, iword_type, md5_digest::bits_per_word::value> ff;
scratch = words[ skipped_indices(words_per_block, 0, 1) ];
for ( size_t i = 0u ; i < words_per_block ; ++i )
@@ -390,7 +469,7 @@
// Round 2
{
- md5_special_op<md5_g, iword_type, md5_digest::bits_per_word> gg;
+ md5_special_op<md5_g, iword_type, md5_digest::bits_per_word::value> gg;
scratch = words[ skipped_indices(words_per_block, 1, 5) ];
for ( size_t i = 0u ; i < words_per_block ; ++i )
@@ -403,7 +482,7 @@
// Round 3
{
- md5_special_op<md5_h, iword_type, md5_digest::bits_per_word> hh;
+ md5_special_op<md5_h, iword_type, md5_digest::bits_per_word::value> hh;
scratch = words[ skipped_indices(words_per_block, 5, 3) ];
for ( size_t i = 0u ; i < words_per_block ; ++i )
@@ -416,7 +495,7 @@
// Round 4
{
- md5_special_op<md5_i, iword_type, md5_digest::bits_per_word> ii;
+ md5_special_op<md5_i, iword_type, md5_digest::bits_per_word::value> ii;
scratch = words[ skipped_indices(words_per_block, 0, 7) ];
for ( size_t i = 0u ; i < words_per_block ; ++i )
@@ -428,11 +507,11 @@
}
// Update buffer
- for ( size_t i = 0u ; i < md5_digest::words_per_digest ; ++i )
+ for ( size_t i = 0u ; i < md5_digest::words_per_digest::value ; ++i )
{
this->buffer_[ i ] += buffer[ i ];
- this->buffer_[ i ] &= low_bits_mask_t< md5_digest :: bits_per_word > ::
- sig_bits;
+ this->buffer_[ i ] &= integer_lo_mask<md5_digest::bits_per_word::value>
+ ::value;
}
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk