diff options
Diffstat (limited to 'graphics/asymptote/LspCpp/third_party/uri/src/detail/uri_parse_authority.cpp')
-rw-r--r-- | graphics/asymptote/LspCpp/third_party/uri/src/detail/uri_parse_authority.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/graphics/asymptote/LspCpp/third_party/uri/src/detail/uri_parse_authority.cpp b/graphics/asymptote/LspCpp/third_party/uri/src/detail/uri_parse_authority.cpp new file mode 100644 index 0000000000..29b7de7f68 --- /dev/null +++ b/graphics/asymptote/LspCpp/third_party/uri/src/detail/uri_parse_authority.cpp @@ -0,0 +1,116 @@ +// Copyright 2016 Glyn Matthews. +// 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) + +#include "uri_parse_authority.hpp" +#include <cstdlib> +#include <iterator> +#include <limits> +#include "grammar.hpp" + +namespace network { +namespace detail { +namespace { +enum class authority_state { user_info, host, host_ipv6, port }; +} // namespace + +bool parse_authority(string_view::const_iterator &it, + string_view::const_iterator last, + optional<uri_part> &user_info, optional<uri_part> &host, + optional<uri_part> &port) { + auto first = it; + + auto state = authority_state::user_info; + while (it != last) { + if (state == authority_state::user_info) { + if (is_in(first, last, "@:")) { + return false; + } + + if (*it == '@') { + user_info = uri_part(first, it); + state = authority_state::host; + ++it; + first = it; + continue; + } else if (*it == '[') { + // this is an IPv6 address + state = authority_state::host_ipv6; + first = it; + continue; + } else if (*it == ':') { + // this is actually the host, and the next part is expected to be the + // port + host = uri_part(first, it); + state = authority_state::port; + ++it; + first = it; + continue; + } + } else if (state == authority_state::host) { + if (*first == ':') { + return false; + } + + if (*it == ':') { + host = uri_part(first, it); + state = authority_state::port; + ++it; + first = it; + continue; + } + } else if (state == authority_state::host_ipv6) { + if (*first != '[') { + return false; + } + + if (*it == ']') { + host = uri_part(first, it); + ++it; + // Then test if the next part is a host, part, or the end of the file + if (it == last) { + break; + } else if (*it == ':') { + host = uri_part(first, it); + state = authority_state::port; + ++it; + first = it; + } + } + } else if (state == authority_state::port) { + if (*first == '/') { + // the port is empty, but valid + port = uri_part(first, it); + if (!is_valid_port(std::begin(*port))) { + return false; + } + + continue; + } + + if (!isdigit(it, last)) { + return false; + } + } + + ++it; + } + + if (state == authority_state::user_info) { + host = uri_part(first, last); + } else if (state == authority_state::host) { + host = uri_part(first, last); + } else if (state == authority_state::host_ipv6) { + host = uri_part(first, last); + } else if (state == authority_state::port) { + port = uri_part(first, last); + if (!is_valid_port(std::begin(*port))) { + return false; + } + } + + return true; +} +} // namespace detail +} // namespace network |