Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -89,26 +89,29 @@ { return (id)[[OFMutableString_UTF8 alloc] initWithCharacters: characters length: length]; } -- initWithCharacters: (const of_unichar_t*)characters - length: (size_t)length - byteOrder: (of_byte_order_t)byteOrder -{ - return (id)[[OFMutableString_UTF8 alloc] - initWithCharacters: characters - length: length - byteOrder: byteOrder]; +- initWithUTF16String: (const uint16_t*)string +{ + return (id)[[OFMutableString_UTF8 alloc] initWithUTF16String: string]; } - initWithUTF16String: (const uint16_t*)string length: (size_t)length { return (id)[[OFMutableString_UTF8 alloc] initWithUTF16String: string length: length]; } + +- initWithUTF16String: (const uint16_t*)string + byteOrder: (of_byte_order_t)byteOrder +{ + return (id)[[OFMutableString_UTF8 alloc] + initWithUTF16String: string + byteOrder: byteOrder]; +} - initWithUTF16String: (const uint16_t*)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { @@ -115,10 +118,40 @@ return (id)[[OFMutableString_UTF8 alloc] initWithUTF16String: string length: length byteOrder: byteOrder]; } + +- initWithUTF32String: (const uint32_t*)string +{ + return (id)[[OFMutableString_UTF8 alloc] initWithUTF32String: string]; +} + +- initWithUTF32String: (const uint32_t*)string + length: (size_t)length +{ + return (id)[[OFMutableString_UTF8 alloc] initWithUTF32String: string + length: length]; +} + +- initWithUTF32String: (const uint32_t*)string + byteOrder: (of_byte_order_t)byteOrder +{ + return (id)[[OFMutableString_UTF8 alloc] + initWithUTF32String: string + byteOrder: byteOrder]; +} + +- initWithUTF32String: (const uint32_t*)string + length: (size_t)length + byteOrder: (of_byte_order_t)byteOrder +{ + return (id)[[OFMutableString_UTF8 alloc] + initWithUTF32String: string + length: length + byteOrder: byteOrder]; +} - initWithFormat: (OFConstantString*)format, ... { id ret; va_list arguments; Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -146,37 +146,24 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithCharacters: (const of_unichar_t*)characters length: (size_t)length; -/*! - * @brief Creates a new OFString from a unicode string with the specified - * length, assuming the specified byte order if no BOM is found. - * - * @param characters An array of unicode characters - * @param length The length of the unicode character array - * @param byteOrder The byte order to assume if there is no BOM - * @return A new autoreleased OFString - */ -+ (instancetype)stringWithCharacters: (const of_unichar_t*)characters - length: (size_t)length - byteOrder: (of_byte_order_t)byteOrder; - /*! * @brief Creates a new OFString from a UTF-16 encoded string. * * @param string The UTF-16 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const uint16_t*)string; /*! - * @brief Creates a new OFString from a UTF-16 encoded string with the specified - * length. + * @brief Creates a new OFString from a UTF-16 encoded string with the + * specified length. * * @param string The UTF-16 string - * @param length The length of the unicode string + * @param length The length of the UTF-16 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const uint16_t*)string length: (size_t)length; @@ -195,11 +182,11 @@ * @brief Creates a new OFString from a UTF-16 encoded string with the * specified length, assuming the specified byte order if no BOM is * found. * * @param string The UTF-16 string - * @param length The length of the unicode string + * @param length The length of the UTF-16 string * @param byteOrder The byte order to assume if there is no BOM * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const uint16_t*)string length: (size_t)length @@ -211,10 +198,21 @@ * @param string The UTF-32 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const uint32_t*)string; +/*! + * @brief Creates a new OFString from a UTF-32 encoded string with the + * specified length. + * + * @param string The UTF-32 string + * @param length The length of the UTF-32 string + * @return A new autoreleased OFString + */ ++ (instancetype)stringWithUTF32String: (const uint32_t*)string + length: (size_t)length; + /*! * @brief Creates a new OFString from a UTF-32 encoded string, assuming the * specified byte order if no BOM is found. * * @param string The UTF-32 string @@ -222,10 +220,24 @@ * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const uint32_t*)string byteOrder: (of_byte_order_t)byteOrder; +/*! + * @brief Creates a new OFString from a UTF-32 encoded string with the + * specified length, assuming the specified byte order if no BOM is + * found. + * + * @param string The UTF-32 string + * @param length The length of the UTF-32 string + * @param byteOrder The byte order to assume if there is no BOM + * @return A new autoreleased OFString + */ ++ (instancetype)stringWithUTF32String: (const uint32_t*)string + length: (size_t)length + byteOrder: (of_byte_order_t)byteOrder; + /*! * @brief Creates a new OFString from a format string. * * See printf for the format syntax. As an addition, %@ is available as format * specifier for objects. @@ -363,24 +375,10 @@ * @return An initialized OFString */ - initWithCharacters: (const of_unichar_t*)characters length: (size_t)length; -/*! - * @brief Initializes an already allocated OFString with a unicode string with - * the specified length, assuming the specified byte order if no BOM is - * found. - * - * @param characters An array of unicode characters - * @param length The length of the unicode character array - * @param byteOrder The byte order to assume if there is no BOM - * @return An initialized OFString - */ -- initWithCharacters: (const of_unichar_t*)characters - length: (size_t)length - byteOrder: (of_byte_order_t)byteOrder; - /*! * @brief Initializes an already allocated OFString with a UTF-16 string. * * @param string The UTF-16 string * @return An initialized OFString @@ -429,10 +427,21 @@ * @param string The UTF-32 string * @return An initialized OFString */ - initWithUTF32String: (const uint32_t*)string; +/*! + * @brief Initializes an already allocated OFString with a UTF-32 string with + * the specified length + * + * @param string The UTF-32 string + * @param length The length of the UTF-32 string + * @return An initialized OFString + */ +- initWithUTF32String: (const uint32_t*)string + length: (size_t)length; + /*! * @brief Initializes an already allocated OFString with a UTF-32 string, * assuming the specified byte order if no BOM is found. * * @param string The UTF-32 string @@ -440,10 +449,24 @@ * @return An initialized OFString */ - initWithUTF32String: (const uint32_t*)string byteOrder: (of_byte_order_t)byteOrder; +/*! + * @brief Initializes an already allocated OFString with a UTF-32 string with + * the specified length, assuming the specified byte order if no BOM is + * found. + * + * @param string The UTF-32 string + * @param length The length of the UTF-32 string + * @param byteOrder The byte order to assume if there is no BOM + * @return An initialized OFString + */ +- initWithUTF32String: (const uint32_t*)string + length: (size_t)length + byteOrder: (of_byte_order_t)byteOrder; + /*! * @brief Initializes an already allocated OFString with a format string. * * See printf for the format syntax. As an addition, %@ is available as format * specifier for objects. Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -312,19 +312,10 @@ { return (id)[[OFString_UTF8 alloc] initWithCharacters: string length: length]; } -- initWithCharacters: (const of_unichar_t*)string - length: (size_t)length - byteOrder: (of_byte_order_t)byteOrder -{ - return (id)[[OFString_UTF8 alloc] initWithCharacters: string - length: length - byteOrder: byteOrder]; -} - - initWithUTF16String: (const uint16_t*)string { return (id)[[OFString_UTF8 alloc] initWithUTF16String: string]; } @@ -355,13 +346,29 @@ { return (id)[[OFString_UTF8 alloc] initWithUTF32String: string]; } - initWithUTF32String: (const uint32_t*)string + length: (size_t)length +{ + return (id)[[OFString_UTF8 alloc] initWithUTF32String: string + length: length]; +} + +- initWithUTF32String: (const uint32_t*)string + byteOrder: (of_byte_order_t)byteOrder +{ + return (id)[[OFString_UTF8 alloc] initWithUTF32String: string + byteOrder: byteOrder]; +} + +- initWithUTF32String: (const uint32_t*)string + length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFString_UTF8 alloc] initWithUTF32String: string + length: length byteOrder: byteOrder]; } - initWithFormat: (OFConstantString*)format, ... { @@ -523,19 +530,10 @@ { return [[[self alloc] initWithCharacters: string length: length] autorelease]; } -+ (instancetype)stringWithCharacters: (const of_unichar_t*)string - length: (size_t)length - byteOrder: (of_byte_order_t)byteOrder -{ - return [[[self alloc] initWithCharacters: string - length: length - byteOrder: byteOrder] autorelease]; -} - + (instancetype)stringWithUTF16String: (const uint16_t*)string { return [[[self alloc] initWithUTF16String: string] autorelease]; } @@ -566,13 +564,29 @@ { return [[[self alloc] initWithUTF32String: string] autorelease]; } + (instancetype)stringWithUTF32String: (const uint32_t*)string + length: (size_t)length +{ + return [[[self alloc] initWithUTF32String: string + length: length] autorelease]; +} + ++ (instancetype)stringWithUTF32String: (const uint32_t*)string + byteOrder: (of_byte_order_t)byteOrder +{ + return [[[self alloc] initWithUTF32String: string + byteOrder: byteOrder] autorelease]; +} + ++ (instancetype)stringWithUTF32String: (const uint32_t*)string + length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { return [[[self alloc] initWithUTF32String: string + length: length byteOrder: byteOrder] autorelease]; } + (instancetype)stringWithFormat: (OFConstantString*)format, ... { @@ -693,19 +707,10 @@ } - initWithCharacters: (const of_unichar_t*)string length: (size_t)length { - return [self initWithCharacters: string - length: length - byteOrder: OF_BYTE_ORDER_NATIVE]; -} - -- initWithCharacters: (const of_unichar_t*)string - length: (size_t)length - byteOrder: (of_byte_order_t)byteOrder -{ @try { [self doesNotRecognizeSelector: _cmd]; abort(); } @catch (id e) { [self release]; @@ -749,21 +754,42 @@ } } - initWithUTF32String: (const uint32_t*)string { - return [self initWithCharacters: string - length: of_string_utf32_length(string) - byteOrder: OF_BYTE_ORDER_NATIVE]; + return [self initWithUTF32String: string + length: of_string_utf32_length(string) + byteOrder: OF_BYTE_ORDER_NATIVE]; +} + +- initWithUTF32String: (const uint32_t*)string + length: (size_t)length +{ + return [self initWithUTF32String: string + length: length + byteOrder: OF_BYTE_ORDER_NATIVE]; +} + +- initWithUTF32String: (const uint32_t*)string + byteOrder: (of_byte_order_t)byteOrder +{ + return [self initWithUTF32String: string + length: of_string_utf32_length(string) + byteOrder: byteOrder]; } - initWithUTF32String: (const uint32_t*)string + length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { - return [self initWithCharacters: string - length: of_string_utf32_length(string) - byteOrder: byteOrder]; + @try { + [self doesNotRecognizeSelector: _cmd]; + abort(); + } @catch (id e) { + [self release]; + @throw e; + } } - initWithFormat: (OFConstantString*)format, ... { id ret; Index: src/OFString_UTF8.m ================================================================== --- src/OFString_UTF8.m +++ src/OFString_UTF8.m @@ -402,40 +402,25 @@ return self; } - initWithCharacters: (const of_unichar_t*)characters length: (size_t)length - byteOrder: (of_byte_order_t)byteOrder { self = [super init]; @try { size_t i, j = 0; - BOOL swap = NO; - - if (length > 0 && *characters == 0xFEFF) { - characters++; - length--; - } else if (length > 0 && *characters == 0xFFFE0000) { - swap = YES; - characters++; - length--; - } else if (byteOrder != OF_BYTE_ORDER_NATIVE) - swap = YES; s = &s_store; s->cString = [self allocMemoryWithSize: (length * 4) + 1]; s->length = length; for (i = 0; i < length; i++) { char buffer[4]; - size_t characterLen = of_string_utf8_encode( - (swap ? OF_BSWAP32(characters[i]) : characters[i]), - buffer); - switch (characterLen) { + switch (of_string_utf8_encode(characters[i], buffer)) { case 1: s->cString[j++] = buffer[0]; break; case 2: s->isUTF8 = YES; @@ -580,10 +565,89 @@ s->cString[j] = '\0'; @try { s->cString = [self resizeMemory: s->cString size: s->cStringLength + 1]; + } @catch (OFOutOfMemoryException *e) { + /* We don't care, as we only tried to make it smaller */ + } + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- initWithUTF32String: (const of_unichar_t*)characters + length: (size_t)length + byteOrder: (of_byte_order_t)byteOrder +{ + self = [super init]; + + @try { + size_t i, j = 0; + BOOL swap = NO; + + if (length > 0 && *characters == 0xFEFF) { + characters++; + length--; + } else if (length > 0 && *characters == 0xFFFE0000) { + swap = YES; + characters++; + length--; + } else if (byteOrder != OF_BYTE_ORDER_NATIVE) + swap = YES; + + s = &s_store; + + s->cString = [self allocMemoryWithSize: (length * 4) + 1]; + s->length = length; + + for (i = 0; i < length; i++) { + char buffer[4]; + size_t characterLen = of_string_utf8_encode( + (swap ? OF_BSWAP32(characters[i]) : characters[i]), + buffer); + + switch (characterLen) { + case 1: + s->cString[j++] = buffer[0]; + break; + case 2: + s->isUTF8 = YES; + + memcpy(s->cString + j, buffer, 2); + j += 2; + + break; + case 3: + s->isUTF8 = YES; + + memcpy(s->cString + j, buffer, 3); + j += 3; + + break; + case 4: + s->isUTF8 = YES; + + memcpy(s->cString + j, buffer, 4); + j += 4; + + break; + default: + @throw [OFInvalidEncodingException + exceptionWithClass: [self class]]; + } + } + + s->cString[j] = '\0'; + s->cStringLength = j; + + @try { + s->cString = [self resizeMemory: s->cString + size: j + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release];