Index: src/OFDataArray.h ================================================================== --- src/OFDataArray.h +++ src/OFDataArray.h @@ -29,11 +29,11 @@ * For security reasons, serialization and deserialization is only implemented * for OFDataArrays with item size 1. */ @interface OFDataArray: OFObject { - char *data; + uint8_t *data; size_t count; size_t itemSize; } #ifdef OF_HAVE_PROPERTIES @@ -73,10 +73,19 @@ * \param URL The URL to the contents for the OFDataArray * \return A new autoreleased OFDataArray */ + dataArrayWithContentsOfURL: (OFURL*)URL; +/** + * \brief Creates a new OFDataArray with an item size of 1, containing the data + * of the string representation. + * + * \param string The string representation of the data + * \return A new autoreleased OFDataArray + */ ++ dataArrayWithStringRepresentation: (OFString*)string; + /** * \brief Creates a new OFDataArray with an item size of 1, containing the data * of the Base64-encoded string. * * \param string The string with the Base64-encoded data @@ -116,10 +125,19 @@ * \param URL The URL to the contents for the OFDataArray * \return A new autoreleased OFDataArray */ - initWithContentsOfURL: (OFURL*)URL; +/** + * \brief Initializes an already allocated OFDataArray with an item size of 1, + * containing the data of the string representation. + * + * \param string The string representation of the data + * \return A new autoreleased OFDataArray + */ +- initWithStringRepresentation: (OFString*)string; + /** * \brief Initializes an already allocated OFDataArray with an item size of 1, * containing the data of the Base64-encoded string. * * \param string The string with the Base64-encoded data @@ -233,10 +251,17 @@ /** * \brief Removes all items. */ - (void)removeAllItems; +/** + * \brief Returns the string representation of the data array. + * + * \return The string representation of the data array. + */ +- (OFString*)stringRepresentation; + /** * \brief Returns a string containing the data in Base64 encoding. * * \return A string containing the data in Base64 encoding */ Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -27,11 +27,11 @@ #import "OFHTTPRequest.h" #import "OFXMLElement.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" -#import "OFInvalidEncodingException.h" +#import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "autorelease.h" @@ -62,10 +62,16 @@ + dataArrayWithContentsOfURL: (OFURL*)URL { return [[[self alloc] initWithContentsOfURL: URL] autorelease]; } + ++ dataArrayWithStringRepresentation: (OFString*)string +{ + return [[[self alloc] + initWithStringRepresentation: string] autorelease]; +} + dataArrayWithBase64EncodedString: (OFString*)string { return [[[self alloc] initWithBase64EncodedString: string] autorelease]; } @@ -158,23 +164,82 @@ self = [[result data] retain]; objc_autoreleasePoolPop(pool); return self; } + +- initWithStringRepresentation: (OFString*)string +{ + self = [super init]; + + @try { + const char *cString; + size_t i; + + itemSize = 1; + count = [string UTF8StringLength]; + + if (count & 1) + @throw [OFInvalidFormatException + exceptionWithClass: [self class]]; + + count >>= 1; + cString = [string UTF8String]; + data = [self allocMemoryWithSize: count]; + + for (i = 0; i < count; i++) { + uint8_t c1 = cString[2 * i]; + uint8_t c2 = cString[2 * i + 1]; + uint8_t byte; + + if (c1 >= '0' && c1 <= '9') + byte = (c1 - '0') << 4; + else if (c1 >= 'a' && c1 <= 'f') + byte = (c1 - 'a' + 10) << 4; + else if (c1 >= 'A' && c1 <= 'F') + byte = (c1 - 'A' + 10) << 4; + else + @throw [OFInvalidFormatException + exceptionWithClass: [self class]]; + + if (c2 >= '0' && c2 <= '9') + byte |= c2 - '0'; + else if (c2 >= 'a' && c2 <= 'f') + byte |= c2 - 'a' + 10; + else if (c2 >= 'A' && c2 <= 'F') + byte |= c2 - 'A' + 10; + else + @throw [OFInvalidFormatException + exceptionWithClass: [self class]]; + + data[i] = byte; + } + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} - initWithBase64EncodedString: (OFString*)string { self = [super init]; - itemSize = 1; + @try { + itemSize = 1; - if (!of_base64_decode(self, - [string cStringWithEncoding: OF_STRING_ENCODING_ASCII], - [string cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) { - Class c = [self class]; + if (!of_base64_decode(self, [string cStringWithEncoding: + OF_STRING_ENCODING_ASCII], [string + cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) { + Class c = [self class]; + [self release]; + @throw [OFInvalidFormatException exceptionWithClass: c]; + } + } @catch (id e) { [self release]; - @throw [OFInvalidEncodingException exceptionWithClass: c]; + @throw e; } return self; } @@ -198,11 +263,11 @@ if (!of_base64_decode(self, [stringValue cStringWithEncoding: OF_STRING_ENCODING_ASCII], [stringValue cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) - @throw [OFInvalidEncodingException + @throw [OFInvalidFormatException exceptionWithClass: [self class]]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @@ -443,10 +508,23 @@ [ret appendFormat: @"%02x", data[i * itemSize + j]]; } [ret appendString: @">"]; + [ret makeImmutable]; + return ret; +} + +- (OFString*)stringRepresentation +{ + OFMutableString *ret = [OFMutableString string]; + size_t i, j; + + for (i = 0; i < count; i++) + for (j = 0; j < itemSize; j++) + [ret appendFormat: @"%02x", data[i * itemSize + j]]; + [ret makeImmutable]; return ret; } - (OFString*)stringByBase64Encoding Index: src/base64.h ================================================================== --- src/base64.h +++ src/base64.h @@ -34,10 +34,10 @@ #ifdef __cplusplus extern "C" { #endif extern const char of_base64_table[64]; -extern OFString *of_base64_encode(const char*, size_t); +extern OFString *of_base64_encode(const void*, size_t); extern BOOL of_base64_decode(OFDataArray*, const char*, size_t); #ifdef __cplusplus } #endif Index: src/base64.m ================================================================== --- src/base64.m +++ src/base64.m @@ -38,11 +38,11 @@ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 }; OFString* -of_base64_encode(const char *data, size_t length) +of_base64_encode(const void *data, size_t length) { OFMutableString *ret = [OFMutableString string]; uint8_t *buffer = (uint8_t*)data; size_t i; uint8_t rest;