changeset 18:3d42ea434d46

Added an error callback. Fixes #3 and #4.
author Jacob Carlborg <doob@me.com>
date Thu, 12 Aug 2010 23:24:51 +0200
parents c4e7e64ffb67
children 8ab9588b92bf 9a575087b961
files orange/serialization/Serializer.d orange/serialization/archives/Archive.d orange/serialization/archives/XMLArchive.d
diffstat 3 files changed, 106 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/orange/serialization/Serializer.d	Sun Aug 08 21:59:59 2010 +0200
+++ b/orange/serialization/Serializer.d	Thu Aug 12 23:24:51 2010 +0200
@@ -37,10 +37,12 @@
 {
 	static assert(isArchive!(ArchiveType), format!(`The type "`, ArchiveType, `" does not implement the necessary methods to be an archive.`));
 	
+	alias ArchiveType.ErrorCallback ErrorCallback;
+	alias ArchiveType.DataType DataType;
+	
 	private
 	{
 		ArchiveType archive;
-		alias ArchiveType.DataType DataType;
 		
 		RegisterBase[string] serializers;
 		RegisterBase[string] deserializers;
@@ -49,11 +51,19 @@
 		
 		bool hasBegunSerializing;
 		bool hasBegunDeserializing;
+		
+		void delegate (ArchiveException exception, DataType[] data) throwOnErrorCallback;		
+		void delegate (ArchiveException exception, DataType[] data) doNothingOnErrorCallback;
 	}
 	
 	this ()
 	{
 		archive = new ArchiveType;
+		
+		throwOnErrorCallback = (ArchiveException exception, DataType[] data) { throw exception; };
+		doNothingOnErrorCallback = (ArchiveException exception, DataType[] data) { /* do nothing */ };
+		
+		setThrowOnErrorCallback();
 	}
 
 	void registerSerializer (T) (string type, void delegate (T, Serializer, DataType) dg)
@@ -85,6 +95,26 @@
 		archive.reset;
 	}
 	
+	ErrorCallback errorCallback ()
+	{
+		return archive.errorCallback;
+	}
+	
+	ErrorCallback errorCallback (ErrorCallback errorCallback)
+	{
+		return archive.errorCallback = errorCallback;
+	}
+	
+	void setThrowOnErrorCallback ()
+	{
+		errorCallback = throwOnErrorCallback;
+	}
+	
+	void setDoNothingOnErrorCallback ()
+	{
+		errorCallback = doNothingOnErrorCallback;
+	}
+	
 	DataType serialize (T) (T value, DataType key = null)
 	{
 		if (!hasBegunSerializing)
--- a/orange/serialization/archives/Archive.d	Sun Aug 08 21:59:59 2010 +0200
+++ b/orange/serialization/archives/Archive.d	Thu Aug 12 23:24:51 2010 +0200
@@ -28,6 +28,10 @@
 	version (Tango) alias U[] DataType;
 	else mixin ("alias immutable(U)[] DataType;");
 	
+	alias void delegate (ArchiveException exception, DataType[] data) ErrorCallback;
+	
+	ErrorCallback errorCallback;
+	
 	abstract void beginArchiving ();
 	abstract void beginUnarchiving (DataType data);
 	abstract DataType data ();
@@ -49,5 +53,5 @@
 		
 		catch (ConversionException e)
 			throw new ArchiveException(e);
-	}
+	}	
 }
\ No newline at end of file
--- a/orange/serialization/archives/XMLArchive.d	Sun Aug 08 21:59:59 2010 +0200
+++ b/orange/serialization/archives/XMLArchive.d	Thu Aug 12 23:24:51 2010 +0200
@@ -105,11 +105,17 @@
 			if (set.nodes.length == 1)
 				lastElement = set.nodes[0];
 			
-			else if (set.nodes.length == 0)
-				throw new ArchiveException(errorMessage!(ArchiveMode.unarchiving) ~ `The "` ~ to!(string)(Tags.dataTag) ~ `" tag could not be found.`, __FILE__, __LINE__);
-			
 			else
-				throw new ArchiveException(errorMessage!(ArchiveMode.unarchiving) ~ `There were more than one "` ~ to!(string)(Tags.dataTag) ~ `" tag.`, __FILE__, __LINE__);
+			{
+				if (errorCallback)
+				{
+					if (set.nodes.length == 0)
+						errorCallback(new ArchiveException(errorMessage!(ArchiveMode.unarchiving) ~ `The "` ~ to!(string)(Tags.dataTag) ~ `" tag could not be found.`, __FILE__, __LINE__), [Tags.dataTag]);
+					
+					else
+						errorCallback(new ArchiveException(errorMessage!(ArchiveMode.unarchiving) ~ `There were more than one "` ~ to!(string)(Tags.dataTag) ~ `" tag.`, __FILE__, __LINE__), [Tags.dataTag]);
+				}	
+			}
 		}
 	}
 	
@@ -350,7 +356,7 @@
 			callDelegate = false;
 			return null;
 		}
-		
+	
 		lastElement = tmp;
 		
 		auto runtimeType = getValueOfAttribute(Attributes.runtimeTypeAttribute);
@@ -375,21 +381,34 @@
 
 	private T unarchiveStruct (T) (DataType key)
 	{
-		lastElement = getElement(Tags.structTag, key);
+		auto element = getElement(Tags.structTag, key);
+		
+		if (element.isValid)
+			lastElement = element;
 		
 		return T.init;
 	}
 	
 	private T unarchiveString (T) (DataType key)
 	{
-		return fromDataType!(T)(getElement(Tags.stringTag, key).value);
+		auto element = getElement(Tags.stringTag, key);
+		
+		if (!element.isValid)
+			return T.init;			
+			
+		return fromDataType!(T)(element.value);
 	}
 
 	private T unarchiveArray (T) (DataType key)
 	{			
 		T value;
 		
-		lastElement = getElement(Tags.arrayTag, key);
+		auto element = getElement(Tags.arrayTag, key);
+		
+		if (!element.isValid)
+			return T.init;
+		
+		lastElement = element;
 		auto length = getValueOfAttribute(Attributes.lengthAttribute);
 		value.length = fromDataType!(size_t)(length);
 		
@@ -398,7 +417,10 @@
 
 	private T unarchiveAssociativeArray (T) (DataType key)
 	{		
-		lastElement = getElement(Tags.associativeArrayTag, key);
+		auto element = getElement(Tags.associativeArrayTag, key);
+		
+		if (element.isValid)		
+			lastElement = element;
 		
 		return T.init;
 	}
@@ -412,8 +434,13 @@
 			callDelegate = false;
 			return *reference;
 		}
+		
+		auto element = getElement(Tags.pointerTag, key);
+		
+		if (!element.isValid)
+			return T.init;
 
-		lastElement = getElement(Tags.pointerTag, key);
+		lastElement = element; 
 		id = getValueOfAttribute(Attributes.idAttribute);
 				
 		T result = new BaseTypeOfPointer!(T);
@@ -425,17 +452,30 @@
 	
 	private T unarchiveEnum (T) (DataType key)
 	{
-		return fromDataType!(T)(getElement(Tags.enumTag, key).value);
+		auto element = getElement(Tags.enumTag, key);
+		
+		if (!element.isValid)
+			return T.init;
+		
+		return fromDataType!(T)(element.value);
 	}
 
 	private T unarchivePrimitive (T) (DataType key)
 	{		
-		return fromDataType!(T)(getElement(toDataType(T.stringof), key).value);
+		auto element = getElement(toDataType(T.stringof), key);
+		
+		if (!element.isValid)
+			return T.init;
+		
+		return fromDataType!(T)(element.value);
 	}
 	
 	private T unarchiveTypeDef (T) (DataType key)
 	{
-		lastElement = getElement(Tags.typedefTag, key);
+		auto element = getElement(Tags.typedefTag, key);
+		
+		if (element.isValid)
+			lastElement = element;
 		
 		return T.init;
 	}
@@ -454,7 +494,10 @@
 	
 	public void unarchiveBaseClass (T : Object) (DataType key)
 	{
-		lastElement = getElement(Tags.baseTag, key);
+		auto element = getElement(Tags.baseTag, key);
+		
+		if (element.isValid)
+			lastElement = element;
 	}
 	
 	version (Tango)
@@ -497,13 +540,13 @@
 		
 		else
 		{
-			if (throwOnError)
+			if (throwOnError && errorCallback)
 			{
 				if (set.nodes.length == 0)					
-					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__);
+					errorCallback(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__), [tag, Attributes.keyAttribute, key]);
 				
 				else
-					throw new ArchiveException(`Could not unarchive the value with the key "` ~ to!(string)(key) ~ `" due to malformed data.`, __FILE__, __LINE__);
+					errorCallback(new ArchiveException(`Could not unarchive the value with the key "` ~ to!(string)(key) ~ `" due to malformed data.`, __FILE__, __LINE__), [tag, Attributes.keyAttribute, key]);
 			}
 
 			return doc.Node.invalid;
@@ -517,11 +560,17 @@
 		if (set.nodes.length == 1)
 			return set.nodes[0].value;
 		
-		else if (set.nodes.length == 0)
-			throw new ArchiveException(`Could not find the attribute "` ~ to!(string)(attribute) ~ `".`, __FILE__, __LINE__);
-		
 		else
-			throw new ArchiveException(`Could not unarchive the value of the attribute "` ~ to!(string)(attribute) ~ `" due to malformed data.`, __FILE__, __LINE__);
+		{
+			if (errorCallback)
+			{
+				if (set.nodes.length == 0)
+					errorCallback(new ArchiveException(`Could not find the attribute "` ~ to!(string)(attribute) ~ `".`, __FILE__, __LINE__), [attribute]);
+				
+				else
+					errorCallback(new ArchiveException(`Could not unarchive the value of the attribute "` ~ to!(string)(attribute) ~ `" due to malformed data.`, __FILE__, __LINE__), [attribute]);
+			}
+		}		
 	}
 	
 	private void addArchivedReference (T) (T value, DataType id)