|
19 | 19 | #ifndef NET_IP4_ADDR_HPP |
20 | 20 | #define NET_IP4_ADDR_HPP |
21 | 21 |
|
22 | | -#include <regex> |
23 | | -#include <string> |
24 | | - |
25 | 22 | #include <common> |
26 | 23 | #include <net/util.hpp> |
| 24 | +#include <cstdlib> |
| 25 | +#include <string> |
27 | 26 |
|
28 | 27 | namespace net { |
29 | 28 | namespace ip4 { |
@@ -98,34 +97,38 @@ struct Addr { |
98 | 97 | * IIf the {std::string} object doesn't representing a valid IPv4 |
99 | 98 | * address |
100 | 99 | */ |
101 | | - template<typename = void> |
102 | | - Addr(const std::string& ipv4_addr) |
| 100 | + Addr(const std::string& str) |
103 | 101 | { |
104 | | - if (not (ipv4_addr.size() >= 7 && ipv4_addr.size() <= 15)) { //< [7, 15] minimum and maximum address length |
105 | | - throw Invalid_address{ipv4_addr + " is not a valid IP"}; |
106 | | - } |
107 | | - |
108 | | - const static std::regex ipv4_address_pattern |
| 102 | + int value[4] = {0}; |
| 103 | + int index = 0; |
| 104 | + bool length_error = true; |
| 105 | + const char* ptr = str.c_str(); |
| 106 | + while (*ptr) |
109 | 107 | { |
110 | | - |
111 | | -#define OCTET_PATTERN "(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)" |
112 | | - "^\\s*" OCTET_PATTERN "\\." OCTET_PATTERN "\\." OCTET_PATTERN "\\." OCTET_PATTERN "\\s*$" |
113 | | -#undef OCTET_PATTERN |
114 | | - |
115 | | - }; |
116 | | - |
117 | | - std::smatch ipv4_parts; |
118 | | - |
119 | | - if (not std::regex_match(ipv4_addr, ipv4_parts, ipv4_address_pattern)) { |
120 | | - throw Invalid_address{ipv4_addr + " is not a valid IP"}; |
| 108 | + if (std::isdigit((int) *ptr)) |
| 109 | + { |
| 110 | + value[index] *= 10; |
| 111 | + value[index] += *ptr - '0'; |
| 112 | + if (value[index] & 0xFFFFFF00) { |
| 113 | + throw Invalid_address("Out-of-range byte values in " + str); |
| 114 | + } |
| 115 | + length_error = false; |
| 116 | + } else { |
| 117 | + if (*ptr == '.') { |
| 118 | + if (++index > 3) |
| 119 | + throw Invalid_address("Too many dots in " + str); |
| 120 | + length_error = true; |
| 121 | + } |
| 122 | + else { |
| 123 | + throw Invalid_address("Unexpected characters in " + str); |
| 124 | + } |
| 125 | + } |
| 126 | + ptr++; |
121 | 127 | } |
122 | | - |
123 | | - const auto p1 = static_cast<uint8_t>(std::stoi(ipv4_parts[1])); |
124 | | - const auto p2 = static_cast<uint8_t>(std::stoi(ipv4_parts[2])); |
125 | | - const auto p3 = static_cast<uint8_t>(std::stoi(ipv4_parts[3])); |
126 | | - const auto p4 = static_cast<uint8_t>(std::stoi(ipv4_parts[4])); |
127 | | - |
128 | | - whole = p1 | (p2 << 8) | (p3 << 16) | (p4 << 24); |
| 128 | + if (length_error) { |
| 129 | + throw Invalid_address("Missing byte value at end of " + str); |
| 130 | + } |
| 131 | + this->whole = value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24); |
129 | 132 | } |
130 | 133 |
|
131 | 134 | /** |
|
0 commit comments