Skip to content

Commit 183116d

Browse files
committed
net/InetAddress: add method Format()
1 parent d88c268 commit 183116d

5 files changed

Lines changed: 96 additions & 1 deletion

File tree

src/net/IPv4Address.cxx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,37 @@
44
#include "IPv4Address.hxx"
55

66
#include <cassert>
7+
#include <cstring> // for strlen()
8+
#include <cstdio> // for sprintf()
9+
10+
#ifndef _WIN32
11+
#include <arpa/inet.h> // for inet_ntop()
12+
#endif
713

814
IPv4Address::IPv4Address(SocketAddress src) noexcept
915
:address(src.CastTo<struct sockaddr_in>())
1016
{
1117
assert(!src.IsNull());
1218
assert(src.GetFamily() == AF_INET);
1319
}
20+
21+
const char *
22+
IPv4Address::Format(std::span<char> buffer) const noexcept
23+
{
24+
if (buffer.size() <= 7) [[unlikely]]
25+
return nullptr;
26+
27+
char *p = buffer.data();
28+
29+
if (inet_ntop(AF_INET, &address.sin_addr,
30+
p, buffer.size() - 7) == nullptr)
31+
return nullptr;
32+
33+
const unsigned port = GetPort();
34+
if (port != 0) {
35+
p += std::strlen(p);
36+
std::sprintf(p, ":%u", port);
37+
}
38+
39+
return buffer.data();
40+
}

src/net/IPv4Address.hxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,12 @@ public:
232232
return IPv4Address(ConstructInAddrBE(GetNumericAddressBE() & other.GetNumericAddressBE()),
233233
GetPort() & other.GetPort());
234234
}
235+
236+
/**
237+
* Format this object as a C string into the given buffer.
238+
*
239+
* @return the C string on success, nullptr on error
240+
*/
241+
[[nodiscard]]
242+
const char *Format(std::span<char> buffer) const noexcept;
235243
};

src/net/IPv6Address.cxx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
#include "IPv4Address.hxx"
66

77
#include <cassert>
8+
#include <cstring> // for strlen()
9+
#include <cstdio> // for sprintf()
810

9-
#include <string.h>
11+
#ifndef _WIN32
12+
#include <arpa/inet.h> // for inet_ntop()
13+
#endif
1014

1115
IPv6Address::IPv6Address(SocketAddress src) noexcept
1216
:address(src.CastTo<struct sockaddr_in6>())
@@ -65,3 +69,27 @@ IPv6Address::operator&(const IPv6Address &other) const
6569
sizeof(result));
6670
return result;
6771
}
72+
73+
const char *
74+
IPv6Address::Format(std::span<char> buffer) const noexcept
75+
{
76+
if (buffer.size() <= 9) [[unlikely]]
77+
return nullptr;
78+
79+
char *p = buffer.data();
80+
81+
const unsigned port = GetPort();
82+
if (port != 0)
83+
*p++ = '[';
84+
85+
if (inet_ntop(AF_INET6, &address.sin6_addr,
86+
p, buffer.size() - 9) == nullptr)
87+
return nullptr;
88+
89+
if (port != 0) {
90+
p += std::strlen(p);
91+
std::sprintf(p, "]:%u", port);
92+
}
93+
94+
return buffer.data();
95+
}

src/net/IPv6Address.hxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,14 @@ public:
212212
[[gnu::pure]]
213213
IPv6Address operator&(const IPv6Address &other) const;
214214

215+
/**
216+
* Format this object as a C string into the given buffer.
217+
*
218+
* @return the C string on success, nullptr on error
219+
*/
220+
[[nodiscard]]
221+
const char *Format(std::span<char> buffer) const noexcept;
222+
215223
private:
216224
/**
217225
* Helper function for MaskFromPrefix().

src/net/InetAddress.hxx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "IPv6Address.hxx"
1111
#endif
1212

13+
#include <span>
14+
1315
/**
1416
* A class that can store either an IPv4 or an IPv6 address.
1517
*/
@@ -116,4 +118,26 @@ public:
116118
return {};
117119
}
118120
}
121+
122+
/**
123+
* Format this object as a C string into the given buffer.
124+
*
125+
* @return the C string on success, nullptr on error
126+
*/
127+
[[nodiscard]]
128+
const char *Format(std::span<char> buffer) const noexcept {
129+
switch (GetFamily()) {
130+
case AF_INET:
131+
return v4.Format(buffer);
132+
133+
#ifdef HAVE_IPV6
134+
case AF_INET6:
135+
return v6.Format(buffer);
136+
#endif
137+
138+
default:
139+
[[unlikely]]
140+
return nullptr;
141+
}
142+
}
119143
};

0 commit comments

Comments
 (0)