Index: src/OFMutableString.h ================================================================== --- src/OFMutableString.h +++ src/OFMutableString.h @@ -30,10 +30,19 @@ * * \param str A C string to append */ - appendCString: (const char*)str; +/** + * Appends a C string with the specified length to the OFString. + * + * \param str A C string to append + * \param len The length of the C string + */ +- appendCString: (const char*)str + withLength: (size_t)len; + /** * Appends a C string to the OFString without checking whether it is valid * UTF-8. * * Only use this if you are 100% sure the string you append is either ASCII or @@ -41,10 +50,23 @@ * * \param str A C string to append */ - appendCStringWithoutUTF8Checking: (const char*)str; +/** + * Appends a C string with the specified length to the OFString 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 str A C string to append + * \param len The length of the C string + */ +- appendCStringWithoutUTF8Checking: (const char*)str + andLength: (size_t)len; + /** * Appends another OFString to the OFString. * * \param str An OFString to append */ Index: src/OFMutableString.m ================================================================== --- src/OFMutableString.m +++ src/OFMutableString.m @@ -78,10 +78,33 @@ memcpy(string + length, str, strlength + 1); length += strlength; return self; } + +- appendCString: (const char*)str + withLength: (size_t)len +{ + if (len > strlen(str)) + @throw [OFOutOfRangeException newWithClass: isa]; + + switch (of_string_check_utf8(str, len)) { + case 1: + is_utf8 = YES; + break; + case -1: + @throw [OFInvalidEncodingException newWithClass: isa]; + } + + string = [self resizeMemory: string + toSize: length + len + 1]; + memcpy(string + length, str, len); + length += len; + string[length] = 0; + + return self; +} - appendCStringWithoutUTF8Checking: (const char*)str { size_t strlength; @@ -89,10 +112,25 @@ string = [self resizeMemory: string toSize: length + strlength + 1]; memcpy(string + length, str, strlength + 1); length += strlength; + return self; +} + +- appendCStringWithoutUTF8Checking: (const char*)str + andLength: (size_t)len +{ + if (len > strlen(str)) + @throw [OFOutOfRangeException newWithClass: isa]; + + string = [self resizeMemory: string + toSize: length + len + 1]; + memcpy(string + length, str, len); + length += len; + string[length] = 0; + return self; } - appendString: (OFString*)str { Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -45,10 +45,20 @@ * \param str A C string to initialize the OFString with * \return A new autoreleased OFString */ + stringWithCString: (const char*)str; +/** + * Creates a new OFString from a C string with the specified length. + * + * \param str A C string to initialize the OFString with + * \param len The length of the string + * \return A new autoreleased OFString + */ ++ stringWithCString: (const char*)str + andLength: (size_t)len; + /** * Creates a new OFString from a format string. * See printf for the format syntax. * * \param fmt A string used as format to initialize the OFString @@ -70,17 +80,28 @@ * \return An initialized OFString */ - init; /** - * Initializes an already allocated OFString with a C string. + * Initializes an already allocated OFString from a C string. * * \param str A C string to initialize the OFString with * \return An initialized OFString */ - initWithCString: (const char*)str; +/** + * Initializes an already allocated OFString from a C string with the specified + * length. + * + * \param str A C string to initialize the OFString with + * \param len The length of the string + * \return An initialized OFString + */ +- initWithCString: (const char*)str + andLength: (size_t)len; + /** * Initializes an already allocated OFString with a format string. * See printf for the format syntax. * * \param fmt A string used as format to initialize the OFString @@ -157,11 +178,15 @@ */ - (OFArray*)splitWithDelimiter: (OFString*)delimiter; - setToCString: (const char*)str; - appendCString: (const char*)str; +- appendCString: (const char*)str + withLength: (size_t)len; - appendCStringWithoutUTF8Checking: (const char*)str; +- appendCStringWithoutUTF8Checking: (const char*)str + andLength: (size_t)len; - appendString: (OFString*)str; - appendWithFormat: (OFString*)fmt, ...; - appendWithFormat: (OFString*)fmt andArguments: (va_list)args; - reverse; Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -114,10 +114,17 @@ + stringWithCString: (const char*)str { return [[[self alloc] initWithCString: str] autorelease]; } + ++ stringWithCString: (const char*)str + andLength: (size_t)len +{ + return [[[self alloc] initWithCString: str + andLength: len] autorelease]; +} + stringWithFormat: (OFString*)fmt, ... { id ret; va_list args; @@ -152,18 +159,17 @@ if (str != NULL) { length = strlen(str); switch (of_string_check_utf8(str, length)) { - case 1: - is_utf8 = YES; - break; - case -1: - c = isa; - [super dealloc]; - @throw [OFInvalidEncodingException - newWithClass: c]; + case 1: + is_utf8 = YES; + break; + case -1: + c = isa; + [super dealloc]; + @throw [OFInvalidEncodingException newWithClass: c]; } @try { string = [self allocMemoryWithSize: length + 1]; } @catch (OFException *e) { @@ -176,10 +182,52 @@ @throw e; } memcpy(string, str, length + 1); } + return self; +} + +- initWithCString: (const char*)str + andLength: (size_t)len +{ + Class c; + + self = [super init]; + + if (len > strlen(str)) { + c = isa; + [super dealloc]; + @throw [OFOutOfRangeException newWithClass: c]; + } + + length = len; + + switch (of_string_check_utf8(str, length)) { + case 1: + is_utf8 = YES; + break; + case -1: + c = isa; + [super dealloc]; + @throw [OFInvalidEncodingException newWithClass: c]; + } + + @try { + string = [self allocMemoryWithSize: length + 1]; + } @catch (OFException *e) { + /* + * We can't use [super dealloc] on OS X here. + * Compiler bug? Anyway, [self dealloc] will do here as + * we don't reimplement dealloc. + */ + [self dealloc]; + @throw e; + } + memcpy(string, str, length); + string[length] = 0; + return self; } - initWithFormat: (OFString*)fmt, ... { @@ -449,12 +497,26 @@ - appendCString: (const char*)str { @throw [OFNotImplementedException newWithClass: isa andSelector: _cmd]; } + +- appendCString: (const char*)str + withLength: (size_t)len +{ + @throw [OFNotImplementedException newWithClass: isa + andSelector: _cmd]; +} + +- appendCStringWithoutUTF8Checking: (const char*)str +{ + @throw [OFNotImplementedException newWithClass: isa + andSelector: _cmd]; +} - appendCStringWithoutUTF8Checking: (const char*)str + andLength: (size_t)len { @throw [OFNotImplementedException newWithClass: isa andSelector: _cmd]; } Index: tests/OFString/OFString.m ================================================================== --- tests/OFString/OFString.m +++ tests/OFString/OFString.m @@ -80,10 +80,18 @@ CHECK([[s1 upper] isEqual: @"321TSET"]) CHECK([[s1 lower] isEqual: @"321tset"]) /* Also clears all the memory of the returned C strings */ [pool release]; + + s1 = [OFMutableString stringWithCString: "foobar" + andLength: 3]; + CHECK([s1 isEqual: @"foo"]) + + [s1 appendCString: "foobarqux" + 3 + withLength: 3]; + CHECK([s1 isEqual: @"foobar"]) /* UTF-8 tests */ CHECK_EXCEPT(s1 = [OFString stringWithCString: "\xE0\x80"], OFInvalidEncodingException) CHECK_EXCEPT(s1 = [OFString stringWithCString: "\xF0\x80\x80\xC0"],