1 module libs.marshal.demarshaller; 2 3 import std.traits; 4 import std.stdio; 5 6 package interface IDemarshalStrategy 7 { 8 void BeginDocumentDemarshal(string name); 9 void EndDocumentDemarshal(string name); 10 11 void BeginArrayDemarshal(T)(T val, string name); 12 void EndArrayDemarshal(T)(T val, string name); 13 14 void BeginObjectDemarshal(T)(T val, string name); 15 void EndObjectDemarshal(T)(T val, string name); 16 17 void DemarshalStructOrClass(T)(string name, ref T val); 18 void DemarshalArray(T)(string name, ref T val); 19 void DemarshalSingleVar(T)(string name, ref T val); 20 void DemarshalEnum(T)(string name, ref T val); 21 void DemarshalUnion(T)(string name, ref T val); 22 } 23 24 package class Demarshaller(alias InDemarshalStrategy, StorageStrategy) 25 { 26 public: 27 alias InDemarshalStrategy!(StorageStrategy) DemarshalStrategy; 28 29 //alias m_storer.SetBuffer SetBuffer; 30 31 static if (__traits(hasMember, StorageStrategy, "SetText")) 32 { 33 final void SetText(const(char)[] data) 34 { 35 m_storer.SetText(data); 36 } 37 } 38 else static if (__traits(hasMember, StorageStrategy, "SetBuffer")) 39 { 40 final void SetBuffer(const(ubyte)[] data) 41 { 42 m_storer.SetBuffer(data); 43 } 44 } 45 46 void Demarshal(T)(string name, out T val) 47 { 48 m_demarshaller.Demarshal(name, val); 49 } 50 51 void Demarshal(T)(out T val) 52 { 53 m_demarshaller.Demarshal(val); 54 } 55 56 this() 57 { 58 m_storer = new StorageStrategy; 59 m_demarshaller = new DemarshalStrategy(m_storer); 60 m_demarshaller.BeginDocumentDemarshal(""); 61 } 62 63 private: 64 StorageStrategy m_storer; 65 DemarshalStrategy m_demarshaller; 66 } 67 68 mixin template DemarshalMixinTemplate(StorageStrategy) 69 { 70 void DemarshalStructOrClass(T)(string name, ref T val) 71 { 72 static if (__traits(hasMember, T, "BeginObjectDemarshal") && __traits(hasMember, T, "EndObjectDemarshal") 73 && (isSomeFunction!(T.BeginObjectDemarshal!(typeof(this), StorageStrategy)) 74 && (is(TemplateArgsOf!(T.BeginObjectDemarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 75 && is(TemplateArgsOf!(T.BeginObjectDemarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy))) 76 && (isSomeFunction!(T.EndObjectDemarshal!(typeof(this), StorageStrategy)) 77 && (is(TemplateArgsOf!(T.EndObjectDemarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 78 && is(TemplateArgsOf!(T.EndObjectDemarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy)))) 79 { 80 val.BeginObjectDemarshal!(typeof(this), StorageStrategy)(storer, name); 81 foreach (item; __traits(allMembers, T)) 82 { 83 static if (__traits(compiles, Demarshal(item, __traits(getMember, val, item))) 84 && !isSomeFunction!(typeof(__traits(getMember, val, item)))) 85 { 86 Demarshal(item, __traits(getMember, val, item)); 87 } 88 } 89 val.EndObjectDemarshal!(typeof(this), StorageStrategy)(storer, name); 90 } 91 else 92 { 93 BeginObjectDemarshal(name, val); 94 foreach (item; __traits(allMembers, T)) 95 { 96 static if (__traits(compiles, Demarshal(item, __traits(getMember, val, item))) 97 && !isSomeFunction!(typeof(__traits(getMember, val, item)))) 98 { 99 Demarshal(item, __traits(getMember, val, item)); 100 // writefln("Demarshal: %s, %s", item, to!string(__traits(getMember, val, item))); 101 } 102 } 103 EndObjectDemarshal(name, val); 104 } 105 } 106 107 void DemarshalArray(T)(string name, ref T val) 108 { 109 static if (__traits(hasMember, T, "BeginArrayDemarshal") && __traits(hasMember, T, "EndArrayDemarshal") 110 && (isSomeFunction!(T.BeginArrayDemarshal!(typeof(this), StorageStrategy)) 111 && (is(TemplateArgsOf!(T.BeginArrayDemarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 112 && is(TemplateArgsOf!(T.BeginArrayDemarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy))) 113 && (isSomeFunction!(T.EndArrayDemarshal!(typeof(this), StorageStrategy)) 114 && (is(TemplateArgsOf!(T.EndArrayDemarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 115 && is(TemplateArgsOf!(T.EndArrayDemarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy)))) 116 { 117 //Begin 118 val.BeginArrayDemarshal!(typeof(this), StorageStrategy)(storer, name); 119 120 int i = 0; 121 val = []; 122 ForeachType!(T) item; 123 try 124 { 125 while (true) 126 { 127 Demarshal(to!string(i), item); 128 val ~= item; 129 ++i; 130 } 131 } 132 catch (InvalidFormattingException ex) 133 { 134 } 135 136 //End 137 val.EndArrayDemarshal!(typeof(this), StorageStrategy)(storer, name); 138 } 139 else 140 { 141 //Begin 142 BeginArrayDemarshal(name, val); 143 144 static if (__traits(hasMember, typeof(this), "LoopArrayDemarshal") && 145 isSomeFunction!(typeof(this).LoopArrayDemarshal!(T))) 146 { 147 LoopArrayDemarshal(name, val); 148 } 149 else 150 { 151 int i = 0; 152 val = []; 153 ForeachType!(T) item; 154 try 155 { 156 while (true) 157 { 158 Demarshal(to!string(i), item); 159 val ~= item; 160 ++i; 161 } 162 } 163 catch (InvalidFormattingException ex) 164 { 165 } 166 } 167 168 //End 169 EndArrayDemarshal(name, val); 170 } 171 } 172 173 void Demarshal(T)(string name, ref T val) 174 { 175 static if (__traits(hasMember, T, "Demarshal") 176 && isSomeFunction!(T.Demarshal!(typeof(this), StorageStrategy)) 177 && (is(TemplateArgsOf!(T.Demarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 178 && is(TemplateArgsOf!(T.Demarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy))) 179 { 180 val.Demarshal!(typeof(this), StorageStrategy)(m_storer, name); 181 } 182 else static if (is(T == struct) || is(T == class)) 183 { 184 DemarshalStructOrClass(name, val); 185 } 186 else static if (isArray!(T) && !isSomeString!(T)) 187 { 188 DemarshalArray(name, val); 189 } 190 else static if (__traits(isPOD, T)) 191 { 192 DemarshalSingleVar(name, val); 193 } 194 } 195 196 private StorageStrategy m_storer; 197 198 package this(StorageStrategy storer) 199 { 200 this.m_storer = storer; 201 } 202 203 }