Add allocation-less overloads of NetworkAddress.to(Address)String.

(cherry picked from commit 997d78ad36bfee853daefe663e3a54314a652b19)
This commit is contained in:
Sönke Ludwig 2016-03-11 08:21:51 +01:00
parent 76626f2fd4
commit 21619e8a30

View file

@ -198,7 +198,15 @@ struct NetworkAddress {
string toAddressString() string toAddressString()
const { const {
import std.array : appender; import std.array : appender;
import std.string : format; auto ret = appender!string();
ret.reserve(40);
toAddressString(str => ret.put(str));
return ret.data;
}
/// ditto
void toAddressString(scope void delegate(const(char)[]) @safe sink)
const {
import std.array : appender;
import std.format : formattedWrite; import std.format : formattedWrite;
ubyte[2] _dummy = void; // Workaround for DMD regression in master ubyte[2] _dummy = void; // Workaround for DMD regression in master
@ -206,17 +214,16 @@ struct NetworkAddress {
default: assert(false, "toAddressString() called for invalid address family."); default: assert(false, "toAddressString() called for invalid address family.");
case AF_INET: case AF_INET:
ubyte[4] ip = () @trusted { return (cast(ubyte*)&addr_ip4.sin_addr.s_addr)[0 .. 4]; } (); ubyte[4] ip = () @trusted { return (cast(ubyte*)&addr_ip4.sin_addr.s_addr)[0 .. 4]; } ();
return format("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); sink.formattedWrite("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
break;
case AF_INET6: case AF_INET6:
ubyte[16] ip = addr_ip6.sin6_addr.s6_addr; ubyte[16] ip = addr_ip6.sin6_addr.s6_addr;
auto ret = appender!string();
ret.reserve(40);
foreach (i; 0 .. 8) { foreach (i; 0 .. 8) {
if (i > 0) ret.put(':'); if (i > 0) sink(":");
_dummy[] = ip[i*2 .. i*2+2]; _dummy[] = ip[i*2 .. i*2+2];
ret.formattedWrite("%x", bigEndianToNative!ushort(_dummy)); sink.formattedWrite("%x", bigEndianToNative!ushort(_dummy));
} }
return ret.data; break;
} }
} }
@ -224,11 +231,26 @@ struct NetworkAddress {
*/ */
string toString() string toString()
const { const {
auto ret = toAddressString(); import std.array : appender;
auto ret = appender!string();
toString(str => ret.put(str));
return ret.data;
}
/// ditto
void toString(scope void delegate(const(char)[]) @safe sink)
const {
import std.format : formattedWrite;
switch (this.family) { switch (this.family) {
default: assert(false, "toString() called for invalid address family."); default: assert(false, "toString() called for invalid address family.");
case AF_INET: return ret ~ format(":%s", port); case AF_INET:
case AF_INET6: return format("[%s]:%s", ret, port); toAddressString(sink);
sink.formattedWrite(":%s", port);
break;
case AF_INET6:
sink("[");
toAddressString(sink);
sink.formattedWrite("]:%s", port);
break;
} }
} }
@ -537,4 +559,4 @@ private pure nothrow {
} }
} }
private enum tracer = ""; private enum tracer = "";