summaryrefslogtreecommitdiff
path: root/graphics/asymptote/LspCpp/third_party/uri/src/detail/uri_parse_authority.cpp
diff options
context:
space:
mode:
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.cpp116
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