Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -103,10 +103,18 @@ * \return A new autoreleased OFString */ + stringWithCString: (const char*)string length: (size_t)length; +/** + * Creates a new OFString from another string. + * + * \param string A string to initialize the OFString with + * \return A new autoreleased OFString + */ ++ stringWithString: (OFString*)string; + /** * Creates a new OFString from a format string. * See printf for the format syntax. * * \param format A string used as format to initialize the OFString @@ -120,18 +128,10 @@ * \param firstComponent The first component of the path * \return A new autoreleased OFString */ + stringWithPath: (OFString*)firstComponent, ...; -/** - * Creates a new OFString from another string. - * - * \param string A string to initialize the OFString with - * \return A new autoreleased OFString - */ -+ stringWithString: (OFString*)string; - /** * Creates a new OFString with the contents of the specified UTF-8 encoded file. * * \param path The path to the file * \return A new autoreleased OFString @@ -215,10 +215,18 @@ * \return An initialized OFString */ - initWithCString: (const char*)string length: (size_t)length; +/** + * Initializes an already allocated OFString with another string. + * + * \param string A string to initialize the OFString with + * \return An initialized OFString + */ +- initWithString: (OFString*)string; + /** * Initializes an already allocated OFString with a format string. * See printf for the format syntax. * * \param format A string used as format to initialize the OFString @@ -255,18 +263,10 @@ * \return A new autoreleased OFString */ - initWithPath: (OFString*)firstComponent arguments: (va_list)arguments; -/** - * Initializes an already allocated OFString with another string. - * - * \param string A string to initialize the OFString with - * \return An initialized OFString - */ -- initWithString: (OFString*)string; - /** * Initializes an already allocated OFString with the contents of the specified * file in the specified encoding. * * \param path The path to the file Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -62,15 +62,15 @@ _OFString_XMLEscaping_reference = 1; _OFString_XMLUnescaping_reference = 1; } static inline int -memcasecmp(const char *first, const char *second, size_t len) +memcasecmp(const char *first, const char *second, size_t length) { size_t i; - for (i = 0; i < len; i++) { + for (i = 0; i < length; i++) { if (tolower((int)first[i]) > tolower((int)second[i])) return OF_ORDERED_DESCENDING; if (tolower((int)first[i]) < tolower((int)second[i])) return OF_ORDERED_ASCENDING; } @@ -77,170 +77,173 @@ return OF_ORDERED_SAME; } int -of_string_check_utf8(const char *str, size_t len) +of_string_check_utf8(const char *string, size_t length) { size_t i; - int utf8 = 0; + int isUTF8 = 0; - madvise((void*)str, len, MADV_SEQUENTIAL); + madvise((void*)string, length, MADV_SEQUENTIAL); - for (i = 0; i < len; i++) { + for (i = 0; i < length; i++) { /* No sign of UTF-8 here */ - if (OF_LIKELY(!(str[i] & 0x80))) + if (OF_LIKELY(!(string[i] & 0x80))) continue; - utf8 = 1; + isUTF8 = 1; /* We're missing a start byte here */ - if (OF_UNLIKELY(!(str[i] & 0x40))) { - madvise((void*)str, len, MADV_NORMAL); + if (OF_UNLIKELY(!(string[i] & 0x40))) { + madvise((void*)string, length, MADV_NORMAL); return -1; } /* We have at minimum a 2 byte character -> check next byte */ - if (OF_UNLIKELY(len < i + 1 || (str[i + 1] & 0xC0) != 0x80)) { - madvise((void*)str, len, MADV_NORMAL); + if (OF_UNLIKELY(length < i + 1 || + (string[i + 1] & 0xC0) != 0x80)) { + madvise((void*)string, length, MADV_NORMAL); return -1; } /* Check if we have at minimum a 3 byte character */ - if (OF_LIKELY(!(str[i] & 0x20))) { + if (OF_LIKELY(!(string[i] & 0x20))) { i++; continue; } /* We have at minimum a 3 byte char -> check second next byte */ - if (OF_UNLIKELY(len < i + 2 || (str[i + 2] & 0xC0) != 0x80)) { - madvise((void*)str, len, MADV_NORMAL); + if (OF_UNLIKELY(length < i + 2 || + (string[i + 2] & 0xC0) != 0x80)) { + madvise((void*)string, length, MADV_NORMAL); return -1; } /* Check if we have a 4 byte character */ - if (OF_LIKELY(!(str[i] & 0x10))) { + if (OF_LIKELY(!(string[i] & 0x10))) { i += 2; continue; } /* We have a 4 byte character -> check third next byte */ - if (OF_UNLIKELY(len < i + 3 || (str[i + 3] & 0xC0) != 0x80)) { - madvise((void*)str, len, MADV_NORMAL); + if (OF_UNLIKELY(length < i + 3 || + (string[i + 3] & 0xC0) != 0x80)) { + madvise((void*)string, length, MADV_NORMAL); return -1; } /* * Just in case, check if there's a 5th character, which is * forbidden by UTF-8 */ - if (OF_UNLIKELY(str[i] & 0x08)) { - madvise((void*)str, len, MADV_NORMAL); + if (OF_UNLIKELY(string[i] & 0x08)) { + madvise((void*)string, length, MADV_NORMAL); return -1; } i += 3; } - madvise((void*)str, len, MADV_NORMAL); + madvise((void*)string, length, MADV_NORMAL); - return utf8; + return isUTF8; } size_t -of_string_unicode_to_utf8(of_unichar_t c, char *buf) +of_string_unicode_to_utf8(of_unichar_t character, char *buffer) { size_t i = 0; - if (c < 0x80) { - buf[i] = c; + if (character < 0x80) { + buffer[i] = character; return 1; } - if (c < 0x800) { - buf[i++] = 0xC0 | (c >> 6); - buf[i] = 0x80 | (c & 0x3F); + if (character < 0x800) { + buffer[i++] = 0xC0 | (character >> 6); + buffer[i] = 0x80 | (character & 0x3F); return 2; } - if (c < 0x10000) { - buf[i++] = 0xE0 | (c >> 12); - buf[i++] = 0x80 | (c >> 6 & 0x3F); - buf[i] = 0x80 | (c & 0x3F); + if (character < 0x10000) { + buffer[i++] = 0xE0 | (character >> 12); + buffer[i++] = 0x80 | (character >> 6 & 0x3F); + buffer[i] = 0x80 | (character & 0x3F); return 3; } - if (c < 0x110000) { - buf[i++] = 0xF0 | (c >> 18); - buf[i++] = 0x80 | (c >> 12 & 0x3F); - buf[i++] = 0x80 | (c >> 6 & 0x3F); - buf[i] = 0x80 | (c & 0x3F); + if (character < 0x110000) { + buffer[i++] = 0xF0 | (character >> 18); + buffer[i++] = 0x80 | (character >> 12 & 0x3F); + buffer[i++] = 0x80 | (character >> 6 & 0x3F); + buffer[i] = 0x80 | (character & 0x3F); return 4; } return 0; } size_t -of_string_utf8_to_unicode(const char *buf_, size_t len, of_unichar_t *ret) +of_string_utf8_to_unicode(const char *buffer_, size_t length, of_unichar_t *ret) { - const uint8_t *buf = (const uint8_t*)buf_; + const uint8_t *buffer = (const uint8_t*)buffer_; - if (!(*buf & 0x80)) { - *ret = buf[0]; + if (!(*buffer & 0x80)) { + *ret = buffer[0]; return 1; } - if ((*buf & 0xE0) == 0xC0) { - if (OF_UNLIKELY(len < 2)) + if ((*buffer & 0xE0) == 0xC0) { + if (OF_UNLIKELY(length < 2)) return 0; - *ret = ((buf[0] & 0x1F) << 6) | (buf[1] & 0x3F); + *ret = ((buffer[0] & 0x1F) << 6) | (buffer[1] & 0x3F); return 2; } - if ((*buf & 0xF0) == 0xE0) { - if (OF_UNLIKELY(len < 3)) + if ((*buffer & 0xF0) == 0xE0) { + if (OF_UNLIKELY(length < 3)) return 0; - *ret = ((buf[0] & 0x0F) << 12) | ((buf[1] & 0x3F) << 6) | - (buf[2] & 0x3F); + *ret = ((buffer[0] & 0x0F) << 12) | ((buffer[1] & 0x3F) << 6) | + (buffer[2] & 0x3F); return 3; } - if ((*buf & 0xF8) == 0xF0) { - if (OF_UNLIKELY(len < 4)) + if ((*buffer & 0xF8) == 0xF0) { + if (OF_UNLIKELY(length < 4)) return 0; - *ret = ((buf[0] & 0x07) << 18) | ((buf[1] & 0x3F) << 12) | - ((buf[2] & 0x3F) << 6) | (buf[3] & 0x3F); + *ret = ((buffer[0] & 0x07) << 18) | ((buffer[1] & 0x3F) << 12) | + ((buffer[2] & 0x3F) << 6) | (buffer[3] & 0x3F); return 4; } return 0; } size_t -of_string_position_to_index(const char *str, size_t pos) -{ - size_t i, idx = pos; - - for (i = 0; i < pos; i++) - if (OF_UNLIKELY((str[i] & 0xC0) == 0x80)) - idx--; - - return idx; +of_string_position_to_index(const char *string, size_t position) +{ + size_t i, index = position; + + for (i = 0; i < position; i++) + if (OF_UNLIKELY((string[i] & 0xC0) == 0x80)) + index--; + + return index; } size_t -of_string_index_to_position(const char *str, size_t idx, size_t len) +of_string_index_to_position(const char *string, size_t index, size_t length) { size_t i; - for (i = 0; i <= idx; i++) - if (OF_UNLIKELY((str[i] & 0xC0) == 0x80)) - if (++idx > len) + for (i = 0; i <= index; i++) + if (OF_UNLIKELY((string[i] & 0xC0) == 0x80)) + if (++index > length) return OF_INVALID_INDEX; - return idx; + return index; } @implementation OFString + string { @@ -272,10 +275,15 @@ length: (size_t)length { return [[[self alloc] initWithCString: string length: length] autorelease]; } + ++ stringWithString: (OFString*)string +{ + return [[[self alloc] initWithString: string] autorelease]; +} + stringWithFormat: (OFString*)format, ... { id ret; va_list arguments; @@ -299,15 +307,10 @@ va_end(arguments); return ret; } -+ stringWithString: (OFString*)string -{ - return [[[self alloc] initWithString: string] autorelease]; -} - + stringWithContentsOfFile: (OFString*)path { return [[[self alloc] initWithContentsOfFile: path] autorelease]; } @@ -483,10 +486,46 @@ { return [self initWithCString: string_ encoding: OF_STRING_ENCODING_UTF_8 length: length_]; } + +- initWithString: (OFString*)string_ +{ + self = [super init]; + + @try { + /* We have no -[dealloc], so this is ok */ + string = (char*)[string_ cString]; + length = [string_ cStringLength]; + + switch (of_string_check_utf8(string, length)) { + case 1: + isUTF8 = YES; + break; + case -1:; + @throw [OFInvalidEncodingException newWithClass: isa]; + } + + if ((string = strdup(string)) == NULL) + @throw [OFOutOfMemoryException + newWithClass: isa + requestedSize: length + 1]; + + @try { + [self addMemoryToPool: string]; + } @catch (id e) { + free(string); + @throw e; + } + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} - initWithFormat: (OFString*)format, ... { id ret; va_list arguments; @@ -602,46 +641,10 @@ memcpy(string + i + 1, [component cString], len); i += len + 1; } string[i] = '\0'; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- initWithString: (OFString*)string_ -{ - self = [super init]; - - @try { - /* We have no -[dealloc], so this is ok */ - string = (char*)[string_ cString]; - length = [string_ cStringLength]; - - switch (of_string_check_utf8(string, length)) { - case 1: - isUTF8 = YES; - break; - case -1:; - @throw [OFInvalidEncodingException newWithClass: isa]; - } - - if ((string = strdup(string)) == NULL) - @throw [OFOutOfMemoryException - newWithClass: isa - requestedSize: length + 1]; - - @try { - [self addMemoryToPool: string]; - } @catch (id e) { - free(string); - @throw e; - } } @catch (id e) { [self release]; @throw e; }