Index: src/OFConstantString.m ================================================================== --- src/OFConstantString.m +++ src/OFConstantString.m @@ -50,14 +50,14 @@ if ((ivars = malloc(sizeof(*ivars))) == NULL) @throw [OFOutOfMemoryException newWithClass: isa requestedSize: sizeof(*ivars)]; memset(ivars, 0, sizeof(*ivars)); - ivars->string = (char*)s; - ivars->length = initialized; + ivars->cString = (char*)s; + ivars->cStringLength = initialized; - switch (of_string_check_utf8(ivars->string, ivars->length)) { + switch (of_string_check_utf8(ivars->cString, ivars->cStringLength)) { case 1: ivars->isUTF8 = YES; break; case -1: free(ivars); @@ -376,19 +376,10 @@ [self completeInitialization]; return [super compare: object]; } -/* From protocol OFSerialization */ -- (OFXMLElement*)XMLElementBySerializing -{ - if (initialized != SIZE_MAX) - [self completeInitialization]; - - return [super XMLElementBySerializing]; -} - /* From OFObject, but reimplemented in OFString */ - (BOOL)isEqual: (id)object { if (initialized != SIZE_MAX) [self completeInitialization]; Index: src/OFMutableString.h ================================================================== --- src/OFMutableString.h +++ src/OFMutableString.h @@ -24,66 +24,66 @@ */ @interface OFMutableString: OFString /** * \brief Sets the OFMutableString to the specified UTF-8 encoded C string. * - * \param string A UTF-8 encoded C string to set the OFMutableString to. + * \param newCString A UTF-8 encoded C string to set the OFMutableString to. */ -- (void)setToCString: (const char*)string; +- (void)setToCString: (const char*)newCString; /** * \brief Appends a UTF-8 encoded C string to the OFMutableString. * - * \param string A UTF-8 encoded C string to append + * \param cString A UTF-8 encoded C string to append */ -- (void)appendCString: (const char*)string; +- (void)appendCString: (const char*)cString; /** * \brief Appends a UTF-8 encoded C string with the specified length to the * OFMutableString. * - * \param string A UTF-8 encoded C string to append - * \param length The length of the UTF-8 encoded C string + * \param cString A UTF-8 encoded C string to append + * \param cStringLength The length of the UTF-8 encoded C string */ -- (void)appendCString: (const char*)string - withLength: (size_t)length; +- (void)appendCString: (const char*)cString + withLength: (size_t)cStringLength; /** * \brief Appends a C string with the specified encoding and length to the * OFMutableString. * - * \param string A C string to append + * \param cString A C string to append * \param encoding The encoding of the C string - * \param length The length of the UTF-8 encoded C string + * \param cStringLength The length of the UTF-8 encoded C string */ -- (void)appendCString: (const char*)string +- (void)appendCString: (const char*)cString withEncoding: (of_string_encoding_t)encoding - length: (size_t)length; + length: (size_t)cStringLength; /** * \brief Appends a UTF-8 encoded C string to the OFMutableString without * checking whether it is valid UTF-8. * * Only use this if you are 100% sure the string you append is either ASCII or * UTF-8! * - * \param string A UTF-8 encoded C string to append + * \param cString A UTF-8 encoded C string to append */ -- (void)appendCStringWithoutUTF8Checking: (const char*)string; +- (void)appendCStringWithoutUTF8Checking: (const char*)cString; /** * \brief Appends a UTF-8 encoded C string with the specified length to the * OFMutableString without checking whether it is valid UTF-8. * * Only use this if you are 100% sure the string you append is either ASCII or * UTF-8! * - * \param string A UTF-8 encoded C string to append - * \param length The length of the UTF-8 encoded C string + * \param cString A UTF-8 encoded C string to append + * \param cStringLength The length of the UTF-8 encoded C string */ -- (void)appendCStringWithoutUTF8Checking: (const char*)string - length: (size_t)length; +- (void)appendCStringWithoutUTF8Checking: (const char*)cString + length: (size_t)cStringLength; /** * \brief Appends another OFString to the OFMutableString. * * \param string An OFString to append Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -46,21 +46,21 @@ - (void)_applyTable: (const of_unichar_t* const[])table withSize: (size_t)tableSize { of_unichar_t c; of_unichar_t *unicodeString; - size_t unicodeLen, newLength, cLen; + size_t unicodeLen, newCStringLength, cLen; size_t i, j, d; - char *newString; + char *newCString; if (!s->isUTF8) { assert(tableSize >= 1); - uint8_t *p = (uint8_t*)s->string + s->length; + uint8_t *p = (uint8_t*)s->cString + s->cStringLength; uint8_t t; - while (--p >= (uint8_t*)s->string) + while (--p >= (uint8_t*)s->cString) if ((t = table[0][*p]) != 0) *p = t; return; } @@ -68,15 +68,15 @@ unicodeLen = [self length]; unicodeString = [self allocMemoryForNItems: unicodeLen withSize: sizeof(of_unichar_t)]; i = j = 0; - newLength = 0; + newCStringLength = 0; - while (i < s->length) { - cLen = of_string_utf8_to_unicode(s->string + i, s->length - i, - &c); + while (i < s->cStringLength) { + cLen = of_string_utf8_to_unicode(s->cString + i, + s->cStringLength - i, &c); if (cLen == 0 || c > 0x10FFFF) { [self freeMemory: unicodeString]; @throw [OFInvalidEncodingException newWithClass: isa]; } @@ -88,63 +88,63 @@ c = tc; } unicodeString[j++] = c; if (c < 0x80) - newLength++; + newCStringLength++; else if (c < 0x800) - newLength += 2; + newCStringLength += 2; else if (c < 0x10000) - newLength += 3; + newCStringLength += 3; else if (c < 0x110000) - newLength += 4; + newCStringLength += 4; else { [self freeMemory: unicodeString]; @throw [OFInvalidEncodingException newWithClass: isa]; } i += cLen; } @try { - newString = [self allocMemoryWithSize: newLength + 1]; + newCString = [self allocMemoryWithSize: newCStringLength + 1]; } @catch (id e) { [self freeMemory: unicodeString]; @throw e; } j = 0; for (i = 0; i < unicodeLen; i++) { if ((d = of_string_unicode_to_utf8(unicodeString[i], - newString + j)) == 0) { + newCString + j)) == 0) { [self freeMemory: unicodeString]; - [self freeMemory: newString]; + [self freeMemory: newCString]; @throw [OFInvalidEncodingException newWithClass: isa]; } j += d; } - assert(j == newLength); - newString[j] = 0; + assert(j == newCStringLength); + newCString[j] = 0; [self freeMemory: unicodeString]; - [self freeMemory: s->string]; - s->string = newString; - s->length = newLength; -} - -- (void)setToCString: (const char*)string -{ - size_t length = strlen(string); - - if (length >= 3 && !memcmp(string, "\xEF\xBB\xBF", 3)) { - string += 3; - length -= 3; - } - - switch (of_string_check_utf8(string, length)) { + [self freeMemory: s->cString]; + s->cString = newCString; + s->cStringLength = newCStringLength; +} + +- (void)setToCString: (const char*)newCString +{ + size_t newCStringLength = strlen(newCString); + + if (newCStringLength >= 3 && !memcmp(newCString, "\xEF\xBB\xBF", 3)) { + newCString += 3; + newCStringLength -= 3; + } + + switch (of_string_check_utf8(newCString, newCStringLength)) { case 0: s->isUTF8 = NO; break; case 1: s->isUTF8 = YES; @@ -151,98 +151,99 @@ break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; } - [self freeMemory: s->string]; - - s->length = length; - s->string = [self allocMemoryWithSize: length + 1]; - memcpy(s->string, string, length + 1); -} - -- (void)appendCString: (const char*)string -{ - size_t length = strlen(string); - - if (length >= 3 && !memcmp(string, "\xEF\xBB\xBF", 3)) { - string += 3; - length -= 3; - } - - switch (of_string_check_utf8(string, length)) { + [self freeMemory: s->cString]; + + s->cStringLength = newCStringLength; + s->cString = [self allocMemoryWithSize: newCStringLength + 1]; + memcpy(s->cString, newCString, newCStringLength + 1); +} + +- (void)appendCString: (const char*)cString +{ + size_t cStringLength = strlen(cString); + + if (cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) { + cString += 3; + cStringLength -= 3; + } + + switch (of_string_check_utf8(cString, cStringLength)) { case 1: s->isUTF8 = YES; break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; } - s->string = [self resizeMemory: s->string - toSize: s->length + length + 1]; - memcpy(s->string + s->length, string, length + 1); - s->length += length; -} - -- (void)appendCString: (const char*)string - withLength: (size_t)length -{ - if (length >= 3 && !memcmp(string, "\xEF\xBB\xBF", 3)) { - string += 3; - length -= 3; - } - - switch (of_string_check_utf8(string, length)) { + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + cStringLength + 1]; + memcpy(s->cString + s->cStringLength, cString, cStringLength + 1); + s->cStringLength += cStringLength; +} + +- (void)appendCString: (const char*)cString + withLength: (size_t)cStringLength +{ + if (cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) { + cString += 3; + cStringLength -= 3; + } + + switch (of_string_check_utf8(cString, cStringLength)) { case 1: s->isUTF8 = YES; break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; } - s->string = [self resizeMemory: s->string - toSize: s->length + length + 1]; - memcpy(s->string + s->length, string, length); - s->length += length; - s->string[s->length] = 0; + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + cStringLength + 1]; + memcpy(s->cString + s->cStringLength, cString, cStringLength); + s->cStringLength += cStringLength; + s->cString[s->cStringLength] = 0; } -- (void)appendCString: (const char*)string +- (void)appendCString: (const char*)cString withEncoding: (of_string_encoding_t)encoding - length: (size_t)length + length: (size_t)cStringLength { if (encoding == OF_STRING_ENCODING_UTF_8) - [self appendCString: string - withLength: length]; + [self appendCString: cString + withLength: cStringLength]; else { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - [self appendString: [OFString stringWithCString: string - encoding: encoding - length: length]]; + [self appendString: + [OFString stringWithCString: cString + encoding: encoding + length: cStringLength]]; [pool release]; } } -- (void)appendCStringWithoutUTF8Checking: (const char*)string -{ - size_t length; - - length = strlen(string); - s->string = [self resizeMemory: s->string - toSize: s->length + length + 1]; - memcpy(s->string + s->length, string, length + 1); - s->length += length; -} - -- (void)appendCStringWithoutUTF8Checking: (const char*)string - length: (size_t)length -{ - s->string = [self resizeMemory: s->string - toSize: s->length + length + 1]; - memcpy(s->string + s->length, string, length); - s->length += length; - s->string[s->length] = 0; +- (void)appendCStringWithoutUTF8Checking: (const char*)cString +{ + size_t cStringLength; + + cStringLength = strlen(cString); + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + cStringLength + 1]; + memcpy(s->cString + s->cStringLength, cString, cStringLength + 1); + s->cStringLength += cStringLength; +} + +- (void)appendCStringWithoutUTF8Checking: (const char*)cString + length: (size_t)cStringLength +{ + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + cStringLength + 1]; + memcpy(s->cString + s->cStringLength, cString, cStringLength); + s->cStringLength += cStringLength; + s->cString[s->cStringLength] = 0; } - (void)appendString: (OFString*)string { if (string == nil) @@ -263,25 +264,26 @@ } - (void)appendFormat: (OFConstantString*)format withArguments: (va_list)arguments { - char *t; - int length; + char *cString; + int cStringLength; if (format == nil) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - if ((length = of_vasprintf(&t, [format cString], arguments)) == -1) + if ((cStringLength = of_vasprintf(&cString, [format cString], + arguments)) == -1) @throw [OFInvalidFormatException newWithClass: isa]; @try { - [self appendCString: t - withLength: length]; + [self appendCString: cString + withLength: cStringLength]; } @finally { - free(t); + free(cString); } } - (void)prependString: (OFString*)string { @@ -289,98 +291,99 @@ atIndex: 0]; } - (void)reverse { - size_t i, j, length = s->length / 2; + size_t i, j; - madvise(s->string, s->length, MADV_SEQUENTIAL); + madvise(s->cString, s->cStringLength, MADV_SEQUENTIAL); /* We reverse all bytes and restore UTF-8 later, if necessary */ - for (i = 0, j = s->length - 1; i < length; i++, j--) { - s->string[i] ^= s->string[j]; - s->string[j] ^= s->string[i]; - s->string[i] ^= s->string[j]; + for (i = 0, j = s->cStringLength - 1; i < s->cStringLength / 2; + i++, j--) { + s->cString[i] ^= s->cString[j]; + s->cString[j] ^= s->cString[i]; + s->cString[i] ^= s->cString[j]; } if (!s->isUTF8) { - madvise(s->string, s->length, MADV_NORMAL); + madvise(s->cString, s->cStringLength, MADV_NORMAL); return; } - for (i = 0; i < s->length; i++) { + for (i = 0; i < s->cStringLength; i++) { /* ASCII */ - if (OF_LIKELY(!(s->string[i] & 0x80))) + if (OF_LIKELY(!(s->cString[i] & 0x80))) continue; /* A start byte can't happen first as we reversed everything */ - if (OF_UNLIKELY(s->string[i] & 0x40)) { - madvise(s->string, s->length, MADV_NORMAL); + if (OF_UNLIKELY(s->cString[i] & 0x40)) { + madvise(s->cString, s->cStringLength, MADV_NORMAL); @throw [OFInvalidEncodingException newWithClass: isa]; } /* Next byte must not be ASCII */ - if (OF_UNLIKELY(s->length < i + 1 || - !(s->string[i + 1] & 0x80))) { - madvise(s->string, s->length, MADV_NORMAL); + if (OF_UNLIKELY(s->cStringLength < i + 1 || + !(s->cString[i + 1] & 0x80))) { + madvise(s->cString, s->cStringLength, MADV_NORMAL); @throw [OFInvalidEncodingException newWithClass: isa]; } /* Next byte is the start byte */ - if (OF_LIKELY(s->string[i + 1] & 0x40)) { - s->string[i] ^= s->string[i + 1]; - s->string[i + 1] ^= s->string[i]; - s->string[i] ^= s->string[i + 1]; + if (OF_LIKELY(s->cString[i + 1] & 0x40)) { + s->cString[i] ^= s->cString[i + 1]; + s->cString[i + 1] ^= s->cString[i]; + s->cString[i] ^= s->cString[i + 1]; i++; continue; } /* Second next byte must not be ASCII */ - if (OF_UNLIKELY(s->length < i + 2 || - !(s->string[i + 2] & 0x80))) { - madvise(s->string, s->length, MADV_NORMAL); + if (OF_UNLIKELY(s->cStringLength < i + 2 || + !(s->cString[i + 2] & 0x80))) { + madvise(s->cString, s->cStringLength, MADV_NORMAL); @throw [OFInvalidEncodingException newWithClass: isa]; } /* Second next byte is the start byte */ - if (OF_LIKELY(s->string[i + 2] & 0x40)) { - s->string[i] ^= s->string[i + 2]; - s->string[i + 2] ^= s->string[i]; - s->string[i] ^= s->string[i + 2]; + if (OF_LIKELY(s->cString[i + 2] & 0x40)) { + s->cString[i] ^= s->cString[i + 2]; + s->cString[i + 2] ^= s->cString[i]; + s->cString[i] ^= s->cString[i + 2]; i += 2; continue; } /* Third next byte must not be ASCII */ - if (OF_UNLIKELY(s->length < i + 3 || - !(s->string[i + 3] & 0x80))) { - madvise(s->string, s->length, MADV_NORMAL); + if (OF_UNLIKELY(s->cStringLength < i + 3 || + !(s->cString[i + 3] & 0x80))) { + madvise(s->cString, s->cStringLength, MADV_NORMAL); @throw [OFInvalidEncodingException newWithClass: isa]; } /* Third next byte is the start byte */ - if (OF_LIKELY(s->string[i + 3] & 0x40)) { - s->string[i] ^= s->string[i + 3]; - s->string[i + 3] ^= s->string[i]; - s->string[i] ^= s->string[i + 3]; - - s->string[i + 1] ^= s->string[i + 2]; - s->string[i + 2] ^= s->string[i + 1]; - s->string[i + 1] ^= s->string[i + 2]; + if (OF_LIKELY(s->cString[i + 3] & 0x40)) { + s->cString[i] ^= s->cString[i + 3]; + s->cString[i + 3] ^= s->cString[i]; + s->cString[i] ^= s->cString[i + 3]; + + s->cString[i + 1] ^= s->cString[i + 2]; + s->cString[i + 2] ^= s->cString[i + 1]; + s->cString[i + 1] ^= s->cString[i + 2]; i += 3; continue; } /* UTF-8 does not allow more than 4 bytes per character */ - madvise(s->string, s->length, MADV_NORMAL); + madvise(s->cString, s->cStringLength, MADV_NORMAL); @throw [OFInvalidEncodingException newWithClass: isa]; } - madvise(s->string, s->length, MADV_NORMAL); + madvise(s->cString, s->cStringLength, MADV_NORMAL); } - (void)upper { [self _applyTable: of_unicode_upper_table @@ -394,54 +397,55 @@ } - (void)insertString: (OFString*)string atIndex: (size_t)index { - size_t newLength; + size_t newCStringLength; if (s->isUTF8) - index = of_string_index_to_position(s->string, index, - s->length); + index = of_string_index_to_position(s->cString, index, + s->cStringLength); - if (index > s->length) + if (index > s->cStringLength) @throw [OFOutOfRangeException newWithClass: isa]; - newLength = s->length + [string cStringLength]; - s->string = [self resizeMemory: s->string - toSize: newLength + 1]; - - memmove(s->string + index + [string cStringLength], s->string + index, - s->length - index); - memcpy(s->string + index, [string cString], [string cStringLength]); - s->string[newLength] = '\0'; - - s->length = newLength; + newCStringLength = s->cStringLength + [string cStringLength]; + s->cString = [self resizeMemory: s->cString + toSize: newCStringLength + 1]; + + memmove(s->cString + index + [string cStringLength], s->cString + index, + s->cStringLength - index); + memcpy(s->cString + index, [string cString], [string cStringLength]); + s->cString[newCStringLength] = '\0'; + + s->cStringLength = newCStringLength; } - (void)deleteCharactersFromIndex: (size_t)start toIndex: (size_t)end { if (s->isUTF8) { - start = of_string_index_to_position(s->string, start, - s->length); - end = of_string_index_to_position(s->string, end, s->length); + start = of_string_index_to_position(s->cString, start, + s->cStringLength); + end = of_string_index_to_position(s->cString, end, + s->cStringLength); } if (start > end) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - if (end > s->length) + if (end > s->cStringLength) @throw [OFOutOfRangeException newWithClass: isa]; - memmove(s->string + start, s->string + end, s->length - end); - s->length -= end - start; - s->string[s->length] = 0; + memmove(s->cString + start, s->cString + end, s->cStringLength - end); + s->cStringLength -= end - start; + s->cString[s->cStringLength] = 0; @try { - s->string = [self resizeMemory: s->string - toSize: s->length + 1]; + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ [e release]; } } @@ -454,36 +458,38 @@ - (void)replaceCharactersFromIndex: (size_t)start toIndex: (size_t)end withString: (OFString*)replacement { - size_t newLength; + size_t newCStringLength; if (s->isUTF8) { - start = of_string_index_to_position(s->string, start, - s->length); - end = of_string_index_to_position(s->string, end, s->length); + start = of_string_index_to_position(s->cString, start, + s->cStringLength); + end = of_string_index_to_position(s->cString, end, + s->cStringLength); } if (start > end) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - if (end > s->length) + if (end > s->cStringLength) @throw [OFOutOfRangeException newWithClass: isa]; - newLength = s->length - (end - start) + [replacement cStringLength]; - s->string = [self resizeMemory: s->string - toSize: newLength + 1]; + newCStringLength = s->cStringLength - (end - start) + + [replacement cStringLength]; + s->cString = [self resizeMemory: s->cString + toSize: newCStringLength + 1]; - memmove(s->string + end, s->string + start + - [replacement cStringLength], s->length - end); - memcpy(s->string + start, [replacement cString], + memmove(s->cString + end, s->cString + start + + [replacement cStringLength], s->cStringLength - end); + memcpy(s->cString + start, [replacement cString], [replacement cStringLength]); - s->string[newLength] = '\0'; + s->cString[newCStringLength] = '\0'; - s->length = newLength; + s->cStringLength = newCStringLength; } - (void)replaceCharactersInRange: (of_range_t)range withString: (OFString*)replacement { @@ -495,74 +501,78 @@ - (void)replaceOccurrencesOfString: (OFString*)string withString: (OFString*)replacement { const char *cString = [string cString]; const char *replacementCString = [replacement cString]; - size_t stringLen = [string cStringLength]; - size_t replacementLen = [replacement cStringLength]; - size_t i, last, newLength; - char *newString; + size_t cStringLength = [string cStringLength]; + size_t replacementCStringLength = [replacement cStringLength]; + size_t i, last, newCStringLength; + char *newCString; - if (stringLen > s->length) + if (cStringLength > s->cStringLength) return; - newString = NULL; - newLength = 0; + newCString = NULL; + newCStringLength = 0; - for (i = 0, last = 0; i <= s->length - stringLen; i++) { - if (memcmp(s->string + i, cString, stringLen)) + for (i = 0, last = 0; i <= s->cStringLength - cStringLength; i++) { + if (memcmp(s->cString + i, cString, cStringLength)) continue; @try { - newString = [self resizeMemory: newString - toSize: newLength + i - last + - replacementLen + 1]; + newCString = [self + resizeMemory: newCString + toSize: newCStringLength + i - last + + replacementCStringLength + 1]; } @catch (id e) { - [self freeMemory: newString]; + [self freeMemory: newCString]; @throw e; } - memcpy(newString + newLength, s->string + last, i - last); - memcpy(newString + newLength + i - last, replacementCString, - replacementLen); - newLength += i - last + replacementLen; - i += stringLen - 1; + memcpy(newCString + newCStringLength, s->cString + last, + i - last); + memcpy(newCString + newCStringLength + i - last, + replacementCString, replacementCStringLength); + newCStringLength += i - last + replacementCStringLength; + i += cStringLength - 1; last = i + 1; } @try { - newString = [self resizeMemory: newString - toSize: newLength + s->length - last + - 1]; + newCString = [self + resizeMemory: newCString + toSize: newCStringLength + + s->cStringLength - last + 1]; } @catch (id e) { - [self freeMemory: newString]; + [self freeMemory: newCString]; @throw e; } - memcpy(newString + newLength, s->string + last, s->length - last); - newLength += s->length - last; - newString[newLength] = 0; + memcpy(newCString + newCStringLength, s->cString + last, + s->cStringLength - last); + newCStringLength += s->cStringLength - last; + newCString[newCStringLength] = 0; - [self freeMemory: s->string]; - s->string = newString; - s->length = newLength; + [self freeMemory: s->cString]; + s->cString = newCString; + s->cStringLength = newCStringLength; } - (void)deleteLeadingWhitespaces { size_t i; - for (i = 0; i < s->length; i++) - if (s->string[i] != ' ' && s->string[i] != '\t' && - s->string[i] != '\n' && s->string[i] != '\r') + for (i = 0; i < s->cStringLength; i++) + if (s->cString[i] != ' ' && s->cString[i] != '\t' && + s->cString[i] != '\n' && s->cString[i] != '\r') break; - s->length -= i; - memmove(s->string, s->string + i, s->length); - s->string[s->length] = '\0'; + s->cStringLength -= i; + memmove(s->cString, s->cString + i, s->cStringLength); + s->cString[s->cStringLength] = '\0'; @try { - s->string = [self resizeMemory: s->string - toSize: s->length + 1]; + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ [e release]; } } @@ -571,23 +581,23 @@ { size_t d; char *p; d = 0; - for (p = s->string + s->length - 1; p >= s->string; p--) { + for (p = s->cString + s->cStringLength - 1; p >= s->cString; p--) { if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r') break; *p = '\0'; d++; } - s->length -= d; + s->cStringLength -= d; @try { - s->string = [self resizeMemory: s->string - toSize: s->length + 1]; + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ [e release]; } } @@ -596,32 +606,32 @@ { size_t d, i; char *p; d = 0; - for (p = s->string + s->length - 1; p >= s->string; p--) { + for (p = s->cString + s->cStringLength - 1; p >= s->cString; p--) { if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r') break; *p = '\0'; d++; } - s->length -= d; + s->cStringLength -= d; - for (i = 0; i < s->length; i++) - if (s->string[i] != ' ' && s->string[i] != '\t' && - s->string[i] != '\n' && s->string[i] != '\r') + for (i = 0; i < s->cStringLength; i++) + if (s->cString[i] != ' ' && s->cString[i] != '\t' && + s->cString[i] != '\n' && s->cString[i] != '\r') break; - s->length -= i; - memmove(s->string, s->string + i, s->length); - s->string[s->length] = '\0'; + s->cStringLength -= i; + memmove(s->cString, s->cString + i, s->cStringLength); + s->cString[s->cStringLength] = '\0'; @try { - s->string = [self resizeMemory: s->string - toSize: s->length + 1]; + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ [e release]; } } Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -73,12 +73,12 @@ * for each constant string. We change the const char* to point to our * struct on the first call to a constant string so we can have more * than those two ivars. */ struct of_string_ivars { - char *string; - size_t length; + char *cString; + size_t cStringLength; BOOL isUTF8; } *restrict s; /* * Unused in OFString, however, OFConstantString sets this to SIZE_MAX * once it allocated and initialized the struct. @@ -92,48 +92,48 @@ + string; /** * Creates a new OFString from a UTF-8 encoded C string. * - * \param string A UTF-8 encoded C string to initialize the OFString with + * \param cString A UTF-8 encoded C string to initialize the OFString with * \return A new autoreleased OFString */ -+ stringWithCString: (const char*)string; ++ stringWithCString: (const char*)cString; /** * Creates a new OFString from a C string with the specified encoding. * * \param string A C string to initialize the OFString with * \param encoding The encoding of the C string * \return A new autoreleased OFString */ -+ stringWithCString: (const char*)string ++ stringWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding; /** * Creates a new OFString from a C string with the specified encoding and * length. * - * \param string A C string to initialize the OFString with + * \param cString A C string to initialize the OFString with * \param encoding The encoding of the C string - * \param length The length of the C string + * \param cStringLength The length of the C string * \return A new autoreleased OFString */ -+ stringWithCString: (const char*)string ++ stringWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding - length: (size_t)length; + length: (size_t)cStringLength; /** * Creates a new OFString from a UTF-8 encoded C string with the specified * length. * - * \param string A UTF-8 encoded C string to initialize the OFString with - * \param length The length of the UTF-8 encoded C string + * \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*)string - length: (size_t)length; ++ stringWithCString: (const char*)cString + length: (size_t)cStringLength; /** * Creates a new OFString from another string. * * \param string A string to initialize the OFString with @@ -290,49 +290,49 @@ encoding: (of_string_encoding_t)encoding; /** * Initializes an already allocated OFString from a UTF-8 encoded C string. * - * \param string A UTF-8 encoded C string to initialize the OFString with + * \param cString A UTF-8 encoded C string to initialize the OFString with * \return An initialized OFString */ -- initWithCString: (const char*)string; +- initWithCString: (const char*)cString; /** * Initializes an already allocated OFString from a C string with the specified * encoding. * - * \param string A C string to initialize the OFString with + * \param cString A C string to initialize the OFString with * \param encoding The encoding of the C string * \return An initialized OFString */ -- initWithCString: (const char*)string +- initWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding; /** * Initializes an already allocated OFString from a C string with the specified * encoding and length. * - * \param string A C string to initialize the OFString with + * \param cString A C string to initialize the OFString with * \param encoding The encoding of the C string - * \param length The length of the C string + * \param cStringLength The length of the C string * \return An initialized OFString */ -- initWithCString: (const char*)string +- initWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding - length: (size_t)length; + length: (size_t)cStringLength; /** * Initializes an already allocated OFString from a UTF-8 encoded C string with * the specified length. * - * \param string A UTF-8 encoded C string to initialize the OFString with - * \param length The length of the UTF-8 encoded C string + * \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*)string - length: (size_t)length; +- initWithCString: (const char*)cString + length: (size_t)cStringLength; /** * Initializes an already allocated OFString with another string. * * \param string A string to initialize the OFString with Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -273,36 +273,36 @@ + string { return [[[self alloc] init] autorelease]; } -+ stringWithCString: (const char*)string ++ stringWithCString: (const char*)cString { - return [[[self alloc] initWithCString: string] autorelease]; + return [[[self alloc] initWithCString: cString] autorelease]; } -+ stringWithCString: (const char*)string ++ stringWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding { - return [[[self alloc] initWithCString: string + return [[[self alloc] initWithCString: cString encoding: encoding] autorelease]; } -+ stringWithCString: (const char*)string ++ stringWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding - length: (size_t)length + length: (size_t)cStringLength { - return [[[self alloc] initWithCString: string + return [[[self alloc] initWithCString: cString encoding: encoding - length: length] autorelease]; + length: cStringLength] autorelease]; } -+ stringWithCString: (const char*)string - length: (size_t)length ++ stringWithCString: (const char*)cString + length: (size_t)cStringLength { - return [[[self alloc] initWithCString: string - length: length] autorelease]; + return [[[self alloc] initWithCString: cString + length: cStringLength] autorelease]; } + stringWithString: (OFString*)string { return [[[self alloc] initWithString: string] autorelease]; @@ -420,100 +420,101 @@ @try { s = [self allocMemoryWithSize: sizeof(*s)]; memset(s, 0, sizeof(*s)); - s->string = [self allocMemoryWithSize: 1]; - s->string[0] = '\0'; + s->cString = [self allocMemoryWithSize: 1]; + s->cString[0] = '\0'; } @catch (id e) { [self release]; @throw e; } return self; } -- initWithCString: (const char*)string +- initWithCString: (const char*)cString { - return [self initWithCString: string + return [self initWithCString: cString encoding: OF_STRING_ENCODING_UTF_8 - length: strlen(string)]; + length: strlen(cString)]; } -- initWithCString: (const char*)string +- initWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding { - return [self initWithCString: string + return [self initWithCString: cString encoding: encoding - length: strlen(string)]; + length: strlen(cString)]; } -- initWithCString: (const char*)string +- initWithCString: (const char*)cString encoding: (of_string_encoding_t)encoding - length: (size_t)length + length: (size_t)cStringLength { self = [super init]; @try { size_t i, j; const uint16_t *table; if (encoding == OF_STRING_ENCODING_UTF_8 && - length >= 3 && !memcmp(string, "\xEF\xBB\xBF", 3)) { - string += 3; - length -= 3; + cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) { + cString += 3; + cStringLength -= 3; } s = [self allocMemoryWithSize: sizeof(*s)]; memset(s, 0, sizeof(*s)); - s->string = [self allocMemoryWithSize: length + 1]; - s->length = length; + s->cString = [self allocMemoryWithSize: cStringLength + 1]; + s->cStringLength = cStringLength; if (encoding == OF_STRING_ENCODING_UTF_8) { - switch (of_string_check_utf8(string, length)) { + switch (of_string_check_utf8(cString, cStringLength)) { case 1: s->isUTF8 = YES; break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; } - memcpy(s->string, string, length); - s->string[length] = 0; + memcpy(s->cString, cString, cStringLength); + s->cString[cStringLength] = 0; return self; } if (encoding == OF_STRING_ENCODING_ISO_8859_1) { - for (i = j = 0; i < length; i++) { + for (i = j = 0; i < cStringLength; i++) { char buffer[4]; size_t bytes; - if (!(string[i] & 0x80)) { - s->string[j++] = string[i]; + if (!(cString[i] & 0x80)) { + s->cString[j++] = cString[i]; continue; } s->isUTF8 = YES; bytes = of_string_unicode_to_utf8( - (uint8_t)string[i], buffer); + (uint8_t)cString[i], buffer); if (bytes == 0) @throw [OFInvalidEncodingException newWithClass: isa]; - s->length += bytes - 1; - s->string = [self resizeMemory: s->string - toSize: s->length + 1]; + s->cStringLength += bytes - 1; + s->cString = [self + resizeMemory: s->cString + toSize: s->cStringLength + 1]; - memcpy(s->string + j, buffer, bytes); + memcpy(s->cString + j, buffer, bytes); j += bytes; } - s->string[s->length] = 0; + s->cString[s->cStringLength] = 0; return self; } switch (encoding) { @@ -525,21 +526,21 @@ break; default: @throw [OFInvalidEncodingException newWithClass: isa]; } - for (i = j = 0; i < length; i++) { + for (i = j = 0; i < cStringLength; i++) { char buffer[4]; of_unichar_t character; size_t characterBytes; - if (!(string[i] & 0x80)) { - s->string[j++] = string[i]; + if (!(cString[i] & 0x80)) { + s->cString[j++] = cString[i]; continue; } - character = table[(uint8_t)string[i]]; + character = table[(uint8_t)cString[i]]; if (character == 0xFFFD) @throw [OFInvalidEncodingException newWithClass: isa]; @@ -549,33 +550,33 @@ if (characterBytes == 0) @throw [OFInvalidEncodingException newWithClass: isa]; - s->length += characterBytes - 1; - s->string = [self resizeMemory: s->string - toSize: s->length + 1]; + s->cStringLength += characterBytes - 1; + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + 1]; - memcpy(s->string + j, buffer, characterBytes); + memcpy(s->cString + j, buffer, characterBytes); j += characterBytes; } - s->string[s->length] = 0; + s->cString[s->cStringLength] = 0; } @catch (id e) { [self release]; @throw e; } return self; } -- initWithCString: (const char*)string - length: (size_t)length +- initWithCString: (const char*)cString + length: (size_t)cStringLength { - return [self initWithCString: string + return [self initWithCString: cString encoding: OF_STRING_ENCODING_UTF_8 - length: length]; + length: cStringLength]; } - initWithString: (OFString*)string { self = [super init]; @@ -585,29 +586,29 @@ s = [self allocMemoryWithSize: sizeof(*s)]; memset(s, 0, sizeof(*s)); cString = [string cString]; - s->length = [string cStringLength]; + s->cStringLength = [string cStringLength]; - switch (of_string_check_utf8(cString, s->length)) { + switch (of_string_check_utf8(cString, s->cStringLength)) { case 1: s->isUTF8 = YES; break; case -1:; @throw [OFInvalidEncodingException newWithClass: isa]; } - if ((s->string = strdup(cString)) == NULL) + if ((s->cString = strdup(cString)) == NULL) @throw [OFOutOfMemoryException newWithClass: isa - requestedSize: s->length + 1]; + requestedSize: s->cStringLength + 1]; @try { - [self addMemoryToPool: s->string]; + [self addMemoryToPool: s->cString]; } @catch (id e) { - free(s->string); + free(s->cString); @throw e; } } @catch (id e) { [self release]; @throw e; @@ -660,58 +661,58 @@ swap = YES; s = [self allocMemoryWithSize: sizeof(*s)]; memset(s, 0, sizeof(*s)); - s->length = length; - s->string = [self allocMemoryWithSize: (length * 4) + 1]; + s->cStringLength = length; + s->cString = [self allocMemoryWithSize: (length * 4) + 1]; for (i = 0; i < length; i++) { char buffer[4]; size_t characterLen = of_string_unicode_to_utf8( (swap ? of_bswap32(string[i]) : string[i]), buffer); switch (characterLen) { case 1: - s->string[j++] = buffer[0]; + s->cString[j++] = buffer[0]; break; case 2: s->isUTF8 = YES; - s->length++; + s->cStringLength++; - memcpy(s->string + j, buffer, 2); + memcpy(s->cString + j, buffer, 2); j += 2; break; case 3: s->isUTF8 = YES; - s->length += 2; + s->cStringLength += 2; - memcpy(s->string + j, buffer, 3); + memcpy(s->cString + j, buffer, 3); j += 3; break; case 4: s->isUTF8 = YES; - s->length += 3; + s->cStringLength += 3; - memcpy(s->string + j, buffer, 4); + memcpy(s->cString + j, buffer, 4); j += 4; break; default: @throw [OFInvalidEncodingException newWithClass: isa]; } } - s->string[j] = '\0'; + s->cString[j] = '\0'; @try { - s->string = [self resizeMemory: s->string - toSize: s->length + 1]; + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ [e release]; } } @catch (id e) { @@ -766,12 +767,12 @@ swap = YES; s = [self allocMemoryWithSize: sizeof(*s)]; memset(s, 0, sizeof(*s)); - s->length = length; - s->string = [self allocMemoryWithSize: (length * 4) + 1]; + s->cStringLength = length; + s->cString = [self allocMemoryWithSize: (length * 4) + 1]; for (i = 0; i < length; i++) { char buffer[4]; of_unichar_t character = (swap ? of_bswap16(string[i]) : string[i]); @@ -801,47 +802,47 @@ characterLen = of_string_unicode_to_utf8( character, buffer); switch (characterLen) { case 1: - s->string[j++] = buffer[0]; + s->cString[j++] = buffer[0]; break; case 2: s->isUTF8 = YES; - s->length++; + s->cStringLength++; - memcpy(s->string + j, buffer, 2); + memcpy(s->cString + j, buffer, 2); j += 2; break; case 3: s->isUTF8 = YES; - s->length += 2; + s->cStringLength += 2; - memcpy(s->string + j, buffer, 3); + memcpy(s->cString + j, buffer, 3); j += 3; break; case 4: s->isUTF8 = YES; - s->length += 3; + s->cStringLength += 3; - memcpy(s->string + j, buffer, 4); + memcpy(s->cString + j, buffer, 4); j += 4; break; default: @throw [OFInvalidEncodingException newWithClass: isa]; } } - s->string[j] = '\0'; + s->cString[j] = '\0'; @try { - s->string = [self resizeMemory: s->string - toSize: s->length + 1]; + s->cString = [self resizeMemory: s->cString + toSize: s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ [e release]; } } @catch (id e) { @@ -869,38 +870,39 @@ arguments: (va_list)arguments { self = [super init]; @try { - int length; + int cStringLength; if (format == nil) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; s = [self allocMemoryWithSize: sizeof(*s)]; memset(s, 0, sizeof(*s)); - if ((length = of_vasprintf(&s->string, [format cString], + if ((cStringLength = of_vasprintf(&s->cString, [format cString], arguments)) == -1) @throw [OFInvalidFormatException newWithClass: isa]; - s->length = length; + s->cStringLength = cStringLength; @try { - switch (of_string_check_utf8(s->string, length)) { + switch (of_string_check_utf8(s->cString, + cStringLength)) { case 1: s->isUTF8 = YES; break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; } - [self addMemoryToPool: s->string]; + [self addMemoryToPool: s->cString]; } @catch (id e) { - free(s->string); + free(s->cString); } } @catch (id e) { [self release]; @throw e; } @@ -926,20 +928,20 @@ { self = [super init]; @try { OFString *component; - size_t i, length; + size_t i, cStringLength; va_list argumentsCopy; s = [self allocMemoryWithSize: sizeof(*s)]; memset(s, 0, sizeof(*s)); - s->length = [firstComponent cStringLength]; + s->cStringLength = [firstComponent cStringLength]; switch (of_string_check_utf8([firstComponent cString], - s->length)) { + s->cStringLength)) { case 1: s->isUTF8 = YES; break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; @@ -946,38 +948,39 @@ } /* Calculate length */ va_copy(argumentsCopy, arguments); while ((component = va_arg(argumentsCopy, OFString*)) != nil) { - length = [component cStringLength]; - s->length += 1 + length; + cStringLength = [component cStringLength]; + s->cStringLength += 1 + cStringLength; switch (of_string_check_utf8([component cString], - length)) { + cStringLength)) { case 1: s->isUTF8 = YES; break; case -1: @throw [OFInvalidEncodingException newWithClass: isa]; } } - s->string = [self allocMemoryWithSize: s->length + 1]; + s->cString = [self allocMemoryWithSize: s->cStringLength + 1]; - length = [firstComponent cStringLength]; - memcpy(s->string, [firstComponent cString], length); - i = length; + cStringLength = [firstComponent cStringLength]; + memcpy(s->cString, [firstComponent cString], cStringLength); + i = cStringLength; while ((component = va_arg(arguments, OFString*)) != nil) { - length = [component cStringLength]; - s->string[i] = OF_PATH_DELIM; - memcpy(s->string + i + 1, [component cString], length); - i += 1 + length; + cStringLength = [component cStringLength]; + s->cString[i] = OF_PATH_DELIM; + memcpy(s->cString + i + 1, [component cString], + cStringLength); + i += 1 + cStringLength; } - s->string[i] = '\0'; + s->cString[i] = '\0'; } @catch (id e) { [self release]; @throw e; } @@ -1117,34 +1120,34 @@ return self; } - (const char*)cString { - return s->string; + return s->cString; } - (size_t)length { /* FIXME: Maybe cache this in an ivar? */ if (!s->isUTF8) - return s->length; + return s->cStringLength; - return of_string_position_to_index(s->string, s->length); + return of_string_position_to_index(s->cString, s->cStringLength); } - (size_t)cStringLength { - return s->length; + return s->cStringLength; } - (BOOL)isEqual: (id)object { if (![object isKindOfClass: [OFString class]]) return NO; - if (strcmp(s->string, [object cString])) + if (strcmp(s->cString, [object cString])) return NO; return YES; } @@ -1159,75 +1162,79 @@ } - (of_comparison_result_t)compare: (id)object { OFString *otherString; - size_t otherLen, minLen; - int cmp; + size_t otherCStringLength, minimumCStringLength; + int compare; if (![object isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; otherString = object; - otherLen = [otherString cStringLength]; - minLen = (s->length > otherLen ? otherLen : s->length); + otherCStringLength = [otherString cStringLength]; + minimumCStringLength = (s->cStringLength > otherCStringLength + ? otherCStringLength : s->cStringLength); - if ((cmp = memcmp(s->string, [otherString cString], minLen)) == 0) { - if (s->length > otherLen) + if ((compare = memcmp(s->cString, [otherString cString], + minimumCStringLength)) == 0) { + if (s->cStringLength > otherCStringLength) return OF_ORDERED_DESCENDING; - if (s->length < otherLen) + if (s->cStringLength < otherCStringLength) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } - if (cmp > 0) + if (compare > 0) return OF_ORDERED_DESCENDING; else return OF_ORDERED_ASCENDING; } - (of_comparison_result_t)caseInsensitiveCompare: (OFString*)otherString { const char *otherCString; - size_t i, j, otherLen, minLen; - int cmp; + size_t i, j, otherCStringLength, minimumCStringLength; + int compare; if (![otherString isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; otherCString = [otherString cString]; - otherLen = [otherString cStringLength]; + otherCStringLength = [otherString cStringLength]; if (!s->isUTF8) { - minLen = (s->length > otherLen ? otherLen : s->length); + minimumCStringLength = (s->cStringLength > otherCStringLength + ? otherCStringLength : s->cStringLength); - if ((cmp = memcasecmp(s->string, otherCString, minLen)) == 0) { - if (s->length > otherLen) + if ((compare = memcasecmp(s->cString, otherCString, + minimumCStringLength)) == 0) { + if (s->cStringLength > otherCStringLength) return OF_ORDERED_DESCENDING; - if (s->length < otherLen) + if (s->cStringLength < otherCStringLength) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } - if (cmp > 0) + if (compare > 0) return OF_ORDERED_DESCENDING; else return OF_ORDERED_ASCENDING; } i = j = 0; - while (i < s->length && j < otherLen) { + while (i < s->cStringLength && j < otherCStringLength) { of_unichar_t c1, c2; size_t l1, l2; - l1 = of_string_utf8_to_unicode(s->string + i, s->length - i, - &c1); - l2 = of_string_utf8_to_unicode(otherCString + j, otherLen - j, - &c2); + l1 = of_string_utf8_to_unicode(s->cString + i, + s->cStringLength - i, &c1); + l2 = of_string_utf8_to_unicode(otherCString + j, + otherCStringLength - j, &c2); if (l1 == 0 || l2 == 0 || c1 > 0x10FFFF || c2 > 0x10FFFF) @throw [OFInvalidEncodingException newWithClass: isa]; if (c1 >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) { @@ -1253,13 +1260,13 @@ i += l1; j += l2; } - if (s->length - i > otherLen - j) + if (s->cStringLength - i > otherCStringLength - j) return OF_ORDERED_DESCENDING; - else if (s->length - i < otherLen - j) + else if (s->cStringLength - i < otherCStringLength - j) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } @@ -1267,12 +1274,12 @@ { uint32_t hash; size_t i; OF_HASH_INIT(hash); - for (i = 0; i < s->length; i++) - OF_HASH_ADD(hash, s->string[i]); + for (i = 0; i < s->cStringLength; i++) + OF_HASH_ADD(hash, s->cString[i]); OF_HASH_FINALIZE(hash); return hash; } @@ -1306,65 +1313,65 @@ return element; } - (of_unichar_t)characterAtIndex: (size_t)index { - of_unichar_t c; - - if (!s->isUTF8) { - if (index >= s->length) - @throw [OFOutOfRangeException newWithClass: isa]; - - return s->string[index]; - } - - index = of_string_index_to_position(s->string, index, s->length); - - if (index >= s->length) - @throw [OFOutOfRangeException newWithClass: isa]; - - if (!of_string_utf8_to_unicode(s->string + index, s->length - index, - &c)) - @throw [OFInvalidEncodingException newWithClass: isa]; - - return c; + of_unichar_t character; + + if (!s->isUTF8) { + if (index >= s->cStringLength) + @throw [OFOutOfRangeException newWithClass: isa]; + + return s->cString[index]; + } + + index = of_string_index_to_position(s->cString, index, + s->cStringLength); + + if (index >= s->cStringLength) + @throw [OFOutOfRangeException newWithClass: isa]; + + if (!of_string_utf8_to_unicode(s->cString + index, + s->cStringLength - index, &character)) + @throw [OFInvalidEncodingException newWithClass: isa]; + + return character; } - (size_t)indexOfFirstOccurrenceOfString: (OFString*)string { const char *cString = [string cString]; - size_t stringLen = [string cStringLength]; - size_t i; + size_t i, cStringLength = [string cStringLength]; - if (stringLen == 0) + if (cStringLength == 0) return 0; - if (stringLen > s->length) + if (cStringLength > s->cStringLength) return OF_INVALID_INDEX; - for (i = 0; i <= s->length - stringLen; i++) - if (!memcmp(s->string + i, cString, stringLen)) - return of_string_position_to_index(s->string, i); + for (i = 0; i <= s->cStringLength - cStringLength; i++) + if (!memcmp(s->cString + i, cString, cStringLength)) + return of_string_position_to_index(s->cString, i); return OF_INVALID_INDEX; } - (size_t)indexOfLastOccurrenceOfString: (OFString*)string { const char *cString = [string cString]; - size_t stringLen = [string cStringLength]; - size_t i; + size_t i, cStringLength = [string cStringLength]; - if (stringLen == 0) - return of_string_position_to_index(s->string, s->length); + if (cStringLength == 0) + return of_string_position_to_index(s->cString, + s->cStringLength); - if (stringLen > s->length) + if (cStringLength > s->cStringLength) return OF_INVALID_INDEX; - for (i = s->length - stringLen;; i--) { - if (!memcmp(s->string + i, cString, stringLen)) - return of_string_position_to_index(s->string, i); + for (i = s->cStringLength - cStringLength;; i--) { + if (!memcmp(s->cString + i, cString, cStringLength)) + return of_string_position_to_index(s->cString, i); /* Did not match and we're at the last char */ if (i == 0) return OF_INVALID_INDEX; } @@ -1371,43 +1378,43 @@ } - (BOOL)containsString: (OFString*)string { const char *cString = [string cString]; - size_t stringLen = [string cStringLength]; - size_t i; + size_t i, cStringLength = [string cStringLength]; - if (stringLen == 0) + if (cStringLength == 0) return YES; - if (stringLen > s->length) + if (cStringLength > s->cStringLength) return NO; - for (i = 0; i <= s->length - stringLen; i++) - if (!memcmp(s->string + i, cString, stringLen)) + for (i = 0; i <= s->cStringLength - cStringLength; i++) + if (!memcmp(s->cString + i, cString, cStringLength)) return YES; return NO; } - (OFString*)substringFromIndex: (size_t)start toIndex: (size_t)end { if (s->isUTF8) { - start = of_string_index_to_position(s->string, start, - s->length); - end = of_string_index_to_position(s->string, end, s->length); + start = of_string_index_to_position(s->cString, start, + s->cStringLength); + end = of_string_index_to_position(s->cString, end, + s->cStringLength); } if (start > end) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - if (end > s->length) + if (end > s->cStringLength) @throw [OFOutOfRangeException newWithClass: isa]; - return [OFString stringWithCString: s->string + start + return [OFString stringWithCString: s->cString + start length: end - start]; } - (OFString*)substringWithRange: (of_range_t)range { @@ -1431,13 +1438,12 @@ return new; } - (OFString*)stringByPrependingString: (OFString*)string { - OFMutableString *new; + OFMutableString *new = [[string mutableCopy] autorelease]; - new = [OFMutableString stringWithString: string]; [new appendString: self]; /* * Class swizzle the string to be immutable. We declared the return type * to be OFString*, so it can't be modified anyway. But not swizzling it @@ -1447,13 +1453,12 @@ return new; } - (OFString*)uppercaseString { - OFMutableString *new; + OFMutableString *new = [[self mutableCopy] autorelease]; - new = [OFMutableString stringWithString: self]; [new upper]; /* * Class swizzle the string to be immutable. We declared the return type * to be OFString*, so it can't be modified anyway. But not swizzling it @@ -1463,13 +1468,12 @@ return new; } - (OFString*)lowercaseString { - OFMutableString *new; + OFMutableString *new = [[self mutableCopy] autorelease]; - new = [OFMutableString stringWithString: self]; [new lower]; /* * Class swizzle the string to be immutable. We declared the return type * to be OFString*, so it can't be modified anyway. But not swizzling it @@ -1479,13 +1483,12 @@ return new; } - (OFString*)stringByDeletingLeadingWhitespaces { - OFMutableString *new; + OFMutableString *new = [[self mutableCopy] autorelease]; - new = [OFMutableString stringWithString: self]; [new deleteLeadingWhitespaces]; /* * Class swizzle the string to be immutable. We declared the return type * to be OFString*, so it can't be modified anyway. But not swizzling it @@ -1495,13 +1498,12 @@ return new; } - (OFString*)stringByDeletingTrailingWhitespaces { - OFMutableString *new; + OFMutableString *new = [[self mutableCopy] autorelease]; - new = [OFMutableString stringWithString: self]; [new deleteTrailingWhitespaces]; /* * Class swizzle the string to be immutable. We declared the return type * to be OFString*, so it can't be modified anyway. But not swizzling it @@ -1511,13 +1513,12 @@ return new; } - (OFString*)stringByDeletingLeadingAndTrailingWhitespaces { - OFMutableString *new; + OFMutableString *new = [[self mutableCopy] autorelease]; - new = [OFMutableString stringWithString: self]; [new deleteLeadingAndTrailingWhitespaces]; /* * Class swizzle the string to be immutable. We declared the return type * to be OFString*, so it can't be modified anyway. But not swizzling it @@ -1527,57 +1528,57 @@ return new; } - (BOOL)hasPrefix: (OFString*)prefix { - size_t length = [prefix cStringLength]; + size_t cStringLength = [prefix cStringLength]; - if (length > s->length) + if (cStringLength > s->cStringLength) return NO; - return !memcmp(s->string, [prefix cString], length); + return !memcmp(s->cString, [prefix cString], cStringLength); } - (BOOL)hasSuffix: (OFString*)suffix { - size_t length = [suffix cStringLength]; + size_t cStringLength = [suffix cStringLength]; - if (length > s->length) + if (cStringLength > s->cStringLength) return NO; - return !memcmp(s->string + (s->length - length), [suffix cString], - length); + return !memcmp(s->cString + (s->cStringLength - cStringLength), + [suffix cString], cStringLength); } - (OFArray*)componentsSeparatedByString: (OFString*)delimiter { OFAutoreleasePool *pool; OFMutableArray *array; - const char *delim = [delimiter cString]; - size_t delimLen = [delimiter cStringLength]; + const char *cString = [delimiter cString]; + size_t cStringLength = [delimiter cStringLength]; size_t i, last; array = [OFMutableArray array]; pool = [[OFAutoreleasePool alloc] init]; - if (delimLen > s->length) { + if (cStringLength > s->cStringLength) { [array addObject: [[self copy] autorelease]]; [pool release]; return array; } - for (i = 0, last = 0; i <= s->length - delimLen; i++) { - if (memcmp(s->string + i, delim, delimLen)) + for (i = 0, last = 0; i <= s->cStringLength - cStringLength; i++) { + if (memcmp(s->cString + i, cString, cStringLength)) continue; - [array addObject: [OFString stringWithCString: s->string + last + [array addObject: [OFString stringWithCString: s->cString + last length: i - last]]; - i += delimLen - 1; + i += cStringLength - 1; last = i + 1; } - [array addObject: [OFString stringWithCString: s->string + last]]; + [array addObject: [OFString stringWithCString: s->cString + last]]; [pool release]; /* * Class swizzle the array to be immutable. We declared the return type @@ -1590,40 +1591,41 @@ - (OFArray*)pathComponents { OFMutableArray *ret; OFAutoreleasePool *pool; - size_t i, last = 0, pathLen = s->length; + size_t i, last = 0, pathCStringLength = s->cStringLength; ret = [OFMutableArray array]; - if (pathLen == 0) + if (pathCStringLength == 0) return ret; pool = [[OFAutoreleasePool alloc] init]; #ifndef _WIN32 - if (s->string[pathLen - 1] == OF_PATH_DELIM) + if (s->cString[pathCStringLength - 1] == OF_PATH_DELIM) #else - if (s->string[pathLen - 1] == '/' || s->string[pathLen - 1] == '\\') + if (s->cString[pathCStringLength - 1] == '/' || + s->cString[pathCStringLength - 1] == '\\') #endif - pathLen--; + pathCStringLength--; - for (i = 0; i < pathLen; i++) { + for (i = 0; i < pathCStringLength; i++) { #ifndef _WIN32 - if (s->string[i] == OF_PATH_DELIM) { + if (s->cString[i] == OF_PATH_DELIM) { #else - if (s->string[i] == '/' || s->string[i] == '\\') { + if (s->cString[i] == '/' || s->cString[i] == '\\') { #endif [ret addObject: - [OFString stringWithCString: s->string + last + [OFString stringWithCString: s->cString + last length: i - last]]; last = i + 1; } } - [ret addObject: [OFString stringWithCString: s->string + last + [ret addObject: [OFString stringWithCString: s->cString + last length: i - last]]; [pool release]; /* @@ -1635,28 +1637,29 @@ return ret; } - (OFString*)lastPathComponent { - size_t pathLen = s->length; + size_t pathCStringLength = s->cStringLength; ssize_t i; - if (pathLen == 0) + if (pathCStringLength == 0) return @""; #ifndef _WIN32 - if (s->string[pathLen - 1] == OF_PATH_DELIM) + if (s->cString[pathCStringLength - 1] == OF_PATH_DELIM) #else - if (s->string[pathLen - 1] == '/' || s->string[pathLen - 1] == '\\') + if (s->cString[pathCStringLength - 1] == '/' || + s->cString[pathCStringLength - 1] == '\\') #endif - pathLen--; + pathCStringLength--; - for (i = pathLen - 1; i >= 0; i--) { + for (i = pathCStringLength - 1; i >= 0; i--) { #ifndef _WIN32 - if (s->string[i] == OF_PATH_DELIM) { + if (s->cString[i] == OF_PATH_DELIM) { #else - if (s->string[i] == '/' || s->string[i] == '\\') { + if (s->cString[i] == '/' || s->string[i] == '\\') { #endif i++; break; } } @@ -1666,171 +1669,172 @@ * removed, so return a new string anyway. */ if (i < 0) i = 0; - return [OFString stringWithCString: s->string + i - length: pathLen - i]; + return [OFString stringWithCString: s->cString + i + length: pathCStringLength - i]; } - (OFString*)stringByDeletingLastPathComponent { - size_t i, pathLen = s->length; + size_t i, pathCStringLength = s->cStringLength; - if (pathLen == 0) + if (pathCStringLength == 0) return @""; #ifndef _WIN32 - if (s->string[pathLen - 1] == OF_PATH_DELIM) + if (s->cString[pathCStringLength - 1] == OF_PATH_DELIM) #else - if (s->string[pathLen - 1] == '/' || s->string[pathLen - 1] == '\\') + if (s->cString[pathCStringLength - 1] == '/' || + s->cString[pathCStringLength - 1] == '\\') #endif - pathLen--; + pathCStringLength--; - if (pathLen == 0) - return [OFString stringWithCString: s->string + if (pathCStringLength == 0) + return [OFString stringWithCString: s->cString length: 1]; - for (i = pathLen - 1; i >= 1; i--) + for (i = pathCStringLength - 1; i >= 1; i--) #ifndef _WIN32 - if (s->string[i] == OF_PATH_DELIM) + if (s->cString[i] == OF_PATH_DELIM) #else - if (s->string[i] == '/' || s->string[i] == '\\') + if (s->cString[i] == '/' || s->cString[i] == '\\') #endif - return [OFString stringWithCString: s->string + return [OFString stringWithCString: s->cString length: i]; #ifndef _WIN32 - if (s->string[0] == OF_PATH_DELIM) + if (s->cString[0] == OF_PATH_DELIM) #else - if (s->string[i] == '/' || s->string[i] == '\\') + if (s->cString[0] == '/' || s->cString[0] == '\\') #endif - return [OFString stringWithCString: s->string + return [OFString stringWithCString: s->cString length: 1]; return @"."; } - (intmax_t)decimalValue { - const char *string = s->string; - size_t length = s->length; - int i = 0; - intmax_t num = 0; - BOOL expectWhitespace = NO; - - while (*string == ' ' || *string == '\t' || *string == '\n' || - *string == '\r') { - string++; - length--; - } - - if (string[0] == '-' || string[0] == '+') - i++; - - for (; i < length; i++) { - if (expectWhitespace) { - if (string[i] != ' ' && string[i] != '\t' && - string[i] != '\n' && string[i] != '\r') - @throw [OFInvalidFormatException - newWithClass: isa]; - continue; - } - - if (string[i] >= '0' && string[i] <= '9') { - if (INTMAX_MAX / 10 < num || - INTMAX_MAX - num * 10 < string[i] - '0') - @throw [OFOutOfRangeException - newWithClass: isa]; - - num = (num * 10) + (string[i] - '0'); - } else if (string[i] == ' ' || string[i] == '\t' || - string[i] == '\n' || string[i] == '\r') - expectWhitespace = YES; - else - @throw [OFInvalidFormatException newWithClass: isa]; - } - - if (string[0] == '-') - num *= -1; - - return num; -} - -- (uintmax_t)hexadecimalValue -{ - const char *string = s->string; - size_t length = s->length; - int i = 0; - uintmax_t num = 0; - BOOL expectWhitespace = NO, gotNumber = NO; - - while (*string == ' ' || *string == '\t' || *string == '\n' || - *string == '\r') { - string++; - length--; - } - - if (length == 0) - return 0; - - if (length >= 2 && string[0] == '0' && string[1] == 'x') - i = 2; - else if (length >= 1 && (string[0] == 'x' || string[0] == '$')) - i = 1; - - for (; i < length; i++) { - uintmax_t newNum; - - if (expectWhitespace) { - if (string[i] != ' ' && string[i] != '\t' && - string[i] != '\n' && string[i] != '\r') - @throw [OFInvalidFormatException - newWithClass: isa]; - continue; - } - - if (string[i] >= '0' && string[i] <= '9') { - newNum = (num << 4) | (string[i] - '0'); - gotNumber = YES; - } else if (string[i] >= 'A' && string[i] <= 'F') { - newNum = (num << 4) | (string[i] - 'A' + 10); - gotNumber = YES; - } else if (string[i] >= 'a' && string[i] <= 'f') { - newNum = (num << 4) | (string[i] - 'a' + 10); - gotNumber = YES; - } else if (string[i] == 'h' || string[i] == ' ' || - string[i] == '\t' || string[i] == '\n' || - string[i] == '\r') { - expectWhitespace = YES; - continue; - } else - @throw [OFInvalidFormatException newWithClass: isa]; - - if (newNum < num) - @throw [OFOutOfRangeException newWithClass: isa]; - - num = newNum; - } - - if (!gotNumber) - @throw [OFInvalidFormatException newWithClass: isa]; - - return num; -} - -- (float)floatValue -{ - const char *string = s->string; - char *endPointer = NULL; - float value; - - while (*string == ' ' || *string == '\t' || *string == '\n' || - *string == '\r') - string++; - - value = strtof(string, &endPointer); + const char *cString = s->cString; + size_t cStringLength = s->cStringLength; + int i = 0; + intmax_t value = 0; + BOOL expectWhitespace = NO; + + while (*cString == ' ' || *cString == '\t' || *cString == '\n' || + *cString == '\r') { + cString++; + cStringLength--; + } + + if (cString[0] == '-' || cString[0] == '+') + i++; + + for (; i < cStringLength; i++) { + if (expectWhitespace) { + if (cString[i] != ' ' && cString[i] != '\t' && + cString[i] != '\n' && cString[i] != '\r') + @throw [OFInvalidFormatException + newWithClass: isa]; + continue; + } + + if (cString[i] >= '0' && cString[i] <= '9') { + if (INTMAX_MAX / 10 < value || + INTMAX_MAX - value * 10 < cString[i] - '0') + @throw [OFOutOfRangeException + newWithClass: isa]; + + value = (value * 10) + (cString[i] - '0'); + } else if (cString[i] == ' ' || cString[i] == '\t' || + cString[i] == '\n' || cString[i] == '\r') + expectWhitespace = YES; + else + @throw [OFInvalidFormatException newWithClass: isa]; + } + + if (cString[0] == '-') + value *= -1; + + return value; +} + +- (uintmax_t)hexadecimalValue +{ + const char *cString = s->cString; + size_t cStringLength = s->cStringLength; + int i = 0; + uintmax_t value = 0; + BOOL expectWhitespace = NO, foundValue = NO; + + while (*cString == ' ' || *cString == '\t' || *cString == '\n' || + *cString == '\r') { + cString++; + cStringLength--; + } + + if (cStringLength == 0) + return 0; + + if (cStringLength >= 2 && cString[0] == '0' && cString[1] == 'x') + i = 2; + else if (cStringLength >= 1 && (cString[0] == 'x' || cString[0] == '$')) + i = 1; + + for (; i < cStringLength; i++) { + uintmax_t newValue; + + if (expectWhitespace) { + if (cString[i] != ' ' && cString[i] != '\t' && + cString[i] != '\n' && cString[i] != '\r') + @throw [OFInvalidFormatException + newWithClass: isa]; + continue; + } + + if (cString[i] >= '0' && cString[i] <= '9') { + newValue = (value << 4) | (cString[i] - '0'); + foundValue = YES; + } else if (cString[i] >= 'A' && cString[i] <= 'F') { + newValue = (value << 4) | (cString[i] - 'A' + 10); + foundValue = YES; + } else if (cString[i] >= 'a' && cString[i] <= 'f') { + newValue = (value << 4) | (cString[i] - 'a' + 10); + foundValue = YES; + } else if (cString[i] == 'h' || cString[i] == ' ' || + cString[i] == '\t' || cString[i] == '\n' || + cString[i] == '\r') { + expectWhitespace = YES; + continue; + } else + @throw [OFInvalidFormatException newWithClass: isa]; + + if (newValue < value) + @throw [OFOutOfRangeException newWithClass: isa]; + + value = newValue; + } + + if (!foundValue) + @throw [OFInvalidFormatException newWithClass: isa]; + + return value; +} + +- (float)floatValue +{ + const char *cString = s->cString; + char *endPointer = NULL; + float value; + + while (*cString == ' ' || *cString == '\t' || *cString == '\n' || + *cString == '\r') + cString++; + + value = strtof(cString, &endPointer); /* Check if there are any invalid chars left */ if (endPointer != NULL) for (; *endPointer != '\0'; endPointer++) if (*endPointer != ' ' && *endPointer != '\t' && @@ -1841,19 +1845,19 @@ return value; } - (double)doubleValue { - const char *string = s->string; + const char *cString = s->cString; char *endPointer = NULL; double value; - while (*string == ' ' || *string == '\t' || *string == '\n' || - *string == '\r') - string++; + while (*cString == ' ' || *cString == '\t' || *cString == '\n' || + *cString == '\r') + cString++; - value = strtod(string, &endPointer); + value = strtod(cString, &endPointer); /* Check if there are any invalid chars left */ if (endPointer != NULL) for (; *endPointer != '\0'; endPointer++) if (*endPointer != ' ' && *endPointer != '\t' && @@ -1876,16 +1880,16 @@ i = 0; j = 0; ret[j++] = 0xFEFF; - while (i < s->length) { + while (i < s->cStringLength) { of_unichar_t c; size_t cLen; - cLen = of_string_utf8_to_unicode(s->string + i, s->length - i, - &c); + cLen = of_string_utf8_to_unicode(s->cString + i, + s->cStringLength - i, &c); if (cLen == 0 || c > 0x10FFFF) @throw [OFInvalidEncodingException newWithClass: isa]; ret[j++] = c;