diff 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
line wrap: on
line diff
--- a/orange/serialization/archives/XMLArchive.d	Fri Nov 19 11:55:04 2010 +0100
+++ b/orange/serialization/archives/XMLArchive.d	Sun Nov 21 16:53:46 2010 +0100
@@ -57,7 +57,7 @@
 		static const Data baseTypeAttribute = "baseType";
 	}
 	
-	private struct ArrayNode
+	private struct Node
 	{
 		XMLDocument!(U).Node parent;
 		XMLDocument!(U).Node node;
@@ -76,7 +76,8 @@
 		bool hasBegunArchiving;
 		bool hasBegunUnarchiving;
 		
-		ArrayNode[Id] archivedArrays;
+		Node[Id] archivedArrays;
+		Node[Id] archivedPointers;
 		void[][Data] unarchivedSlices;
 	}
 	
@@ -307,14 +308,27 @@
 	void archivePointer (string key, Id id, void delegate () dg)
 	{
 		restore(lastElement) in {
-			lastElement = lastElement.element(Tags.pointerTag)
+			auto parent = lastElement;
+			lastElement = doc.createNode(Tags.pointerTag);
+			
+			lastElement.element(Tags.pointerTag)
 			.attribute(Attributes.keyAttribute, toData(key))
 			.attribute(Attributes.idAttribute, toData(id));
 			
+			addArchivedPointer(id, parent, lastElement, key);			
 			dg();
 		};
 	}
 	
+	void archivePointer (Id pointerId, Id pointeeId)
+	{
+		if (auto pointerNode = getArchivedPointer(pointerId))
+		{
+			pointerNode.parent.element(Tags.referenceTag, toData(pointeeId)).
+			attribute(Attributes.keyAttribute, toData(pointerNode.key));
+		}
+	}
+	
 	void archiveReference (string key, Id id)
 	{
 		lastElement.element(Tags.referenceTag, toData(id))
@@ -992,17 +1006,40 @@
 			array.parent.attach(array.node);
 	}
 	
+	void postProcessPointer (Id id)
+	{
+		if (auto pointer = getArchivedPointer(id))
+			pointer.parent.attach(pointer.node);
+	}
+	
 	private void addArchivedArray (Id id, doc.Node parent, doc.Node element, string key)
 	{
-		archivedArrays[id] = ArrayNode(parent, element, id, key);
+		archivedArrays[id] = Node(parent, element, id, key);
 	}
 	
-	private ArrayNode* getArchivedArray (Id id)
+	private Node* getArchivedArray (Id id)
 	{
 		if (auto array = id in archivedArrays)
 			return array;
 
-		errorCallback(new ArchiveException(`Could not continue archiving due to no array with the Id "` ~ to!(string)(id) ~ `" was found.`, __FILE__, __LINE__), [to!(string)(id)]);
+		if (errorCallback)
+			errorCallback(new ArchiveException(`Could not continue archiving due to no array with the Id "` ~ to!(string)(id) ~ `" was found.`, __FILE__, __LINE__), [to!(string)(id)]);
+		
+		return null;
+	}
+	
+	private void addArchivedPointer (Id id, doc.Node parent, doc.Node element, string key)
+	{
+		archivedPointers[id] = Node(parent, element, id, key);
+	}
+	
+	private Node* getArchivedPointer (Id id)
+	{
+		if (auto pointer = id in archivedPointers)
+			return pointer;
+
+		if (errorCallback)
+			errorCallback(new ArchiveException(`Could not continue archiving due to no pointer with the Id "` ~ to!(string)(id) ~ `" was found.`, __FILE__, __LINE__), [to!(string)(id)]);
 		
 		return null;
 	}