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 dots_seen += (issued[i] ==
'.');
327 if(issued[i] ==
'*') {
338 const size_t advance = (host.size() - issued.size() + 1);
340 if(host_idx + advance > host.size()) {
345 if(std::count(host.begin() + host_idx, host.begin() + host_idx + advance,
'.') != 0) {
351 if(issued[i] != host[host_idx]) {
368 if(name.size() > 255) {
376 if(name.starts_with(
".")) {
385 constexpr uint8_t DNS_CHAR_MAPPING[128] = {
386 '\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
387 '\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
388 '\0',
'\0',
'\0',
'\0',
'*',
'\0',
'\0',
'-',
'.',
'\0',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
389 '9',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'\0',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
390 'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'\0',
'\0',
'\0',
'\0',
391 '\0',
'\0',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
392 'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'\0',
'\0',
'\0',
'\0',
'\0',
397 canon.reserve(name.size());
399 for(
size_t i = 0; i != name.size(); ++i) {
403 if(name[i - 1] ==
'.') {
404 throw Decoding_Error(
"DNS name contains sequential period chars");
406 if(i == name.size() - 1) {
411 const uint8_t cu =
static_cast<uint8_t
>(c);
413 throw Decoding_Error(
"DNS name must not contain any extended ASCII code points");
415 const uint8_t mapped = DNS_CHAR_MAPPING[cu];
420 canon.push_back(
static_cast<char>(mapped));