19std::array<unsigned short, 8> ipv6_parser(std::string_view a_input) {
20 std::array<unsigned short, 8> address{0, 0, 0, 0, 0, 0, 0, 0};
22 unsigned short pieceIndex{0};
24 std::string_view::const_iterator pointer{a_input.begin()};
27 unsigned char c = pointer < a_input.end() ? (
unsigned char)*pointer :
'\0';
30 if (pointer + 1 >= a_input.end() ||
31 *(pointer + 1) != (
unsigned char)
':') {
32 failure_line = __LINE__;
36 pointer = pointer + 2;
38 compress = pieceIndex;
41 while (pointer < a_input.end()) {
42 if (pieceIndex >= 8) {
43 failure_line = __LINE__;
47 if (*pointer == (
unsigned char)
':') {
49 failure_line = __LINE__;
55 compress = pieceIndex;
60 unsigned short value{};
62 while (length < 4 && pointer < a_input.end() &&
63 std::isxdigit((
unsigned char)*pointer)) {
64 unsigned char hx = (
unsigned char)*pointer;
67 (hx >=
'A') ? (hx >=
'a') ? (hx -
'a' + 10) : (hx -
'A' + 10)
70 value = (
unsigned short)(value * 0x10 + v);
75 if (pointer < a_input.end() && *pointer == (
unsigned char)
'.') {
77 failure_line = __LINE__;
81 pointer = pointer - length;
84 failure_line = __LINE__;
89 while (pointer < a_input.end()) {
93 unsigned short ipv4Piece{65535};
94 if (numbersSeen > 0) {
95 if (*pointer == (
unsigned char)
'.' && numbersSeen < 4) {
98 failure_line = __LINE__;
103 if (pointer < a_input.end() &&
104 !std::isdigit((
unsigned char)*pointer)) {
105 failure_line = __LINE__;
109 while (pointer < a_input.end() &&
110 std::isdigit((
unsigned char)*pointer)) {
112 unsigned short number = (
unsigned short)(*pointer -
'0');
118 failure_line = __LINE__;
123 ipv4Piece = (
unsigned short)(ipv4Piece * 10 + number);
126 if (ipv4Piece > 255) {
127 failure_line = __LINE__;
135 address[pieceIndex] =
136 (
unsigned short)(address[pieceIndex] * 0x100 + ipv4Piece);
138 if (numbersSeen == 2 || numbersSeen == 4)
142 if (numbersSeen != 4) {
143 failure_line = __LINE__;
149 }
else if (pointer < a_input.end() && *pointer == (
unsigned char)
':') {
151 if (pointer >= a_input.end()) {
152 failure_line = __LINE__;
156 }
else if (pointer < a_input.end()) {
157 failure_line = __LINE__;
161 address[pieceIndex] = value;
166 int swaps{pieceIndex - compress};
169 while (pieceIndex != 0 && swaps > 0) {
171 unsigned short swapIndex = (
unsigned short)(compress + swaps - 1);
172 unsigned short piece = address[pieceIndex];
173 address[pieceIndex] = address[swapIndex];
174 address[swapIndex] = piece;
179 }
else if (compress < 0 && pieceIndex != 8) {
180 failure_line = __LINE__;
187 std::string errormsg =
188 "Error: " + (std::string) __func__ +
"(\"" + (std::string)a_input +
189 "\"):" + std::to_string(failure_line) +
" - Invalid IPv6 address.";
190 std::clog << errormsg << std::endl;
191 throw std::invalid_argument(errormsg);
197std::string host_parser(std::string_view a_input,
198 bool a_isNotSpecial =
false)
200 if (!a_input.empty() && a_input.front() ==
'[') {
201 if (a_input.back() !=
']') {
202 std::clog <<
"Error: missing closing ']'." << std::endl;
203 throw std::invalid_argument(
"Missing closing ']': '" +
204 (std::string)a_input +
"'");
208 return "2001:DB8:1234:5678:9ABC:DEF0:1234:5678";
211 if (a_isNotSpecial) {
218 throw std::invalid_argument(
"Host string must not be empty.");
220 return "dummy.final.parsed.host";
Reengineered Object Oriented UPnP+ program code.
Free functions to parse IPv6 and host URLs. Not usable, work in progess.