# HG changeset patch # User Jacob Carlborg # Date 1281648291 -7200 # Node ID 3d42ea434d469045e1d86ef127db758571ba27e5 # Parent c4e7e64ffb679985d2779925426945dcc6daf25b Added an error callback. Fixes #3 and #4. diff -r c4e7e64ffb67 -r 3d42ea434d46 orange/serialization/Serializer.d --- 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) diff -r c4e7e64ffb67 -r 3d42ea434d46 orange/serialization/archives/Archive.d --- 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 diff -r c4e7e64ffb67 -r 3d42ea434d46 orange/serialization/archives/XMLArchive.d --- 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)