// 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 #include #include #include namespace boost { namespace network { namespace uri { namespace detail { template 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 OutputIterator decode(const InputIterator &in_begin, const InputIterator &in_end, const OutputIterator &out_begin) { typedef typename boost::iterator_value::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 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__