93 lines
2.1 KiB
C++
93 lines
2.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_DECODE_INC__
|
|
#define __BOOST_NETWORK_URI_DECODE_INC__
|
|
|
|
#include <boost/iterator/iterator_traits.hpp>
|
|
#include <boost/range/begin.hpp>
|
|
#include <boost/range/end.hpp>
|
|
#include <cassert>
|
|
|
|
namespace boost {
|
|
namespace network {
|
|
namespace uri {
|
|
namespace detail {
|
|
template <typename CharT>
|
|
CharT letter_to_hex(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 'a':
|
|
case 'b':
|
|
case 'c':
|
|
case 'd':
|
|
case 'e':
|
|
case 'f':
|
|
return in + 10 - 'a';
|
|
case 'A':
|
|
case 'B':
|
|
case 'C':
|
|
case 'D':
|
|
case 'E':
|
|
case 'F':
|
|
return in + 10 - 'A';
|
|
}
|
|
return CharT();
|
|
}
|
|
} // namespace detail
|
|
|
|
template <class InputIterator, class OutputIterator>
|
|
OutputIterator decode(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) {
|
|
if (*it == '%') {
|
|
++it;
|
|
value_type v0 = detail::letter_to_hex(*it);
|
|
++it;
|
|
value_type v1 = detail::letter_to_hex(*it);
|
|
++it;
|
|
*out++ = 0x10 * v0 + v1;
|
|
} else if (*it == '+') {
|
|
*out++ = ' ';
|
|
++it;
|
|
} else {
|
|
*out++ = *it++;
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
template <class SinglePassRange, class OutputIterator>
|
|
inline OutputIterator decode(const SinglePassRange &range,
|
|
const OutputIterator &out) {
|
|
return decode(boost::begin(range), boost::end(range), out);
|
|
}
|
|
|
|
inline std::string decoded(const std::string &input) {
|
|
std::string decoded;
|
|
decode(input, std::back_inserter(decoded));
|
|
return decoded;
|
|
}
|
|
} // namespace uri
|
|
} // namespace network
|
|
} // namespace boost
|
|
|
|
#endif // __BOOST_NETWORK_URI_DECODE_INC__
|