From 314f6dcfe061e4435ee33d70e1672810a2be3bb5 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Thu, 19 Jul 2012 15:12:33 +0000 Subject: [PATCH] Merge changes from [79588] to Release; fixes a unhex bug [SVN r79604] --- include/boost/algorithm/hex.hpp | 36 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/include/boost/algorithm/hex.hpp b/include/boost/algorithm/hex.hpp index b6b1548..3f3c0c6 100644 --- a/include/boost/algorithm/hex.hpp +++ b/include/boost/algorithm/hex.hpp @@ -110,33 +110,25 @@ namespace detail { typedef T value_type; }; -// Output Iterators have a value type of 'void'. Kinda sucks. -// We special case some output iterators, but we can't enumerate them all. -// If we can't figure it out, we assume that you want to output chars. -// If you don't, pass in an iterator with a real value_type. - template struct value_type_or_char { typedef T value_type; }; - template <> struct value_type_or_char { typedef char value_type; }; - -// All in one step - template - struct iterator_value_type { -// typedef typename value_type_or_char::value_type>::value_type value_type; - typedef typename hex_iterator_traits::value_type value_type; - }; - + template + bool iter_end ( Iterator current, Iterator last ) { return current == last; } + + template + bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; } + // What can we assume here about the inputs? // is std::iterator_traits::value_type always 'char' ? // Could it be wchar_t, say? Does it matter? // We are assuming ASCII for the values - but what about the storage? - template - typename boost::enable_if::value_type>, OutputIterator>::type - decode_one ( InputIterator &first, InputIterator last, OutputIterator out ) { - typedef typename iterator_value_type::value_type T; + template + typename boost::enable_if::value_type>, OutputIterator>::type + decode_one ( InputIterator &first, InputIterator last, OutputIterator out, EndPred pred ) { + typedef typename hex_iterator_traits::value_type T; T res (0); // Need to make sure that we get can read that many chars here. for ( std::size_t i = 0; i < 2 * sizeof ( T ); ++i, ++first ) { - if ( first == last ) + if ( pred ( first, last )) BOOST_THROW_EXCEPTION (not_enough_input ()); res = ( 16 * res ) + hex_char_to_int (static_cast (*first)); } @@ -205,7 +197,7 @@ hex ( const Range &r, OutputIterator out ) { template OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ) { while ( first != last ) - out = detail::decode_one ( first, last, out ); + out = detail::decode_one ( first, last, out, detail::iter_end ); return out; } @@ -219,12 +211,12 @@ OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator o /// \note Based on the MySQL function of the same name template OutputIterator unhex ( const T *ptr, OutputIterator out ) { - typedef typename detail::iterator_value_type::value_type OutputType; + typedef typename detail::hex_iterator_traits::value_type OutputType; // If we run into the terminator while decoding, we will throw a // malformed input exception. It would be nicer to throw a 'Not enough input' // exception - but how much extra work would that require? while ( *ptr ) - out = detail::decode_one ( ptr, (const T *) NULL, out ); + out = detail::decode_one ( ptr, (const T *) NULL, out, detail::ptr_end ); return out; }