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 }