Files
2026-06-01 12:46:52 +02:00

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__