util: Refactor IP toString
Change-Id: I9aea159e95e5b66d6a02809c3d5832c8697df2e1
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/util.cpp b/src/util.cpp
index 915f2b4..7ede99c 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -164,44 +164,23 @@
[=]<int f>() -> InAddrAny { return addrFromBuf<f>(buf); }, family);
}
-std::string toString(const struct in_addr& addr)
+template <typename Addr>
+std::string toString(const Addr& addr)
{
- std::string ip(INET_ADDRSTRLEN, '\0');
- if (inet_ntop(AF_INET, &addr, ip.data(), ip.size()) == nullptr)
+ static constexpr int family = AddrToFamily<Addr>::value;
+ std::string ret(FamilyTraits<family>::strlen, '\0');
+ if (inet_ntop(family, &addr, ret.data(), ret.size()) == nullptr)
{
- throw std::runtime_error("Failed to convert IP4 to string");
+ throw std::runtime_error("Failed to convert IP to string");
}
- ip.resize(strlen(ip.c_str()));
- return ip;
-}
-
-std::string toString(const struct in6_addr& addr)
-{
- std::string ip(INET6_ADDRSTRLEN, '\0');
- if (inet_ntop(AF_INET6, &addr, ip.data(), ip.size()) == nullptr)
- {
- throw std::runtime_error("Failed to convert IP6 to string");
- }
-
- ip.resize(strlen(ip.c_str()));
- return ip;
+ ret.resize(strlen(ret.c_str()));
+ return ret;
}
std::string toString(const InAddrAny& addr)
{
- if (std::holds_alternative<struct in_addr>(addr))
- {
- const auto& v = std::get<struct in_addr>(addr);
- return toString(v);
- }
- else if (std::holds_alternative<struct in6_addr>(addr))
- {
- const auto& v = std::get<struct in6_addr>(addr);
- return toString(v);
- }
-
- throw std::runtime_error("Invalid addr type");
+ return std::visit([](auto&& a) { return toString(a); }, addr);
}
bool isValidIP(int family, stdplus::const_zstring address) noexcept
diff --git a/src/util.hpp b/src/util.hpp
index 84c6574..52abfb7 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -81,12 +81,31 @@
struct FamilyTraits<AF_INET>
{
using addr = in_addr;
+ static constexpr std::size_t strlen = INET_ADDRSTRLEN;
};
template <>
struct FamilyTraits<AF_INET6>
{
using addr = in6_addr;
+ static constexpr std::size_t strlen = INET6_ADDRSTRLEN;
+};
+
+template <typename Addr>
+struct AddrToFamily
+{
+};
+
+template <>
+struct AddrToFamily<in_addr>
+{
+ static constexpr int value = AF_INET;
+};
+
+template <>
+struct AddrToFamily<in6_addr>
+{
+ static constexpr int value = AF_INET6;
};
/* @brief converts a sockaddr for the specified address family into
@@ -102,9 +121,9 @@
* @param[in] addr - input ip address to convert.
* @returns String representation of the ip.
*/
+template <typename Addr>
+std::string toString(const Addr& addr);
std::string toString(const InAddrAny& addr);
-std::string toString(const struct in_addr& addr);
-std::string toString(const struct in6_addr& addr);
/* @brief checks that the given ip address valid or not.
* @param[in] family - IP address family(AF_INET/AF_INET6).