Merge changes from [79588] to Release; fixes a unhex bug

[SVN r79604]
This commit is contained in:
Marshall Clow
2012-07-19 15:12:33 +00:00
parent 167aa6e31c
commit 314f6dcfe0

View File

@ -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 <typename T> struct value_type_or_char { typedef T value_type; };
template <> struct value_type_or_char<void> { typedef char value_type; };
// All in one step
template <typename Iterator>
struct iterator_value_type {
// typedef typename value_type_or_char<typename hex_iterator_traits<Iterator>::value_type>::value_type value_type;
typedef typename hex_iterator_traits<Iterator>::value_type value_type;
};
template <typename Iterator>
bool iter_end ( Iterator current, Iterator last ) { return current == last; }
template <typename T>
bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; }
// What can we assume here about the inputs?
// is std::iterator_traits<InputIterator>::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 InputIterator, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename iterator_value_type<OutputIterator>::value_type>, OutputIterator>::type
decode_one ( InputIterator &first, InputIterator last, OutputIterator out ) {
typedef typename iterator_value_type<OutputIterator>::value_type T;
template <typename InputIterator, typename OutputIterator, typename EndPred>
typename boost::enable_if<boost::is_integral<typename hex_iterator_traits<OutputIterator>::value_type>, OutputIterator>::type
decode_one ( InputIterator &first, InputIterator last, OutputIterator out, EndPred pred ) {
typedef typename hex_iterator_traits<OutputIterator>::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<char> (*first));
}
@ -205,7 +197,7 @@ hex ( const Range &r, OutputIterator out ) {
template <typename InputIterator, typename OutputIterator>
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<InputIterator> );
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 <typename T, typename OutputIterator>
OutputIterator unhex ( const T *ptr, OutputIterator out ) {
typedef typename detail::iterator_value_type<OutputIterator>::value_type OutputType;
typedef typename detail::hex_iterator_traits<OutputIterator>::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<T> );
return out;
}