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