Boost logo

Boost-Commit :

From: dwalker07_at_[hidden]
Date: 2008-07-05 05:18:13


Author: dlwalker
Date: 2008-07-05 05:18:12 EDT (Sat, 05 Jul 2008)
New Revision: 47091
URL: http://svn.boost.org/trac/boost/changeset/47091

Log:
Created completely new system of segregating the MD5-specific code from the common-coding code. To-do: add comments; clean out old system. (The new system is currently using it.) Deferring to work on Boost.Integer, which this library needs.
Added:
   sandbox/md5/boost/coding/coding_shell.hpp (contents, props changed)
Text files modified:
   sandbox/md5/boost/coding/md5.hpp | 154 ++++++++++++++++++++++++++++++---------
   sandbox/md5/boost/coding_fwd.hpp | 15 +++
   sandbox/md5/libs/coding/src/md5.cpp | 27 ++++--
   sandbox/md5/libs/coding/test/md5_computer_test.cpp | 18 +++-
   4 files changed, 163 insertions(+), 51 deletions(-)

Added: sandbox/md5/boost/coding/coding_shell.hpp
==============================================================================
--- (empty file)
+++ sandbox/md5/boost/coding/coding_shell.hpp 2008-07-05 05:18:12 EDT (Sat, 05 Jul 2008)
@@ -0,0 +1,275 @@
+// Boost coding/coding_shell.hpp header file --------------------------------//
+
+// (C) Copyright Daryle Walker 2008. Distributed under the Boost Software
+// License, Version 1.0. (See the accompanying file LICENSE_1_0.txt or a copy
+// at <http://www.boost.org/LICENSE_1_0.txt>.)
+
+// See <http://www.boost.org/libs/coding> for documentation.
+
+/** \file
+ \brief Definitions of coding shell helper class templates
+
+ Contains the definition of templates that encapsulate bit- and byte-encoding
+ computer types, given a coding kernel.
+ */
+
+#ifndef BOOST_CODING_CODING_SHELL_HPP
+#define BOOST_CODING_CODING_SHELL_HPP
+
+#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/int.hpp> // for boost::mpl::int_
+#include <boost/typeof/typeof.hpp> // for BOOST_AUTO
+
+#include <algorithm> // for std::copy, equal
+#include <climits> // for CHAR_BIT
+
+
+namespace boost
+{
+namespace coding
+{
+
+
+// Byte-processing coding shell class template declaration -----------------//
+
+template < class ByteProcessor, typename SizeType >
+class byte_coding_shell
+{
+ class applicator
+ {
+ friend class byte_coding_shell;
+ ByteProcessor source;
+ explicit applicator( ByteProcessor const &p = ByteProcessor() )
+ : source( p ) {}
+ public:
+ void operator ()( unsigned char byte ) { this->source( byte ); }
+ bool operator ==( applicator const &o ) const
+ { return this->source == o.source; }
+ bool operator !=( applicator const &o ) const
+ { return !this->operator ==( o ); }
+ };
+
+public:
+ // Types
+ typedef ByteProcessor processor_type;
+ typedef SizeType size_type;
+ typedef typename ByteProcessor::value_type value_type;
+
+ // Member data
+ applicator bytes;
+
+ // Lifetime management (use automatic copy constructor and destructor)
+ explicit byte_coding_shell( processor_type const &p = processor_type() )
+ : bytes( p ) {}
+
+ // Accessors
+ processor_type const & context() const { return this->bytes.source; }
+ processor_type & context() { return this->bytes.source; }
+
+ // Processors
+ void process_byte( unsigned char byte ) { this->bytes( byte ); }
+ void process_byte_copies( unsigned char value, size_type byte_count )
+ { while ( byte_count-- ) this->bytes( value ); }
+ void process_block( void const *bytes_begin, void const *bytes_end )
+ {
+ BOOST_ASSERT( !bytes_begin == !bytes_end );
+
+ for ( BOOST_AUTO(p, static_cast<unsigned char const *>( bytes_begin )) ;
+ p != bytes_end ; ++p )
+ this->bytes( *p );
+ }
+ void 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 );
+ }
+
+ // Finishers
+ value_type checksum() const { return this->context()(); }
+
+ // Operators (use automatic copy-assignment)
+ bool operator ==( byte_coding_shell const &o ) const
+ { return this->bytes == o.bytes; }
+ bool operator !=( byte_coding_shell const &o ) const
+ { return !this->operator ==( o ); }
+
+ value_type operator ()() const { return this->checksum(); }
+
+}; // byte_coding_shell
+
+
+// Bit-processing coding shell class template declarations -----------------//
+
+template < class BitProcessor, bool BigEndian >
+class bit_to_byte_processor
+{
+public:
+ // Types
+ typedef BitProcessor processor_type;
+ typedef typename BitProcessor::value_type value_type;
+
+ // Constants
+ static bool const reads_start_from_high_order_bit = BigEndian;
+
+ // Member data
+ processor_type inner;
+
+ // Lifetime management (use automatic copy constructor and destructor)
+ explicit bit_to_byte_processor( processor_type const &p = processor_type() )
+ : inner( p ) {}
+
+ // Operators (use automatic copy-assignment)
+ void operator ()( unsigned char byte )
+ {
+ using mpl::if_c;
+ using mpl::int_;
+
+ typedef typename if_c< BigEndian, int_<1>, int_<0> >::type starting;
+ typedef typename if_c< BigEndian, int_<-1>, int_<+1> >::type direction;
+
+ for ( int i = 0, j = starting::value * (CHAR_BIT - 1) ; i < CHAR_BIT ;
+ ++i, j += direction::value )
+ this->inner( byte & (0x01u << j) );
+ }
+
+ bool operator ==( bit_to_byte_processor const &o ) const
+ { return this->inner == o.inner; }
+ bool operator !=( bit_to_byte_processor const &o ) const
+ { return !this->operator ==( o ); }
+
+ value_type operator ()() const { return this->inner(); }
+
+}; // bit_to_byte_processor
+
+template < class BitProcessor, bool BigEndian, typename SizeType >
+class bit_coding_shell
+ : private byte_coding_shell< bit_to_byte_processor<BitProcessor, BigEndian>,
+ SizeType >
+{
+ typedef byte_coding_shell< bit_to_byte_processor<BitProcessor, BigEndian>,
+ SizeType > base_type;
+
+ class applicator
+ {
+ friend class bit_coding_shell;
+ BitProcessor * source;
+ bool own;
+ explicit applicator( BitProcessor *pp )
+ : source( pp ), own( false ) {}
+ public:
+ applicator( applicator const &c )
+ : source( new BitProcessor(*c.source) ), own( true ) {}
+ ~applicator() { if ( own ) delete source; }
+ applicator & operator =( applicator const &c )
+ { *this->source = *c.source; return *this; }
+ void operator ()( bool bit ) { (*this->source)( bit ); }
+ bool operator ==( applicator const &o ) const
+ { return *this->source == *o.source; }
+ bool operator !=( applicator const &o ) const
+ { return !this->operator ==( o ); }
+ };
+
+public:
+ // Types
+ typedef BitProcessor processor_type;
+ typedef SizeType size_type;
+ typedef typename BitProcessor::value_type value_type;
+
+ // Constants
+ static bool const reads_start_from_high_order_bit = BigEndian;
+
+ // Member data
+ using base_type::bytes;
+
+ applicator bits;
+
+ // Lifetime management (use automatic destructor)
+ explicit bit_coding_shell( processor_type const &p = processor_type() )
+ : base_type( typename base_type::processor_type(p) )
+ , bits( &this->base_type::context().inner )
+ {
+ }
+ bit_coding_shell( bit_coding_shell const &c )
+ : base_type( typename base_type::processor_type(c.context()) )
+ , bits( &this->base_type::context().inner )
+ {
+ }
+
+ // Accessors
+ processor_type const & context() const { return *this->bits.source; }
+ processor_type & context() { return *this->bits.source; }
+
+ // Processors
+ using base_type::process_byte;
+ using base_type::process_byte_copies;
+ using base_type::process_block;
+ using base_type::process_bytes;
+
+ void process_bit( bool bit ) { this->bits( bit ); }
+ void process_bits( unsigned char bits, size_type bit_count )
+ {
+ using mpl::if_c;
+ using mpl::int_;
+
+ BOOST_ASSERT( (0u <= bit_count) && (bit_count <= CHAR_BIT) );
+
+ typedef typename if_c< BigEndian, int_<1>, int_<0> >::type starting;
+ typedef typename if_c< BigEndian, int_<-1>, int_<+1> >::type direction;
+
+ for ( int i = (static_cast<int>(bit_count) - 1) * starting::value ;
+ bit_count-- ; i += direction::value )
+ this->bits( bits & (0x01u << i) );
+ }
+ void process_bit_copies( bool value, size_type bit_count )
+ { while ( bit_count-- ) this->bits( value ); }
+
+ void process_octet( uint_least8_t octet )
+ { this->process_bits( octet, 8 ); }
+
+ // Finishers
+ using base_type::checksum;
+
+ // Operators
+ bit_coding_shell & operator =( bit_coding_shell const &c )
+ {
+ // Make sure "bits" isn't reseated
+ static_cast<base_type &>( *this ) = static_cast<base_type const &>( c );
+ return *this;
+ }
+ bool operator ==( bit_coding_shell const &o ) const
+ { return this->bits == o.bits; }
+ bool operator !=( bit_coding_shell const &o ) const
+ { return !this->operator ==( o ); }
+
+ using base_type::operator ();
+
+}; // bit_coding_shell
+
+
+// Byte-processing coding shell class template member definitions ----------//
+
+// Put something here
+
+
+// Bit-processing coding shell class templates member defintions -----------//
+
+template < class BitProcessor, bool BigEndian >
+bool const bit_to_byte_processor<BitProcessor,
+ BigEndian>::reads_start_from_high_order_bit;
+
+template < class BitProcessor, bool BigEndian, typename SizeType >
+bool const bit_coding_shell<BitProcessor, BigEndian,
+ SizeType>::reads_start_from_high_order_bit;
+
+
+} // namespace coding
+} // namespace boost
+
+
+#endif // BOOST_CODING_CODING_SHELL_HPP

Modified: sandbox/md5/boost/coding/md5.hpp
==============================================================================
--- sandbox/md5/boost/coding/md5.hpp (original)
+++ sandbox/md5/boost/coding/md5.hpp 2008-07-05 05:18:12 EDT (Sat, 05 Jul 2008)
@@ -21,6 +21,7 @@
 
 #include <boost/array.hpp> // for boost::array
 #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::uint_t
 #include <boost/serialization/access.hpp> // for boost::serialization::access
@@ -57,7 +58,7 @@
     purposes, but not ordering. Persistence is supported through the standard
     text stream I/O system.
 
- \see boost::coding::md5_computer
+ \see boost::coding::md5_computerX
     \see boost::coding::compute_md5(void const*,std::size_t)
  */
 class md5_digest
@@ -121,11 +122,11 @@
            i.e., both "friend base_type" and "friend class base_type" didn't
            work. I don't know why either.)
  */
-class md5_computer
- : protected queued_bit_processing_base<md5_computer, uint_fast64_t, 16u *
+class md5_computerX
+ : protected queued_bit_processing_base<md5_computerX, uint_fast64_t, 16u *
        md5_digest::bits_per_word>
 {
- typedef queued_bit_processing_base<md5_computer, uint_fast64_t, 16u *
+ typedef queued_bit_processing_base<md5_computerX, uint_fast64_t, 16u *
      md5_digest::bits_per_word> base_type;
 
     friend void base_type::process_bit( bool ); // needs "update_hash" access
@@ -203,19 +204,19 @@
 
     // Lifetime management (use automatic destructor)
     //! Default construction
- md5_computer();
+ md5_computerX();
     //! Copy construction
- md5_computer( md5_computer const &c );
+ md5_computerX( md5_computerX const &c );
 
     /*! \name Assignment */ //@{
     // Assignment
     //! Sets state back to initial conditions
     void reset();
     //! Changes the current state to a copy of another object's
- void assign( md5_computer const &c );
+ void assign( md5_computerX const &c );
 
     //! Exchanges state with another object
- void swap( md5_computer &other );//@}
+ void swap( md5_computerX &other );//@}
 
     /*! \name Inspection */ //@{
     // Inspectors
@@ -225,7 +226,7 @@
     buffer_type last_buffer() const;
 
     using base_type::bits_unbuffered;
- using base_type::copy_unbuffered;
+ using base_type::copy_unbuffered;//@}
 
     /*! \name Bit-stream reading */ //@{
     // Input processing
@@ -256,12 +257,12 @@
     /*! \name Operators */ //@{
     // Operators
     //! Copy-assignment
- md5_computer & operator =( md5_computer const &c );
+ md5_computerX & operator =( md5_computerX const &c );
 
     //! Equals
- bool operator ==( md5_computer const &c ) const;
+ bool operator ==( md5_computerX const &c ) const;
     //! Not-equals
- bool operator !=( md5_computer const &c ) const;
+ bool operator !=( md5_computerX const &c ) const;
 
     //! Application
     value_type operator ()() const;//@}
@@ -299,7 +300,7 @@
     void update_hash( bool const *queue_b, bool const *queue_e );
 
     // Implementation types
- typedef md5_computer self_type;
+ 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;
@@ -309,6 +310,87 @@
 
     static ibuffer_type const initial_buffer_;
 
+}; // md5_computerX
+
+class md5_context
+{
+ friend class md5_computer;
+
+public:
+ typedef md5_computerX::value_type value_type;
+
+ void operator ()( bool bit ) { this->worker.process_bit(bit); }
+ bool operator ==( md5_context const &o ) const
+ { return this->worker == o.worker; }
+ bool operator !=( md5_context const &o ) const
+ { return !this->operator ==( o ); }
+ value_type operator ()() const { return this->worker.checksum(); }
+
+private:
+ md5_computerX worker;
+
+}; // md5_context
+
+class md5_computer
+ : public bit_coding_shell<md5_context, true>
+{
+ typedef bit_coding_shell<md5_context, true> base_type;
+ typedef md5_computer self_type;
+
+public:
+ // Constants
+ static int const significant_bits_per_length =
+ md5_computerX::significant_bits_per_length;
+ static std::size_t const bits_per_block = md5_computerX::bits_per_block;
+ static array<md5_digest::word_type, 64> const hashing_table;
+
+ // Types
+ typedef uint_least64_t length_type;
+ typedef array<md5_digest::word_type, md5_digest::words_per_digest>
+ buffer_type;
+
+ // Assignment
+ //! Sets state back to initial conditions
+ void reset() { *this = self_type(); }
+ //! Changes the current state to a copy of another object's
+ void assign( self_type const &c ) { *this = c; }
+
+ //! Exchanges state with another object
+ void swap( self_type &other ) { std::swap( *this, other ); }
+
+ // Inspectors
+ //! Returns the count of bits read so far
+ length_type bits_read() const
+ { return this->context().worker.bits_read(); }
+ //! Returns the checksum buffer of hashed bits
+ buffer_type last_buffer() const
+ { return this->context().worker.last_buffer(); }
+ //! Returns the count of the queued bits
+ length_type bits_unbuffered() const
+ { return this->context().worker.bits_unbuffered(); }
+ //! Copies out the queued bits
+ template < typename OutputIterator >
+ OutputIterator copy_unbuffered( OutputIterator o ) const
+ { return this->context().worker.copy_unbuffered( o ); }
+
+ // Input processing
+ //! Enters a word for hashing
+ void process_word( md5_digest::word_type word )
+ { this->context().worker.process_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 ); }
+
+ // Extras
+ static array<md5_digest::word_type, 64> generate_hashing_table()
+ { return md5_computerX::generate_hashing_table(); }
+
 }; // md5_computer
 
 
@@ -534,7 +616,7 @@
 
 // MD5 message-digest computation constructor definitions ------------------//
 
-/** Constructs a \c md5_computer set to initial conditions. That is, with the
+/** Constructs a \c md5_computerX set to initial conditions. That is, with the
     buffer initialized as in RFC 1321, section 3.3, and no bits counted as read
     or currently left to be hashed.
 
@@ -545,14 +627,14 @@
     \post \c #bits and \c #bytes point to \c *this
  */
 inline
-md5_computer::md5_computer()
+md5_computerX::md5_computerX()
     : base_type()
     , buffer_( self_type::initial_buffer_ )
 {
     BOOST_ASSERT( this->test_invariant() );
 }
 
-/** Constructs a \c md5_computer to the same computation state as <var>c</var>.
+/** Constructs a \c md5_computerX to the same computation state as <var>c</var>.
 
     \param c The original object to be copied.
 
@@ -567,7 +649,7 @@
     \post \c #bits and \c #bytes point to \c *this
  */
 inline
-md5_computer::md5_computer( md5_computer const &c )
+md5_computerX::md5_computerX( md5_computerX const &c )
     : base_type( c )
     , buffer_( c.buffer_ )
 {
@@ -584,8 +666,8 @@
     \return How many bits have been submitted, hashed and queued.
  */
 inline
-md5_computer::length_type
-md5_computer::bits_read() const
+md5_computerX::length_type
+md5_computerX::bits_read() const
 {
     // Don't count any wrap-around past 2**64
     // (Use mask value once Boost.Integer is upped to 64-bit support)
@@ -599,8 +681,8 @@
     \return The current state of the MD buffer, not counting any unhashed bits.
  */
 inline
-md5_computer::buffer_type
-md5_computer::last_buffer() const
+md5_computerX::buffer_type
+md5_computerX::last_buffer() const
 {
     // boost::array has no constructors (since it's POD), that means that if
     // buffer_type and ibuffer_type differ, we need to convert via assignment.
@@ -620,11 +702,11 @@
            0x10325476 }</code>
     \post <code>#copy_unbuffered(<var>o</var>)</code> leaves \p o unused
 
- \see #md5_computer()
+ \see #md5_computerX()
  */
 inline
 void
-md5_computer::reset()
+md5_computerX::reset()
 {
     this->base_type::reset();
     this->buffer_ = self_type::initial_buffer_;
@@ -647,11 +729,11 @@
            ) == true</code>
     \post \c #bits and \c #bytes \e still point to \c *this
 
- \see #md5_computer(md5_computer const&)
+ \see #md5_computerX(md5_computerX const&)
  */
 inline
 void
-md5_computer::assign( md5_computer const &c )
+md5_computerX::assign( md5_computerX const &c )
 {
     this->base_type::assign( c );
     this->buffer_ = c.buffer_;
@@ -669,7 +751,7 @@
  */
 inline
 void
-md5_computer::swap( md5_computer &other )
+md5_computerX::swap( md5_computerX &other )
 {
     // Use the appropriate swap via Koeing look-up
     using std::swap;
@@ -711,7 +793,7 @@
  */
 inline
 void
-md5_computer::process_word( md5_digest::word_type word )
+md5_computerX::process_word( md5_digest::word_type word )
 {
     this->process_octet( word & 0xFFul );
     this->process_octet( (word >> 8) & 0xFFul );
@@ -745,7 +827,7 @@
  */
 inline
 void
-md5_computer::process_double_word( md5_computer::length_type dword )
+md5_computerX::process_double_word( md5_computerX::length_type dword )
 {
     this->process_word( dword & 0xFFFFFFFFull );
     this->process_word( (dword >> 32) & 0xFFFFFFFFull );
@@ -771,11 +853,11 @@
            ) == true</code>
     \post \c #bits and \c #bytes \e still point to \c *this
 
- \see #assign(md5_computer const&)
+ \see #assign(md5_computerX const&)
  */
 inline
-md5_computer &
-md5_computer::operator =( md5_computer const &c )
+md5_computerX &
+md5_computerX::operator =( md5_computerX const &c )
 {
     this->assign( c );
     return *this;
@@ -796,7 +878,7 @@
  */
 inline
 bool
-md5_computer::operator ==( md5_computer const &c ) const
+md5_computerX::operator ==( md5_computerX const &c ) const
 {
     // Don't compare the function object proxies since they don't carry
     // significant state. (Furthermore, they can't change once initalized and
@@ -813,11 +895,11 @@
     \retval true \c *this and \p c are not equivalent.
     \retval false \c *this and \p c are equivalent.
 
- \see #operator==(md5_computer const&)const
+ \see #operator==(md5_computerX const&)const
  */
 inline
 bool
-md5_computer::operator !=( md5_computer const &c ) const
+md5_computerX::operator !=( md5_computerX const &c ) const
 {
     return !this->operator ==( c );
 }
@@ -830,8 +912,8 @@
     \see #checksum()const
  */
 inline
-md5_computer::value_type
-md5_computer::operator ()() const
+md5_computerX::value_type
+md5_computerX::operator ()() const
 {
     return this->checksum();
 }

Modified: sandbox/md5/boost/coding_fwd.hpp
==============================================================================
--- sandbox/md5/boost/coding_fwd.hpp (original)
+++ sandbox/md5/boost/coding_fwd.hpp 2008-07-05 05:18:12 EDT (Sat, 05 Jul 2008)
@@ -31,6 +31,18 @@
 {
 
 
+// From <boost/coding/coding_shell.hpp> ------------------------------------//
+
+template < class ByteProcessor, typename SizeType = std::size_t >
+class byte_coding_shell;
+
+template < class BitProcessor, bool BigEndian >
+class bit_to_byte_processor;
+
+template < class BitProcessor, bool BigEndian, typename SizeType = std::size_t >
+class bit_coding_shell;
+
+
 // From <boost/coding/operations.hpp> --------------------------------------//
 
 template < class Derived, typename SizeType = std::size_t >
@@ -48,6 +60,9 @@
 
 class md5_digest;
 
+class md5_computerX;
+
+class md5_context;
 class md5_computer;
 
 // Also has a free function

Modified: sandbox/md5/libs/coding/src/md5.cpp
==============================================================================
--- sandbox/md5/libs/coding/src/md5.cpp (original)
+++ sandbox/md5/libs/coding/src/md5.cpp 2008-07-05 05:18:12 EDT (Sat, 05 Jul 2008)
@@ -173,8 +173,8 @@
 // The exact amount of bits needed to be in the queue so an appendage of the
 // length will exactly fill the queue.
 std::size_t const padding_remainder =
- boost::coding::md5_computer::bits_per_block -
- boost::coding::md5_computer::significant_bits_per_length;
+ boost::coding::md5_computerX::bits_per_block -
+ boost::coding::md5_computerX::significant_bits_per_length;
 
 } // unnamed namespace
 
@@ -216,12 +216,12 @@
 
 // MD5 message-digest computer class-static member definitions -------------//
 
-std::size_t const md5_computer::words_per_block;
+std::size_t const md5_computerX::words_per_block;
 
-int const md5_computer::significant_bits_per_length;
-std::size_t const md5_computer::bits_per_block;
+int const md5_computerX::significant_bits_per_length;
+std::size_t const md5_computerX::bits_per_block;
 
-array<md5_digest::word_type, 64> const md5_computer::hashing_table = { {
+array<md5_digest::word_type, 64> const md5_computerX::hashing_table = { {
     0xD76AA478ul,
     0xE8C7B756ul,
     0x242070DBul,
@@ -291,7 +291,7 @@
 // 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_computer::ibuffer_type const md5_computer::initial_buffer_ = {
+md5_computerX::ibuffer_type const md5_computerX::initial_buffer_ = {
  {0x67452301ul, 0xEFCDAB89ul, 0x98BADCFEul, 0x10325476ul} };
 
 
@@ -299,7 +299,7 @@
 
 // Generated copy of "hashing_table"; see header for notes
 array<md5_digest::word_type, 64>
-md5_computer::generate_hashing_table()
+md5_computerX::generate_hashing_table()
 {
     array<md5_digest::word_type, 64> r;
 
@@ -319,7 +319,7 @@
 
 // Hash an entire block into the running checksum, using RFC 1321, section 3.4
 void
-md5_computer::update_hash( bool const *queue_b, bool const *queue_e )
+md5_computerX::update_hash( bool const *queue_b, bool const *queue_e )
 {
     using std::size_t;
 
@@ -409,8 +409,8 @@
 // MD5 message-digest computation digest-output member function definition -//
 
 // Check-sum computation; see header for notes
-md5_computer::value_type
-md5_computer::checksum() const
+md5_computerX::value_type
+md5_computerX::checksum() const
 {
     // As explained in RFC 1321, section 3, the final check-sum is the state of
     // the hash after padding and the original length are appended to the
@@ -438,6 +438,11 @@
     return r;
 }
 
+int const md5_computer::significant_bits_per_length;
+std::size_t const md5_computer::bits_per_block;
+array<md5_digest::word_type, 64> const md5_computer::hashing_table =
+ md5_computerX::hashing_table;
+
 
 } // namespace coding
 } // namespace boost

Modified: sandbox/md5/libs/coding/test/md5_computer_test.cpp
==============================================================================
--- sandbox/md5/libs/coding/test/md5_computer_test.cpp (original)
+++ sandbox/md5/libs/coding/test/md5_computer_test.cpp 2008-07-05 05:18:12 EDT (Sat, 05 Jul 2008)
@@ -480,11 +480,14 @@
         c2.bits( b );
     BOOST_CHECK( c1 == c2 );
 
- // Use with algorithms, note that it works by reference!
+ // Use with algorithms, note that it NO LONGER works by reference!
     md5_computer c3, c4;
 
     BOOST_CHECK( c3 == c4 );
     for_each( value_bits.begin(), value_bits.end(), c3.bits );
+ BOOST_CHECK( c3 == c4 );
+ BOOST_CHECK( c3 != c2 );
+ c3.bits = for_each( value_bits.begin(), value_bits.end(), c3.bits );
     BOOST_CHECK( c3 != c4 );
     BOOST_CHECK( c3 == c2 );
 
@@ -492,11 +495,15 @@
     c4.bits = c3.bits;
     BOOST_CHECK( c4 == c3 );
 
- // Just a formality
+ // NO LONGER just a formality
     c4.reset();
     BOOST_CHECK( c4 != c3 );
     c4.bits = for_each( value_bits.begin(), value_bits.end(), c4.bits );
     BOOST_CHECK( c4 == c3 );
+
+ // TODO: temporary bit-applicator objects call "operator new" in their copy
+ // constructor. We need to cause this allocation to fail so that can be
+ // tested! (Maybe a custom "operator new" is needed?)
 }
 
 // Byte-wise function-object computation test
@@ -513,11 +520,14 @@
         c2.bytes( b );
     BOOST_CHECK( c1 == c2 );
 
- // Use with algorithms, note that it works by reference!
+ // Use with algorithms, note that it NO LONGER works by reference!
     md5_computer c3, c4;
 
     BOOST_CHECK( c3 == c4 );
     for_each( values.begin(), values.end(), c3.bytes );
+ BOOST_CHECK( c3 == c4 );
+ BOOST_CHECK( c3 != c2 );
+ c3.bytes = for_each( values.begin(), values.end(), c3.bytes );
     BOOST_CHECK( c3 != c4 );
     BOOST_CHECK( c3 == c2 );
 
@@ -525,7 +535,7 @@
     c4.bytes = c3.bytes;
     BOOST_CHECK( c4 == c3 );
 
- // Just a formality
+ // NO LONGER just a formality
     c4.reset();
     BOOST_CHECK( c4 != c3 );
     c4.bytes = for_each( values.begin(), values.end(), c4.bytes );


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