@@ -11,87 +11,204 @@ #import "config.h" #import #import +#import #import "OFString.h" -#import "OFConstCString.h" -#import "OFConstWideCString.h" -#import "OFCString.h" -#import "OFWideCString.h" #import "OFExceptions.h" -#import "OFMacros.h" @implementation OFString -+ newAsConstCString: (const char*)str -{ - return [[OFConstCString alloc] initAsConstCString: str]; -} - -+ newAsConstWideCString: (const wchar_t*)str -{ - return [[OFConstWideCString alloc] initAsConstWideCString: str]; -} - -+ newAsCString: (char*)str -{ - return [[OFCString alloc] initAsCString: str]; -} - -+ newAsWideCString: (wchar_t*)str -{ - return [[OFWideCString alloc] initAsWideCString: str]; ++ new +{ + return [[OFString alloc] init]; +} + ++ newFromCString: (const char*)str +{ + return [[OFString alloc] initFromCString: str]; +} + ++ newFromWideCString: (const wchar_t*)str +{ + return [[OFString alloc] initFromWideCString: str]; +} + +- init +{ + if ((self = [super init])) { + length = 0; + string = NULL; + } + + return self; +} + +- initFromCString: (const char*)str +{ + if ((self = [super init])) { + if (str == NULL) { + length = 0; + string = NULL; + } else { + if ((length = mbstowcs(NULL, str, 0)) == (size_t)-1) { + /* FIXME: Throw exception */ + [super free]; + return nil; + } + + string = [self getMemForNItems: length + 1 + ofSize: sizeof(wchar_t)]; + + if (mbstowcs(string, str, length) != length) { + [super free]; + return nil; + } + } + } + + return self; +} + +- initFromWideCString: (const wchar_t*)str +{ + if ((self = [super init])) { + if (str == NULL) { + length = 0; + string = NULL; + } else { + length = wcslen(str); + string = [self getMemForNItems: length + 1 + ofSize: sizeof(wchar_t)]; + wmemcpy(string, str, length + 1); + } + } + + return self; } - (char*)cString { - OF_NOT_IMPLEMENTED(NULL) + char *str; + size_t len; + + if ((len = wcstombs(NULL, string, 0)) == (size_t)-1) { + /* FIXME: Throw exception */ + return NULL; + } + + str = [self getMemWithSize: len]; + + if (wcstombs(str, string, len) != len) { + /* FIXME: Throw exception */ + [self freeMem: str]; + return NULL; + } + + return str; } -- (wchar_t*)wCString +- (wchar_t*)wideCString { - OF_NOT_IMPLEMENTED(NULL) + return string; } - (size_t)length { - OF_NOT_IMPLEMENTED(0) + return length; +} + +- (OFString*)clone +{ + return [OFString newFromWideCString: string]; } - (OFString*)setTo: (OFString*)str { [self free]; - self = [str clone]; - return self; + return (self = [str clone]); } -- (OFString*)clone -{ - OF_NOT_IMPLEMENTED(nil) -} - -- (int)compareTo: (OFString*)str -{ - OF_NOT_IMPLEMENTED(0) +- (int)compare: (OFString*)str +{ + return wcscmp(string, [str wideCString]); } - append: (OFString*)str { - OF_NOT_IMPLEMENTED(nil) + return [self appendWideCString: [str wideCString]]; } - appendCString: (const char*)str { - OF_NOT_IMPLEMENTED(nil) + wchar_t *newstr, *tmpstr; + size_t newlen, strlength; + + if (string == NULL) + return [self setTo: [OFString newFromCString: str]]; + + if ((strlength = mbstowcs(NULL, str, 0)) == (size_t)-1) { + /* FIXME: Throw exception */ + return nil; + } + + tmpstr = [self getMemForNItems: strlength + 1 + ofSize: sizeof(wchar_t)]; + + if (mbstowcs(tmpstr, str, strlength) != strlength) { + /* FIXME: Throw exception */ + [self freeMem: tmpstr]; + return nil; + } + + newlen = length + strlength; + newstr = [self resizeMem: string + toNItems: newlen + 1 + ofSize: sizeof(wchar_t)]; + + wmemcpy(newstr + length, tmpstr, strlength + 1); + + length = newlen; + string = newstr; + + [self freeMem: tmpstr]; + + return self; } - appendWideCString: (const wchar_t*)str { - OF_NOT_IMPLEMENTED(nil) + wchar_t *newstr; + size_t newlen, strlength; + + if (string == NULL) + return [self setTo: [OFString newFromWideCString: str]]; + + strlength = wcslen(str); + newlen = length + strlength; + + newstr = [self resizeMem: string + toNItems: newlen + 1 + ofSize: sizeof(wchar_t)]; + + wmemcpy(newstr + length, str, strlength + 1); + + length = newlen; + string = newstr; + + return self; } - reverse { - OF_NOT_IMPLEMENTED(nil) + size_t i, j, len = length / 2; + + for (i = 0, j = length - 1; i < len; i++, j--) { + string[i] ^= string[j]; + string[j] ^= string[i]; + string[i] ^= string[j]; + } + + return self; } @end