@@ -344,10 +344,41 @@ objc_autoreleasePoolPop(pool); return [ret autorelease]; } + +static OFString * +decomposedString(OFString *self, const char *const *const *table, size_t size) +{ + OFMutableString *ret = [OFMutableString string]; + void *pool = objc_autoreleasePoolPush(); + const of_unichar_t *characters = [self characters]; + size_t length = [self length]; + + for (size_t i = 0; i < length; i++) { + of_unichar_t c = characters[i]; + const char *const *page; + + if (c >= size) { + [ret appendCharacters: &c + length: 1]; + continue; + } + + page = table[c >> 8]; + if (page != NULL && page[c & 0xFF] != NULL) + [ret appendUTF8String: page[c & 0xFF]]; + else + [ret appendCharacters: &c + length: 1]; + } + + objc_autoreleasePoolPop(pool); + + return ret; +} static struct { Class isa; } placeholder; @@ -2713,36 +2744,18 @@ } #ifdef OF_HAVE_UNICODE_TABLES - (OFString *)decomposedStringWithCanonicalMapping { - OFMutableString *ret = [OFMutableString string]; - void *pool = objc_autoreleasePoolPush(); - const of_unichar_t *characters = [self characters]; - size_t length = [self length]; - - for (size_t i = 0; i < length; i++) { - of_unichar_t c = characters[i]; - const char *const *table; - - if (c >= OF_UNICODE_DECOMPOSITION_TABLE_SIZE) { - [ret appendCharacters: &c - length: 1]; - continue; - } - - table = of_unicode_decomposition_table[c >> 8]; - if (table != NULL && table[c & 0xFF] != NULL) - [ret appendUTF8String: table[c & 0xFF]]; - else - [ret appendCharacters: &c - length: 1]; - } - - objc_autoreleasePoolPop(pool); - - return ret; + return decomposedString(self, of_unicode_decomposition_table, + OF_UNICODE_DECOMPOSITION_TABLE_SIZE); +} + +- (OFString *)decomposedStringWithCompatibilityMapping +{ + return decomposedString(self, of_unicode_decomposition_compat_table, + OF_UNICODE_DECOMPOSITION_COMPAT_TABLE_SIZE); } #endif #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path