Changeset 586
- Timestamp:
- 05/28/09 01:06:24 (3 years ago)
- Files:
-
- trunk/Serial/Common.d (added)
- trunk/Serial/Demarshal.d (modified) (4 diffs)
- trunk/Serial/Marshal.d (modified) (1 diff)
- trunk/Serial/Serialize.d (modified) (2 diffs)
- trunk/Serial/test1.d (modified) (4 diffs)
- trunk/Serial/utill.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Serial/Demarshal.d
r585 r586 14 14 if(str == "") throw new Exception("Unexpected end of Source"); 15 15 16 char c; 16 17 // eat whitespace. 17 outter: for(;;) switch( source.Peek())18 outter: for(;;) switch(c = source.Peek()) 18 19 { 19 case ' ', '\n', '\r', '\v', '\t': break;20 case ' ', '\n', '\r', '\v', '\t': source.Pick(c); break; 20 21 default: break outter; 21 22 } … … 35 36 } 36 37 37 38 T demarshal(T)(Source!(char) source) 38 struct OutMap 39 39 { 40 static if(is(T == byte) || is(T == ubyte) || is(T == short) || is(T == ushort) || 41 is(T == int) || is(T == uint) || is(T == long) || is(T == ulong) || 42 is(T == float) || is(T == double) || is(T == real)) 40 void*[uint] map; 41 bool Hold(uint sn, void* ptr) 43 42 { 44 auto ret = DemarshalNative!(T)(source); 45 //writef("%s (%s)\n", ret, T.stringof); 46 return ret; 43 if(sn in map) return false; 44 map[sn] = ptr; 45 return true; 46 47 47 } 48 else static if(is(T == struct))48 bool Get(uint sn, ref void* ptr) 49 49 { 50 static assert(is(typeof(T.DemarshalMe(source))), T.stringof~" doesn't define DemarshalMe"); 51 return T.DemarshalMe(source); 50 if(auto pptr = sn in map) 51 { 52 ptr = *pptr; 53 return true; 54 } 55 return false; 52 56 } 53 else static if(is(T == class))54 {55 static assert(is(typeof(T.DemarshalMe(source))), T.stringof~" doesn't define DemarshalMe");56 return T.DemarshalMe(source);57 }58 else static if(is(T == interface))59 {60 static assert(false,"Can't Marshal type "~T.stringof~", interfaces don't work yet");61 }62 else63 static assert(false);64 57 } 65 58 66 59 template DemarshalMixin() 67 60 { 68 static utill.Usefull!(typeof(this)).BaseType DemarshalMe(Source!(char) source) 61 static utill.Usefull!(typeof(this)).BaseType Deserialize(Source!(char) source) 62 { 63 mixin utill.Usefull!(typeof(this)); 64 static const char[] name = "root"; 65 66 OutMap map; 67 BaseType ret; 68 D!(name, BaseType, CyclicType)(source,ret,map); 69 return ret; 70 } 71 72 // Entry point for hierarchy recursion 73 static utill.Usefull!(typeof(this)).BaseType DemarshalMe(Source!(char) source, ref OutMap map) 69 74 { 70 75 mixin utill.Usefull!(typeof(this)); … … 75 80 ret = new BaseType(); 76 81 77 DoIt!(BaseType)(ret, source );82 DoIt!(BaseType)(ret, source, map); 78 83 return ret; 79 84 } 80 81 static void DoIt(ref utill.Usefull!(typeof(this)).BaseType ret, Source!(char) source) 85 86 // Shell for base class recursion 87 private static void DoIt(ref utill.Usefull!(typeof(this)).BaseType ret, Source!(char) source, ref OutMap map) 82 88 { 83 89 mixin utill.Usefull!(typeof(this)); 90 84 91 static if(is(BaseType == class)) 85 92 { … … 90 97 { 91 98 Super sret = ret; 92 Super.DoIt(sret, source );99 Super.DoIt(sret, source, map); 93 100 } 94 101 } 95 102 } 96 103 97 foreach(i, _;ret.tupleof)104 foreach(i,v;ret.tupleof) 98 105 { 99 106 static const name = TrimType(BaseType.tupleof[i].stringof); 100 static if(is(typeof(_) == class)) 101 { 102 //writef(" is class (%s)\n", "<"~name~">NULL</"~name~">"); 103 if(source.Pick("<"~name~">NULL</"~name~">")) 104 { 105 //writef(" is null\n"); 106 _ = null; 107 } 108 else 109 { 110 source.Pick("<"~name~" type=\""); 111 char[] type = XML.ReadContentXML!('\"')(source); 112 source.Pick("\">"); 113 if(auto fact = type in .Serialize.Factories) 114 { 115 (ret.tupleof)[i] = cast(typeof(BaseType.tupleof[i]))(*fact)(source); 116 assert((ret.tupleof)[i] !is null, "Invvalid type returned by "~type~", expected " ~typeof(BaseType.tupleof[i]).stringof); 117 118 } 119 else 120 assert(false, "Unknown derived type "~type); 121 source.Pick("</"~name~">"); 122 } 123 } 124 else 125 { 126 //writef(" is !class (%s)\n", typeof(_).stringof); 127 source.Pick("<"~name~">"); 128 (ret.tupleof)[i] = demarshal!(typeof(BaseType.tupleof[i]))(source); 129 source.Pick("</"~name~">"); 130 } 107 D!(name, typeof(v), CyclicType)(source,(ret.tupleof)[i], map); 131 108 } 132 109 } 133 110 } 111 112 void D(char[] name, V, bool cycle)(Source!(char) source, ref V v, ref OutMap map) 113 { 114 static if(is(V == class)) 115 { 116 if(source.Pick("<"~name~">NULL</"~name~">",false)) 117 { 118 v = null; 119 } 120 else 121 { 122 source.Pick("<"~name); 123 124 static if(cycle) 125 { 126 source.Pick(" ID=\""); 127 char[] ids = XML.ReadContentXML!('\"')(source); 128 source.Pick("\""); 129 130 uint id = toUint(ids); 131 void* vp; 132 if(source.Pick("/>",false)) 133 { 134 if(!map.Get(id, vp)) throw new Error("Back ref not found: "~ids); 135 v = cast(typeof(v))vp; 136 return; 137 } 138 } 139 140 141 source.Pick(" type=\""); 142 char[] type = XML.ReadContentXML!('\"')(source); 143 source.Pick("\">"); 144 if(auto fact = type in .Serialize.Factories) 145 { 146 v = cast(V)(*fact)(source,map); 147 assert(v !is null, "Invalid type returned by "~type~", expected " ~V.stringof); 148 } 149 else 150 throw new Error("Unknown derived type "~type); 151 152 source.Pick("</"~name~">"); 153 154 static if(cycle) map.Hold(id,cast(void*)v); 155 } 156 } 157 else static if(is(V == struct) || (is(V S == S*) && is(S==struct))) 158 { 159 source.Pick("<"~name~">"); 160 v = V.DemarshalMe(source, map); 161 source.Pick("</"~name~">"); 162 } 163 else 164 { 165 source.Pick("<"~name~">"); 166 v = DemarshalNative!(V)(source); 167 source.Pick("</"~name~">"); 168 } 169 170 } trunk/Serial/Marshal.d
r585 r586 14 14 void MarshalNative(T)(Sink!(char) sink, T t) 15 15 { 16 sink.Dump(std.string.format("%s", t)); 16 static if(is(T == int) || is(T == uint) || is(T == long) 17 || is(T == ulong) || is(T == short) ||is(T == ushort) 18 || is(T == byte) || is(T == ubyte) || is(T == float) 19 || is(T == double) || is(T == real)) 20 sink.Dump(std.string.format("%s", t)); 21 else static assert(false, "Don't known how to Marshal "~T.stringof); 17 22 } 18 23 19 void marshal(S,T)(S sink, T t) 24 struct InMap 20 25 { 21 static assert(is(S : Sink!(char))); 22 23 static if(is(T == byte) || is(T == ubyte) || is(T == short) || is(T == ushort) || 24 is(T == int) || is(T == uint) || is(T == long) || is(T == ulong) || 25 is(T == float) || is(T == double) || is(T == real)) 26 MarshalNative!(T)(sink,t); 27 else static if(is(T == struct)) 26 uint at = 0; 27 uint[void*] map; 28 29 bool Hold(void* ptr, ref uint sn) 28 30 { 29 static assert(is(typeof(T.MarshalMe(sink))), T.stringof~" doesn't define MarshalMe"); 30 t.MarshalMe(sink); 31 if(auto snp = ptr in map) 32 { 33 sn = *snp; 34 return true; 35 } 36 else 37 { 38 sn = at; 39 at++; 40 map[ptr] = sn; 41 return false; 42 } 31 43 } 32 else static if(is(T == class))33 {34 static assert(is(typeof(T.MarshalMe(sink))), T.stringof~" doesn't define MarshalMe");35 assert(t !is null);36 t.MarshalMe(sink);37 }38 else static if(is(T == interface))39 static assert(false,"Can't Marshal type "~T.stringof~", interfaces don't work yet");40 else41 static assert(false);42 44 } 43 44 45 45 46 template MarshalMixin() 46 47 { 47 void MarshalMe(Sink!(char) sink)48 void Serialize(Sink!(char) sink) 48 49 { 50 InMap map; 51 static const char[] name = "root"; 52 M!(name,typeof(this),CyclicType)(sink,this,map); 53 } 54 55 void MarshalMe(Sink!(char) sink, ref InMap map) 56 { 57 //writef("Doing %s\n", typeof(this).stringof); 49 58 mixin utill.Usefull!(typeof(this)); 50 59 51 static if(is(typeof(super.MarshalMe(sink)))) 52 super.MarshalMe(sink); 60 static if(is(typeof(this) == class)) 61 { 62 static if(is(typeof(super.MarshalMe(sink,map)))) 63 super.MarshalMe(sink,map); 64 } 53 65 54 foreach(i, _;this.tupleof)66 foreach(i,v;this.tupleof) 55 67 { 56 68 static const name = TrimType(BaseType.tupleof[i].stringof); 57 58 static if(is(typeof(_) == class)) 69 M!(name,typeof(v),CyclicType)(sink,v,map); 70 } 71 } 72 } 73 74 void M(char[] name, V, bool cycle)(Sink!(char)sink, V v, ref InMap map) 75 { 76 static if(is(typeof(v) == class)) 77 { 78 if(v is null) 79 { 80 sink.Dump("<"~name~">NULL</"~name~">"); 81 } 82 else 83 { 84 sink.Dump("<"~name); 85 static if(cycle) 59 86 { 60 if((this.tupleof)[i] is null) 87 uint id; 88 if(map.Hold(cast(void*)v,id)) 61 89 { 62 sink.Dump("<"~name~">NULL</"~name~">"); 90 sink.Dump(std.string.format(" ID=\"%s\"/>", id)); 91 return; 63 92 } 64 93 else 65 94 { 66 sink.Dump("<"~name~" type=\""); 67 XML.WriteContentXML(sink,_.Tag()); 68 sink.Dump("\">"); 69 marshal(sink, (this.tupleof)[i]); 70 sink.Dump("</"~name~">"); 95 sink.Dump(std.string.format(" ID=\"%s\"", id)); 71 96 } 72 97 } 73 else 74 { 75 sink.Dump("<"~name~">"); 76 marshal(sink, (this.tupleof)[i]); 77 sink.Dump("</"~name~">"); 78 } 98 sink.Dump(" type=\""); 99 XML.WriteContentXML(sink,v.TypeTag()); 100 sink.Dump("\">"); 101 v.MarshalMe(sink,map); 102 sink.Dump("</"~name~">"); 79 103 } 80 104 } 105 else static if(is(utill.Usefull!(V).BaseType == struct)) 106 { 107 sink.Dump("<"~name~">"); 108 v.MarshalMe(sink,map); 109 sink.Dump("</"~name~">"); 110 } 111 else 112 { 113 sink.Dump("<"~name~">"); 114 MarshalNative!(typeof(v))(sink,v); 115 sink.Dump("</"~name~">"); 116 } 81 117 } trunk/Serial/Serialize.d
r585 r586 2 2 3 3 import utill; 4 public import Interface;5 4 import XML; 6 5 7 alias Object function(Source!(char) source) Factory; 8 Factory[char[]] Factories; 6 public import Interface; 7 public import Marshal; 8 public import Demarshal; 9 public import Common; 9 10 10 11 /** … … 15 16 template Serializable() 16 17 { 18 const bool CyclicType = false; 19 17 20 mixin MarshalMixin!(); 18 21 mixin DemarshalMixin!(); 22 mixin CommonMixin!(); 23 } 19 24 20 static if(is(typeof(this) == class)) 21 { 22 static char[] sTag() { return typeof(this).stringof; } 23 24 char[] Tag() { return sTag(); } 25 26 static this() 27 { 28 Factories[sTag()] = function Object(Source!(char) source) 29 { 30 return DemarshalMe(source); 31 }; 32 } 33 } 25 /** 26 * Mixin template that attempt to "do the right" thing for general cases 27 * Handels repeated instances of the same object (hard links) 28 * 29 * Authors: Benjamin 30 */ 31 template SerializableRecuring() 32 { 33 const bool CyclicType = true; 34 34 35 mixin MarshalMixin!(); 36 mixin DemarshalMixin!(); 37 mixin CommonMixin!(); 35 38 } trunk/Serial/test1.d
r585 r586 4 4 import std.string; 5 5 6 import Marshal;7 import Demarshal;8 6 import Serialize; 9 7 import StringSourceSink; … … 11 9 class CS 12 10 { 13 mixin Serializable !();11 mixin SerializableRecuring!(); 14 12 15 13 int i = 5; float j = 3.1415926; … … 23 21 class DS : CS 24 22 { 25 mixin Serializable !();23 mixin SerializableRecuring!(); 26 24 27 25 real f = 2.717; … … 44 42 } 45 43 44 struct SC 45 { 46 mixin SerializableRecuring!(); 47 CS a; 48 CS b; 49 char[] toString() { return format("<%s,%s>", this.tupleof); } 50 } 51 46 52 void main() 47 53 { 48 54 SS ss = SS(42, 2.717, null); 55 SC sc; 49 56 Si c; 50 57 51 ss.cs = null; 52 c = new Si(); marshal(c,ss); writef("%s\n\t%s\n", c.get, SS.DemarshalMe(new So(c.get)));58 ss.cs = null; c = new Si(); 59 ss.Serialize(c); writef("%s\n\t%s\n", c.get, SS.Deserialize(new So(c.get))); 53 60 54 ss.cs = new CS(1); 55 c = new Si(); marshal(c,ss); writef("%s\n\t%s\n", c.get, SS.DemarshalMe(new So(c.get))); 61 ss.cs = new CS(1); c = new Si(); 62 ss.Serialize(c); writef("%s\n\t%s\n", c.get, SS.Deserialize(new So(c.get))); 63 64 ss.cs = new DS(1); c = new Si(); 65 ss.Serialize(c); writef("%s\n\t%s\n", c.get, SS.Deserialize(new So(c.get))); 56 66 57 ss.cs = new DS(1); 58 c = new Si(); marshal(c,ss); writef("%s\n\t%s\n", c.get, SS.DemarshalMe(new So(c.get))); 67 c = new Si(); 68 (new DS(1)).Serialize(c); writef("%s\n\t%s\n", c.get, CS.Deserialize(new So(c.get))); 69 70 71 sc.a = new CS(1); sc.b = new CS(1); c = new Si(); sc.Serialize(c); 72 auto same = SC.Deserialize(new So(c.get)); 73 writef("%s\n\t%s\n", c.get, same); 74 assert(same.a !is same.b); 75 76 sc.b = sc.a; c = new Si(); sc.Serialize(c); 77 auto dif = SC.Deserialize(new So(c.get)); 78 writef("%s\n\t%s\n", c.get, dif); 79 assert(dif.a is dif.b); 59 80 } trunk/Serial/utill.d
r585 r586 11 11 else static if(is(T == class)) 12 12 alias T BaseType; 13 else14 static assert(false, T.stringof);15 13 }
