diff options
Diffstat (limited to 'graphics/asymptote/LspCpp/third_party/uri/include/network/uri/detail/decode.hpp')
-rw-r--r-- | graphics/asymptote/LspCpp/third_party/uri/include/network/uri/detail/decode.hpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/graphics/asymptote/LspCpp/third_party/uri/include/network/uri/detail/decode.hpp b/graphics/asymptote/LspCpp/third_party/uri/include/network/uri/detail/decode.hpp new file mode 100644 index 0000000000..9d0aaaa1b5 --- /dev/null +++ b/graphics/asymptote/LspCpp/third_party/uri/include/network/uri/detail/decode.hpp @@ -0,0 +1,78 @@ +// Copyright (c) Glyn Matthews 2011-2016. +// Copyright 2012 Dean Michael Berris <dberris@google.com> +// Copyright 2012 Google, Inc. +// 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 NETWORK_URI_DECODE_INC +#define NETWORK_URI_DECODE_INC + +#include <network/uri/uri_errors.hpp> +#include <iterator> +#include <cassert> + +namespace network { +namespace detail { +template <typename CharT> +CharT letter_to_hex(CharT in) { + if ((in >= '0') && (in <= '9')) { + return in - '0'; + } + + if ((in >= 'a') && (in <= 'f')) { + return in + 10 - 'a'; + } + + if ((in >= 'A') && (in <= 'F')) { + return in + 10 - 'A'; + } + + throw percent_decoding_error(uri_error::non_hex_input); +} + +template <class InputIterator, class charT> +InputIterator decode_char(InputIterator it, charT *out) { + assert(*it == '%'); + ++it; + auto h0 = *it; + auto v0 = detail::letter_to_hex(h0); + ++it; + auto h1 = *it; + auto v1 = detail::letter_to_hex(h1); + ++it; + *out = static_cast<charT>((0x10 * v0) + v1); + return it; +} + +template <class InputIterator, class OutputIterator> +OutputIterator decode(InputIterator in_begin, InputIterator in_end, + OutputIterator out_begin) { + auto it = in_begin; + auto out = out_begin; + while (it != in_end) { + if (*it == '%') { + if (std::distance(it, in_end) < 3) { + throw percent_decoding_error(uri_error::not_enough_input); + } + char c = '\0'; + it = decode_char(it, &c); + *out = c; + ++out; + } else { + *out++ = *it++; + } + } + return out; +} + +template <class String> +String decode(const String &source) { + String unencoded; + decode(std::begin(source), std::end(source), std::back_inserter(unencoded)); + return unencoded; +} +} // namespace detail +} // namespace network + +#endif // NETWORK_URI_DECODE_INC |