1
- /*
1
+ /*
2
2
Copyright (c) Marshall Clow 2011-2012.
3
3
4
4
Distributed under the Boost Software License, Version 1.0. (See accompanying
5
5
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
-
6
+
7
7
Thanks to Nevin for his comments/help.
8
8
*/
9
9
13
13
*/
14
14
15
15
// / \file hex.hpp
16
- // / \brief Convert sequence of integral types into a sequence of hexadecimal
16
+ // / \brief Convert sequence of integral types into a sequence of hexadecimal
17
17
// / characters and back. Based on the MySQL functions HEX and UNHEX
18
18
// / \author Marshall Clow
19
19
33
33
34
34
namespace boost { namespace algorithm {
35
35
36
- /* !
37
- \struct hex_decode_error
38
- \brief Base exception class for all hex decoding errors
36
+ /* !
37
+ \struct hex_decode_error
38
+ \brief Base exception class for all hex decoding errors
39
39
*/ /* !
40
- \struct non_hex_input
40
+ \struct non_hex_input
41
41
\brief Thrown when a non-hex value (0-9, A-F) encountered when decoding.
42
42
Contains the offending character
43
- */ /* !
44
- \struct not_enough_input
43
+ */ /* !
44
+ \struct not_enough_input
45
45
\brief Thrown when the input sequence unexpectedly ends
46
-
46
+
47
47
*/
48
48
struct hex_decode_error : virtual boost::exception , virtual std::exception {};
49
49
struct not_enough_input : virtual hex_decode_error {};
@@ -54,12 +54,12 @@ namespace detail {
54
54
// / \cond DOXYGEN_HIDE
55
55
56
56
template <typename T, typename OutputIterator>
57
- OutputIterator encode_one ( T val, OutputIterator out ) {
57
+ OutputIterator encode_one ( T val, OutputIterator out, const char * hexDigits ) {
58
58
const std::size_t num_hex_digits = 2 * sizeof ( T );
59
59
char res [ num_hex_digits ];
60
60
char *p = res + num_hex_digits;
61
61
for ( std::size_t i = 0 ; i < num_hex_digits; ++i, val >>= 4 )
62
- *--p = " 0123456789ABCDEF " [ val & 0x0F ];
62
+ *--p = hexDigits [ val & 0x0F ];
63
63
return std::copy ( res, res + num_hex_digits, out );
64
64
}
65
65
@@ -106,12 +106,12 @@ namespace detail {
106
106
typedef T value_type;
107
107
};
108
108
109
- template <typename Iterator>
109
+ template <typename Iterator>
110
110
bool iter_end ( Iterator current, Iterator last ) { return current == last; }
111
-
111
+
112
112
template <typename T>
113
113
bool ptr_end ( const T* ptr, const T* /* end*/ ) { return *ptr == ' \0 ' ; }
114
-
114
+
115
115
// What can we assume here about the inputs?
116
116
// is std::iterator_traits<InputIterator>::value_type always 'char' ?
117
117
// Could it be wchar_t, say? Does it matter?
@@ -124,11 +124,11 @@ namespace detail {
124
124
125
125
// Need to make sure that we get can read that many chars here.
126
126
for ( std::size_t i = 0 ; i < 2 * sizeof ( T ); ++i, ++first ) {
127
- if ( pred ( first, last ))
127
+ if ( pred ( first, last ))
128
128
BOOST_THROW_EXCEPTION (not_enough_input ());
129
129
res = ( 16 * res ) + hex_char_to_int (*first);
130
130
}
131
-
131
+
132
132
*out = res;
133
133
return ++out;
134
134
}
@@ -138,7 +138,7 @@ namespace detail {
138
138
139
139
// / \fn hex ( InputIterator first, InputIterator last, OutputIterator out )
140
140
// / \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
141
- // /
141
+ // /
142
142
// / \param first The start of the input sequence
143
143
// / \param last One past the end of the input sequence
144
144
// / \param out An output iterator to the results into
@@ -148,14 +148,31 @@ template <typename InputIterator, typename OutputIterator>
148
148
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<InputIterator>::value_type>, OutputIterator>::type
149
149
hex ( InputIterator first, InputIterator last, OutputIterator out ) {
150
150
for ( ; first != last; ++first )
151
- out = detail::encode_one ( *first, out );
151
+ out = detail::encode_one ( *first, out, " 0123456789ABCDEF" );
152
+ return out;
153
+ }
154
+
155
+
156
+ // / \fn hex_lower ( InputIterator first, InputIterator last, OutputIterator out )
157
+ // / \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
158
+ // /
159
+ // / \param first The start of the input sequence
160
+ // / \param last One past the end of the input sequence
161
+ // / \param out An output iterator to the results into
162
+ // / \return The updated output iterator
163
+ // / \note Based on the MySQL function of the same name
164
+ template <typename InputIterator, typename OutputIterator>
165
+ typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<InputIterator>::value_type>, OutputIterator>::type
166
+ hex_lower ( InputIterator first, InputIterator last, OutputIterator out ) {
167
+ for ( ; first != last; ++first )
168
+ out = detail::encode_one ( *first, out, " 0123456789abcdef" );
152
169
return out;
153
170
}
154
-
171
+
155
172
156
173
// / \fn hex ( const T *ptr, OutputIterator out )
157
174
// / \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
158
- // /
175
+ // /
159
176
// / \param ptr A pointer to a 0-terminated sequence of data.
160
177
// / \param out An output iterator to the results into
161
178
// / \return The updated output iterator
@@ -164,13 +181,30 @@ template <typename T, typename OutputIterator>
164
181
typename boost::enable_if<boost::is_integral<T>, OutputIterator>::type
165
182
hex ( const T *ptr, OutputIterator out ) {
166
183
while ( *ptr )
167
- out = detail::encode_one ( *ptr++, out );
184
+ out = detail::encode_one ( *ptr++, out, " 0123456789ABCDEF" );
185
+ return out;
186
+ }
187
+
188
+
189
+ // / \fn hex_lower ( const T *ptr, OutputIterator out )
190
+ // / \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
191
+ // /
192
+ // / \param ptr A pointer to a 0-terminated sequence of data.
193
+ // / \param out An output iterator to the results into
194
+ // / \return The updated output iterator
195
+ // / \note Based on the MySQL function of the same name
196
+ template <typename T, typename OutputIterator>
197
+ typename boost::enable_if<boost::is_integral<T>, OutputIterator>::type
198
+ hex_lower ( const T *ptr, OutputIterator out ) {
199
+ while ( *ptr )
200
+ out = detail::encode_one ( *ptr++, out, " 0123456789abcdef" );
168
201
return out;
169
202
}
170
203
204
+
171
205
// / \fn hex ( const Range &r, OutputIterator out )
172
206
// / \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
173
- // /
207
+ // /
174
208
// / \param r The input range
175
209
// / \param out An output iterator to the results into
176
210
// / \return The updated output iterator
@@ -182,9 +216,23 @@ hex ( const Range &r, OutputIterator out ) {
182
216
}
183
217
184
218
219
+ // / \fn hex_lower ( const Range &r, OutputIterator out )
220
+ // / \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
221
+ // /
222
+ // / \param r The input range
223
+ // / \param out An output iterator to the results into
224
+ // / \return The updated output iterator
225
+ // / \note Based on the MySQL function of the same name
226
+ template <typename Range, typename OutputIterator>
227
+ typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<typename Range::iterator>::value_type>, OutputIterator>::type
228
+ hex_lower ( const Range &r, OutputIterator out ) {
229
+ return hex_lower (boost::begin (r), boost::end (r), out);
230
+ }
231
+
232
+
185
233
// / \fn unhex ( InputIterator first, InputIterator last, OutputIterator out )
186
234
// / \brief Converts a sequence of hexadecimal characters into a sequence of integers.
187
- // /
235
+ // /
188
236
// / \param first The start of the input sequence
189
237
// / \param last One past the end of the input sequence
190
238
// / \param out An output iterator to the results into
@@ -200,7 +248,7 @@ OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator o
200
248
201
249
// / \fn unhex ( const T *ptr, OutputIterator out )
202
250
// / \brief Converts a sequence of hexadecimal characters into a sequence of integers.
203
- // /
251
+ // /
204
252
// / \param ptr A pointer to a null-terminated input sequence.
205
253
// / \param out An output iterator to the results into
206
254
// / \return The updated output iterator
@@ -218,7 +266,7 @@ OutputIterator unhex ( const T *ptr, OutputIterator out ) {
218
266
219
267
// / \fn OutputIterator unhex ( const Range &r, OutputIterator out )
220
268
// / \brief Converts a sequence of hexadecimal characters into a sequence of integers.
221
- // /
269
+ // /
222
270
// / \param r The input range
223
271
// / \param out An output iterator to the results into
224
272
// / \return The updated output iterator
@@ -231,7 +279,7 @@ OutputIterator unhex ( const Range &r, OutputIterator out ) {
231
279
232
280
// / \fn String hex ( const String &input )
233
281
// / \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
234
- // /
282
+ // /
235
283
// / \param input A container to be converted
236
284
// / \return A container with the encoded text
237
285
template <typename String>
@@ -242,9 +290,24 @@ String hex ( const String &input ) {
242
290
return output;
243
291
}
244
292
293
+
294
+ // / \fn String hex_lower ( const String &input )
295
+ // / \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
296
+ // /
297
+ // / \param input A container to be converted
298
+ // / \return A container with the encoded text
299
+ template <typename String>
300
+ String hex_lower ( const String &input ) {
301
+ String output;
302
+ output.reserve (input.size () * (2 * sizeof (typename String::value_type)));
303
+ (void ) hex_lower (input, std::back_inserter (output));
304
+ return output;
305
+ }
306
+
307
+
245
308
// / \fn String unhex ( const String &input )
246
309
// / \brief Converts a sequence of hexadecimal characters into a sequence of characters.
247
- // /
310
+ // /
248
311
// / \param input A container to be converted
249
312
// / \return A container with the decoded text
250
313
template <typename String>
0 commit comments