comparison orange/serialization/archives/XMLArchive.d @ 9:99c52d46822a

Serialization works now with D2, deserialization still doesn't work
author Jacob Carlborg <doob@me.com>
date Sat, 24 Jul 2010 18:58:18 +0200
parents ae24aae69a3b
children d17ae98330bf
comparison
equal deleted inserted replaced
8:613a0bb20207 9:99c52d46822a
6 */ 6 */
7 module orange.serialization.archives.XMLArchive; 7 module orange.serialization.archives.XMLArchive;
8 8
9 version (Tango) 9 version (Tango)
10 { 10 {
11 import tango.text.xml.DocPrinter; 11 /*import tango.text.xml.DocPrinter;
12 import tango.text.xml.Document; 12 import tango.text.xml.Document;*/
13 import tango.util.Convert : to; 13 import tango.util.Convert : to;
14 } 14 }
15 15
16 else
17 import std.conv;
18
16 import orange.serialization.archives._; 19 import orange.serialization.archives._;
17 import orange.util._; 20 import orange.util._;
21 import orange.xml.XMLDocument;
18 22
19 private enum ArchiveMode 23 private enum ArchiveMode
20 { 24 {
21 archiving, 25 archiving,
22 unarchiving 26 unarchiving
58 private 62 private
59 { 63 {
60 DataType archiveType = "org.dsource.orange.xml"; 64 DataType archiveType = "org.dsource.orange.xml";
61 DataType archiveVersion = "0.1"; 65 DataType archiveVersion = "0.1";
62 66
63 Document!(U) doc; 67 XMLDocument!(U) doc;
64 doc.Node lastElement; 68 doc.Node lastElement;
65 DocPrinter!(U) printer; 69 //DocPrinter!(U) printer;
66 doc.Node lastElementSaved; 70 doc.Node lastElementSaved;
67 71
68 bool hasBegunArchiving; 72 bool hasBegunArchiving;
69 bool hasBegunUnarchiving; 73 bool hasBegunUnarchiving;
70 74
74 size_t idCounter; 78 size_t idCounter;
75 } 79 }
76 80
77 this () 81 this ()
78 { 82 {
79 doc = new Document!(U); 83 doc = new XMLDocument!(U);
80 } 84 }
81 85
82 public void beginArchiving () 86 public void beginArchiving ()
83 { 87 {
84 if (!hasBegunArchiving) 88 if (!hasBegunArchiving)
85 { 89 {
86 doc.header; 90 doc.header;
87 lastElement = doc.tree.element(null, Tags.archiveTag) 91 lastElement = doc.tree.element(Tags.archiveTag)
88 .attribute(null, Attributes.typeAttribute, archiveType) 92 .attribute(Attributes.typeAttribute, archiveType)
89 .attribute(null, Attributes.versionAttribute, archiveVersion); 93 .attribute(Attributes.versionAttribute, archiveVersion);
90 lastElement = lastElement.element(null, Tags.dataTag); 94 lastElement = lastElement.element(Tags.dataTag);
91 95
92 hasBegunArchiving = true; 96 hasBegunArchiving = true;
93 } 97 }
94 } 98 }
95 99
113 } 117 }
114 } 118 }
115 119
116 public DataType data () 120 public DataType data ()
117 { 121 {
118 if (!printer) 122 /*if (!printer)
119 printer = new DocPrinter!(U); 123 printer = new DocPrinter!(U);
120 124
121 return printer.print(doc); 125 return printer.print(doc);*/
126
127 return doc.toString();
122 } 128 }
123 129
124 public void reset () 130 public void reset ()
125 { 131 {
126 hasBegunArchiving = false; 132 hasBegunArchiving = false;
184 190
185 private void archiveObject (T) (T value, DataType key, ref bool callDelegate) 191 private void archiveObject (T) (T value, DataType key, ref bool callDelegate)
186 { 192 {
187 if (!value) 193 if (!value)
188 { 194 {
189 lastElement.element(null, Tags.nullTag) 195 lastElement.element(Tags.nullTag)
190 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) 196 .attribute(Attributes.typeAttribute, toDataType(T.stringof))
191 .attribute(null, Attributes.keyAttribute, key); 197 .attribute(Attributes.keyAttribute, key);
192 callDelegate = false; 198 callDelegate = false;
193 } 199 }
194 200
195 else if (auto reference = getArchivedReference(value)) 201 else if (auto reference = getArchivedReference(value))
196 { 202 {
200 206
201 else 207 else
202 { 208 {
203 DataType id = nextId; 209 DataType id = nextId;
204 210
205 lastElement = lastElement.element(null, Tags.objectTag) 211 lastElement = lastElement.element(Tags.objectTag)
206 .attribute(null, Attributes.runtimeTypeAttribute, toDataType(value.classinfo.name)) 212 .attribute(Attributes.runtimeTypeAttribute, toDataType(value.classinfo.name))
207 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) 213 .attribute(Attributes.typeAttribute, toDataType(T.stringof))
208 .attribute(null, Attributes.keyAttribute, key) 214 .attribute(Attributes.keyAttribute, key)
209 .attribute(null, Attributes.idAttribute, id); 215 .attribute(Attributes.idAttribute, id);
210 216
211 addArchivedReference(value, id); 217 addArchivedReference(value, id);
212 } 218 }
213 } 219 }
214 220
215 private void archiveStruct (T) (T value, DataType key) 221 private void archiveStruct (T) (T value, DataType key)
216 { 222 {
217 lastElement = lastElement.element(null, Tags.structTag) 223 lastElement = lastElement.element(Tags.structTag)
218 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) 224 .attribute(Attributes.typeAttribute, toDataType(T.stringof))
219 .attribute(null, Attributes.keyAttribute, key); 225 .attribute(Attributes.keyAttribute, key);
220 } 226 }
221 227
222 private void archiveString (T) (T value, DataType key) 228 private void archiveString (T) (T value, DataType key)
223 { 229 {
224 lastElement.element(null, Tags.stringTag, toDataType(value)) 230 lastElement.element(Tags.stringTag, toDataType(value))
225 .attribute(null, Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof)) 231 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof))
226 .attribute(null, Attributes.keyAttribute, key); 232 .attribute(Attributes.keyAttribute, key);
227 } 233 }
228 234
229 private void archiveArray (T) (T value, DataType key) 235 private void archiveArray (T) (T value, DataType key)
230 { 236 {
231 lastElement = lastElement.element(null, Tags.arrayTag) 237 lastElement = lastElement.element(Tags.arrayTag)
232 .attribute(null, Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof)) 238 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof))
233 .attribute(null, Attributes.lengthAttribute, toDataType(value.length)) 239 .attribute(Attributes.lengthAttribute, toDataType(value.length))
234 .attribute(null, Attributes.keyAttribute, key); 240 .attribute(Attributes.keyAttribute, key);
235 } 241 }
236 242
237 private void archiveAssociativeArray (T) (T value, DataType key) 243 private void archiveAssociativeArray (T) (T value, DataType key)
238 { 244 {
239 lastElement = lastElement.element(null, Tags.associativeArrayTag) 245 lastElement = lastElement.element(Tags.associativeArrayTag)
240 .attribute(null, Attributes.keyTypeAttribute, toDataType(KeyTypeOfAssociativeArray!(T).stringof)) 246 .attribute(Attributes.keyTypeAttribute, toDataType(KeyTypeOfAssociativeArray!(T).stringof))
241 .attribute(null, Attributes.valueTypeAttribute, toDataType(ValueTypeOfAssociativeArray!(T).stringof)) 247 .attribute(Attributes.valueTypeAttribute, toDataType(ValueTypeOfAssociativeArray!(T).stringof))
242 .attribute(null, Attributes.lengthAttribute, toDataType(value.length)) 248 .attribute(Attributes.lengthAttribute, toDataType(value.length))
243 .attribute(null, Attributes.keyAttribute, key); 249 .attribute(Attributes.keyAttribute, key);
244 } 250 }
245 251
246 private void archivePointer (T) (T value, DataType key, ref bool callDelegate) 252 private void archivePointer (T) (T value, DataType key, ref bool callDelegate)
247 { 253 {
248 if (auto reference = getArchivedReference(value)) 254 if (auto reference = getArchivedReference(value))
253 259
254 else 260 else
255 { 261 {
256 DataType id = nextId; 262 DataType id = nextId;
257 263
258 lastElement = lastElement.element(null, Tags.pointerTag) 264 lastElement = lastElement.element(Tags.pointerTag)
259 .attribute(null, Attributes.keyAttribute, key) 265 .attribute(Attributes.keyAttribute, key)
260 .attribute(null, Attributes.idAttribute, id); 266 .attribute(Attributes.idAttribute, id);
261 267
262 addArchivedReference(value, id); 268 addArchivedReference(value, id);
263 } 269 }
264 } 270 }
265 271
266 private void archiveEnum (T) (T value, DataType key) 272 private void archiveEnum (T) (T value, DataType key)
267 { 273 {
268 lastElement.element(null, Tags.enumTag, toDataType(value)) 274 lastElement.element(Tags.enumTag, toDataType(value))
269 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) 275 .attribute(Attributes.typeAttribute, toDataType(T.stringof))
270 .attribute(null, Attributes.keyAttribute, key); 276 .attribute(Attributes.keyAttribute, key);
271 } 277 }
272 278
273 private void archivePrimitive (T) (T value, DataType key) 279 private void archivePrimitive (T) (T value, DataType key)
274 { 280 {
275 lastElement.element(null, toDataType(T.stringof), toDataType(value)) 281 lastElement.element(toDataType(T.stringof), toDataType(value))
276 .attribute(null, Attributes.keyAttribute, key); 282 .attribute(Attributes.keyAttribute, key);
277 } 283 }
278 284
279 private void archiveTypeDef (T) (T value, DataType key) 285 private void archiveTypeDef (T) (T value, DataType key)
280 { 286 {
281 lastElement = lastElement.element(null, Tags.typedefTag) 287 lastElement = lastElement.element(Tags.typedefTag)
282 .attribute(null, Attributes.typeAttribute, toDataType(BaseTypeOfTypeDef!(T).stringof)); 288 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfTypeDef!(T).stringof));
283 .attribute(null, Attributes.key, key); 289 .attribute(Attributes.key, key);
284 } 290 }
285 291
286 public T unarchive (T) (DataType key, T delegate (T) dg = null) 292 public T unarchive (T) (DataType key, T delegate (T) dg = null)
287 { 293 {
288 if (!hasBegunUnarchiving) 294 if (!hasBegunUnarchiving)
340 return *reference; 346 return *reference;
341 } 347 }
342 348
343 auto tmp = getElement(Tags.objectTag, key, Attributes.keyAttribute, false); 349 auto tmp = getElement(Tags.objectTag, key, Attributes.keyAttribute, false);
344 350
345 if (!tmp) 351 if (!tmp.isValid)
346 { 352 {
353 println(T.stringof);
354 println(key);
347 lastElement = getElement(Tags.nullTag, key); 355 lastElement = getElement(Tags.nullTag, key);
348 callDelegate = false; 356 callDelegate = false;
349 return null; 357 return null;
350 } 358 }
351 359
355 auto name = fromDataType!(string)(runtimeType); 363 auto name = fromDataType!(string)(runtimeType);
356 id = getValueOfAttribute(Attributes.idAttribute); 364 id = getValueOfAttribute(Attributes.idAttribute);
357 365
358 T result; 366 T result;
359 367
360 static if (is(typeof(T._ctor))) 368 /*static if (is(typeof(T._ctor)))
361 { 369 {
362 ParameterTupleOf!(typeof(T._ctor)) params; 370 ParameterTupleOf!(typeof(T._ctor)) params;
363 result = factory!(T, typeof(params))(name, params); 371 result = factory!(T, typeof(params))(name, params);
364 } 372 }
365 373
366 else 374 else*/
367 result = factory!(T)(name); 375 result = cast(T) newInstance(name);
368 376
369 addUnarchivedReference(result, id); 377 addUnarchivedReference(result, id);
370 378
371 return result; 379 return result;
372 } 380 }
443 return AssociativeArrayVisitor!(KeyTypeOfAssociativeArray!(T), ValueTypeOfAssociativeArray!(T))(this); 451 return AssociativeArrayVisitor!(KeyTypeOfAssociativeArray!(T), ValueTypeOfAssociativeArray!(T))(this);
444 } 452 }
445 453
446 public void archiveBaseClass (T : Object) (DataType key) 454 public void archiveBaseClass (T : Object) (DataType key)
447 { 455 {
448 lastElement = lastElement.element(null, Tags.baseTag) 456 lastElement = lastElement.element(Tags.baseTag)
449 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) 457 .attribute(Attributes.typeAttribute, toDataType(T.stringof))
450 .attribute(null, Attributes.keyAttribute, key); 458 .attribute(Attributes.keyAttribute, key);
451 } 459 }
452 460
453 public void unarchiveBaseClass (T : Object) (DataType key) 461 public void unarchiveBaseClass (T : Object) (DataType key)
454 { 462 {
455 lastElement = getElement(Tags.baseTag, key); 463 lastElement = getElement(Tags.baseTag, key);
456 } 464 }
457 465
458 template errorMessage (ArchiveMode mode = ArchiveMode.archiving) 466 version (Tango)
459 { 467 {
460 static if (mode == ArchiveMode.archiving) 468 template errorMessage (ArchiveMode mode = ArchiveMode.archiving)
461 const errorMessage = "Could not continue archiving due to unrecognized data format: "; 469 {
462 470 static if (mode == ArchiveMode.archiving)
463 else static if (mode == ArchiveMode.unarchiving) 471 const errorMessage = "Could not continue archiving due to unrecognized data format: ";
464 const errorMessage = "Could not continue unarchiving due to unrecognized data format: "; 472
473 else static if (mode == ArchiveMode.unarchiving)
474 const errorMessage = "Could not continue unarchiving due to unrecognized data format: ";
475 }
476 }
477
478 else
479 {
480 mixin(
481 `template errorMessage (ArchiveMode mode = ArchiveMode.archiving)
482 {
483 static if (mode == ArchiveMode.archiving)
484 enum errorMessage = "Could not continue archiving due to unrecognized data format: ";
485
486 else static if (mode == ArchiveMode.unarchiving)
487 enum errorMessage = "Could not continue unarchiving due to unrecognized data format: ";
488 }`
489 );
465 } 490 }
466 491
467 private doc.Node getElement (DataType tag, DataType key, DataType attribute = Attributes.keyAttribute, bool throwOnError = true) 492 private doc.Node getElement (DataType tag, DataType key, DataType attribute = Attributes.keyAttribute, bool throwOnError = true)
468 { 493 {
469 auto set = lastElement.query[tag].attribute((doc.Node node) { 494 auto set = lastElement.query[tag].attribute((doc.Node node) {
470 if (node.name == attribute && node.value == key) 495 if (node.name == attribute && node.value == key)
471 return true; 496 return true;
472 497
473 return false; 498 return false;
474 }); 499 });
478 503
479 else 504 else
480 { 505 {
481 if (throwOnError) 506 if (throwOnError)
482 { 507 {
483 if (set.nodes.length == 0) 508 if (set.nodes.length == 0)
484 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__); 509 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__);
485 510
486 else 511 else
487 throw new ArchiveException(`Could not unarchive the value with the key "` ~ to!(string)(key) ~ `" due to malformed data.`, __FILE__, __LINE__); 512 throw new ArchiveException(`Could not unarchive the value with the key "` ~ to!(string)(key) ~ `" due to malformed data.`, __FILE__, __LINE__);
488 } 513 }
489 514
490 return null; 515 return doc.Node.invalid;
491 } 516 }
492 } 517 }
493 518
494 private DataType getValueOfAttribute (DataType attribute) 519 private DataType getValueOfAttribute (DataType attribute)
495 { 520 {
540 return toDataType(idCounter++); 565 return toDataType(idCounter++);
541 } 566 }
542 567
543 private void archiveReference (DataType key, DataType id) 568 private void archiveReference (DataType key, DataType id)
544 { 569 {
545 lastElement.element(null, Tags.referenceTag, id) 570 lastElement.element(Tags.referenceTag, id)
546 .attribute(null, Attributes.keyAttribute, key); 571 .attribute(Attributes.keyAttribute, key);
547 } 572 }
548 573
549 private DataType unarchiveReference (DataType key) 574 private DataType unarchiveReference (DataType key)
550 { 575 {
551 auto element = getElement(Tags.referenceTag, key, Attributes.keyAttribute, false); 576 auto element = getElement(Tags.referenceTag, key, Attributes.keyAttribute, false);
552 577
553 if (element) 578 if (element.isValid)
554 return element.value; 579 return element.value;
555 580
556 return cast(DataType) null; 581 return cast(DataType) null;
557 } 582 }
558 583