root/trunk/Serial/Marshal.d

Revision 591, 2.4 kB (checked in by BCS, 3 years ago)

Added support for 3rd party types and arrays

Line 
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 }
Note: See TracBrowser for help on using the browser.