Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -127,13 +127,17 @@ fprintf(stderr, "Warning: Invalid environment " "variable: %s\n", *env); continue; } - key = [OFString stringWithCString: *env - length: sep - *env]; - value = [OFString stringWithCString: sep + 1]; + key = [OFString + stringWithCString: *env + encoding: OF_STRING_ENCODING_NATIVE + length: sep - *env]; + value = [OFString + stringWithCString: sep + 1 + encoding: OF_STRING_ENCODING_NATIVE]; [environment setObject: value forKey: key]; [pool releaseObjects]; } @@ -186,15 +190,19 @@ [arguments release]; argc = argc_; argv = argv_; - programName = [[OFString alloc] initWithCString: (*argv)[0]]; + programName = [[OFString alloc] + initWithCString: (*argv)[0] + encoding: OF_STRING_ENCODING_NATIVE]; arguments = [[OFMutableArray alloc] init]; for (i = 1; i < *argc; i++) - [arguments addObject: [OFString stringWithCString: (*argv)[i]]]; + [arguments addObject: + [OFString stringWithCString: (*argv)[i] + encoding: OF_STRING_ENCODING_NATIVE]]; [arguments makeImmutable]; [pool release]; } Index: src/OFConstantString.m ================================================================== --- src/OFConstantString.m +++ src/OFConstantString.m @@ -85,39 +85,39 @@ [self release]; @throw [OFNotImplementedException newWithClass: c selector: _cmd]; } -- initWithCString: (const char*)str -{ - Class c = isa; - [self release]; - @throw [OFNotImplementedException newWithClass: c - selector: _cmd]; -} - -- initWithCString: (const char*)str - encoding: (of_string_encoding_t)encoding -{ - Class c = isa; - [self release]; - @throw [OFNotImplementedException newWithClass: c - selector: _cmd]; -} - -- initWithCString: (const char*)str - encoding: (of_string_encoding_t)encoding - length: (size_t)len -{ - Class c = isa; - [self release]; - @throw [OFNotImplementedException newWithClass: c - selector: _cmd]; -} - -- initWithCString: (const char*)str - length: (size_t)len +- initWithUTF8String: (const char*)UTF8String +{ + Class c = isa; + [self release]; + @throw [OFNotImplementedException newWithClass: c + selector: _cmd]; +} + +- initWithUTF8String: (const char*)UTF8String + length: (size_t)UTF8StringLength +{ + Class c = isa; + [self release]; + @throw [OFNotImplementedException newWithClass: c + selector: _cmd]; +} + +- initWithCString: (const char*)cString + encoding: (of_string_encoding_t)encoding +{ + Class c = isa; + [self release]; + @throw [OFNotImplementedException newWithClass: c + selector: _cmd]; +} + +- initWithCString: (const char*)cString + encoding: (of_string_encoding_t)encoding + length: (size_t)cStringLength { Class c = isa; [self release]; @throw [OFNotImplementedException newWithClass: c selector: _cmd]; @@ -403,16 +403,24 @@ return [super description]; } /* From OFString */ -- (const char*)cString +- (const char*)UTF8String +{ + if (initialized != SIZE_MAX) + [self finishInitialization]; + + return [super UTF8String]; +} + +- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding { if (initialized != SIZE_MAX) [self finishInitialization]; - return [super cString]; + return [super cStringWithEncoding: encoding]; } - (size_t)length { if (initialized != SIZE_MAX) @@ -419,16 +427,24 @@ [self finishInitialization]; return [super length]; } -- (size_t)cStringLength +- (size_t)UTF8StringLength +{ + if (initialized != SIZE_MAX) + [self finishInitialization]; + + return [super UTF8StringLength]; +} + +- (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding { if (initialized != SIZE_MAX) [self finishInitialization]; - return [super cStringLength]; + return [super cStringLengthWithEncoding: encoding]; } - (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString { if (initialized != SIZE_MAX) Index: src/OFDataArray+Hashing.m ================================================================== --- src/OFDataArray+Hashing.m +++ src/OFDataArray+Hashing.m @@ -48,10 +48,11 @@ } [pool release]; return [OFString stringWithCString: cString + encoding: OF_STRING_ENCODING_ASCII length: 32]; } - (OFString*)SHA1Hash { @@ -76,8 +77,9 @@ } [pool release]; return [OFString stringWithCString: cString + encoding: OF_STRING_ENCODING_ASCII length: 40]; } @end Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -165,11 +165,13 @@ { self = [super init]; itemSize = 1; - if (!of_base64_decode(self, [string cString], [string cStringLength])) { + if (!of_base64_decode(self, + [string cStringWithEncoding: OF_STRING_ENCODING_ASCII], + [string cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) { Class c = isa; [self release]; @throw [OFInvalidEncodingException newWithClass: c]; } @@ -191,12 +193,14 @@ @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; stringValue = [element stringValue]; - if (!of_base64_decode(self, [stringValue cString], - [stringValue cStringLength])) + if (!of_base64_decode(self, + [stringValue cStringWithEncoding: OF_STRING_ENCODING_ASCII], + [stringValue cStringLengthWithEncoding: + OF_STRING_ENCODING_ASCII])) @throw [OFInvalidEncodingException newWithClass: isa]; [pool release]; } @catch (id e) { [self release]; Index: src/OFDate.m ================================================================== --- src/OFDate.m +++ src/OFDate.m @@ -473,14 +473,14 @@ #endif buffer = [self allocMemoryWithSize: of_pagesize]; @try { - if (!strftime(buffer, of_pagesize, [format cString], &tm)) + if (!strftime(buffer, of_pagesize, [format UTF8String], &tm)) @throw [OFOutOfRangeException newWithClass: isa]; - ret = [OFString stringWithCString: buffer]; + ret = [OFString stringWithUTF8String: buffer]; } @finally { [self freeMemory: buffer]; } return ret; @@ -519,14 +519,14 @@ #endif buffer = [self allocMemoryWithSize: of_pagesize]; @try { - if (!strftime(buffer, of_pagesize, [format cString], &tm)) + if (!strftime(buffer, of_pagesize, [format UTF8String], &tm)) @throw [OFOutOfRangeException newWithClass: isa]; - ret = [OFString stringWithCString: buffer]; + ret = [OFString stringWithUTF8String: buffer]; } @finally { [self freeMemory: buffer]; } return ret; Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -185,11 +185,12 @@ { OFString *ret; char *buffer = getcwd(NULL, 0); @try { - ret = [OFString stringWithCString: buffer]; + ret = [OFString stringWithCString: buffer + encoding: OF_STRING_ENCODING_NATIVE]; } @finally { free(buffer); } return ret; @@ -197,11 +198,12 @@ + (BOOL)fileExistsAtPath: (OFString*)path { struct stat s; - if (stat([path cString], &s) == -1) + if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + &s) == -1) return NO; if (S_ISREG(s.st_mode)) return YES; @@ -210,11 +212,12 @@ + (BOOL)directoryExistsAtPath: (OFString*)path { struct stat s; - if (stat([path cString], &s) == -1) + if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + &s) == -1) return NO; if (S_ISDIR(s.st_mode)) return YES; @@ -222,13 +225,14 @@ } + (void)createDirectoryAtPath: (OFString*)path { #ifndef _WIN32 - if (mkdir([path cString], DIR_MODE)) + if (mkdir([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + DIR_MODE)) #else - if (mkdir([path cString])) + if (mkdir([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) #endif @throw [OFCreateDirectoryFailedException newWithClass: self path: path]; } @@ -239,11 +243,12 @@ #ifndef _WIN32 DIR *dir; struct dirent *dirent; - if ((dir = opendir([path cString])) == NULL) + if ((dir = opendir([path cStringWithEncoding: + OF_STRING_ENCODING_NATIVE])) == NULL) @throw [OFOpenFileFailedException newWithClass: self path: path mode: @"r"]; @try { @@ -254,11 +259,13 @@ if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..")) continue; - file = [OFString stringWithCString: dirent->d_name]; + file = [OFString + stringWithCString: dirent->d_name + encoding: OF_STRING_ENCODING_NATIVE]; [files addObject: file]; [pool releaseObjects]; } @@ -308,21 +315,21 @@ return files; } + (void)changeToDirectory: (OFString*)path { - if (chdir([path cString])) + if (chdir([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) @throw [OFChangeDirectoryFailedException newWithClass: self path: path]; } #ifndef _PSP + (void)changeModeOfFile: (OFString*)path toMode: (mode_t)mode { # ifndef _WIN32 - if (chmod([path cString], mode)) + if (chmod([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], mode)) @throw [OFChangeFileModeFailedException newWithClass: self path: path mode: mode]; # else DWORD attributes = GetFileAttributes([path cString]); @@ -347,11 +354,12 @@ + (OFDate*)modificationDateOfFile: (OFString*)path { struct stat s; - if (stat([path cString], &s) == -1) + if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + &s) == -1) /* FIXME: Maybe use another exception? */ @throw [OFOpenFileFailedException newWithClass: self path: path mode: @"r"]; @@ -377,11 +385,12 @@ @try { # endif if (owner != nil) { struct passwd *passwd; - if ((passwd = getpwnam([owner cString])) == NULL) + if ((passwd = getpwnam([owner cStringWithEncoding: + OF_STRING_ENCODING_NATIVE])) == NULL) @throw [OFChangeFileOwnerFailedException newWithClass: self path: path owner: owner group: group]; @@ -390,11 +399,12 @@ } if (group != nil) { struct group *group_; - if ((group_ = getgrnam([group cString])) == NULL) + if ((group_ = getgrnam([group cStringWithEncoding: + OF_STRING_ENCODING_NATIVE])) == NULL) @throw [OFChangeFileOwnerFailedException newWithClass: self path: path owner: owner group: group]; @@ -405,11 +415,12 @@ } @finally { [mutex unlock]; } # endif - if (chown([path cString], uid, gid)) + if (chown([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + uid, gid)) @throw [OFChangeFileOwnerFailedException newWithClass: self path: path owner: owner group: group]; } @@ -477,13 +488,15 @@ destination = [OFString stringWithPath: destination, filename, nil]; } #ifndef _WIN32 - if (rename([source cString], [destination cString])) + if (rename([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) #else - if (!MoveFile([source cString], [destination cString])) + if (!MoveFile([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) #endif @throw [OFRenameFileFailedException newWithClass: self sourcePath: source destinationPath: destination]; @@ -491,21 +504,21 @@ } + (void)deleteFileAtPath: (OFString*)path { #ifndef _WIN32 - if (unlink([path cString])) + if (unlink([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) #else - if (!DeleteFile([path cString])) + if (!DeleteFile([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) #endif @throw [OFDeleteFileFailedException newWithClass: self path: path]; } + (void)deleteDirectoryAtPath: (OFString*)path { - if (rmdir([path cString])) + if (rmdir([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) @throw [OFDeleteDirectoryFailedException newWithClass: self path: path]; } #ifndef _WIN32 @@ -518,11 +531,12 @@ OFString *filename = [source lastPathComponent]; destination = [OFString stringWithPath: destination, filename, nil]; } - if (link([source cString], [destination cString]) != 0) + if (link([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE]) != 0) @throw [OFLinkFailedException newWithClass: self sourcePath: source destinationPath: destination]; [pool release]; @@ -539,11 +553,12 @@ OFString *filename = [source lastPathComponent]; destination = [OFString stringWithPath: destination, filename, nil]; } - if (symlink([source cString], [destination cString]) != 0) + if (symlink([source cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + [destination cStringWithEncoding: OF_STRING_ENCODING_NATIVE]) != 0) @throw [OFSymlinkFailedException newWithClass: self sourcePath: source destinationPath: destination]; [pool release]; @@ -564,16 +579,17 @@ self = [super init]; @try { int flags; - if ((flags = parse_mode([mode cString])) == -1) + if ((flags = parse_mode([mode cStringWithEncoding: + OF_STRING_ENCODING_NATIVE])) == -1) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - if ((fileDescriptor = open([path cString], flags, - DEFAULT_MODE)) == -1) + if ((fileDescriptor = open([path cStringWithEncoding: + OF_STRING_ENCODING_NATIVE], flags, DEFAULT_MODE)) == -1) @throw [OFOpenFileFailedException newWithClass: isa path: path mode: mode]; closable = YES; Index: src/OFHTTPRequest.m ================================================================== --- src/OFHTTPRequest.m +++ src/OFHTTPRequest.m @@ -40,11 +40,11 @@ Class of_http_request_tls_socket_class = Nil; static OF_INLINE void normalize_key(OFString *key) { - uint8_t *str = (uint8_t*)[key cString]; + uint8_t *str = (uint8_t*)[key UTF8String]; BOOL firstLetter = YES; while (*str != '\0') { if (!isalnum(*str)) { firstLetter = YES; @@ -260,11 +260,11 @@ [sock writeString: @"Content-Type: " @"application/x-www-form-urlencoded\r\n"]; if ([headers objectForKey: @"Content-Length"] == nil) [sock writeFormat: @"Content-Length: %d\r\n", - [queryString cStringLength]]; + [queryString UTF8StringLength]]; } [sock writeString: @"\r\n"]; /* Work around a bug in lighttpd, see above */ @@ -289,28 +289,28 @@ serverHeaders = [OFMutableDictionary dictionary]; while ((line = [sock readLine]) != nil) { OFString *key, *value; - const char *line_c = [line cString], *tmp; + const char *line_c = [line UTF8String], *tmp; if ([line isEqual: @""]) break; if ((tmp = strchr(line_c, ':')) == NULL) @throw [OFInvalidServerReplyException newWithClass: isa]; - key = [OFString stringWithCString: line_c - length: tmp - line_c]; + key = [OFString stringWithUTF8String: line_c + length: tmp - line_c]; normalize_key(key); do { tmp++; } while (*tmp == ' '); - value = [OFString stringWithCString: tmp]; + value = [OFString stringWithUTF8String: tmp]; if ((redirects > 0 && (status == 301 || status == 302 || status == 303) && [key isEqual: @"Location"]) && (redirectsFromHTTPSToHTTPAllowed || [scheme isEqual: @"http"] || Index: src/OFIntrospection.m ================================================================== --- src/OFIntrospection.m +++ src/OFIntrospection.m @@ -38,11 +38,12 @@ self = [super init]; @try { selector = method_getName(method); name = [[OFString alloc] - initWithCString: sel_getName(selector)]; + initWithCString: sel_getName(selector) + encoding: OF_STRING_ENCODING_ASCII]; typeEncoding = method_getTypeEncoding(method); } @catch (id e) { [self release]; @throw e; } Index: src/OFMutableString.h ================================================================== --- src/OFMutableString.h +++ src/OFMutableString.h @@ -24,23 +24,32 @@ */ @interface OFMutableString: OFString /** * \brief Appends a UTF-8 encoded C string to the OFMutableString. * - * \param cString A UTF-8 encoded C string to append + * \param UTF8String A UTF-8 encoded C string to append */ -- (void)appendCString: (const char*)cString; +- (void)appendUTF8String: (const char*)UTF8String; /** * \brief Appends a UTF-8 encoded C string with the specified length to the * OFMutableString. * - * \param cString A UTF-8 encoded C string to append - * \param cStringLength The length of the UTF-8 encoded C string + * \param UTF8String A UTF-8 encoded C string to append + * \param UTF8StringLength The length of the UTF-8 encoded C string + */ +- (void)appendUTF8String: (const char*)UTF8String + withLength: (size_t)UTF8StringLength; + +/** + * \brief Appends a C string with the specified encoding to the OFMutableString. + * + * \param cString A C string to append + * \param encoding The encoding of the C string */ - (void)appendCString: (const char*)cString - withLength: (size_t)cStringLength; + withEncoding: (of_string_encoding_t)encoding; /** * \brief Appends a C string with the specified encoding and length to the * OFMutableString. * Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -136,71 +136,81 @@ * Even though cStringLength can change, length cannot, therefore no * need to change it. */ } -- (void)appendCString: (const char*)cString +- (void)appendUTF8String: (const char*)UTF8String { - size_t cStringLength = strlen(cString); + size_t UTF8StringLength = strlen(UTF8String); size_t length; - if (cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) { - cString += 3; - cStringLength -= 3; + if (UTF8StringLength >= 3 && !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) { + UTF8String += 3; + UTF8StringLength -= 3; } - switch (of_string_check_utf8(cString, cStringLength, &length)) { + switch (of_string_check_utf8(UTF8String, UTF8StringLength, &length)) { case 1: s->isUTF8 = YES; break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; } s->cString = [self resizeMemory: s->cString - toSize: s->cStringLength + cStringLength + 1]; - memcpy(s->cString + s->cStringLength, cString, cStringLength + 1); + toSize: s->cStringLength + + UTF8StringLength + 1]; + memcpy(s->cString + s->cStringLength, UTF8String, UTF8StringLength + 1); - s->cStringLength += cStringLength; + s->cStringLength += UTF8StringLength; s->length += length; } -- (void)appendCString: (const char*)cString - withLength: (size_t)cStringLength +- (void)appendUTF8String: (const char*)UTF8String + withLength: (size_t)UTF8StringLength { size_t length; - if (cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) { - cString += 3; - cStringLength -= 3; + if (UTF8StringLength >= 3 && !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) { + UTF8String += 3; + UTF8StringLength -= 3; } - switch (of_string_check_utf8(cString, cStringLength, &length)) { + switch (of_string_check_utf8(UTF8String, UTF8StringLength, &length)) { case 1: s->isUTF8 = YES; break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; } s->cString = [self resizeMemory: s->cString - toSize: s->cStringLength + cStringLength + 1]; - memcpy(s->cString + s->cStringLength, cString, cStringLength); + toSize: s->cStringLength + + UTF8StringLength + 1]; + memcpy(s->cString + s->cStringLength, UTF8String, UTF8StringLength); - s->cStringLength += cStringLength; + s->cStringLength += UTF8StringLength; s->length += length; s->cString[s->cStringLength] = 0; } - (void)appendCString: (const char*)cString withEncoding: (of_string_encoding_t)encoding +{ + return [self appendCString: cString + withEncoding: encoding + length: strlen(cString)]; +} + +- (void)appendCString: (const char*)cString + withEncoding: (of_string_encoding_t)encoding length: (size_t)cStringLength { if (encoding == OF_STRING_ENCODING_UTF_8) - [self appendCString: cString - withLength: cStringLength]; + [self appendUTF8String: cString + withLength: cStringLength]; else { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self appendString: [OFString stringWithCString: cString encoding: encoding @@ -209,24 +219,25 @@ } } - (void)appendString: (OFString*)string { - size_t cStringLength; + size_t UTF8StringLength; if (string == nil) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - cStringLength = [string cStringLength]; + UTF8StringLength = [string UTF8StringLength]; s->cString = [self resizeMemory: s->cString - toSize: s->cStringLength + cStringLength + 1]; + toSize: s->cStringLength + + UTF8StringLength + 1]; memcpy(s->cString + s->cStringLength, string->s->cString, - cStringLength); + UTF8StringLength); - s->cStringLength += cStringLength; + s->cStringLength += UTF8StringLength; s->length += string->s->length; s->cString[s->cStringLength] = 0; if (string->s->isUTF8) @@ -244,26 +255,26 @@ } - (void)appendFormat: (OFConstantString*)format withArguments: (va_list)arguments { - char *cString; - int cStringLength; + char *UTF8String; + int UTF8StringLength; if (format == nil) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - if ((cStringLength = of_vasprintf(&cString, [format cString], + if ((UTF8StringLength = of_vasprintf(&UTF8String, [format UTF8String], arguments)) == -1) @throw [OFInvalidFormatException newWithClass: isa]; @try { - [self appendCString: cString - withLength: cStringLength]; + [self appendUTF8String: UTF8String + withLength: UTF8StringLength]; } @finally { - free(cString); + free(UTF8String); } } - (void)prependString: (OFString*)string { @@ -386,11 +397,11 @@ if (s->isUTF8) index = of_string_index_to_position(s->cString, index, s->cStringLength); - newCStringLength = s->cStringLength + [string cStringLength]; + newCStringLength = s->cStringLength + [string UTF8StringLength]; s->cString = [self resizeMemory: s->cString toSize: newCStringLength + 1]; memmove(s->cString + index + string->s->cStringLength, s->cString + index, s->cStringLength - index); @@ -475,47 +486,47 @@ } - (void)replaceOccurrencesOfString: (OFString*)string withString: (OFString*)replacement { - const char *cString = [string cString]; - const char *replacementCString = [replacement cString]; - size_t cStringLength = string->s->cStringLength; - size_t replacementCStringLength = replacement->s->cStringLength; + const char *UTF8String = [string UTF8String]; + const char *replacementUTF8String = [replacement UTF8String]; + size_t UTF8StringLength = string->s->cStringLength; + size_t replacementUTF8StringLength = replacement->s->cStringLength; size_t i, last, newCStringLength, newLength; char *newCString; - if (cStringLength > s->cStringLength) + if (UTF8StringLength > s->cStringLength) return; newCString = NULL; newCStringLength = 0; newLength = s->length; - for (i = 0, last = 0; i <= s->cStringLength - cStringLength; i++) { - if (memcmp(s->cString + i, cString, cStringLength)) + for (i = 0, last = 0; i <= s->cStringLength - UTF8StringLength; i++) { + if (memcmp(s->cString + i, UTF8String, UTF8StringLength)) continue; @try { newCString = [self resizeMemory: newCString toSize: newCStringLength + i - last + - replacementCStringLength + 1]; + replacementUTF8StringLength + 1]; } @catch (id e) { [self freeMemory: newCString]; @throw e; } memcpy(newCString + newCStringLength, s->cString + last, i - last); memcpy(newCString + newCStringLength + i - last, - replacementCString, replacementCStringLength); + replacementUTF8String, replacementUTF8StringLength); - newCStringLength += i - last + replacementCStringLength; + newCStringLength += i - last + replacementUTF8StringLength; newLength = newLength - string->s->length + replacement->s->length; - i += cStringLength - 1; + i += UTF8StringLength - 1; last = i + 1; } @try { newCString = [self Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -118,11 +118,12 @@ #endif const char* _NSPrintForDebugger(id object) { - return [[object description] cString]; + return [[object description] + cStringWithEncoding: OF_STRING_ENCODING_NATIVE]; } /* References for static linking */ void _references_to_categories_of_OFObject(void) { @@ -230,11 +231,12 @@ return self; } + (OFString*)className { - return [OFString stringWithCString: class_getName(self)]; + return [OFString stringWithCString: class_getName(self) + encoding: OF_STRING_ENCODING_ASCII]; } + (BOOL)isSubclassOfClass: (Class)class { Class iter; @@ -715,11 +717,12 @@ return isa; } - (OFString*)className { - return [OFString stringWithCString: class_getName(isa)]; + return [OFString stringWithCString: class_getName(isa) + encoding: OF_STRING_ENCODING_ASCII]; } - (BOOL)isKindOfClass: (Class)class { Class iter; Index: src/OFPlugin.m ================================================================== --- src/OFPlugin.m +++ src/OFPlugin.m @@ -45,13 +45,14 @@ OFPlugin *(*initPlugin)(); OFPlugin *plugin; pool = [[OFAutoreleasePool alloc] init]; file = [OFMutableString stringWithString: path]; - [file appendCString: PLUGIN_SUFFIX]; + [file appendString: @PLUGIN_SUFFIX]; - if ((handle = dlopen([file cString], RTLD_LAZY)) == NULL) + if ((handle = dlopen([file cStringWithEncoding: + OF_STRING_ENCODING_NATIVE], RTLD_LAZY)) == NULL) @throw [OFInitializationFailedException newWithClass: self]; [pool release]; initPlugin = (OFPlugin*(*)())dlsym(handle, "init_plugin"); Index: src/OFSOCKS5Socket.m ================================================================== --- src/OFSOCKS5Socket.m +++ src/OFSOCKS5Socket.m @@ -89,12 +89,16 @@ [self setBuffersWrites: YES]; /* CONNECT request */ [self writeNBytes: 4 fromBuffer: request]; - [self writeInt8: [host cStringLength]]; - [self writeString: host]; + [self writeInt8: + [host cStringLengthWithEncoding: OF_STRING_ENCODING_NATIVE]]; + [self writeNBytes: [host cStringLengthWithEncoding: + OF_STRING_ENCODING_NATIVE] + fromBuffer: [host cStringWithEncoding: + OF_STRING_ENCODING_NATIVE]]; [self writeBigEndianInt16: port]; [self flushWriteBuffer]; [self setBuffersWrites: oldBuffersWrites]; Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -668,28 +668,28 @@ } - (OFString*)readTillDelimiter: (OFString*)delimiter withEncoding: (of_string_encoding_t)encoding { - const char *delimiterCString; + const char *delimiterUTF8String; size_t i, j, delimiterLength, bufferLength, retLength; char *retCString, *buffer, *newCache; OFString *ret; /* FIXME: Convert delimiter to specified charset */ - delimiterCString = [delimiter cString]; - delimiterLength = [delimiter cStringLength]; + delimiterUTF8String = [delimiter UTF8String]; + delimiterLength = [delimiter UTF8StringLength]; j = 0; if (delimiterLength == 0) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; /* Look if there's something in our cache */ if (cache != NULL) { for (i = 0; i < cacheLength; i++) { - if (cache[i] != delimiterCString[j++]) + if (cache[i] != delimiterUTF8String[j++]) j = 0; if (j == delimiterLength || cache[i] == '\0') { if (cache[i] == '\0') delimiterLength = 1; @@ -737,11 +737,11 @@ bufferLength = [self _readNBytes: of_pagesize intoBuffer: buffer]; /* Look if there's the delimiter or \0 */ for (i = 0; i < bufferLength; i++) { - if (buffer[i] != delimiterCString[j++]) + if (buffer[i] != delimiterUTF8String[j++]) j = 0; if (j == delimiterLength || buffer[i] == '\0') { if (buffer[i] == '\0') delimiterLength = 1; @@ -1244,27 +1244,27 @@ return [dataArray count] * [dataArray itemSize]; } - (size_t)writeString: (OFString*)string { - size_t length = [string cStringLength]; + size_t length = [string UTF8StringLength]; [self writeNBytes: length - fromBuffer: [string cString]]; + fromBuffer: [string UTF8String]]; return length; } - (size_t)writeLine: (OFString*)string { - size_t stringLength = [string cStringLength]; + size_t stringLength = [string UTF8StringLength]; char *buffer; buffer = [self allocMemoryWithSize: stringLength + 1]; @try { - memcpy(buffer, [string cString], stringLength); + memcpy(buffer, [string UTF8String], stringLength); buffer[stringLength] = '\n'; [self writeNBytes: stringLength + 1 fromBuffer: buffer]; } @finally { @@ -1288,26 +1288,26 @@ } - (size_t)writeFormat: (OFConstantString*)format withArguments: (va_list)arguments { - char *cString; + char *UTF8String; int length; if (format == nil) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - if ((length = of_vasprintf(&cString, [format cString], + if ((length = of_vasprintf(&UTF8String, [format UTF8String], arguments)) == -1) @throw [OFInvalidFormatException newWithClass: isa]; @try { [self writeNBytes: length - fromBuffer: cString]; + fromBuffer: UTF8String]; } @finally { - free(cString); + free(UTF8String); } return length; } Index: src/OFString+Hashing.m ================================================================== --- src/OFString+Hashing.m +++ src/OFString+Hashing.m @@ -30,12 +30,12 @@ OFMD5Hash *hash = [OFMD5Hash MD5Hash]; uint8_t *digest; char ret[OF_MD5_DIGEST_SIZE * 2]; size_t i; - [hash updateWithBuffer: [self cString] - length: [self cStringLength]]; + [hash updateWithBuffer: [self UTF8String] + length: [self UTF8StringLength]]; digest = [hash digest]; for (i = 0; i < OF_MD5_DIGEST_SIZE; i++) { uint8_t high, low; @@ -47,10 +47,11 @@ } [pool release]; return [OFString stringWithCString: ret + encoding: OF_STRING_ENCODING_ASCII length: 32]; } - (OFString*)SHA1Hash { @@ -58,12 +59,12 @@ OFMD5Hash *hash = [OFSHA1Hash SHA1Hash]; uint8_t *digest; char ret[OF_SHA1_DIGEST_SIZE * 2]; size_t i; - [hash updateWithBuffer: [self cString] - length: [self cStringLength]]; + [hash updateWithBuffer: [self UTF8String] + length: [self UTF8StringLength]]; digest = [hash digest]; for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++) { uint8_t high, low; @@ -75,8 +76,9 @@ } [pool release]; return [OFString stringWithCString: ret + encoding: OF_STRING_ENCODING_ASCII length: 40]; } @end Index: src/OFString+URLEncoding.m ================================================================== --- src/OFString+URLEncoding.m +++ src/OFString+URLEncoding.m @@ -29,24 +29,24 @@ int _OFString_URLEncoding_reference; @implementation OFString (URLEncoding) - (OFString*)stringByURLEncoding { - const char *string = [self cString]; + const char *string = [self UTF8String]; char *retCString; size_t i; OFString *ret; /* * Worst case: 3 times longer than before. * Oh, and we can't use [self allocWithSize:] here as self might be a * @"" literal. */ - if ((retCString = malloc(([self cStringLength] * 3) + 1)) == NULL) + if ((retCString = malloc(([self UTF8StringLength] * 3) + 1)) == NULL) @throw [OFOutOfMemoryException newWithClass: isa - requestedSize: ([self cStringLength] * 3) + 1]; + requestedSize: ([self UTF8StringLength] * 3) + 1]; for (i = 0; *string != '\0'; string++) { if (isalnum((int)*string) || *string == '-' || *string == '_' || *string == '.' || *string == '~') retCString[i++] = *string; @@ -63,12 +63,12 @@ (low > 9 ? low - 10 + 'A' : low + '0'); } } @try { - ret = [OFString stringWithCString: retCString - length: i]; + ret = [OFString stringWithUTF8String: retCString + length: i]; } @finally { free(retCString); } return ret; @@ -75,20 +75,20 @@ } - (OFString*)stringByURLDecoding { OFString *ret; - const char *string = [self cString]; + const char *string = [self UTF8String]; char *retCString; char byte = 0; int state = 0; size_t i; - if ((retCString = malloc([self cStringLength] + 1)) == NULL) + if ((retCString = malloc([self UTF8StringLength] + 1)) == NULL) @throw [OFOutOfMemoryException newWithClass: isa - requestedSize: [self cStringLength] + 1]; + requestedSize: [self UTF8StringLength] + 1]; for (i = 0; *string; string++) { switch (state) { case 0: if (*string == '%') @@ -129,12 +129,13 @@ free(retCString); @throw [OFInvalidEncodingException newWithClass: isa]; } @try { - ret = [OFString stringWithCString: retCString]; + ret = [OFString stringWithUTF8String: retCString + length: i]; } @finally { free(retCString); } return ret; } @end Index: src/OFString+XMLEscaping.m ================================================================== --- src/OFString+XMLEscaping.m +++ src/OFString+XMLEscaping.m @@ -33,12 +33,12 @@ const char *string, *append; size_t length, retLength, appendLen; size_t i, j; OFString *ret; - string = [self cString]; - length = [self cStringLength]; + string = [self UTF8String]; + length = [self UTF8StringLength]; j = 0; retLength = length; /* @@ -99,13 +99,13 @@ } assert(j == retLength); @try { - ret = [OFString stringWithCString: retCString - length: retLength]; + ret = [OFString stringWithUTF8String: retCString + length: retLength]; } @finally { free(retCString); } return ret; } @end Index: src/OFString+XMLUnescaping.m ================================================================== --- src/OFString+XMLUnescaping.m +++ src/OFString+XMLUnescaping.m @@ -69,12 +69,12 @@ if ((i = of_string_unicode_to_utf8(c, buffer)) == 0) return nil; buffer[i] = 0; - return [OFString stringWithCString: buffer - length: i]; + return [OFString stringWithUTF8String: buffer + length: i]; } @implementation OFString (XMLUnescaping) - (OFString*)stringByXMLUnescaping { @@ -87,46 +87,51 @@ const char *string; size_t i, last, length; BOOL inEntity; OFMutableString *ret; - string = [self cString]; - length = [self cStringLength]; + string = [self UTF8String]; + length = [self UTF8StringLength]; ret = [OFMutableString string]; last = 0; inEntity = NO; for (i = 0; i < length; i++) { if (!inEntity && string[i] == '&') { - [ret appendCString: string + last - withLength: i - last]; + [ret appendUTF8String: string + last + withLength: i - last]; last = i + 1; inEntity = YES; } else if (inEntity && string[i] == ';') { const char *entity = string + last; size_t entityLength = i - last; if (entityLength == 2 && !memcmp(entity, "lt", 2)) [ret appendCString: "<" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entityLength == 2 && !memcmp(entity, "gt", 2)) [ret appendCString: ">" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entityLength == 4 && !memcmp(entity, "quot", 4)) [ret appendCString: "\"" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entityLength == 4 && !memcmp(entity, "apos", 4)) [ret appendCString: "'" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entityLength == 3 && !memcmp(entity, "amp", 3)) [ret appendCString: "&" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entity[0] == '#') { OFAutoreleasePool *pool; OFString *tmp; pool = [[OFAutoreleasePool alloc] init]; @@ -143,12 +148,13 @@ OFAutoreleasePool *pool; OFString *n, *tmp; pool = [[OFAutoreleasePool alloc] init]; - n = [OFString stringWithCString: entity - length: entityLength]; + n = [OFString + stringWithUTF8String: entity + length: entityLength]; tmp = [delegate string: self containsUnknownEntityNamed: n]; if (tmp == nil) @throw [OFInvalidEncodingException @@ -166,12 +172,12 @@ } if (inEntity) @throw [OFInvalidEncodingException newWithClass: isa]; - [ret appendCString: string + last - withLength: i - last]; + [ret appendUTF8String: string + last + withLength: i - last]; [ret makeImmutable]; return ret; } @@ -183,46 +189,51 @@ const char *string; size_t i, last, length; BOOL inEntity; OFMutableString *ret; - string = [self cString]; - length = [self cStringLength]; + string = [self UTF8String]; + length = [self UTF8StringLength]; ret = [OFMutableString string]; last = 0; inEntity = NO; for (i = 0; i < length; i++) { if (!inEntity && string[i] == '&') { - [ret appendCString: string + last - withLength: i - last]; + [ret appendUTF8String: string + last + withLength: i - last]; last = i + 1; inEntity = YES; } else if (inEntity && string[i] == ';') { const char *entity = string + last; size_t entityLength = i - last; if (entityLength == 2 && !memcmp(entity, "lt", 2)) [ret appendCString: "<" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entityLength == 2 && !memcmp(entity, "gt", 2)) [ret appendCString: ">" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entityLength == 4 && !memcmp(entity, "quot", 4)) [ret appendCString: "\"" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entityLength == 4 && !memcmp(entity, "apos", 4)) [ret appendCString: "'" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entityLength == 3 && !memcmp(entity, "amp", 3)) [ret appendCString: "&" - withLength: 1]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 1]; else if (entity[0] == '#') { OFAutoreleasePool *pool; OFString *tmp; pool = [[OFAutoreleasePool alloc] init]; @@ -240,12 +251,12 @@ OFString *entityString, *tmp; pool = [[OFAutoreleasePool alloc] init]; entityString = [OFString - stringWithCString: entity - length: entityLength]; + stringWithUTF8String: entity + length: entityLength]; tmp = block(self, entityString); if (tmp == nil) @throw [OFInvalidEncodingException newWithClass: isa]; @@ -260,14 +271,14 @@ } if (inEntity) @throw [OFInvalidEncodingException newWithClass: isa]; - [ret appendCString: string + last - withLength: i - last]; + [ret appendUTF8String: string + last + withLength: i - last]; [ret makeImmutable]; return ret; } #endif @end Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -92,12 +92,10 @@ */ size_t initialized; } #ifdef OF_HAVE_PROPERTIES -@property (readonly) const char *cString; -@property (readonly) size_t cStringLength; @property (readonly) size_t length; #endif /** * \brief Creates a new OFString. @@ -107,14 +105,25 @@ + string; /** * \brief Creates a new OFString from a UTF-8 encoded C string. * - * \param cString A UTF-8 encoded C string to initialize the OFString with + * \param UTF8String A UTF-8 encoded C string to initialize the OFString with + * \return A new autoreleased OFString + */ ++ stringWithUTF8String: (const char*)UTF8String; + +/** + * \brief Creates a new OFString from a UTF-8 encoded C string with the + * specified length. + * + * \param UTF8String A UTF-8 encoded C string to initialize the OFString with + * \param UTF8StringLength The length of the UTF-8 encoded C string * \return A new autoreleased OFString */ -+ stringWithCString: (const char*)cString; ++ stringWithUTF8String: (const char*)UTF8String + length: (size_t)UTF8StringLength; /** * \brief Creates a new OFString from a C string with the specified encoding. * * \param string A C string to initialize the OFString with @@ -135,21 +144,10 @@ */ + stringWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength; -/** - * \brief Creates a new OFString from a UTF-8 encoded C string with the - * specified length. - * - * \param cString A UTF-8 encoded C string to initialize the OFString with - * \param cStringLength The length of the UTF-8 encoded C string - * \return A new autoreleased OFString - */ -+ stringWithCString: (const char*)cString - length: (size_t)cStringLength; - /** * \brief Creates a new OFString from another string. * * \param string A string to initialize the OFString with * \return A new autoreleased OFString @@ -309,14 +307,25 @@ /** * \brief Initializes an already allocated OFString from a UTF-8 encoded C * string. * - * \param cString A UTF-8 encoded C string to initialize the OFString with + * \param UTF8String A UTF-8 encoded C string to initialize the OFString with + * \return An initialized OFString + */ +- initWithUTF8String: (const char*)UTF8String; + +/** + * \brief Initializes an already allocated OFString from a UTF-8 encoded C + * string with the specified length. + * + * \param UTF8String A UTF-8 encoded C string to initialize the OFString with + * \param UTF8StringLength The length of the UTF-8 encoded C string * \return An initialized OFString */ -- initWithCString: (const char*)cString; +- initWithUTF8String: (const char*)UTF8String + length: (size_t)UTF8StringLength; /** * \brief Initializes an already allocated OFString from a C string with the * specified encoding. * @@ -338,21 +347,10 @@ */ - initWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength; -/** - * \brief Initializes an already allocated OFString from a UTF-8 encoded C - * string with the specified length. - * - * \param cString A UTF-8 encoded C string to initialize the OFString with - * \param cStringLength The length of the UTF-8 encoded C string - * \return An initialized OFString - */ -- initWithCString: (const char*)cString - length: (size_t)cStringLength; - /** * \brief Initializes an already allocated OFString with another string. * * \param string A string to initialize the OFString with * \return An initialized OFString @@ -540,11 +538,11 @@ /** * \brief Returns the OFString as a UTF-8 encoded C string. * * \return The OFString as a UTF-8 encoded C string */ -- (const char*)cString; +- (const char*)UTF8String; /** * \brief Returns the OFString as a C string in the specified encoding. * * \param encoding The encoding for the C string @@ -558,15 +556,15 @@ * \return The length of the string in Unicode characters */ - (size_t)length; /** - * \brief Returns the length of the string which cString would return. + * \brief Returns the number of bytes the string needs in UTF-8 encoding. * - * \return The length of the string which cString would return + * \return The number of bytes the string needs in UTF-8 encoding. */ -- (size_t)cStringLength; +- (size_t)UTF8StringLength; /** * \brief Returns the number of bytes the string needs in the specified * encoding. * Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -286,13 +286,21 @@ + string { return [[[self alloc] init] autorelease]; } -+ stringWithCString: (const char*)cString ++ stringWithUTF8String: (const char*)UTF8String { - return [[[self alloc] initWithCString: cString] autorelease]; + return [[[self alloc] initWithUTF8String: UTF8String] autorelease]; +} + ++ stringWithUTF8String: (const char*)UTF8String + length: (size_t)UTF8StringLength +{ + return [[[self alloc] + initWithUTF8String: UTF8String + length: UTF8StringLength] autorelease]; } + stringWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding { @@ -304,17 +312,10 @@ encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength { return [[[self alloc] initWithCString: cString encoding: encoding - length: cStringLength] autorelease]; -} - -+ stringWithCString: (const char*)cString - length: (size_t)cStringLength -{ - return [[[self alloc] initWithCString: cString length: cStringLength] autorelease]; } + stringWithString: (OFString*)string { @@ -443,15 +444,23 @@ } return self; } -- initWithCString: (const char*)cString +- initWithUTF8String: (const char*)UTF8String +{ + return [self initWithCString: UTF8String + encoding: OF_STRING_ENCODING_UTF_8 + length: strlen(UTF8String)]; +} + +- initWithUTF8String: (const char*)UTF8String + length: (size_t)UTF8StringLength { - return [self initWithCString: cString + return [self initWithCString: UTF8String encoding: OF_STRING_ENCODING_UTF_8 - length: strlen(cString)]; + length: UTF8StringLength]; } - initWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding { @@ -589,18 +598,10 @@ } return self; } -- initWithCString: (const char*)cString - length: (size_t)cStringLength -{ - return [self initWithCString: cString - encoding: OF_STRING_ENCODING_UTF_8 - length: cStringLength]; -} - - initWithString: (OFString*)string { self = [super init]; @try { @@ -609,11 +610,11 @@ /* * We need one call to make sure it's initialized (in case it's * a constant string). */ - s->cStringLength = [string cStringLength]; + s->cStringLength = [string UTF8StringLength]; s->isUTF8 = string->s->isUTF8; s->length = string->s->length; s->cString = [self allocMemoryWithSize: s->cStringLength + 1]; memcpy(s->cString, string->s->cString, s->cStringLength + 1); @@ -891,12 +892,12 @@ selector: _cmd]; s = [self allocMemoryWithSize: sizeof(*s)]; memset(s, 0, sizeof(*s)); - if ((cStringLength = of_vasprintf(&s->cString, [format cString], - arguments)) == -1) + if ((cStringLength = of_vasprintf(&s->cString, + [format UTF8String], arguments)) == -1) @throw [OFInvalidFormatException newWithClass: isa]; s->cStringLength = cStringLength; @try { @@ -950,29 +951,29 @@ /* * First needs to be a call to be sure it is initialized, in * case it's a constant string. */ - s->cStringLength = [firstComponent cStringLength]; + s->cStringLength = [firstComponent UTF8StringLength]; s->isUTF8 = firstComponent->s->isUTF8; s->length = firstComponent->s->length; /* Calculate length and see if we need UTF-8 */ va_copy(argumentsCopy, arguments); while ((component = va_arg(argumentsCopy, OFString*)) != nil) { /* First needs to be a call, see above */ - s->cStringLength += 1 + [component cStringLength]; + s->cStringLength += 1 + [component UTF8StringLength]; s->length += 1 + component->s->length; if (component->s->isUTF8) s->isUTF8 = YES; } s->cString = [self allocMemoryWithSize: s->cStringLength + 1]; - cStringLength = [firstComponent cStringLength]; - memcpy(s->cString, [firstComponent cString], cStringLength); + cStringLength = [firstComponent UTF8StringLength]; + memcpy(s->cString, [firstComponent UTF8String], cStringLength); i = cStringLength; while ((component = va_arg(arguments, OFString*)) != nil) { /* * We already sent each component a message, so we can @@ -1010,11 +1011,12 @@ struct stat st; @try { OFFile *file; - if (stat([path cString], &st) == -1) + if (stat([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + &st) == -1) @throw [OFOpenFileFailedException newWithClass: isa path: path mode: @"rb"]; if (st.st_size > SIZE_MAX) @@ -1128,11 +1130,11 @@ } return self; } -- (const char*)cString +- (const char*)UTF8String { return s->cString; } - (const char*)cStringWithEncoding: (of_string_encoding_t)encoding @@ -1154,11 +1156,11 @@ - (size_t)length { return s->length; } -- (size_t)cStringLength +- (size_t)UTF8StringLength { return s->cStringLength; } - (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding @@ -1184,11 +1186,11 @@ if (![object isKindOfClass: [OFString class]]) return NO; otherString = object; - if ([otherString cStringLength] != s->cStringLength || + if ([otherString UTF8StringLength] != s->cStringLength || otherString->s->length != s->length) return NO; if (strcmp(s->cString, otherString->s->cString)) return NO; @@ -1215,15 +1217,15 @@ if (![object isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; otherString = object; - otherCStringLength = [otherString cStringLength]; + otherCStringLength = [otherString UTF8StringLength]; minimumCStringLength = (s->cStringLength > otherCStringLength ? otherCStringLength : s->cStringLength); - if ((compare = memcmp(s->cString, [otherString cString], + if ((compare = memcmp(s->cString, [otherString UTF8String], minimumCStringLength)) == 0) { if (s->cStringLength > otherCStringLength) return OF_ORDERED_DESCENDING; if (s->cStringLength < otherCStringLength) return OF_ORDERED_ASCENDING; @@ -1244,12 +1246,12 @@ if (![otherString isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - otherCString = [otherString cString]; - otherCStringLength = [otherString cStringLength]; + otherCString = [otherString UTF8String]; + otherCStringLength = [otherString UTF8StringLength]; if (!s->isUTF8) { minimumCStringLength = (s->cStringLength > otherCStringLength ? otherCStringLength : s->cStringLength); @@ -1375,12 +1377,12 @@ return character; } - (size_t)indexOfFirstOccurrenceOfString: (OFString*)string { - const char *cString = [string cString]; - size_t i, cStringLength = [string cStringLength]; + const char *cString = [string UTF8String]; + size_t i, cStringLength = [string UTF8StringLength]; if (cStringLength == 0) return 0; if (cStringLength > s->cStringLength) @@ -1393,12 +1395,12 @@ return OF_INVALID_INDEX; } - (size_t)indexOfLastOccurrenceOfString: (OFString*)string { - const char *cString = [string cString]; - size_t i, cStringLength = [string cStringLength]; + const char *cString = [string UTF8String]; + size_t i, cStringLength = [string UTF8StringLength]; if (cStringLength == 0) return of_string_position_to_index(s->cString, s->cStringLength); @@ -1415,11 +1417,11 @@ } } - (BOOL)containsString: (OFString*)string { - const char *cString = [string cString]; + const char *cString = [string UTF8String]; size_t i, cStringLength = string->s->cStringLength; if (cStringLength == 0) return YES; @@ -1446,12 +1448,12 @@ s->cStringLength); end = of_string_index_to_position(s->cString, end, s->cStringLength); } - return [OFString stringWithCString: s->cString + start - length: end - start]; + return [OFString stringWithUTF8String: s->cString + start + length: end - start]; } - (OFString*)stringByAppendingString: (OFString*)string { OFMutableString *new; @@ -1543,35 +1545,35 @@ return new; } - (BOOL)hasPrefix: (OFString*)prefix { - size_t cStringLength = [prefix cStringLength]; + size_t cStringLength = [prefix UTF8StringLength]; if (cStringLength > s->cStringLength) return NO; - return !memcmp(s->cString, [prefix cString], cStringLength); + return !memcmp(s->cString, [prefix UTF8String], cStringLength); } - (BOOL)hasSuffix: (OFString*)suffix { - size_t cStringLength = [suffix cStringLength]; + size_t cStringLength = [suffix UTF8StringLength]; if (cStringLength > s->cStringLength) return NO; return !memcmp(s->cString + (s->cStringLength - cStringLength), - [suffix cString], cStringLength); + [suffix UTF8String], cStringLength); } - (OFArray*)componentsSeparatedByString: (OFString*)delimiter { OFAutoreleasePool *pool; OFMutableArray *array; - const char *cString = [delimiter cString]; - size_t cStringLength = [delimiter cStringLength]; + const char *cString = [delimiter UTF8String]; + size_t cStringLength = [delimiter UTF8StringLength]; size_t i, last; array = [OFMutableArray array]; pool = [[OFAutoreleasePool alloc] init]; @@ -1584,16 +1586,17 @@ for (i = 0, last = 0; i <= s->cStringLength - cStringLength; i++) { if (memcmp(s->cString + i, cString, cStringLength)) continue; - [array addObject: [OFString stringWithCString: s->cString + last - length: i - last]]; + [array addObject: + [OFString stringWithUTF8String: s->cString + last + length: i - last]]; i += cStringLength - 1; last = i + 1; } - [array addObject: [OFString stringWithCString: s->cString + last]]; + [array addObject: [OFString stringWithUTF8String: s->cString + last]]; [array makeImmutable]; [pool release]; @@ -1626,18 +1629,18 @@ if (s->cString[i] == OF_PATH_DELIMITER) { #else if (s->cString[i] == '/' || s->cString[i] == '\\') { #endif [ret addObject: - [OFString stringWithCString: s->cString + last - length: i - last]]; + [OFString stringWithUTF8String: s->cString + last + length: i - last]]; last = i + 1; } } - [ret addObject: [OFString stringWithCString: s->cString + last - length: i - last]]; + [ret addObject: [OFString stringWithUTF8String: s->cString + last + length: i - last]]; [ret makeImmutable]; [pool release]; @@ -1676,12 +1679,12 @@ * removed, so return a new string anyway. */ if (i < 0) i = 0; - return [OFString stringWithCString: s->cString + i - length: pathCStringLength - i]; + return [OFString stringWithUTF8String: s->cString + i + length: pathCStringLength - i]; } - (OFString*)stringByDeletingLastPathComponent { size_t i, pathCStringLength = s->cStringLength; @@ -1696,29 +1699,29 @@ s->cString[pathCStringLength - 1] == '\\') #endif pathCStringLength--; if (pathCStringLength == 0) - return [OFString stringWithCString: s->cString - length: 1]; + return [OFString stringWithUTF8String: s->cString + length: 1]; for (i = pathCStringLength - 1; i >= 1; i--) #ifndef _WIN32 if (s->cString[i] == OF_PATH_DELIMITER) #else if (s->cString[i] == '/' || s->cString[i] == '\\') #endif - return [OFString stringWithCString: s->cString - length: i]; + return [OFString stringWithUTF8String: s->cString + length: i]; #ifndef _WIN32 if (s->cString[0] == OF_PATH_DELIMITER) #else if (s->cString[0] == '/' || s->cString[0] == '\\') #endif - return [OFString stringWithCString: s->cString - length: 1]; + return [OFString stringWithUTF8String: s->cString + length: 1]; return @"."; } - (intmax_t)decimalValue Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -95,11 +95,12 @@ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(portCString, 7, "%" PRIu16, port); - if (getaddrinfo([host cString], portCString, &hints, &res0)) + if (getaddrinfo([host cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + portCString, &hints, &res0)) @throw [OFAddressTranslationFailedException newWithClass: isa socket: self host: host]; for (res = res0; res != NULL; res = res->ai_next) { @@ -127,11 +128,12 @@ addrlist = [[OFDataArray alloc] initWithItemSize: sizeof(char**)]; [mutex lock]; # endif - if ((he = gethostbyname([host cString])) == NULL) { + if ((he = gethostbyname([host cStringWithEncoding: + OF_STRING_ENCODING_NATIVE])) == NULL) { # ifdef OF_THREADS [addrlist release]; [mutex unlock]; # endif @throw [OFAddressTranslationFailedException newWithClass: isa @@ -220,11 +222,12 @@ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(portCString, 7, "%" PRIu16, port); - if (getaddrinfo([host cString], portCString, &hints, &res)) + if (getaddrinfo([host cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + portCString, &hints, &res)) @throw [OFAddressTranslationFailedException newWithClass: isa socket: self host: host]; if ((sock = socket(res->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET) @@ -249,11 +252,12 @@ # ifdef OF_THREADS [mutex lock]; # endif - if ((he = gethostbyname([host cString])) == NULL) { + if ((he = gethostbyname([host cStringWithEncoding: + OF_STRING_ENCODING_NATIVE])) == NULL) { # ifdef OF_THREADS [mutex unlock]; # endif @throw [OFAddressTranslationFailedException newWithClass: isa socket: self @@ -403,11 +407,12 @@ if (getnameinfo((struct sockaddr*)sockAddr, sockAddrLen, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST)) @throw [OFAddressTranslationFailedException newWithClass: isa]; - return [OFString stringWithCString: host]; + return [OFString stringWithCString: host + encoding: OF_STRING_ENCODING_NATIVE]; } @finally { [self freeMemory: host]; } #else # ifdef OF_THREADS @@ -419,11 +424,12 @@ if (host == NULL) @throw [OFAddressTranslationFailedException newWithClass: isa]; - return [OFString stringWithCString: host]; + return [OFString stringWithCString: host + encoding: OF_STRING_ENCODING_NATIVE]; # ifdef OF_THREADS } @finally { [mutex unlock]; } # endif Index: src/OFURL.m ================================================================== --- src/OFURL.m +++ src/OFURL.m @@ -90,133 +90,136 @@ relativeToURL: URL] autorelease]; } - initWithString: (OFString*)string { - char *cString, *cString2 = NULL; + char *UTF8String, *UTF8String2 = NULL; self = [super init]; @try { char *tmp, *tmp2; - if ((cString2 = strdup([string cString])) == NULL) + if ((UTF8String2 = strdup([string UTF8String])) == NULL) @throw [OFOutOfMemoryException newWithClass: isa - requestedSize: [string cStringLength]]; + requestedSize: [string UTF8StringLength]]; - cString = cString2; + UTF8String = UTF8String2; - if (!strncmp(cString, "file://", 7)) { + if (!strncmp(UTF8String, "file://", 7)) { scheme = @"file"; - path = [[OFString alloc] initWithCString: cString + 7]; + path = [[OFString alloc] + initWithUTF8String: UTF8String + 7]; return self; - } else if (!strncmp(cString, "http://", 7)) { + } else if (!strncmp(UTF8String, "http://", 7)) { scheme = @"http"; - cString += 7; - } else if (!strncmp(cString, "https://", 8)) { + UTF8String += 7; + } else if (!strncmp(UTF8String, "https://", 8)) { scheme = @"https"; - cString += 8; + UTF8String += 8; } else @throw [OFInvalidFormatException newWithClass: isa]; - if ((tmp = strchr(cString, '/')) != NULL) { + if ((tmp = strchr(UTF8String, '/')) != NULL) { *tmp = '\0'; tmp++; } - if ((tmp2 = strchr(cString, '@')) != NULL) { + if ((tmp2 = strchr(UTF8String, '@')) != NULL) { char *tmp3; *tmp2 = '\0'; tmp2++; - if ((tmp3 = strchr(cString, ':')) != NULL) { + if ((tmp3 = strchr(UTF8String, ':')) != NULL) { *tmp3 = '\0'; tmp3++; user = [[OFString alloc] - initWithCString: cString]; + initWithUTF8String: UTF8String]; password = [[OFString alloc] - initWithCString: tmp3]; + initWithUTF8String: tmp3]; } else user = [[OFString alloc] - initWithCString: cString]; + initWithUTF8String: UTF8String]; - cString = tmp2; + UTF8String = tmp2; } - if ((tmp2 = strchr(cString, ':')) != NULL) { + if ((tmp2 = strchr(UTF8String, ':')) != NULL) { OFAutoreleasePool *pool; OFString *portString; *tmp2 = '\0'; tmp2++; - host = [[OFString alloc] initWithCString: cString]; + host = [[OFString alloc] + initWithUTF8String: UTF8String]; pool = [[OFAutoreleasePool alloc] init]; - portString = [OFString stringWithCString: tmp2]; + portString = [OFString stringWithUTF8String: tmp2]; if ([portString decimalValue] > 65535) @throw [OFInvalidFormatException newWithClass: isa]; port = [portString decimalValue]; [pool release]; } else { - host = [[OFString alloc] initWithCString: cString]; + host = [[OFString alloc] + initWithUTF8String: UTF8String]; if ([scheme isEqual: @"http"]) port = 80; else if ([scheme isEqual: @"https"]) port = 443; else assert(0); } - if ((cString = tmp) != NULL) { - if ((tmp = strchr(cString, '#')) != NULL) { + if ((UTF8String = tmp) != NULL) { + if ((tmp = strchr(UTF8String, '#')) != NULL) { *tmp = '\0'; fragment = [[OFString alloc] - initWithCString: tmp + 1]; + initWithUTF8String: tmp + 1]; } - if ((tmp = strchr(cString, '?')) != NULL) { + if ((tmp = strchr(UTF8String, '?')) != NULL) { *tmp = '\0'; query = [[OFString alloc] - initWithCString: tmp + 1]; + initWithUTF8String: tmp + 1]; } - if ((tmp = strchr(cString, ';')) != NULL) { + if ((tmp = strchr(UTF8String, ';')) != NULL) { *tmp = '\0'; parameters = [[OFString alloc] - initWithCString: tmp + 1]; + initWithUTF8String: tmp + 1]; } path = [[OFString alloc] initWithFormat: @"/%s", - cString]; + UTF8String]; } else path = @""; } @catch (id e) { [self release]; @throw e; } @finally { - free(cString2); + free(UTF8String2); } return self; } - initWithString: (OFString*)string relativeToURL: (OFURL*)URL { - char *cString, *cString2 = NULL; + char *UTF8String, *UTF8String2 = NULL; if ([string containsString: @"://"]) return [self initWithString: string]; self = [super init]; @@ -228,59 +231,61 @@ host = [URL->host copy]; port = URL->port; user = [URL->user copy]; password = [URL->password copy]; - if ((cString2 = strdup([string cString])) == NULL) + if ((UTF8String2 = strdup([string UTF8String])) == NULL) @throw [OFOutOfMemoryException newWithClass: isa - requestedSize: [string cStringLength]]; - - cString = cString2; - - if ((tmp = strchr(cString, '#')) != NULL) { - *tmp = '\0'; - fragment = [[OFString alloc] initWithCString: tmp + 1]; - } - - if ((tmp = strchr(cString, '?')) != NULL) { - *tmp = '\0'; - query = [[OFString alloc] initWithCString: tmp + 1]; - } - - if ((tmp = strchr(cString, ';')) != NULL) { + requestedSize: [string UTF8StringLength]]; + + UTF8String = UTF8String2; + + if ((tmp = strchr(UTF8String, '#')) != NULL) { + *tmp = '\0'; + fragment = [[OFString alloc] + initWithUTF8String: tmp + 1]; + } + + if ((tmp = strchr(UTF8String, '?')) != NULL) { + *tmp = '\0'; + query = [[OFString alloc] initWithUTF8String: tmp + 1]; + } + + if ((tmp = strchr(UTF8String, ';')) != NULL) { *tmp = '\0'; parameters = [[OFString alloc] - initWithCString: tmp + 1]; + initWithUTF8String: tmp + 1]; } - if (*cString == '/') - path = [[OFString alloc] initWithCString: cString]; + if (*UTF8String == '/') + path = [[OFString alloc] + initWithUTF8String: UTF8String]; else { OFAutoreleasePool *pool; OFString *s; pool = [[OFAutoreleasePool alloc] init]; if ([URL->path hasSuffix: @"/"]) s = [OFString stringWithFormat: @"%@%s", URL->path, - cString]; + UTF8String]; else s = [OFString stringWithFormat: @"%@/../%s", URL->path, - cString]; + UTF8String]; path = [resolve_relative_path(s) copy]; [pool release]; } } @catch (id e) { [self release]; @throw e; } @finally { - free(cString2); + free(UTF8String2); } return self; } Index: src/OFXMLElement+Serialization.m ================================================================== --- src/OFXMLElement+Serialization.m +++ src/OFXMLElement+Serialization.m @@ -36,11 +36,12 @@ Class class; id object; pool = [[OFAutoreleasePool alloc] init]; - if ((class = objc_lookUpClass([name cString])) == Nil) + if ((class = objc_lookUpClass([name cStringWithEncoding: + OF_STRING_ENCODING_ASCII])) == Nil) @throw [OFNotImplementedException newWithClass: Nil]; if (![class conformsToProtocol: @protocol(OFSerialization)]) @throw [OFNotImplementedException newWithClass: class Index: src/OFXMLElement.m ================================================================== --- src/OFXMLElement.m +++ src/OFXMLElement.m @@ -560,41 +560,42 @@ defaultNS = parent->defaultNamespace; else defaultNS = defaultNamespace; i = 0; - length = [name cStringLength] + 3 + (level * indentation); + length = [name UTF8StringLength] + 3 + (level * indentation); cString = [self allocMemoryWithSize: length]; memset(cString + i, ' ', level * indentation); i += level * indentation; /* Start of tag */ cString[i++] = '<'; if (prefix != nil && ![ns isEqual: defaultNS]) { - length += [prefix cStringLength] + 1; + length += [prefix UTF8StringLength] + 1; @try { cString = [self resizeMemory: cString toSize: length]; } @catch (id e) { [self freeMemory: cString]; @throw e; } - memcpy(cString + i, [prefix cString], [prefix cStringLength]); - i += [prefix cStringLength]; + memcpy(cString + i, [prefix UTF8String], + [prefix UTF8StringLength]); + i += [prefix UTF8StringLength]; cString[i++] = ':'; } - memcpy(cString + i, [name cString], [name cStringLength]); - i += [name cStringLength]; + memcpy(cString + i, [name UTF8String], [name UTF8StringLength]); + i += [name UTF8StringLength]; /* xmlns if necessary */ if (prefix == nil && ((ns != nil && ![ns isEqual: defaultNS]) || (ns == nil && defaultNS != nil))) { - length += [ns cStringLength] + 9; + length += [ns UTF8StringLength] + 9; @try { cString = [self resizeMemory: cString toSize: length]; } @catch (id e) { [self freeMemory: cString]; @@ -601,12 +602,12 @@ @throw e; } memcpy(cString + i, " xmlns='", 8); i += 8; - memcpy(cString + i, [ns cString], [ns cStringLength]); - i += [ns cStringLength]; + memcpy(cString + i, [ns UTF8String], [ns UTF8StringLength]); + i += [ns UTF8StringLength]; cString[i++] = '\''; } /* Attributes */ attributesCArray = [attributes cArray]; @@ -624,14 +625,14 @@ [attributesCArray[j] namespace]]) == nil) @throw [OFUnboundNamespaceException newWithClass: isa namespace: [attributesCArray[j] namespace]]; - length += [attributeName cStringLength] + + length += [attributeName UTF8StringLength] + (attributePrefix != nil ? - [attributePrefix cStringLength] + 1 : 0) + - [tmp cStringLength] + 4; + [attributePrefix UTF8StringLength] + 1 : 0) + + [tmp UTF8StringLength] + 4; @try { cString = [self resizeMemory: cString toSize: length]; } @catch (id e) { @@ -639,22 +640,22 @@ @throw e; } cString[i++] = ' '; if (attributePrefix != nil) { - memcpy(cString + i, [attributePrefix cString], - [attributePrefix cStringLength]); - i += [attributePrefix cStringLength]; + memcpy(cString + i, [attributePrefix UTF8String], + [attributePrefix UTF8StringLength]); + i += [attributePrefix UTF8StringLength]; cString[i++] = ':'; } - memcpy(cString + i, [attributeName cString], - [attributeName cStringLength]); - i += [attributeName cStringLength]; + memcpy(cString + i, [attributeName UTF8String], + [attributeName UTF8StringLength]); + i += [attributeName UTF8StringLength]; cString[i++] = '='; cString[i++] = '\''; - memcpy(cString + i, [tmp cString], [tmp cStringLength]); - i += [tmp cStringLength]; + memcpy(cString + i, [tmp UTF8String], [tmp UTF8StringLength]); + i += [tmp UTF8StringLength]; cString[i++] = '\''; [pool2 releaseObjects]; } @@ -688,18 +689,18 @@ _XMLStringWithParent: self namespaces: allNamespaces indentation: (indent ? indentation : 0) level: level + 1]; - [tmp addNItems: [child cStringLength] - fromCArray: [child cString]]; + [tmp addNItems: [child UTF8StringLength] + fromCArray: [child UTF8String]]; } if (indent) [tmp addItem: "\n"]; - length += [tmp count] + [name cStringLength] + 2 + + length += [tmp count] + [name UTF8StringLength] + 2 + (indent ? level * indentation : 0); @try { cString = [self resizeMemory: cString toSize: length]; } @catch (id e) { @@ -718,37 +719,37 @@ } cString[i++] = '<'; cString[i++] = '/'; if (prefix != nil) { - length += [prefix cStringLength] + 1; + length += [prefix UTF8StringLength] + 1; @try { cString = [self resizeMemory: cString toSize: length]; } @catch (id e) { [self freeMemory: cString]; @throw e; } - memcpy(cString + i, [prefix cString], - [prefix cStringLength]); - i += [prefix cStringLength]; + memcpy(cString + i, [prefix UTF8String], + [prefix UTF8StringLength]); + i += [prefix UTF8StringLength]; cString[i++] = ':'; } - memcpy(cString + i, [name cString], [name cStringLength]); - i += [name cStringLength]; + memcpy(cString + i, [name UTF8String], [name UTF8StringLength]); + i += [name UTF8StringLength]; } else cString[i++] = '/'; cString[i++] = '>'; assert(i == length); [pool release]; @try { - ret = [OFString stringWithCString: cString - length: length]; + ret = [OFString stringWithUTF8String: cString + length: length]; } @finally { [self freeMemory: cString]; } return ret; } Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -52,23 +52,23 @@ else { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFString *tmp = [OFString stringWithCString: string encoding: encoding length: length]; - [cache addNItems: [tmp cStringLength] - fromCArray: [tmp cString]]; + [cache addNItems: [tmp UTF8StringLength] + fromCArray: [tmp UTF8String]]; [pool release]; } } static OFString* transform_string(OFDataArray *cache, size_t cut, BOOL unescape, OFObject *delegate) { OFMutableString *ret = [OFMutableString - stringWithCString: [cache cArray] - length: [cache count]]; + stringWithUTF8String: [cache cArray] + length: [cache count]]; [ret replaceOccurrencesOfString: @"\r\n" withString: @"\n"]; [ret replaceOccurrencesOfString: @"\r" withString: @"\n"]; @@ -253,12 +253,12 @@ cache_append(cache, buffer + last, encoding, length - last); } - (void)parseString: (OFString*)string { - [self parseBuffer: [string cString] - withLength: [string cStringLength]]; + [self parseBuffer: [string UTF8String] + withLength: [string UTF8StringLength]]; } - (void)parseStream: (OFStream*)stream { char *buffer = [self allocMemoryWithSize: of_pagesize]; @@ -381,12 +381,12 @@ acceptProlog = NO; pi = [pi substringWithRange: of_range(3, [pi length] - 3)]; pi = [pi stringByDeletingEnclosingWhitespaces]; - cString = [pi cString]; - length = [pi cStringLength]; + cString = [pi UTF8String]; + length = [pi UTF8StringLength]; for (i = last = 0; i < length; i++) { switch (piState) { case 0: if (cString[i] == ' ' || cString[i] == '\t' || @@ -401,12 +401,13 @@ break; case 1: if (cString[i] != '=') continue; - attribute = [OFString stringWithCString: cString + last - length: i - last]; + attribute = [OFString + stringWithUTF8String: cString + last + length: i - last]; last = i + 1; piState = 2; break; case 2: @@ -421,12 +422,12 @@ case 3: if (cString[i] != piDelimiter) continue; value = [OFMutableString - stringWithCString: cString + last - length: i - last]; + stringWithUTF8String: cString + last + length: i - last]; if ([attribute isEqual: @"version"]) if (![value hasPrefix: @"1."]) return NO; @@ -516,20 +517,20 @@ pool = [[OFAutoreleasePool alloc] init]; cacheCString = [cache cArray]; cacheLength = [cache count]; - cacheString = [OFString stringWithCString: cacheCString - length: cacheLength]; + cacheString = [OFString stringWithUTF8String: cacheCString + length: cacheLength]; if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) { - name = [[OFString alloc] initWithCString: tmp + 1 - length: cacheLength - - (tmp - cacheCString) - - 1]; - prefix = [[OFString alloc] initWithCString: cacheCString - length: tmp - cacheCString]; + name = [[OFString alloc] + initWithUTF8String: tmp + 1 + length: cacheLength - (tmp - cacheCString) - 1]; + prefix = [[OFString alloc] + initWithUTF8String: cacheCString + length: tmp - cacheCString]; } else { name = [cacheString copy]; prefix = nil; } @@ -607,20 +608,20 @@ pool = [[OFAutoreleasePool alloc] init]; cacheCString = [cache cArray]; cacheLength = [cache count]; - cacheString = [OFString stringWithCString: cacheCString - length: cacheLength]; + cacheString = [OFString stringWithUTF8String: cacheCString + length: cacheLength]; if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) { - name = [[OFString alloc] initWithCString: tmp + 1 - length: cacheLength - - (tmp - cacheCString) - - 1]; - prefix = [[OFString alloc] initWithCString: cacheCString - length: tmp - cacheCString]; + name = [[OFString alloc] + initWithUTF8String: tmp + 1 + length: cacheLength - (tmp - cacheCString) - 1]; + prefix = [[OFString alloc] + initWithUTF8String: cacheCString + length: tmp - cacheCString]; } else { name = [cacheString copy]; prefix = nil; } @@ -748,26 +749,26 @@ if ((length = *i - *last) > 0) cache_append(cache, buffer + *last, encoding, length); pool = [[OFAutoreleasePool alloc] init]; - cacheString = [OFMutableString stringWithCString: [cache cArray] - length: [cache count]]; + cacheString = [OFMutableString stringWithUTF8String: [cache cArray] + length: [cache count]]; [cacheString deleteEnclosingWhitespaces]; /* Prevent a useless copy later */ [cacheString makeImmutable]; - cacheCString = [cacheString cString]; - cacheLength = [cacheString cStringLength]; + cacheCString = [cacheString UTF8String]; + cacheLength = [cacheString UTF8StringLength]; if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) { attributeName = [[OFString alloc] - initWithCString: tmp + 1 - length: cacheLength - (tmp - cacheCString) - 1]; + initWithUTF8String: tmp + 1 + length: cacheLength - (tmp - cacheCString) - 1]; attributePrefix = [[OFString alloc] - initWithCString: cacheCString - length: tmp - cacheCString]; + initWithUTF8String: cacheCString + length: tmp - cacheCString]; } else { attributeName = [cacheString copy]; attributePrefix = nil; } Index: src/base64.m ================================================================== --- src/base64.m +++ src/base64.m @@ -58,21 +58,23 @@ tb[1] = of_base64_encode_table[(sb & 0x03F000) >> 12]; tb[2] = of_base64_encode_table[(sb & 0x000FC0) >> 6]; tb[3] = of_base64_encode_table[sb & 0x00003F]; [ret appendCString: tb - withLength: 4]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 4]; } switch (rest) { case 1: tb[0] = of_base64_encode_table[buffer[i] >> 2]; tb[1] = of_base64_encode_table[(buffer[i] & 3) << 4]; tb[2] = tb[3] = '='; [ret appendCString: tb - withLength: 4]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 4]; break; case 2: sb = (buffer[i] << 16) | (buffer[i + 1] << 8); @@ -80,11 +82,12 @@ tb[1] = of_base64_encode_table[(sb & 0x03F000) >> 12]; tb[2] = of_base64_encode_table[(sb & 0x000FC0) >> 6]; tb[3] = '='; [ret appendCString: tb - withLength: 4]; + withEncoding: OF_STRING_ENCODING_ASCII + length: 4]; break; } [ret makeImmutable]; Index: src/of_asprintf.m ================================================================== --- src/of_asprintf.m +++ src/of_asprintf.m @@ -286,11 +286,11 @@ @try { id object; if ((object = va_arg(ctx->arguments, id)) != nil) tmpLen = asprintf(&tmp, ctx->subformat, - [[object description] cString]); + [[object description] UTF8String]); else tmpLen = asprintf(&tmp, ctx->subformat, "(nil)"); } @catch (id e) { free(ctx->buffer); @@ -512,11 +512,11 @@ formatLengthModifierState, formatConversionSpecifierState }; int -of_vasprintf(char **cString, const char *format, va_list arguments) +of_vasprintf(char **UTF8String, const char *format, va_list arguments) { struct context ctx; ctx.format = format; ctx.formatLen = strlen(format); @@ -549,21 +549,21 @@ return -1; } ctx.buffer[ctx.bufferLen] = 0; - *cString = ctx.buffer; + *UTF8String = ctx.buffer; return (ctx.bufferLen <= INT_MAX ? (int)ctx.bufferLen : -1); } int -of_asprintf(char **cString, const char *format, ...) +of_asprintf(char **UTF8String, const char *format, ...) { va_list arguments; int ret; va_start(arguments, format); - ret = of_vasprintf(cString, format, arguments); + ret = of_vasprintf(UTF8String, format, arguments); va_end(arguments); return ret; } Index: tests/OFStreamTests.m ================================================================== --- tests/OFStreamTests.m +++ tests/OFStreamTests.m @@ -77,10 +77,10 @@ memset(cstr, 'X', of_pagesize - 3); cstr[of_pagesize - 3] = '\0'; TEST(@"-[readLine]", [[t readLine] isEqual: @"foo"] && [(str = [t readLine]) length] == of_pagesize - 3 && - !strcmp([str cString], cstr)) + !strcmp([str UTF8String], cstr)) [pool drain]; } @end Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -97,24 +97,24 @@ [@"Ä" caseInsensitiveCompare: @"ä"] == OF_ORDERED_SAME && [@"я" caseInsensitiveCompare: @"Я"] == OF_ORDERED_SAME && [@"€" caseInsensitiveCompare: @"ß"] == OF_ORDERED_DESCENDING && [@"ß" caseInsensitiveCompare: @"→"] == OF_ORDERED_ASCENDING && [@"AA" caseInsensitiveCompare: @"z"] == OF_ORDERED_ASCENDING && - [[OFString stringWithCString: "ABC"] caseInsensitiveCompare: - [OFString stringWithCString: "AbD"]] == [@"abc" compare: @"abd"]) + [[OFString stringWithUTF8String: "ABC"] caseInsensitiveCompare: + [OFString stringWithUTF8String: "AbD"]] == [@"abc" compare: @"abd"]) TEST(@"-[hash] is the same if -[isEqual:] is YES", [s[0] hash] == [s[2] hash]) TEST(@"-[description]", [[s[0] description] isEqual: s[0]]) - TEST(@"-[appendString:] and -[appendCString:]", - R([s[1] appendCString: "1𝄞"]) && R([s[1] appendString: @"3"]) && + TEST(@"-[appendString:] and -[appendUTF8String:]", + R([s[1] appendUTF8String: "1𝄞"]) && R([s[1] appendString: @"3"]) && R([s[0] appendString: s[1]]) && [s[0] isEqual: @"täs€1𝄞3"]) TEST(@"-[length]", [s[0] length] == 7) - TEST(@"-[cStringLength]", [s[0] cStringLength] == 13) + TEST(@"-[UTF8StringLength]", [s[0] UTF8StringLength] == 13) TEST(@"-[hash]", [s[0] hash] == 0xD576830E) TEST(@"-[characterAtIndex:]", [s[0] characterAtIndex: 0] == 't' && [s[0] characterAtIndex: 1] == 0xE4 && [s[0] characterAtIndex: 3] == 0x20AC && @@ -137,13 +137,14 @@ [[s[0] uppercaseString] isEqual: @"3𝄞1€SÄT"]) TEST(@"-[lowercaseString]", R([s[0] upper]) && [[s[0] lowercaseString] isEqual: @"3𝄞1€sät"]) - TEST(@"+[stringWithCString:length:]", - (s[0] = [OFMutableString stringWithCString: "\xEF\xBB\xBF" "foobar" - length: 6]) && + TEST(@"+[stringWithUTF8String:length:]", + (s[0] = [OFMutableString stringWithUTF8String: "\xEF\xBB\xBF" + "foobar" + length: 6]) && [s[0] isEqual: @"foo"]) TEST(@"+[stringWithUnicodeString:]", (s[1] = [OFString stringWithUnicodeString: ucstr]) && [s[1] isEqual: @"fööbär🀺"] && @@ -165,23 +166,23 @@ stringWithContentsOfURL: [OFURL URLWithString: @"file://testfile.txt"] encoding: OF_STRING_ENCODING_ISO_8859_1]) && [s[1] isEqual: @"testäöü"]) - TEST(@"-[appendCStringWithLength:]", - R([s[0] appendCString: "foo\xEF\xBB\xBF" "barqux" + 3 - withLength: 6]) && [s[0] isEqual: @"foobar"]) + TEST(@"-[appendUTFString:withLength:]", + R([s[0] appendUTF8String: "foo\xEF\xBB\xBF" "barqux" + 3 + withLength: 6]) && [s[0] isEqual: @"foobar"]) EXPECT_EXCEPTION(@"Detection of invalid UTF-8 encoding #1", OFInvalidEncodingException, - [OFString stringWithCString: "\xE0\x80"]) + [OFString stringWithUTF8String: "\xE0\x80"]) EXPECT_EXCEPTION(@"Detection of invalid UTF-8 encoding #2", OFInvalidEncodingException, - [OFString stringWithCString: "\xF0\x80\x80\xC0"]) + [OFString stringWithUTF8String: "\xF0\x80\x80\xC0"]) TEST(@"-[reverse] on UTF-8 strings", - (s[0] = [OFMutableString stringWithCString: "äöü€𝄞"]) && + (s[0] = [OFMutableString stringWithUTF8String: "äöü€𝄞"]) && R([s[0] reverse]) && [s[0] isEqual: @"𝄞€üöä"]) TEST(@"Conversion of ISO 8859-1 to UTF-8", [[OFString stringWithCString: "\xE4\xF6\xFC" encoding: OF_STRING_ENCODING_ISO_8859_1] Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -54,11 +54,11 @@ pspDebugScreenSetTextColor(0x0000FF); break; } pspDebugScreenSetXY(0, y); - pspDebugScreenPrintData([str cString], [str cStringLength]); + pspDebugScreenPrintData([str UTF8String], [str UTF8StringLength]); #elif defined(STDOUT) switch (color) { case 0: [of_stdout writeString: @"\r\033[K\033[1;33m"]; break; @@ -79,35 +79,32 @@ - (void)outputTesting: (OFString*)test inModule: (OFString*)module { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - [self outputString: [OFString stringWithFormat: @"[%s] %s: testing...", - [module cString], - [test cString]] + [self outputString: [OFString stringWithFormat: @"[%@] %@: testing...", + module, test] withColor: 0]; [pool release]; } - (void)outputSuccess: (OFString*)test inModule: (OFString*)module { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - [self outputString: [OFString stringWithFormat: @"[%s] %s: ok\n", - [module cString], - [test cString]] + [self outputString: [OFString stringWithFormat: @"[%@] %@: ok\n", + module, test] withColor: 1]; [pool release]; } - (void)outputFailure: (OFString*)test inModule: (OFString*)module { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - [self outputString: [OFString stringWithFormat: @"[%s] %s: failed\n", - [module cString], - [test cString]] + [self outputString: [OFString stringWithFormat: @"[%@] %@: failed\n", + module, test] withColor: 2]; [pool release]; } - (void)applicationDidFinishLaunching