util: Refactor addrFromBuf

Change-Id: I1b2deed483eb25034ca9b4717388119af3da1c8d
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/util.cpp b/src/util.cpp
index d69357d..8a39bb1 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -151,30 +151,17 @@
     throw std::invalid_argument("Invalid addr family");
 }
 
-InAddrAny addrFromBuf(int addressFamily, std::string_view buf)
+template <int family>
+typename FamilyTraits<family>::addr addrFromBuf(std::string_view buf)
 {
-    if (addressFamily == AF_INET)
-    {
-        struct in_addr ret;
-        if (buf.size() != sizeof(ret))
-        {
-            throw std::runtime_error("Buf not in_addr sized");
-        }
-        memcpy(&ret, buf.data(), sizeof(ret));
-        return ret;
-    }
-    else if (addressFamily == AF_INET6)
-    {
-        struct in6_addr ret;
-        if (buf.size() != sizeof(ret))
-        {
-            throw std::runtime_error("Buf not in6_addr sized");
-        }
-        memcpy(&ret, buf.data(), sizeof(ret));
-        return ret;
-    }
+    return stdplus::raw::copyFromStrict<typename FamilyTraits<family>::addr>(
+        buf);
+}
 
-    throw std::runtime_error("Unsupported address family");
+InAddrAny addrFromBuf(int family, std::string_view buf)
+{
+    return familyVisit(
+        [=]<int f>() -> InAddrAny { return addrFromBuf<f>(buf); }, family);
 }
 
 std::string toString(const struct in_addr& addr)