async_mqtt 5.0.0
Loading...
Searching...
No Matches
host_port.hpp
1// Copyright Takatoshi Kondo 2023
2//
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7#if !defined(ASYNC_MQTT_HOST_PORT_HPP)
8#define ASYNC_MQTT_HOST_PORT_HPP
9
10#include <string>
11
12#include <boost/lexical_cast.hpp>
13#include <boost/asio/ip/address.hpp>
14
15#include <async_mqtt/util/move.hpp>
16#include <async_mqtt/util/optional.hpp>
17#include <async_mqtt/log.hpp>
18
19namespace async_mqtt {
20
21namespace as = boost::asio;
22
23struct host_port {
24 host_port(std::string host, std::uint16_t port)
25 :host{force_move(host)},
26 port{port}
27 {}
28 std::string host;
29 std::uint16_t port;
30};
31
32inline std::string to_string(host_port const& hp) {
33 return hp.host + ':' + std::to_string(hp.port);
34}
35
36inline std::ostream& operator<<(std::ostream& s, host_port const& hp) {
37 s << to_string(hp);
38 return s;
39}
40
41inline bool operator==(host_port const& lhs, host_port const& rhs) {
42 return std::tie(lhs.host, lhs.port) == std::tie(rhs.host, rhs.port);
43}
44
45inline bool operator!=(host_port const& lhs, host_port const& rhs) {
46 return !(lhs == rhs);
47}
48
49inline optional<host_port> host_port_from_string(std::string_view str) {
50 // parse port ...:1234
51 auto last_colon = str.find_last_of(':');
52 if (last_colon == std::string::npos) return nullopt;
53
54 std::uint16_t port;
55 try {
56 auto port_size = std::size_t(str.size() - (last_colon + 1));
57 port = boost::lexical_cast<std::uint16_t>(
58 std::string_view(&str[last_colon + 1], port_size)
59 );
60 str.remove_suffix(port_size + 1); // remove :1234
61 }
62 catch (std::exception const& e) {
63 ASYNC_MQTT_LOG("mqtt_api", error)
64 << "invalid host port string:" << str
65 << " " << e.what();
66 return nullopt;
67 }
68
69 if (str.empty()) return nullopt;
70 if (str.front() == '[' && str.back() == ']') {
71 // IPv6 [host]
72 str.remove_prefix(1);
73 str.remove_suffix(1);
74 if (str.empty()) return nullopt;
75 }
76
77 return host_port{std::string(str), port};
78}
79
80} // namespace async_mqtt
81
82#endif // ASYNC_MQTT_HOST_PORT_HPP