net/addr/ip: Add In4Addr ToStr conversion
Change-Id: Id2f16834c02a2bc500aae45dc852113cee1eff87
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/stdplus/net/addr/ip.hpp b/include/stdplus/net/addr/ip.hpp
index 0f5b30f..59a8f2f 100644
--- a/include/stdplus/net/addr/ip.hpp
+++ b/include/stdplus/net/addr/ip.hpp
@@ -77,6 +77,28 @@
}
};
+template <>
+struct ToStr<In4Addr>
+{
+ using type = In4Addr;
+ using ToOct = IntToStr<10, uint8_t>;
+ // 4 octets * 3 dec chars + 3 separators
+ static constexpr std::size_t buf_size = 12 + ToOct::buf_size;
+
+ template <typename CharT>
+ constexpr CharT* operator()(CharT* buf, In4Addr v) const noexcept
+ {
+ auto n = bswap(ntoh(v.s4_addr32));
+ for (size_t i = 0; i < 3; ++i)
+ {
+ buf = ToOct{}(buf, n & 0xff);
+ (buf++)[0] = '.';
+ n >>= 8;
+ }
+ return ToOct{}(buf, n & 0xff);
+ }
+};
+
struct In6Addr : in6_addr
{
constexpr In6Addr() noexcept : in6_addr() {}
@@ -144,3 +166,8 @@
return std::hash<stdplus::detail::InAnyAddrV>{}(a);
}
};
+
+template <typename CharT>
+struct fmt::formatter<stdplus::In4Addr, CharT> :
+ stdplus::Format<stdplus::ToStr<stdplus::In4Addr>, CharT>
+{};
diff --git a/src/net/addr/ip.cpp b/src/net/addr/ip.cpp
index 81d2a4a..fca752a 100644
--- a/src/net/addr/ip.cpp
+++ b/src/net/addr/ip.cpp
@@ -3,4 +3,5 @@
namespace stdplus
{
template In4Addr FromStr<In4Addr>::operator()(std::string_view) const;
-}
+template char* ToStr<In4Addr>::operator()(char*, In4Addr) const noexcept;
+} // namespace stdplus
diff --git a/test/net/addr/ip.cpp b/test/net/addr/ip.cpp
index 625633e..0a2bc30 100644
--- a/test/net/addr/ip.cpp
+++ b/test/net/addr/ip.cpp
@@ -1,3 +1,5 @@
+#include <fmt/format.h>
+
#include <stdplus/net/addr/ip.hpp>
#include <stdplus/numeric/endian.hpp>
@@ -30,6 +32,15 @@
EXPECT_EQ((In4Addr{192, 168, 1, 1}), fromStr<In4Addr>("192.168.001.1"));
}
+TEST(ToStr, In4Addr)
+{
+ ToStrHandle<ToStr<In4Addr>> tsh;
+ EXPECT_EQ("255.255.255.255", tsh(in_addr{0xffffffff}));
+ EXPECT_EQ("1.15.3.4", tsh(In4Addr{1, 15, 3, 4}));
+ EXPECT_EQ("0.0.0.0", tsh(In4Addr{}));
+ EXPECT_EQ("a 1.15.3.4 b", fmt::format("a {} b", In4Addr{1, 15, 3, 4}));
+}
+
TEST(EqualOperator, In6Addr)
{
EXPECT_EQ((In6Addr{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff}),