Index: src/OFDataArray.h ================================================================== --- src/OFDataArray.h +++ src/OFDataArray.h @@ -13,21 +13,25 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" +#import "OFSerialization.h" @class OFString; @class OFURL; /** * \brief A class for storing arbitrary data in an array. * * If you plan to store large hunks of data, you should consider using * OFBigDataArray, which allocates the memory in pages rather than in bytes. + * + * For security reasons, serialization and deserialization is only implemented + * for OFDataArrays with item size 1. */ -@interface OFDataArray: OFObject +@interface OFDataArray: OFObject { char *data; size_t count; size_t itemSize; } Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -23,10 +23,11 @@ #import "OFDataArray.h" #import "OFString.h" #import "OFFile.h" #import "OFURL.h" #import "OFHTTPRequest.h" +#import "OFXMLElement.h" #import "OFAutoreleasePool.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" @@ -169,10 +170,40 @@ if (!of_base64_decode(self, [string cString], [string cStringLength])) { Class c = isa; [self release]; @throw [OFInvalidEncodingException newWithClass: c]; } + + return self; +} + +- initWithSerialization: (OFXMLElement*)element +{ + self = [super init]; + + itemSize = 1; + + @try { + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFString *stringValue; + + if (![[element name] isEqual: [self className]] || + ![[element namespace] isEqual: OF_SERIALIZATION_NS]) + @throw [OFInvalidArgumentException newWithClass: isa + selector: _cmd]; + + stringValue = [element stringValue]; + + if (!of_base64_decode(self, [stringValue cString], + [stringValue cStringLength])) + @throw [OFInvalidEncodingException newWithClass: isa]; + + [pool release]; + } @catch (id e) { + [self release]; + @throw e; + } return self; } - (size_t)count @@ -413,10 +444,35 @@ fromBuffer: data]; } @finally { [file release]; } } + +- (OFXMLElement*)XMLElementBySerializing +{ + OFAutoreleasePool *pool; + OFXMLElement *element; + + if (itemSize != 1) + @throw [OFNotImplementedException newWithClass: isa + selector: _cmd]; + + pool = [[OFAutoreleasePool alloc] init]; + element = [OFXMLElement + elementWithName: [self className] + namespace: OF_SERIALIZATION_NS + stringValue: of_base64_encode(data, count * itemSize)]; + + [element retain]; + @try { + [pool release]; + } @finally { + [element autorelease]; + } + + return element; +} @end @implementation OFBigDataArray - (void)addItem: (const void*)item { Index: tests/OFSerializationTests.m ================================================================== --- tests/OFSerializationTests.m +++ tests/OFSerializationTests.m @@ -22,10 +22,11 @@ #import "OFDictionary.h" #import "OFList.h" #import "OFNumber.h" #import "OFDate.h" #import "OFURL.h" +#import "OFDataArray.h" #import "OFAutoreleasePool.h" #import "OFXMLElement.h" #import "TestsAppDelegate.h" @@ -36,10 +37,11 @@ { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFMutableDictionary *d = [OFMutableDictionary dictionary]; OFMutableArray *a = [OFMutableArray array]; OFList *l = [OFList list]; + OFDataArray *da = [OFDataArray dataArray]; OFString *s; [a addObject: @"Qu\"xbar\ntest"]; [a addObject: [OFNumber numberWithInt: 1234]]; [a addObject: [OFMutableString stringWithString: @"asd"]]; @@ -58,10 +60,15 @@ [OFXMLElement elementWithXMLString: @""]]; [d setObject: @"list" forKey: l]; + [da addNItems: 39 + fromCArray: "0123456789:;Blub B"la + + MDEyMzQ1Njc4OTo7PEFCQ0RFRkdISklLTE1OT1BRUlNUVVZXWFla + + + data +