comparison orange/serialization/archives/XMLArchive.d @ 29:c422ff6477dd experimental

Better handling of serializing pointers.
author Jacob Carlborg <doob@me.com>
date Sun, 21 Nov 2010 16:53:46 +0100
parents bffcbc8c392b
children 9d1a8023bb89
comparison
equal deleted inserted replaced
28:bffcbc8c392b 29:c422ff6477dd
55 static const Data valueTypeAttribute = "valueType"; 55 static const Data valueTypeAttribute = "valueType";
56 static const Data offsetAttribute = "offset"; 56 static const Data offsetAttribute = "offset";
57 static const Data baseTypeAttribute = "baseType"; 57 static const Data baseTypeAttribute = "baseType";
58 } 58 }
59 59
60 private struct ArrayNode 60 private struct Node
61 { 61 {
62 XMLDocument!(U).Node parent; 62 XMLDocument!(U).Node parent;
63 XMLDocument!(U).Node node; 63 XMLDocument!(U).Node node;
64 Id id; 64 Id id;
65 string key; 65 string key;
74 doc.Node lastElement; 74 doc.Node lastElement;
75 75
76 bool hasBegunArchiving; 76 bool hasBegunArchiving;
77 bool hasBegunUnarchiving; 77 bool hasBegunUnarchiving;
78 78
79 ArrayNode[Id] archivedArrays; 79 Node[Id] archivedArrays;
80 Node[Id] archivedPointers;
80 void[][Data] unarchivedSlices; 81 void[][Data] unarchivedSlices;
81 } 82 }
82 83
83 this (ErrorCallback errorCallback = null) 84 this (ErrorCallback errorCallback = null)
84 { 85 {
305 } 306 }
306 307
307 void archivePointer (string key, Id id, void delegate () dg) 308 void archivePointer (string key, Id id, void delegate () dg)
308 { 309 {
309 restore(lastElement) in { 310 restore(lastElement) in {
310 lastElement = lastElement.element(Tags.pointerTag) 311 auto parent = lastElement;
312 lastElement = doc.createNode(Tags.pointerTag);
313
314 lastElement.element(Tags.pointerTag)
311 .attribute(Attributes.keyAttribute, toData(key)) 315 .attribute(Attributes.keyAttribute, toData(key))
312 .attribute(Attributes.idAttribute, toData(id)); 316 .attribute(Attributes.idAttribute, toData(id));
313 317
318 addArchivedPointer(id, parent, lastElement, key);
314 dg(); 319 dg();
315 }; 320 };
321 }
322
323 void archivePointer (Id pointerId, Id pointeeId)
324 {
325 if (auto pointerNode = getArchivedPointer(pointerId))
326 {
327 pointerNode.parent.element(Tags.referenceTag, toData(pointeeId)).
328 attribute(Attributes.keyAttribute, toData(pointerNode.key));
329 }
316 } 330 }
317 331
318 void archiveReference (string key, Id id) 332 void archiveReference (string key, Id id)
319 { 333 {
320 lastElement.element(Tags.referenceTag, toData(id)) 334 lastElement.element(Tags.referenceTag, toData(id))
990 { 1004 {
991 if (auto array = getArchivedArray(id)) 1005 if (auto array = getArchivedArray(id))
992 array.parent.attach(array.node); 1006 array.parent.attach(array.node);
993 } 1007 }
994 1008
1009 void postProcessPointer (Id id)
1010 {
1011 if (auto pointer = getArchivedPointer(id))
1012 pointer.parent.attach(pointer.node);
1013 }
1014
995 private void addArchivedArray (Id id, doc.Node parent, doc.Node element, string key) 1015 private void addArchivedArray (Id id, doc.Node parent, doc.Node element, string key)
996 { 1016 {
997 archivedArrays[id] = ArrayNode(parent, element, id, key); 1017 archivedArrays[id] = Node(parent, element, id, key);
998 } 1018 }
999 1019
1000 private ArrayNode* getArchivedArray (Id id) 1020 private Node* getArchivedArray (Id id)
1001 { 1021 {
1002 if (auto array = id in archivedArrays) 1022 if (auto array = id in archivedArrays)
1003 return array; 1023 return array;
1004 1024
1005 errorCallback(new ArchiveException(`Could not continue archiving due to no array with the Id "` ~ to!(string)(id) ~ `" was found.`, __FILE__, __LINE__), [to!(string)(id)]); 1025 if (errorCallback)
1026 errorCallback(new ArchiveException(`Could not continue archiving due to no array with the Id "` ~ to!(string)(id) ~ `" was found.`, __FILE__, __LINE__), [to!(string)(id)]);
1027
1028 return null;
1029 }
1030
1031 private void addArchivedPointer (Id id, doc.Node parent, doc.Node element, string key)
1032 {
1033 archivedPointers[id] = Node(parent, element, id, key);
1034 }
1035
1036 private Node* getArchivedPointer (Id id)
1037 {
1038 if (auto pointer = id in archivedPointers)
1039 return pointer;
1040
1041 if (errorCallback)
1042 errorCallback(new ArchiveException(`Could not continue archiving due to no pointer with the Id "` ~ to!(string)(id) ~ `" was found.`, __FILE__, __LINE__), [to!(string)(id)]);
1006 1043
1007 return null; 1044 return null;
1008 } 1045 }
1009 1046
1010 private doc.Node getElement (Data tag, string k, Data attribute = Attributes.keyAttribute, bool throwOnError = true) 1047 private doc.Node getElement (Data tag, string k, Data attribute = Attributes.keyAttribute, bool throwOnError = true)