177 lines
3.1 KiB
C++
177 lines
3.1 KiB
C++
// Copyright (c) Glyn Matthews 2011.
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
|
|
#ifndef __BOOST_NETWORK_URI_ENCODE_INC__
|
|
# define __BOOST_NETWORK_URI_ENCODE_INC__
|
|
|
|
|
|
# include <boost/iterator/iterator_traits.hpp>
|
|
# include <boost/iterator/transform_iterator.hpp>
|
|
# include <boost/range/begin.hpp>
|
|
# include <boost/range/end.hpp>
|
|
# include <cassert>
|
|
|
|
|
|
namespace boost {
|
|
namespace network {
|
|
namespace uri {
|
|
namespace detail {
|
|
template <
|
|
typename CharT
|
|
>
|
|
inline
|
|
CharT hex_to_letter(CharT in) {
|
|
switch (in)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
return in + '0';
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 13:
|
|
case 14:
|
|
default:
|
|
return in - 10 + 'A';
|
|
}
|
|
return CharT();
|
|
}
|
|
|
|
|
|
template <
|
|
typename CharT,
|
|
class OutputIterator
|
|
>
|
|
void encode_char(CharT in, OutputIterator &out) {
|
|
switch (in)
|
|
{
|
|
case 'a':
|
|
case 'A':
|
|
case 'b':
|
|
case 'B':
|
|
case 'c':
|
|
case 'C':
|
|
case 'd':
|
|
case 'D':
|
|
case 'e':
|
|
case 'E':
|
|
case 'f':
|
|
case 'F':
|
|
case 'g':
|
|
case 'G':
|
|
case 'h':
|
|
case 'H':
|
|
case 'i':
|
|
case 'I':
|
|
case 'j':
|
|
case 'J':
|
|
case 'k':
|
|
case 'K':
|
|
case 'l':
|
|
case 'L':
|
|
case 'm':
|
|
case 'M':
|
|
case 'n':
|
|
case 'N':
|
|
case 'o':
|
|
case 'O':
|
|
case 'p':
|
|
case 'P':
|
|
case 'q':
|
|
case 'Q':
|
|
case 'r':
|
|
case 'R':
|
|
case 's':
|
|
case 'S':
|
|
case 't':
|
|
case 'T':
|
|
case 'u':
|
|
case 'U':
|
|
case 'v':
|
|
case 'V':
|
|
case 'w':
|
|
case 'W':
|
|
case 'x':
|
|
case 'X':
|
|
case 'y':
|
|
case 'Y':
|
|
case 'z':
|
|
case 'Z':
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
case '-':
|
|
case '.':
|
|
case '_':
|
|
case '~':
|
|
case '/':
|
|
out++ = in;
|
|
break;
|
|
default:
|
|
out++ = '%';
|
|
out++ = hex_to_letter(in >> 4);
|
|
out++ = hex_to_letter(in & 0x0f);
|
|
;
|
|
}
|
|
}
|
|
} // namespace detail
|
|
|
|
template <
|
|
class InputIterator,
|
|
class OutputIterator
|
|
>
|
|
OutputIterator encode(const InputIterator &in_begin,
|
|
const InputIterator &in_end,
|
|
const OutputIterator &out_begin) {
|
|
typedef typename boost::iterator_value<InputIterator>::type value_type;
|
|
|
|
InputIterator it = in_begin;
|
|
OutputIterator out = out_begin;
|
|
while (it != in_end) {
|
|
detail::encode_char(*it, out);
|
|
++it;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
template <
|
|
class SinglePassRange,
|
|
class OutputIterator
|
|
>
|
|
inline
|
|
OutputIterator encode(const SinglePassRange &range,
|
|
const OutputIterator &out) {
|
|
return encode(boost::begin(range), boost::end(range), out);
|
|
}
|
|
|
|
inline
|
|
std::string encoded(const std::string &input) {
|
|
std::string encoded;
|
|
encode(input, std::back_inserter(encoded));
|
|
return encoded;
|
|
}
|
|
} // namespace uri
|
|
} // namespace network
|
|
} // namespace boost
|
|
|
|
|
|
#endif // __BOOST_NETWORK_URI_ENCODE_INC__
|