Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -255,31 +255,74 @@ return (id)[[OFString_UTF8 alloc] init]; } - initWithUTF8String: (const char*)UTF8String { - return (id)[[OFString_UTF8 alloc] initWithUTF8String: UTF8String]; + id string; + size_t length; + void *storage; + + length = strlen(UTF8String); + string = of_alloc_object([OFString_UTF8 class], + length + 1, 1, &storage); + + return (id)[string _initWithUTF8String: UTF8String + length: length + storage: storage]; } - initWithUTF8String: (const char*)UTF8String length: (size_t)UTF8StringLength { - return (id)[[OFString_UTF8 alloc] initWithUTF8String: UTF8String - length: UTF8StringLength]; + id string; + void *storage; + + string = of_alloc_object([OFString_UTF8 class], + UTF8StringLength + 1, 1, &storage); + + return (id)[string _initWithUTF8String: UTF8String + length: UTF8StringLength + storage: storage]; } - initWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding { + if (encoding == OF_STRING_ENCODING_UTF_8) { + id string; + size_t length; + void *storage; + + length = strlen(cString); + string = of_alloc_object([OFString_UTF8 class], + length + 1, 1, &storage); + + return (id)[string _initWithUTF8String: cString + length: length + storage: storage]; + } + return (id)[[OFString_UTF8 alloc] initWithCString: cString encoding: encoding]; } - initWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength { + if (encoding == OF_STRING_ENCODING_UTF_8) { + id string; + void *storage; + + string = of_alloc_object([OFString_UTF8 class], + cStringLength + 1, 1, &storage); + + return (id)[string _initWithUTF8String: cString + length: cStringLength + storage: storage]; + } + return (id)[[OFString_UTF8 alloc] initWithCString: cString encoding: encoding length: cStringLength]; } Index: src/OFString_UTF8.h ================================================================== --- src/OFString_UTF8.h +++ src/OFString_UTF8.h @@ -34,6 +34,10 @@ BOOL hashed; uint32_t hash; } *restrict s; struct of_string_utf8_ivars s_store; } + +- _initWithUTF8String: (const char*)UTF8String + length: (size_t)UTF8StringLength + storage: (char*)storage; @end Index: src/OFString_UTF8.m ================================================================== --- src/OFString_UTF8.m +++ src/OFString_UTF8.m @@ -70,10 +70,48 @@ s->cString[0] = '\0'; } @catch (id e) { [self release]; @throw e; } + + return self; +} + +- _initWithUTF8String: (const char*)UTF8String + length: (size_t)UTF8StringLength + storage: (char*)storage +{ + self = [super init]; + + @try { + if (UTF8StringLength >= 3 && + !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) { + UTF8String += 3; + UTF8StringLength -= 3; + } + + s = &s_store; + + s->cString = storage; + s->cStringLength = UTF8StringLength; + + switch (of_string_check_utf8(UTF8String, UTF8StringLength, + &s->length)) { + case 1: + s->UTF8 = YES; + break; + case -1: + @throw [OFInvalidEncodingException + exceptionWithClass: isa]; + } + + memcpy(s->cString, UTF8String, UTF8StringLength); + s->cString[UTF8StringLength] = 0; + } @catch (id e) { + [self release]; + @throw e; + } return self; } - initWithCString: (const char*)cString