Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -373,10 +373,20 @@ * \param string The string to append * \return A new autoreleased OFString with the specified string appended */ - (OFString*)stringByAppendingString: (OFString*)string; +/** + * \return The string in uppercase + */ +- (OFString*)uppercaseString; + +/** + * \return The string in lowercase + */ +- (OFString*)lowercaseString; + /** * Creates a new string by deleting leading whitespaces. * * \return A new autoreleased OFString with leading whitespaces deleted */ Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -1018,10 +1018,42 @@ OFMutableString *new; new = [OFMutableString stringWithString: self]; [new appendString: string_]; + /* + * 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 + * would create a real copy each time -[copy] is called. + */ + new->isa = [OFString class]; + return new; +} + +- (OFString*)uppercaseString +{ + OFMutableString *new; + + 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 + * would create a real copy each time -[copy] is called. + */ + new->isa = [OFString class]; + return new; +} + +- (OFString*)lowercaseString +{ + OFMutableString *new; + + 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 * would create a real copy each time -[copy] is called. */ Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -118,10 +118,16 @@ R([s[1] upper]) && [s[1] isEqual: @"ABC"]) TEST(@"-[lower]", R([s[0] lower]) && [s[0] isEqual: @"3𝄞1€sät"] && R([s[1] lower]) && [s[1] isEqual: @"abc"]) + TEST(@"-[uppercaseString]", + [[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]) && [s[0] isEqual: @"foo"])