1 module libs.marshal.compact_binary_demarshaller; 2 3 import libs.marshal.binary_demarshaller, libs.marshal.demarshaller; 4 import std.conv, std.string, std.traits; 5 import std.stdio; 6 7 alias Demarshaller!(CompactBinaryDemarshallerStrategy, BinaryDemarshallerStorageStrategy) CompactBinaryDemarshaller; 8 9 package class CompactBinaryDemarshallerStrategy(StorageStrategy) : IDemarshalStrategy 10 { 11 mixin DemarshalMixinTemplate!(StorageStrategy); 12 13 void BeginArrayDemarshal(T)(string name, ref T val) 14 { 15 val.length = m_storer.ReadVal!(typeof(val.length))(); 16 } 17 18 void EndArrayDemarshal(T)(string name, ref T val) 19 { 20 } 21 22 void LoopArrayDemarshal(T)(string name, ref T val) 23 { 24 foreach (ref item; val) 25 { 26 Demarshal("", item); 27 } 28 } 29 30 void BeginDocumentDemarshal(string name) 31 { 32 } 33 34 void EndDocumentDemarshal(string name) 35 { 36 } 37 38 void BeginObjectDemarshal(T)(string name, ref T val) 39 { 40 } 41 42 void EndObjectDemarshal(T)(string name, ref T val) 43 { 44 } 45 46 void DemarshalSingleVar(T)(string name, ref T val) 47 { 48 static if (isSomeString!(T)) 49 { 50 Unqual!(ForeachType!(T))[] str; 51 str.length = m_storer.ReadVal!(typeof(val.length))(); 52 foreach(ref item; str) 53 { 54 item = m_storer.ReadVal!(typeof(item))(); 55 } 56 val = to!(T)(str); 57 } 58 else 59 { 60 val = m_storer.ReadVal!(T)(); 61 } 62 } 63 64 void DemarshalEnum(T)(out T val, string name) 65 { 66 MarshalSingleVar(val, name); 67 } 68 69 void DemarshalUnion(T)(out T val, string name) 70 { 71 MarshalSingleVar(val, name); 72 } 73 } 74 75 unittest { 76 //Integers 77 CompactBinaryDemarshaller binary_demarshaller = new CompactBinaryDemarshaller; 78 binary_demarshaller.SetBuffer([0, 0, 0, 42]); 79 80 int meaning_of_life; 81 binary_demarshaller.Demarshal("", meaning_of_life); 82 assert(meaning_of_life == 42); 83 84 //Strings 85 char[] name; 86 binary_demarshaller = new CompactBinaryDemarshaller; 87 binary_demarshaller.SetBuffer([0, 0, 0, 8, '1', ' ', 's', 't', 'r', 'i', 'n', 'g']); 88 binary_demarshaller.Demarshal("", name); 89 // writefln("name = %s", name); 90 assert(name == "1 string"); 91 92 //Enums 93 enum MyEnum 94 { 95 a = 10, 96 b, 97 c 98 } 99 MyEnum myenum; 100 binary_demarshaller = new CompactBinaryDemarshaller; 101 binary_demarshaller.SetBuffer([0, 0, 0, 11]); 102 binary_demarshaller.Demarshal("", myenum); 103 assert(myenum == MyEnum.b); 104 105 //Arrays 106 binary_demarshaller = new CompactBinaryDemarshaller; 107 binary_demarshaller.SetBuffer([/*length*/0,0,0,5, 108 /*ary[0]*/0,0,0,1, 109 /*ary[1]*/0,0,0,2, 110 /*ary[2]*/0,0,0,3, 111 /*ary[3]*/0,0,0,44, 112 /*ary[4]*/0,0,0,5]); 113 114 int[] ary_expect = [1, 2, 3, 44, 5]; 115 int[] ary; 116 binary_demarshaller.Demarshal("", ary); 117 assert(ary == ary_expect); 118 119 //Structs 120 binary_demarshaller = new CompactBinaryDemarshaller; 121 static struct A 122 { 123 int x; 124 float y; 125 string z; 126 } 127 A a_expect; 128 A a; 129 a_expect.x = 10; 130 a_expect.y = 11.2; 131 a_expect.z = "abc"; 132 binary_demarshaller.SetBuffer([/*x*/0, 0, 0, 10, 133 /*y*/65, 51, 51, 51, 134 /*z*/0, 0, 0, 3, 'a', 'b', 'c']); 135 136 binary_demarshaller.Demarshal("", a); 137 assert(a == a_expect); 138 139 //Nested Structs 140 binary_demarshaller = new CompactBinaryDemarshaller; 141 static struct B 142 { 143 int i1 = 1024; 144 float f1 = 22.2; 145 A a; 146 } 147 B b_expect; 148 B b; 149 b_expect.i1 = 1024; 150 b_expect.f1 = 22.2; 151 b_expect.a.x = 10; 152 b_expect.a.y = 11.2; 153 b_expect.a.z = "abc"; 154 binary_demarshaller.SetBuffer([/*b.i1 */0, 0, 4, 0, 155 /*b.f1 */65, 177, 153, 154, 156 /*b.a.x*/0, 0, 0, 10, 157 /*b.a.y*/65, 51, 51, 51, 158 /*b.a.z*/0, 0, 0, 3, 'a', 'b', 'c']); 159 160 binary_demarshaller.Demarshal("", b); 161 // writeln(to!string(b)); 162 assert( b == b_expect ); 163 164 //Self Defined Marshal Function 165 binary_demarshaller = new CompactBinaryDemarshaller; 166 static struct C 167 { 168 int x; 169 int y; 170 int z; 171 void Demarshal(DemarshalStrategy : CompactBinaryDemarshallerStrategy!StorageStrategy, 172 StorageStrategy : BinaryDemarshallerStorageStrategy) 173 (StorageStrategy storer, string name) 174 { 175 assert(name == "test"); 176 x = storer.ReadVal!int; 177 y = 122; 178 z = 333; 179 } 180 } 181 C c_expect; 182 C c; 183 c_expect.x = 1; 184 c_expect.y = 122; 185 c_expect.z = 333; 186 binary_demarshaller.SetBuffer([0, 0, 0, 1]); 187 binary_demarshaller.Demarshal("test", c); 188 189 assert(c == c_expect); 190 191 //Read in multiple variables 192 int v1; 193 char[] s1; 194 int v2; 195 binary_demarshaller = new CompactBinaryDemarshaller; 196 binary_demarshaller.SetBuffer([0,0,0,1,0,0,0,3,'a','b','c',0,0,0,5]); 197 198 binary_demarshaller.Demarshal("", v1); 199 binary_demarshaller.Demarshal("", s1); 200 binary_demarshaller.Demarshal("", v2); 201 202 assert( v1 == 1 ); 203 assert( s1 == "abc" ); 204 assert( v2 == 5 ); 205 }