58 if(namex.find(
'(') == std::string::npos && namex.find(
')') == std::string::npos) {
59 return {std::string(namex)};
62 std::string name(namex);
63 std::string substring;
64 std::vector<std::string> elems;
67 elems.push_back(name.substr(0, name.find(
'(')));
68 name = name.substr(name.find(
'('));
70 for(
auto i = name.begin(); i != name.end(); ++i) {
77 if(level == 1 && i == name.end() - 1) {
78 if(elems.size() == 1) {
79 elems.push_back(substring.substr(1));
81 elems.push_back(substring);
86 if(level == 0 || (level == 1 && i != name.end() - 1)) {
92 if(c ==
',' && level == 1) {
93 if(elems.size() == 1) {
94 elems.push_back(substring.substr(1));
96 elems.push_back(substring);
104 if(!substring.empty()) {
256 if(host.empty() || issued.empty()) {
264 if(std::count(issued.begin(), issued.end(),
char(0)) > 0) {
269 const size_t stars = std::count(issued.begin(), issued.end(),
'*');
275 if(std::count(host.begin(), host.end(),
'*') != 0) {
280 if(host[host.size() - 1] ==
'.') {
285 if(host.find(
"..") != std::string::npos) {
302 if(issued.size() > host.size() + 1) {
321 size_t dots_seen = 0;
324 for(
size_t i = 0; i != issued.size(); ++i) {
325 if(issued[i] ==
'.') {
329 if(issued[i] ==
'*') {
340 const size_t advance = (host.size() - issued.size() + 1);
342 if(host_idx + advance > host.size()) {
347 if(std::count(host.begin() + host_idx, host.begin() + host_idx + advance,
'.') != 0) {
353 if(issued[i] != host[host_idx]) {
370 if(name.size() > 255) {
378 if(name.starts_with(
".") || name.ends_with(
".")) {
387 constexpr uint8_t DNS_CHAR_MAPPING[128] = {
388 '\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
389 '\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
390 '\0',
'\0',
'\0',
'\0',
'*',
'\0',
'\0',
'-',
'.',
'\0',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
391 '9',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
392 'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'\0',
'\0',
'\0',
'\0',
393 '\0',
'\0',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
394 'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'\0',
'\0',
'\0',
'\0',
'\0',
399 canon.reserve(name.size());
402 size_t current_label_length = 0;
404 for(
size_t i = 0; i != name.size(); ++i) {
408 if(i > 0 && name[i - 1] ==
'.') {
409 throw Decoding_Error(
"DNS name contains sequential period chars");
412 if(current_label_length == 0) {
415 current_label_length = 0;
417 current_label_length++;
419 if(current_label_length > 63) {
420 throw Decoding_Error(
"DNS name label exceeds maximum length of 63 characters");
424 const uint8_t cu =
static_cast<uint8_t
>(c);
426 throw Decoding_Error(
"DNS name must not contain any extended ASCII code points");
428 const uint8_t mapped = DNS_CHAR_MAPPING[cu];
434 if(i == 0 || (i > 0 && name[i - 1] ==
'.')) {
436 }
else if(i == name.size() - 1 || (i < name.size() - 1 && name[i + 1] ==
'.')) {
440 canon.push_back(
static_cast<char>(mapped));
443 if(current_label_length == 0) {