diff --git a/include/ircd/m/id.h b/include/ircd/m/id.h index a69ad3d51..d0d421b4d 100644 --- a/include/ircd/m/id.h +++ b/include/ircd/m/id.h @@ -62,11 +62,11 @@ struct ircd::m::id public: // Extract elements - string_view local() const; - string_view host() const; - string_view name() const; - string_view hostname() const; - uint16_t hostport() const; + string_view local() const; // The full localpart including sigil + string_view host() const; // The full server part including port + string_view localname() const; // The localpart not including sigil + string_view hostname() const; // The server part not including port + uint16_t port() const; // Just the port number or 8448 if none IRCD_USING_OVERLOAD(generate, m::generate); diff --git a/ircd/m/id.cc b/ircd/m/id.cc index e4a66e087..49a9b8edc 100644 --- a/ircd/m/id.cc +++ b/ircd/m/id.cc @@ -122,7 +122,7 @@ struct ircd::m::id::input //TODO: ---- share grammar with rfc3986.cc - const rule<> port + const rule port { ushort_ ,"port number" @@ -526,52 +526,106 @@ ircd::m::id::id(const enum sigil &sigil, } uint16_t -ircd::m::id::hostport() -const try +ircd::m::id::port() +const { - //TODO: grammar - const auto port + static const parser::rule rule { - split(host(), ':').second + omit[parser.prefix >> ':' >> parser.dns_name >> ':'] >> parser.port }; - return port? lex_cast(port) : 8448; -} -catch(const std::exception &e) -{ - return 8448; + uint16_t ret{8448}; + auto *start{data()}; + const auto res + { + qi::parse(start, data() + size(), rule, ret) + }; + + assert(res || ret == 8448); + return ret; } ircd::string_view ircd::m::id::hostname() const { - //TODO: grammar - return rsplit(host(), ':').first; + static const parser::rule dns_name + { + parser.dns_name + }; + + static const parser::rule rule + { + omit[parser.prefix >> ':'] >> raw[dns_name] + }; + + string_view ret; + auto *start{data()}; + const auto res + { + qi::parse(start, data() + size(), rule, ret) + }; + + assert(res == true); + assert(!ret.empty()); + return ret; } ircd::string_view -ircd::m::id::name() +ircd::m::id::localname() const { - //TODO: grammar - return lstrip(local(), at(0)); + auto ret{local()}; + assert(!ret.empty()); + ret.pop_front(); + return ret; } ircd::string_view ircd::m::id::host() const { - //TODO: grammar - return split(*this, ':').second; + static const parser::rule server_name + { + parser.server_name + }; + + static const parser::rule rule + { + omit[parser.prefix >> ':'] >> raw[server_name] + }; + + string_view ret; + auto *start{data()}; + const auto res + { + qi::parse(start, data() + size(), rule, ret) + }; + + assert(res == true); + assert(!ret.empty()); + return ret; } ircd::string_view ircd::m::id::local() const { - //TODO: grammar - return split(*this, ':').first; + static const parser::rule prefix + { + parser.prefix + }; + + static const parser::rule rule + { + eps > raw[prefix] + }; + + string_view ret; + auto *start{data()}; + qi::parse(start, data() + size(), rule, ret); + assert(!ret.empty()); + return ret; } bool