| 1 |
module Marshal; |
|---|
| 2 |
|
|---|
| 3 |
import std.string; |
|---|
| 4 |
|
|---|
| 5 |
import Serialize; |
|---|
| 6 |
import utill; |
|---|
| 7 |
import Third; |
|---|
| 8 |
import XML; |
|---|
| 9 |
public import State; |
|---|
| 10 |
|
|---|
| 11 |
char[] TrimType(char[] name) |
|---|
| 12 |
{ |
|---|
| 13 |
foreach_reverse(i,c; name) if(c == '.') return name[i+1..$]; |
|---|
| 14 |
return name; |
|---|
| 15 |
} |
|---|
| 16 |
|
|---|
| 17 |
void MarshalNative(T)(Sink!(char) sink, T t, ref InMap map) |
|---|
| 18 |
{ |
|---|
| 19 |
static if(is(T == char[])) |
|---|
| 20 |
{ |
|---|
| 21 |
XML.WriteContentXML(sink,t); |
|---|
| 22 |
} |
|---|
| 23 |
else static if(is(T B == B[])) |
|---|
| 24 |
{ |
|---|
| 25 |
if(t.length == 0) |
|---|
| 26 |
{ |
|---|
| 27 |
sink.Dump("null"); |
|---|
| 28 |
} |
|---|
| 29 |
else |
|---|
| 30 |
{ |
|---|
| 31 |
static if(NativeBaseType!(B)) |
|---|
| 32 |
{ |
|---|
| 33 |
MarshalNative!(B)(sink,t[0],map); |
|---|
| 34 |
foreach(b;t[1..$]) |
|---|
| 35 |
{ |
|---|
| 36 |
sink.Dump(","); |
|---|
| 37 |
MarshalNative!(B)(sink,b,map); |
|---|
| 38 |
} |
|---|
| 39 |
} |
|---|
| 40 |
else |
|---|
| 41 |
{ |
|---|
| 42 |
const static char[] tag = NameFromType!(B); |
|---|
| 43 |
foreach(b;t) |
|---|
| 44 |
{ |
|---|
| 45 |
M!(tag,B)(sink,b,map); |
|---|
| 46 |
} |
|---|
| 47 |
} |
|---|
| 48 |
} |
|---|
| 49 |
} |
|---|
| 50 |
else static if(NativeBaseType!(T)) |
|---|
| 51 |
sink.Dump(std.string.format("%s", t)); |
|---|
| 52 |
else static assert(false, "Don't known how to Marshal "~T.stringof); |
|---|
| 53 |
} |
|---|
| 54 |
|
|---|
| 55 |
template MarshalMixin() |
|---|
| 56 |
{ |
|---|
| 57 |
void Serialize(Sink!(char) sink) |
|---|
| 58 |
{ |
|---|
| 59 |
InMap map; |
|---|
| 60 |
static const char[] name = "root"; |
|---|
| 61 |
M!(name,typeof(this))(sink,this,map); |
|---|
| 62 |
} |
|---|
| 63 |
|
|---|
| 64 |
void MarshalMe(Sink!(char) sink, ref InMap map) |
|---|
| 65 |
{ |
|---|
| 66 |
//writef("Doing %s\n", typeof(this).stringof); |
|---|
| 67 |
mixin utill.Usefull!(typeof(this)); |
|---|
| 68 |
|
|---|
| 69 |
static if(is(typeof(this) == class)) |
|---|
| 70 |
{ |
|---|
| 71 |
static if(is(typeof(super.MarshalMe(sink,map)))) |
|---|
| 72 |
super.MarshalMe(sink,map); |
|---|
| 73 |
} |
|---|
| 74 |
|
|---|
| 75 |
foreach(i,v;this.tupleof) |
|---|
| 76 |
{ |
|---|
| 77 |
static const name = TrimType(BaseType.tupleof[i].stringof); |
|---|
| 78 |
M!(name,typeof(v))(sink,v,map); |
|---|
| 79 |
} |
|---|
| 80 |
} |
|---|
| 81 |
} |
|---|
| 82 |
|
|---|
| 83 |
void M(char[] name, V)(Sink!(char)sink, V v, ref InMap map) |
|---|
| 84 |
{ |
|---|
| 85 |
static if(is(typeof(&v.MarshalMe))) |
|---|
| 86 |
{ |
|---|
| 87 |
static if(is(V == class)) |
|---|
| 88 |
{ |
|---|
| 89 |
if(v is null) |
|---|
| 90 |
{ |
|---|
| 91 |
sink.Dump("<"~name~">NULL</"~name~">"); |
|---|
| 92 |
} |
|---|
| 93 |
else |
|---|
| 94 |
{ |
|---|
| 95 |
sink.Dump("<"~name); |
|---|
| 96 |
if(v.TypeTag(sink, map)) return; |
|---|
| 97 |
sink.Dump("\">"); |
|---|
| 98 |
v.MarshalMe(sink,map); |
|---|
| 99 |
sink.Dump("</"~name~">"); |
|---|
| 100 |
} |
|---|
| 101 |
} |
|---|
| 102 |
else static if(is(utill.Usefull!(V).BaseType == struct)) |
|---|
| 103 |
{ |
|---|
| 104 |
sink.Dump("<"~name~">"); |
|---|
| 105 |
v.MarshalMe(sink,map); |
|---|
| 106 |
sink.Dump("</"~name~">"); |
|---|
| 107 |
} |
|---|
| 108 |
else static assert(false, "Internal Error"); |
|---|
| 109 |
} |
|---|
| 110 |
else static if(is(V == struct) || is(V == class)) |
|---|
| 111 |
{ |
|---|
| 112 |
sink.Dump("<"~name~">"); |
|---|
| 113 |
ThirdPartyAccess!(V).marshial(v,SinkHandle(&map, sink)); |
|---|
| 114 |
sink.Dump("</"~name~">"); |
|---|
| 115 |
} |
|---|
| 116 |
else |
|---|
| 117 |
{ |
|---|
| 118 |
sink.Dump("<"~name~">"); |
|---|
| 119 |
MarshalNative!(typeof(v))(sink,v,map); |
|---|
| 120 |
sink.Dump("</"~name~">"); |
|---|
| 121 |
} |
|---|
| 122 |
} |
|---|