Mercurial > projects > orange
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) |