Sending a struct over TCP
Downs
default_357-line at yahoo.de
Thu Mar 8 04:29:16 PST 2007
SirErugor wrote:
> Hi there,
>
> I've set up a server and a client application and I want to be able to send a struct with fx. an integer and a char[]. So first I convert it to a ubyte[] like this:
>
This is rather easy to achieve with templates
I needed to do something similar a bit back, so here's the code I used:
template isArray(T) { const isArray=false; }
template isArray(T: T[]) { const isArray=true; }
/// serialize
void ser(T)(T value, void delegate(char[]) dg) {
static if (isArray!(T)) {
/// First dump the length (as uint, so it's fixed across platforms), then the data
/// \todo special case for char[] arrays
ser!(uint)(value.length, dg);
foreach (element; value) ser(element, dg);
} else {
static if (is(T==struct)) {
/// Just serialize the elements in order
foreach (element; value.tupleof) ser(element, dg);
} else {
dg((cast(char*)&value)[0..value.sizeof]);
}
}
}
void ser(T, dummy=void)(T value, inout char[] target) {
ser!(T)(value, (char[] c) { target~=c; });
}
char[] splinter(inout char[] c, size_t amount) {
assert(c.length!<amount);
auto res=c[0..amount];
c=c[amount..$];
return res;
}
T carve(T)(inout char[] t) {
T result;
static if (isArray!(T)) {
result.length=carve!(uint)(t);
foreach (inout elem; result) elem=carve!(typeof(result[0]))(t);
} else {
static if (is(T==struct)) {
foreach (idx, bogus; result.tupleof)
result.tupleof[idx]=carve!(typeof(bogus))(t);
} else {
result=*(cast(T*)(splinter(t, T.sizeof).ptr));
}
}
return result;
}
Use it like
struct test {
int e;
char[] f;
}
char[] send; test t;
ser(t, (char[] c) { send~=c; });
/* Now send "send" over the socket .. at the other end: */
char[] received; test t=carve!(test)(received);
Greetings --downs
More information about the Digitalmars-d-learn
mailing list