Index: SERIALIZATION ================================================================== --- SERIALIZATION +++ SERIALIZATION @@ -152,13 +152,14 @@ 6.) Extension Type The extension type allows adding new objects to ObjFW serialization. The extension type has a parameter class= which specifies the class which should -handle deserialization. The extension type starts with a [ and ends with a ]. -Inside those brackets can be arbitray basic types, which should be passed -unmodified to the class for deserialization. +handle deserialization and a version= parameter which specifies the version of +the class serialization as a single integer. The extension type starts with a [ +and ends with a ]. Inside those brackets can be arbitray basic types, which +should be passed unmodified to the class for deserialization. If an implementation can't deserialize an extension type, it is required to error out. Other languages are allowed to parse extension types of classes which are in ObjFW, like OFXMLElement, but are by no means required to do so. Other languages may also add their own extension types, but are required to add the foreign= parameter and set it to their name, so other implementations don't try Index: src/OFDate.h ================================================================== --- src/OFDate.h +++ src/OFDate.h @@ -13,17 +13,18 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" +#import "OFSerialization.h" @class OFString; /** * \brief A class for storing, accessing and comparing dates. */ -@interface OFDate: OFObject +@interface OFDate: OFObject { int64_t seconds; uint32_t microseconds; } Index: src/OFDate.m ================================================================== --- src/OFDate.m +++ src/OFDate.m @@ -22,10 +22,12 @@ #include #import "OFDate.h" #import "OFString.h" +#import "OFDictionary.h" +#import "OFNumber.h" #import "OFAutoreleasePool.h" #ifdef OF_THREADS # import "OFThread.h" #endif @@ -259,19 +261,19 @@ - copy { return [self retain]; } -- (of_comparison_result_t)compare: (id)obj +- (of_comparison_result_t)compare: (id)object { OFDate *otherDate; - if (![obj isKindOfClass: [OFDate class]]) + if (![object isKindOfClass: [OFDate class]]) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - otherDate = (OFDate*)obj; + otherDate = (OFDate*)object; if (seconds < otherDate->seconds) return OF_ORDERED_ASCENDING; if (seconds > otherDate->seconds) return OF_ORDERED_DESCENDING; @@ -286,10 +288,29 @@ - (OFString*)description { return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"]; } + +- (OFString*)stringBySerializing +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFDictionary *dictionary = [OFDictionary dictionaryWithKeysAndObjects: + @"seconds", [OFNumber numberWithInt64: seconds], + @"microseconds", [OFNumber numberWithUInt32: microseconds], nil]; + OFString *ret = [[OFString alloc] + initWithFormat: @"(class=OFDate,version=0)<%@>", + [dictionary stringBySerializing]]; + + @try { + [pool release]; + } @finally { + [ret autorelease]; + } + + return ret; +} - (uint32_t)microsecond { return microseconds; } Index: src/OFURL.m ================================================================== --- src/OFURL.m +++ src/OFURL.m @@ -532,11 +532,11 @@ - (OFString*)stringBySerializing { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFString *ret = [[OFString alloc] - initWithFormat: @"(class=OFURL)<%@>", + initWithFormat: @"(class=OFURL,version=0)<%@>", [[self string] stringBySerializing]]; @try { [pool release]; } @finally { Index: src/OFXMLAttribute.h ================================================================== --- src/OFXMLAttribute.h +++ src/OFXMLAttribute.h @@ -13,17 +13,18 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" +#import "OFSerialization.h" @class OFString; /** * \brief A representation of an attribute of an XML element as an object. */ -@interface OFXMLAttribute: OFObject +@interface OFXMLAttribute: OFObject { @public OFString *name; OFString *ns; OFString *stringValue; Index: src/OFXMLAttribute.m ================================================================== --- src/OFXMLAttribute.m +++ src/OFXMLAttribute.m @@ -16,10 +16,11 @@ #include "config.h" #import "OFXMLAttribute.h" #import "OFString.h" +#import "OFDictionary.h" #import "OFAutoreleasePool.h" @implementation OFXMLAttribute + attributeWithName: (OFString*)name namespace: (OFString*)ns @@ -69,6 +70,37 @@ - (OFString*)stringValue { return [[stringValue copy] autorelease]; } + +- (OFString*)stringBySerializing +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFMutableDictionary *dictionary = [OFMutableDictionary dictionary]; + OFString *ret; + + if (name != nil) + [dictionary setObject: name + forKey: @"name"]; + if (ns != nil) + [dictionary setObject: ns + forKey: @"namespace"]; + if (stringValue != nil) + [dictionary setObject: stringValue + forKey: @"stringValue"]; + + dictionary->isa = [OFDictionary class]; + + ret = [[OFString alloc] + initWithFormat: @"(class=OFXMLElement,version=0)<%@>", + [dictionary stringBySerializing]]; + + @try { + [pool release]; + } @finally { + [ret autorelease]; + } + + return ret; +} @end Index: src/OFXMLElement.m ================================================================== --- src/OFXMLElement.m +++ src/OFXMLElement.m @@ -569,13 +569,46 @@ } - (OFString*)stringBySerializing { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - OFString *ret = [[OFString alloc] - initWithFormat: @"(class=OFXMLElement)<%@>", - [[self XMLString] stringBySerializing]]; + OFMutableDictionary *dictionary = [OFMutableDictionary dictionary]; + OFString *ret; + + if (name != nil) + [dictionary setObject: name + forKey: @"name"]; + if (ns != nil) + [dictionary setObject: ns + forKey: @"namespace"]; + if (defaultNamespace != nil) + [dictionary setObject: defaultNamespace + forKey: @"defaultNamespace"]; + if (attributes != nil) + [dictionary setObject: attributes + forKey: @"attributes"]; + if (namespaces != nil) + [dictionary setObject: namespaces + forKey: @"namespaces"]; + if (children != nil) + [dictionary setObject: children + forKey: @"children"]; + if (characters != nil) + [dictionary setObject: characters + forKey: @"characters"]; + if (CDATA != nil) + [dictionary setObject: CDATA + forKey: @"CDATA"]; + if (comment != nil) + [dictionary setObject: comment + forKey: @"comment"]; + + dictionary->isa = [OFDictionary class]; + + ret = [[OFString alloc] + initWithFormat: @"(class=OFXMLElement,version=0)<%@>", + [dictionary stringBySerializing]]; @try { [pool release]; } @finally { [ret autorelease];