-
Notifications
You must be signed in to change notification settings - Fork 0
/
endpoint.cpp
109 lines (86 loc) · 2.45 KB
/
endpoint.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "endpoint.h"
#include <cstring>
#include <limits>
#include <netinet/in.h>
template <class T>
static bool srt_to_number(const std::string &str, T &value, size_t &last)
{
if (str.empty() || str[0] < '0' || str[0] > '9') {
return false;
}
int parsed = 0;
try {
parsed = std::stoi(str, &last);
} catch (const std::exception &) {
return false;
}
if (parsed < std::numeric_limits<T>::min() || parsed > std::numeric_limits<T>::max()) {
return false;
}
value = static_cast<T>(parsed);
return true;
}
endpoint_t* endpoint_t::create(const std::string &url)
{
const auto proto_delim_pos = url.find("://");
if (proto_delim_pos == std::string::npos) {
throw bad_endpoint_t();
}
std::string proto = url.substr(0, proto_delim_pos);
std::string full_address = url.substr(proto_delim_pos + 3);
if (proto == "udp") {
return new ipv4_endpoint_t(full_address);
}
#ifndef NO_CAN_SOCKETS
else if (proto == "can") {
return new can_endpoint_t(full_address);
}
#endif
throw bad_endpoint_t();
}
ipv4_endpoint_t::ipv4_endpoint_t(const std::string &endpoint)
{
parse_text(endpoint);
}
void ipv4_endpoint_t::parse_text(const std::string &endpoint)
{
address_ = 0;
port_ = 0;
const auto port_delim_pos = endpoint.find(':');
if (port_delim_pos == std::string::npos) {
throw bad_endpoint_t();
}
std::string address = endpoint.substr(0, port_delim_pos);
std::string port_string = endpoint.substr(port_delim_pos + 1);
// parse address
for (size_t i = 0; i < 4; ++i) {
std::uint8_t byte = 0;
size_t last_index = 0;
if (!srt_to_number(address, byte, last_index)) {
throw bad_endpoint_t();
}
if (last_index < address.length() && address[last_index] != '.') {
throw bad_endpoint_t();
}
address = last_index >= address.size() ? std::string{} : address.substr(last_index + 1);
address_ <<= 8;
address_ += byte;
}
if (!address.empty()) {
throw bad_endpoint_t();
}
// parse port
size_t last_index = 0;
if (!srt_to_number(port_string, port_, last_index) || last_index != port_string.size()) {
throw bad_endpoint_t();
}
}
#ifndef NO_CAN_SOCKETS
can_endpoint_t::can_endpoint_t(const std::string &device)
: device_(device)
{
if (device.empty()) {
throw bad_endpoint_t();
}
}
#endif