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