diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Utility/UriParser.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Utility/UriParser.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Utility/UriParser.cpp b/contrib/llvm-project/lldb/source/Utility/UriParser.cpp new file mode 100644 index 000000000000..1932e11acb4c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Utility/UriParser.cpp @@ -0,0 +1,74 @@ +//===-- UriParser.cpp -----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/UriParser.h" +#include "llvm/Support/raw_ostream.h" + +#include <string> + +#include <cstdint> +#include <optional> +#include <tuple> + +using namespace lldb_private; + +llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS, + const URI &U) { + OS << U.scheme << "://[" << U.hostname << ']'; + if (U.port) + OS << ':' << *U.port; + return OS << U.path; +} + +std::optional<URI> URI::Parse(llvm::StringRef uri) { + URI ret; + + const llvm::StringRef kSchemeSep("://"); + auto pos = uri.find(kSchemeSep); + if (pos == std::string::npos) + return std::nullopt; + + // Extract path. + ret.scheme = uri.substr(0, pos); + auto host_pos = pos + kSchemeSep.size(); + auto path_pos = uri.find('/', host_pos); + if (path_pos != std::string::npos) + ret.path = uri.substr(path_pos); + else + ret.path = "/"; + + auto host_port = uri.substr( + host_pos, + ((path_pos != std::string::npos) ? path_pos : uri.size()) - host_pos); + + // Extract hostname + if (host_port.starts_with('[')) { + // hostname is enclosed with square brackets. + pos = host_port.rfind(']'); + if (pos == std::string::npos) + return std::nullopt; + + ret.hostname = host_port.substr(1, pos - 1); + host_port = host_port.drop_front(pos + 1); + if (!host_port.empty() && !host_port.consume_front(":")) + return std::nullopt; + } else { + std::tie(ret.hostname, host_port) = host_port.split(':'); + } + + // Extract port + if (!host_port.empty()) { + uint16_t port_value = 0; + if (host_port.getAsInteger(0, port_value)) + return std::nullopt; + ret.port = port_value; + } else + ret.port = std::nullopt; + + return ret; +} |