Mercurial > projects > orange
annotate orange/serialization/archives/XMLArchive.d @ 10:d17ae98330bf
Removed some left over debugging code
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Sat, 24 Jul 2010 19:37:45 +0200 |
parents | 99c52d46822a |
children | 27c5b6c5425f |
rev | line source |
---|---|
0 | 1 /** |
2 * Copyright: Copyright (c) 2010 Jacob Carlborg. | |
3 * Authors: Jacob Carlborg | |
4 * Version: Initial created: Jan 26, 2010 | |
5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) | |
6 */ | |
7 module orange.serialization.archives.XMLArchive; | |
8 | |
9 version (Tango) | |
10 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
11 /*import tango.text.xml.DocPrinter; |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
12 import tango.text.xml.Document;*/ |
0 | 13 import tango.util.Convert : to; |
14 } | |
15 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
16 else |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
17 import std.conv; |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
18 |
0 | 19 import orange.serialization.archives._; |
20 import orange.util._; | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
21 import orange.xml.XMLDocument; |
0 | 22 |
23 private enum ArchiveMode | |
24 { | |
25 archiving, | |
26 unarchiving | |
27 } | |
28 | |
29 class XMLArchive (U = char) : Archive!(U) | |
30 { | |
31 static assert (isChar!(U), format!(`The given type "`, U, `" is not a valid type. Valid types are: "char", "wchar" and "dchar".`)); | |
32 | |
33 private struct Tags | |
34 { | |
35 static const DataType structTag = "struct"; | |
36 static const DataType dataTag = "data"; | |
37 static const DataType archiveTag = "archive"; | |
38 static const DataType arrayTag = "array"; | |
39 static const DataType objectTag = "object"; | |
40 static const DataType baseTag = "base"; | |
41 static const DataType stringTag = "string"; | |
42 static const DataType referenceTag = "reference"; | |
43 static const DataType pointerTag = "pointer"; | |
44 static const DataType associativeArrayTag = "associativeArray"; | |
45 static const DataType typedefTag = "typedef"; | |
46 static const DataType nullTag = "null"; | |
47 static const DataType enumTag = "enum"; | |
48 } | |
49 | |
50 private struct Attributes | |
51 { | |
52 static const DataType typeAttribute = "type"; | |
53 static const DataType versionAttribute = "version"; | |
54 static const DataType lengthAttribute = "length"; | |
55 static const DataType keyAttribute = "key"; | |
56 static const DataType runtimeTypeAttribute = "runtimeType"; | |
57 static const DataType idAttribute = "id"; | |
58 static const DataType keyTypeAttribute = "keyType"; | |
59 static const DataType valueTypeAttribute = "valueType"; | |
60 } | |
61 | |
62 private | |
63 { | |
64 DataType archiveType = "org.dsource.orange.xml"; | |
65 DataType archiveVersion = "0.1"; | |
66 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
67 XMLDocument!(U) doc; |
0 | 68 doc.Node lastElement; |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
69 //DocPrinter!(U) printer; |
0 | 70 doc.Node lastElementSaved; |
71 | |
72 bool hasBegunArchiving; | |
73 bool hasBegunUnarchiving; | |
74 | |
75 DataType[void*] archivedReferences; | |
76 void*[DataType] unarchivedReferences; | |
77 | |
78 size_t idCounter; | |
79 } | |
80 | |
81 this () | |
82 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
83 doc = new XMLDocument!(U); |
0 | 84 } |
85 | |
86 public void beginArchiving () | |
87 { | |
88 if (!hasBegunArchiving) | |
89 { | |
90 doc.header; | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
91 lastElement = doc.tree.element(Tags.archiveTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
92 .attribute(Attributes.typeAttribute, archiveType) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
93 .attribute(Attributes.versionAttribute, archiveVersion); |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
94 lastElement = lastElement.element(Tags.dataTag); |
0 | 95 |
96 hasBegunArchiving = true; | |
97 } | |
98 } | |
99 | |
100 public void beginUnarchiving (DataType data) | |
101 { | |
102 if (!hasBegunUnarchiving) | |
103 { | |
104 doc.parse(data); | |
105 hasBegunUnarchiving = true; | |
106 | |
107 auto set = doc.query[Tags.archiveTag][Tags.dataTag]; | |
108 | |
109 if (set.nodes.length == 1) | |
110 lastElement = set.nodes[0]; | |
111 | |
112 else if (set.nodes.length == 0) | |
113 throw new ArchiveException(errorMessage!(ArchiveMode.unarchiving) ~ `The "` ~ to!(string)(Tags.dataTag) ~ `" tag could not be found.`, __FILE__, __LINE__); | |
114 | |
115 else | |
116 throw new ArchiveException(errorMessage!(ArchiveMode.unarchiving) ~ `There were more than one "` ~ to!(string)(Tags.dataTag) ~ `" tag.`, __FILE__, __LINE__); | |
117 } | |
118 } | |
119 | |
120 public DataType data () | |
121 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
122 /*if (!printer) |
0 | 123 printer = new DocPrinter!(U); |
124 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
125 return printer.print(doc);*/ |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
126 |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
127 return doc.toString(); |
0 | 128 } |
129 | |
130 public void reset () | |
131 { | |
132 hasBegunArchiving = false; | |
133 hasBegunUnarchiving = false; | |
134 idCounter = 0; | |
135 doc.reset; | |
136 } | |
137 | |
138 private void begin () | |
139 { | |
140 lastElementSaved = lastElement; | |
141 } | |
142 | |
143 private void end () | |
144 { | |
145 lastElement = lastElementSaved; | |
146 } | |
147 | |
148 public void archive (T) (T value, DataType key, void delegate () dg = null) | |
149 { | |
150 if (!hasBegunArchiving) | |
151 beginArchiving(); | |
152 | |
153 restore(lastElement) in { | |
154 bool callDelegate = true; | |
155 | |
156 static if (isTypeDef!(T)) | |
157 archiveTypeDef(value, key); | |
158 | |
159 else static if (isObject!(T)) | |
160 archiveObject(value, key, callDelegate); | |
161 | |
162 else static if (isStruct!(T)) | |
163 archiveStruct(value, key); | |
164 | |
165 else static if (isString!(T)) | |
166 archiveString(value, key); | |
167 | |
168 else static if (isArray!(T)) | |
169 archiveArray(value, key); | |
170 | |
171 else static if (isAssociativeArray!(T)) | |
172 archiveAssociativeArray(value, key); | |
173 | |
174 else static if (isPrimitive!(T)) | |
175 archivePrimitive(value, key); | |
176 | |
177 else static if (isPointer!(T)) | |
178 archivePointer(value, key, callDelegate); | |
179 | |
180 else static if (isEnum!(T)) | |
181 archiveEnum(value, key); | |
182 | |
183 else | |
184 static assert(false, format!(`The type "`, T, `" cannot be archived.`)); | |
185 | |
186 if (callDelegate && dg) | |
187 dg(); | |
188 }; | |
189 } | |
190 | |
191 private void archiveObject (T) (T value, DataType key, ref bool callDelegate) | |
192 { | |
193 if (!value) | |
194 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
195 lastElement.element(Tags.nullTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
196 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
197 .attribute(Attributes.keyAttribute, key); |
0 | 198 callDelegate = false; |
199 } | |
200 | |
201 else if (auto reference = getArchivedReference(value)) | |
202 { | |
203 archiveReference(key, reference); | |
204 callDelegate = false; | |
205 } | |
206 | |
207 else | |
208 { | |
209 DataType id = nextId; | |
210 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
211 lastElement = lastElement.element(Tags.objectTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
212 .attribute(Attributes.runtimeTypeAttribute, toDataType(value.classinfo.name)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
213 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
214 .attribute(Attributes.keyAttribute, key) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
215 .attribute(Attributes.idAttribute, id); |
0 | 216 |
217 addArchivedReference(value, id); | |
218 } | |
219 } | |
220 | |
221 private void archiveStruct (T) (T value, DataType key) | |
222 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
223 lastElement = lastElement.element(Tags.structTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
224 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
225 .attribute(Attributes.keyAttribute, key); |
0 | 226 } |
227 | |
228 private void archiveString (T) (T value, DataType key) | |
229 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
230 lastElement.element(Tags.stringTag, toDataType(value)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
231 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
232 .attribute(Attributes.keyAttribute, key); |
0 | 233 } |
234 | |
235 private void archiveArray (T) (T value, DataType key) | |
236 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
237 lastElement = lastElement.element(Tags.arrayTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
238 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
239 .attribute(Attributes.lengthAttribute, toDataType(value.length)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
240 .attribute(Attributes.keyAttribute, key); |
0 | 241 } |
242 | |
243 private void archiveAssociativeArray (T) (T value, DataType key) | |
244 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
245 lastElement = lastElement.element(Tags.associativeArrayTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
246 .attribute(Attributes.keyTypeAttribute, toDataType(KeyTypeOfAssociativeArray!(T).stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
247 .attribute(Attributes.valueTypeAttribute, toDataType(ValueTypeOfAssociativeArray!(T).stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
248 .attribute(Attributes.lengthAttribute, toDataType(value.length)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
249 .attribute(Attributes.keyAttribute, key); |
0 | 250 } |
251 | |
252 private void archivePointer (T) (T value, DataType key, ref bool callDelegate) | |
253 { | |
254 if (auto reference = getArchivedReference(value)) | |
255 { | |
256 archiveReference(key, reference); | |
257 callDelegate = false; | |
258 } | |
259 | |
260 else | |
261 { | |
262 DataType id = nextId; | |
263 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
264 lastElement = lastElement.element(Tags.pointerTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
265 .attribute(Attributes.keyAttribute, key) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
266 .attribute(Attributes.idAttribute, id); |
0 | 267 |
268 addArchivedReference(value, id); | |
269 } | |
270 } | |
271 | |
272 private void archiveEnum (T) (T value, DataType key) | |
273 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
274 lastElement.element(Tags.enumTag, toDataType(value)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
275 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
276 .attribute(Attributes.keyAttribute, key); |
0 | 277 } |
278 | |
279 private void archivePrimitive (T) (T value, DataType key) | |
280 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
281 lastElement.element(toDataType(T.stringof), toDataType(value)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
282 .attribute(Attributes.keyAttribute, key); |
0 | 283 } |
284 | |
285 private void archiveTypeDef (T) (T value, DataType key) | |
286 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
287 lastElement = lastElement.element(Tags.typedefTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
288 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfTypeDef!(T).stringof)); |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
289 .attribute(Attributes.key, key); |
0 | 290 } |
291 | |
292 public T unarchive (T) (DataType key, T delegate (T) dg = null) | |
293 { | |
294 if (!hasBegunUnarchiving) | |
295 beginUnarchiving(data); | |
296 | |
297 return restore!(T)(lastElement) in { | |
298 T value; | |
299 | |
300 bool callDelegate = true; | |
301 | |
302 static if (isTypeDef!(T)) | |
303 value = unarchiveTypeDef!(T)(key); | |
304 | |
305 else static if (isObject!(T)) | |
306 value = unarchiveObject!(T)(key, callDelegate); | |
307 | |
308 else static if (isStruct!(T)) | |
309 value = unarchiveStruct!(T)(key); | |
310 | |
311 else static if (isString!(T)) | |
312 value = unarchiveString!(T)(key); | |
313 | |
314 else static if (isArray!(T)) | |
315 value = unarchiveArray!(T)(key); | |
316 | |
317 else static if (isAssociativeArray!(T)) | |
318 value = unarchiveAssociativeArray!(T)(key); | |
319 | |
320 else static if (isPrimitive!(T)) | |
321 value = unarchivePrimitive!(T)(key); | |
322 | |
323 else static if (isPointer!(T)) | |
324 value = unarchivePointer!(T)(key, callDelegate); | |
325 | |
326 else static if (isEnum!(T)) | |
327 value = unarchiveEnum!(T)(key); | |
328 | |
329 else | |
330 static assert(false, format!(`The type "`, T, `" cannot be unarchived.`)); | |
331 | |
332 if (callDelegate && dg) | |
333 return dg(value); | |
334 | |
335 return value; | |
336 }; | |
337 } | |
338 | |
339 private T unarchiveObject (T) (DataType key, ref bool callDelegate) | |
340 { | |
341 DataType id = unarchiveReference(key); | |
342 | |
343 if (auto reference = getUnarchivedReference!(T)(id)) | |
344 { | |
345 callDelegate = false; | |
346 return *reference; | |
347 } | |
348 | |
349 auto tmp = getElement(Tags.objectTag, key, Attributes.keyAttribute, false); | |
350 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
351 if (!tmp.isValid) |
0 | 352 { |
353 lastElement = getElement(Tags.nullTag, key); | |
354 callDelegate = false; | |
355 return null; | |
356 } | |
357 | |
358 lastElement = tmp; | |
359 | |
360 auto runtimeType = getValueOfAttribute(Attributes.runtimeTypeAttribute); | |
361 auto name = fromDataType!(string)(runtimeType); | |
362 id = getValueOfAttribute(Attributes.idAttribute); | |
363 | |
364 T result; | |
365 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
366 /*static if (is(typeof(T._ctor))) |
0 | 367 { |
368 ParameterTupleOf!(typeof(T._ctor)) params; | |
369 result = factory!(T, typeof(params))(name, params); | |
370 } | |
371 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
372 else*/ |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
373 result = cast(T) newInstance(name); |
0 | 374 |
375 addUnarchivedReference(result, id); | |
376 | |
377 return result; | |
378 } | |
379 | |
380 private T unarchiveStruct (T) (DataType key) | |
381 { | |
382 lastElement = getElement(Tags.structTag, key); | |
383 | |
384 return T.init; | |
385 } | |
386 | |
387 private T unarchiveString (T) (DataType key) | |
388 { | |
389 return fromDataType!(T)(getElement(Tags.stringTag, key).value); | |
390 } | |
391 | |
392 private T unarchiveArray (T) (DataType key) | |
393 { | |
394 T value; | |
395 | |
396 lastElement = getElement(Tags.arrayTag, key); | |
397 auto length = getValueOfAttribute(Attributes.lengthAttribute); | |
398 value.length = fromDataType!(size_t)(length); | |
399 | |
400 return value; | |
401 } | |
402 | |
403 private T unarchiveAssociativeArray (T) (DataType key) | |
404 { | |
405 lastElement = getElement(Tags.associativeArrayTag, key); | |
406 | |
407 return T.init; | |
408 } | |
409 | |
410 private T unarchivePointer (T) (DataType key, ref bool callDelegate) | |
411 { | |
412 DataType id = unarchiveReference(key); | |
413 | |
414 if (auto reference = getUnarchivedReference!(T)(id)) | |
415 { | |
416 callDelegate = false; | |
417 return *reference; | |
418 } | |
419 | |
420 lastElement = getElement(Tags.pointerTag, key); | |
421 id = getValueOfAttribute(Attributes.idAttribute); | |
422 | |
423 T result = new BaseTypeOfPointer!(T); | |
424 | |
425 addUnarchivedReference(result, id); | |
426 | |
427 return result; | |
428 } | |
429 | |
430 private T unarchiveEnum (T) (DataType key) | |
431 { | |
432 return fromDataType!(T)(getElement(Tags.enumTag, key).value); | |
433 } | |
434 | |
435 private T unarchivePrimitive (T) (DataType key) | |
436 { | |
437 return fromDataType!(T)(getElement(toDataType(T.stringof), key).value); | |
438 } | |
439 | |
440 private T unarchiveTypeDef (T) (DataType key) | |
441 { | |
442 lastElement = getElement(Tags.typedefTag, key); | |
443 | |
444 return T.init; | |
445 } | |
446 | |
447 public AssociativeArrayVisitor!(KeyTypeOfAssociativeArray!(T), ValueTypeOfAssociativeArray!(T)) unarchiveAssociativeArrayVisitor (T) () | |
448 { | |
449 return AssociativeArrayVisitor!(KeyTypeOfAssociativeArray!(T), ValueTypeOfAssociativeArray!(T))(this); | |
450 } | |
451 | |
452 public void archiveBaseClass (T : Object) (DataType key) | |
453 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
454 lastElement = lastElement.element(Tags.baseTag) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
455 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
456 .attribute(Attributes.keyAttribute, key); |
0 | 457 } |
458 | |
459 public void unarchiveBaseClass (T : Object) (DataType key) | |
460 { | |
461 lastElement = getElement(Tags.baseTag, key); | |
462 } | |
463 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
464 version (Tango) |
0 | 465 { |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
466 template errorMessage (ArchiveMode mode = ArchiveMode.archiving) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
467 { |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
468 static if (mode == ArchiveMode.archiving) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
469 const errorMessage = "Could not continue archiving due to unrecognized data format: "; |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
470 |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
471 else static if (mode == ArchiveMode.unarchiving) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
472 const errorMessage = "Could not continue unarchiving due to unrecognized data format: "; |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
473 } |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
474 } |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
475 |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
476 else |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
477 { |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
478 mixin( |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
479 `template errorMessage (ArchiveMode mode = ArchiveMode.archiving) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
480 { |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
481 static if (mode == ArchiveMode.archiving) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
482 enum errorMessage = "Could not continue archiving due to unrecognized data format: "; |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
483 |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
484 else static if (mode == ArchiveMode.unarchiving) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
485 enum errorMessage = "Could not continue unarchiving due to unrecognized data format: "; |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
486 }` |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
487 ); |
0 | 488 } |
489 | |
490 private doc.Node getElement (DataType tag, DataType key, DataType attribute = Attributes.keyAttribute, bool throwOnError = true) | |
491 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
492 auto set = lastElement.query[tag].attribute((doc.Node node) { |
0 | 493 if (node.name == attribute && node.value == key) |
494 return true; | |
495 | |
496 return false; | |
497 }); | |
498 | |
499 if (set.nodes.length == 1) | |
500 return set.nodes[0].parent; | |
501 | |
502 else | |
503 { | |
504 if (throwOnError) | |
505 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
506 if (set.nodes.length == 0) |
0 | 507 throw new ArchiveException(`Could not find an element "` ~ to!(string)(tag) ~ `" with the attribute "` ~ to!(string)(Attributes.keyAttribute) ~ `" with the value "` ~ to!(string)(key) ~ `".`, __FILE__, __LINE__); |
508 | |
509 else | |
510 throw new ArchiveException(`Could not unarchive the value with the key "` ~ to!(string)(key) ~ `" due to malformed data.`, __FILE__, __LINE__); | |
511 } | |
512 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
513 return doc.Node.invalid; |
0 | 514 } |
515 } | |
516 | |
517 private DataType getValueOfAttribute (DataType attribute) | |
518 { | |
519 auto set = lastElement.query.attribute(attribute); | |
520 | |
521 if (set.nodes.length == 1) | |
522 return set.nodes[0].value; | |
523 | |
524 else if (set.nodes.length == 0) | |
525 throw new ArchiveException(`Could not find the attribute "` ~ to!(string)(attribute) ~ `".`, __FILE__, __LINE__); | |
526 | |
527 else | |
528 throw new ArchiveException(`Could not unarchive the value of the attribute "` ~ to!(string)(attribute) ~ `" due to malformed data.`, __FILE__, __LINE__); | |
529 } | |
530 | |
531 private void addArchivedReference (T) (T value, DataType id) | |
532 { | |
533 static assert(isReference!(T), format!(`The given type "`, T, `" is not a reference type, i.e. object or pointer.`)); | |
534 | |
535 archivedReferences[cast(void*) value] = id; | |
536 } | |
537 | |
538 private void addUnarchivedReference (T) (T value, DataType id) | |
539 { | |
540 static assert(isReference!(T), format!(`The given type "`, T, `" is not a reference type, i.e. object or pointer.`)); | |
541 | |
542 unarchivedReferences[id] = cast(void*) value; | |
543 } | |
544 | |
545 private DataType getArchivedReference (T) (T value) | |
546 { | |
547 if (auto tmp = cast(void*) value in archivedReferences) | |
548 return *tmp; | |
549 | |
550 return null; | |
551 } | |
552 | |
553 private T* getUnarchivedReference (T) (DataType id) | |
554 { | |
555 if (auto reference = id in unarchivedReferences) | |
556 return cast(T*) reference; | |
557 | |
558 return null; | |
559 } | |
560 | |
561 private DataType nextId () | |
562 { | |
563 return toDataType(idCounter++); | |
564 } | |
565 | |
566 private void archiveReference (DataType key, DataType id) | |
567 { | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
568 lastElement.element(Tags.referenceTag, id) |
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
569 .attribute(Attributes.keyAttribute, key); |
0 | 570 } |
571 | |
572 private DataType unarchiveReference (DataType key) | |
573 { | |
574 auto element = getElement(Tags.referenceTag, key, Attributes.keyAttribute, false); | |
575 | |
9
99c52d46822a
Serialization works now with D2, deserialization still doesn't work
Jacob Carlborg <doob@me.com>
parents:
6
diff
changeset
|
576 if (element.isValid) |
0 | 577 return element.value; |
578 | |
579 return cast(DataType) null; | |
580 } | |
581 | |
6 | 582 private struct AssociativeArrayVisitor (Key, Value) |
0 | 583 { |
584 private XMLArchive archive; | |
585 | |
586 static AssociativeArrayVisitor opCall (XMLArchive archive) | |
587 { | |
588 AssociativeArrayVisitor aai; | |
589 aai.archive = archive; | |
590 | |
591 return aai; | |
592 } | |
593 | |
594 int opApply(int delegate(ref Key, ref Value) dg) | |
595 { | |
596 int result; | |
597 | |
598 foreach (node ; archive.lastElement.children) | |
599 { | |
600 restore(archive.lastElement) in { | |
601 archive.lastElement = node; | |
602 | |
603 if (node.attributes.exist) | |
604 { | |
605 Key key = to!(Key)(archive.getValueOfAttribute(Attributes.keyAttribute)); | |
606 Value value = to!(Value)(node.value); | |
607 | |
608 result = dg(key, value); | |
609 } | |
610 }; | |
611 | |
612 if (result) | |
613 break; | |
614 } | |
615 | |
616 return result; | |
617 } | |
618 } | |
619 } |