diff --git a/beast/net/IPEndpoint.h b/beast/net/IPEndpoint.h index f37439455..8135898fb 100644 --- a/beast/net/IPEndpoint.h +++ b/beast/net/IPEndpoint.h @@ -214,6 +214,11 @@ public: /** Copy assign another IPEndpoint. */ IPEndpoint& operator= (IPEndpoint const& other); + /** Create an IPEndpoint from a string. + If a parsing error occurs, the endpoint will be empty. + */ + static IPEndpoint from_string (std::string const& s); + /** Copy assign an IPv4 address. The port is set to zero. */ @@ -289,59 +294,28 @@ private: }; /** Comparison. */ -inline bool operator== (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return lhs.value == rhs.value; } -inline bool operator!= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return lhs.value != rhs.value; } -inline bool operator< (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return lhs.value < rhs.value; } -inline bool operator<= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return lhs.value <= rhs.value; } -inline bool operator> (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return lhs.value > rhs.value; } -inline bool operator>= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return lhs.value >= rhs.value; } -//inline bool operator== (IPEndpoint::V6 const& lhs, IPEndpoint::V6 const& rhs) { return lhs.value == rhs.value; } -//inline bool operator!= (IPEndpoint::V6 const& lhs, IPEndpoint::V6 const& rhs) { return lhs.value != rhs.value; } -//inline bool operator< (IPEndpoint::V6 const& lhs, IPEndpoint::V6 const& rhs) { return lhs.value < rhs.value; } -//inline bool operator<= (IPEndpoint::V6 const& lhs, IPEndpoint::V6 const& rhs) { return lhs.value <= rhs.value; } -//inline bool operator> (IPEndpoint::V6 const& lhs, IPEndpoint::V6 const& rhs) { return lhs.value > rhs.value; } -//inline bool operator>= (IPEndpoint::V6 const& lhs, IPEndpoint::V6 const& rhs) { return lhs.value >= rhs.value; } +/** @{ */ +int compare (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs); +bool operator== (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs); +bool operator!= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs); +bool operator< (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs); +bool operator<= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs); +bool operator> (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs); +bool operator>= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs); -inline bool operator== (IPEndpoint const& lhs, IPEndpoint const& rhs) -{ - if (lhs.type() != rhs.type()) - return false; - switch (lhs.type()) - { - case IPEndpoint::none: return true; - case IPEndpoint::ipv4: return lhs.v4() == rhs.v4(); - case IPEndpoint::ipv6: return lhs.v6() == rhs.v6(); - default: - bassertfalse; - break; - } - return false; -} - -inline bool operator!= (IPEndpoint const& lhs, IPEndpoint const& rhs) -{ - return ! (lhs == rhs); -} +int compare (IPEndpoint const& lhs, IPEndpoint const& rhs); +bool operator== (IPEndpoint const& lhs, IPEndpoint const& rhs); +bool operator!= (IPEndpoint const& lhs, IPEndpoint const& rhs); +bool operator< (IPEndpoint const& lhs, IPEndpoint const& rhs); +bool operator<= (IPEndpoint const& lhs, IPEndpoint const& rhs); +bool operator> (IPEndpoint const& lhs, IPEndpoint const& rhs); +bool operator>= (IPEndpoint const& lhs, IPEndpoint const& rhs); /** Output stream conversions. */ /** @{ */ -inline std::ostream& operator<< (std::ostream &os, IPEndpoint::V4 const& addr) -{ - os << addr.to_string(); - return os; -} - -inline std::ostream& operator<< (std::ostream &os, IPEndpoint::V6 const& addr) -{ - os << addr.to_string(); - return os; -} - -inline std::ostream& operator<< (std::ostream &os, IPEndpoint const& ep) -{ - os << ep.to_string(); - return os; -} +std::ostream& operator<< (std::ostream &os, IPEndpoint::V4 const& addr); +std::ostream& operator<< (std::ostream &os, IPEndpoint::V6 const& addr); +std::ostream& operator<< (std::ostream &os, IPEndpoint const& ep); /** @} */ /** Input stream conversions. */ diff --git a/beast/net/impl/IPEndpoint.cpp b/beast/net/impl/IPEndpoint.cpp index cdd1c3639..ae9fd2f93 100644 --- a/beast/net/impl/IPEndpoint.cpp +++ b/beast/net/impl/IPEndpoint.cpp @@ -195,6 +195,16 @@ IPEndpoint& IPEndpoint::operator= (IPEndpoint const& other) return *this; } +IPEndpoint IPEndpoint::from_string (std::string const& s) +{ + std::stringstream ss (s); + IPEndpoint ep; + ss >> ep; + if (! ss.fail()) + return ep; + return IPEndpoint(); +} + IPEndpoint& IPEndpoint::operator= (V4 const& address) { m_type = ipv4; @@ -490,6 +500,79 @@ std::istream& operator>> (std::istream &is, IPEndpoint& ep) //------------------------------------------------------------------------------ +int compare (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) +{ + if (lhs.value < rhs.value) + return -1; + else if (lhs.value > rhs.value) + return 1; + return 0; +} + +bool operator== (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return compare (lhs, rhs) == 0; } +bool operator!= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return compare (lhs, rhs) != 0; } +bool operator< (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return compare (lhs, rhs) < 0; } +bool operator<= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return compare (lhs, rhs) <= 0; } +bool operator> (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return compare (lhs, rhs) > 0; } +bool operator>= (IPEndpoint::V4 const& lhs, IPEndpoint::V4 const& rhs) { return compare (lhs, rhs) >= 0; } + +static int type_compare (IPEndpoint const& lhs, IPEndpoint const& rhs) +{ + if (lhs.type() < rhs.type()) + return -1; + else if (lhs.type() > rhs.type()) + return 1; + return 0; +} + +int compare (IPEndpoint const& lhs, IPEndpoint const& rhs) +{ + int const tc (type_compare (lhs, rhs)); + + if (tc < 0) + return -1; + else if (tc > 0) + return 1; + + switch (lhs.type()) + { + case IPEndpoint::none: return 0; + case IPEndpoint::ipv4: return compare (lhs.v4(), rhs.v4()); + default: + case IPEndpoint::ipv6: + break; + }; + bassertfalse; + return 0; +} + +bool operator== (IPEndpoint const& lhs, IPEndpoint const& rhs) { return compare (lhs, rhs) == 0; } +bool operator!= (IPEndpoint const& lhs, IPEndpoint const& rhs) { return compare (lhs, rhs) != 0; } +bool operator< (IPEndpoint const& lhs, IPEndpoint const& rhs) { return compare (lhs, rhs) < 0; } +bool operator<= (IPEndpoint const& lhs, IPEndpoint const& rhs) { return compare (lhs, rhs) <= 0; } +bool operator> (IPEndpoint const& lhs, IPEndpoint const& rhs) { return compare (lhs, rhs) > 0; } +bool operator>= (IPEndpoint const& lhs, IPEndpoint const& rhs) { return compare (lhs, rhs) >= 0; } + +std::ostream& operator<< (std::ostream &os, IPEndpoint::V4 const& addr) +{ + os << addr.to_string(); + return os; +} + +std::ostream& operator<< (std::ostream &os, IPEndpoint::V6 const& addr) +{ + os << addr.to_string(); + return os; +} + +std::ostream& operator<< (std::ostream &os, IPEndpoint const& ep) +{ + os << ep.to_string(); + return os; +} + +//------------------------------------------------------------------------------ + class IPEndpointTests : public UnitTest { public: