Skip to content

Commit f7a781f

Browse files
authored
Replace ipv4 inet_ntop with a handrolled function (#367)
* Replace ipv4 inet_ntop with a handrolled function * make iptos static * Make codegen better behaved on msvc / gcc For some reason gcc assumes that static constexpr array can be modified and does not attempt to zero init the string, reading from the array instead. Having the buffer be initialized in the function instead via a consteval seems to yield proper results. MSVC just straight up doesn't understand static initialization and attempts to initialize the static buffer on every function call. Microsoft never fails to disappoint.
1 parent 3772d17 commit f7a781f

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

trantor/net/InetAddress.cc

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,40 @@ bool InetAddress::isLoopbackIp() const
196196
return false;
197197
}
198198

199+
static void byteToChars(std::string::iterator &dst, unsigned char byte)
200+
{
201+
*dst = byte / 100 + '0';
202+
dst += byte >= 100;
203+
*dst = byte % 100 / 10 + '0';
204+
dst += byte >= 10;
205+
*dst = byte % 10 + '0';
206+
++dst;
207+
}
208+
209+
static std::string iptos(unsigned inet_addr)
210+
{
211+
// Initialize with a static buffer to force the constructor of string to get
212+
// fully inlined
213+
constexpr char stringInitBuffer[15]{};
214+
std::string out(stringInitBuffer, 15);
215+
std::string::iterator dst = out.begin();
216+
byteToChars(dst, inet_addr >> 0 & 0xff);
217+
*(dst++) = '.';
218+
byteToChars(dst, inet_addr >> 8 & 0xff);
219+
*(dst++) = '.';
220+
byteToChars(dst, inet_addr >> 16 & 0xff);
221+
*(dst++) = '.';
222+
byteToChars(dst, inet_addr >> 24 & 0xff);
223+
out.erase(dst, out.end());
224+
return out;
225+
}
226+
199227
std::string InetAddress::toIp() const
200228
{
201-
char buf[64];
229+
char buf[INET6_ADDRSTRLEN]{};
202230
if (addr_.sin_family == AF_INET)
203231
{
204-
#if defined _WIN32
205-
::inet_ntop(AF_INET, (PVOID)&addr_.sin_addr, buf, sizeof(buf));
206-
#else
207-
::inet_ntop(AF_INET, &addr_.sin_addr, buf, sizeof(buf));
208-
#endif
232+
return iptos(addr_.sin_addr.s_addr);
209233
}
210234
else if (addr_.sin_family == AF_INET6)
211235
{

0 commit comments

Comments
 (0)