Sending a struct over TCP

SirErugor ontherenth at gmail.com
Fri Mar 9 02:49:19 PST 2007


Downs Wrote:
> 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

Thank you very much, Downs!
This works perfectly and I've gotten quite a better understanding on templates as well.

Cheers! :)


More information about the Digitalmars-d-learn mailing list