diff --git a/ChangeLog b/ChangeLog index 5921899b6..c8547e46d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2002-08-30 Richard Frith-Macdonald + + * Source/NSString.m: Implemented new MacOS-X methods - + ([-stringByPaddingToLength:withString:startingAtIndex:]), and + ([-stringByTrimmingCharactersInSet:]) + 2002-08-29 Richard Frith-Macdonald * Source/Additions/GSXML.m: Get libxml to put filename in error diff --git a/Headers/gnustep/base/NSString.h b/Headers/gnustep/base/NSString.h index 9961b4a04..85dd60e3d 100644 --- a/Headers/gnustep/base/NSString.h +++ b/Headers/gnustep/base/NSString.h @@ -239,6 +239,7 @@ enum { - (NSString*) stringByResolvingSymlinksInPath; - (NSString*) stringByStandardizingPath; + // for methods working with decomposed strings - (int) _baseLength; @@ -263,15 +264,15 @@ enum { - (id) initWithContentsOfURL: (NSURL*)url; - (NSString*) substringWithRange: (NSRange)aRange; - (NSComparisonResult) caseInsensitiveCompare: (NSString*)aString; -- (NSComparisonResult)compare:(NSString *)string - options:(unsigned int)mask - range:(NSRange)compareRange - locale:(NSDictionary *)dict; -- (NSComparisonResult)localizedCompare:(NSString *)string; -- (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)string; +- (NSComparisonResult) compare: (NSString*)string + options: (unsigned int)mask + range: (NSRange)compareRange + locale: (NSDictionary*)dict; +- (NSComparisonResult) localizedCompare: (NSString *)string; +- (NSComparisonResult) localizedCaseInsensitiveCompare: (NSString *)string; - (BOOL) writeToFile: (NSString*)filename atomically: (BOOL)useAuxiliaryFile; -- (BOOL)writeToURL:(NSURL *)anURL atomically:(BOOL)atomically; +- (BOOL) writeToURL: (NSURL*)anURL atomically: (BOOL)atomically; - (double) doubleValue; + (NSStringEncoding*) availableStringEncodings; + (NSString*) localizedNameOfStringEncoding: (NSStringEncoding)encoding; @@ -281,6 +282,10 @@ enum { forRange: (NSRange)aRange; - (NSRange) lineRangeForRange: (NSRange)aRange; - (const char*) lossyCString; +- (NSString*) stringByPaddingToLength: (unsigned int)newLength + withString: (NSString*)padString + startingAtIndex: (unsigned int)padIndex; +- (NSString*) stringByTrimmingCharactersInSet: (NSCharacterSet*)aSet; - (const char *)UTF8String; #endif diff --git a/Source/NSString.m b/Source/NSString.m index 8c43997b8..a462110d2 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -2971,6 +2971,85 @@ handle_printf_atsign (FILE *stream, [self substringFromIndex: [homedir length] + 1]]; } +/** + * Returns a string formed by extending or truncating the receiver to + * newLength characters. If the new string is larger, it is padded + * by appending characters from padString (appending it as many times + * as required). The first character from padString to be appended + * is specified by padIndex.
+ */ +- (NSString*) stringByPaddingToLength: (unsigned int)newLength + withString: (NSString*)padString + startingAtIndex: (unsigned int)padIndex +{ + unsigned length = [self length]; + unsigned padLength; + + if (padString == nil || [padString isKindOfClass: [NSString class]] == NO) + { + [NSException raise: NSInvalidArgumentException + format: @"%@ - Illegal pad string", NSStringFromSelector(_cmd)]; + } + padLength = [padString length]; + if (padIndex >= padLength) + { + [NSException raise: NSRangeException + format: @"%@ - pad index larger too big", NSStringFromSelector(_cmd)]; + } + if (newLength == length) + { + return self; + } + else if (newLength < length) + { + return [self substringToIndex: newLength]; + } + else + { + length = newLength - length; // What we want to add. + if (length <= (padLength - padIndex)) + { + return [self stringByAppendingString: + [padString substringWithRange: NSMakeRange(padIndex, length)]]; + } + else + { + NSMutableString *m = [self mutableCopy]; + + if (padIndex > 0) + { + [m appendString: + [padString substringWithRange: NSMakeRange(padIndex, length)]]; + length -= (padLength - padIndex); + } + /* + * In case we have to append a small string lots of times, + * we cache the method impllementation to do it. + */ + if (length >= padLength) + { + void (*appImp)(NSMutableString*, SEL, NSString*); + SEL appSel; + + appSel = @selector(appendString:); + appImp = (void (*)(NSMutableString*, SEL, NSString*)) + [m methodForSelector: appSel]; + while (length >= padLength) + { + (*appImp)(m, appSel, padString); + length -= padLength; + } + } + if (length > 0) + { + [m appendString: + [padString substringWithRange: NSMakeRange(0, length)]]; + } + return AUTORELEASE(m); + } + } +} + - (NSString*) stringByResolvingSymlinksInPath { #if defined(__MINGW__) @@ -3250,6 +3329,63 @@ handle_printf_atsign (FILE *stream, #endif } +/** + * Return a string formed by removing characters from the ends of the + * receiver. Characters are removed only if they are in aSet.
+ * If the string consists entirely of characters in aSet, an empty + * string is returned.
+ * The aSet argument nust not be nil.
+ */ +- (NSString*) stringByTrimmingCharactersInSet: (NSCharacterSet*)aSet +{ + unsigned length = [self length]; + unsigned end = length; + unsigned start = 0; + + if (aSet == nil) + { + [NSException raise: NSInvalidArgumentException + format: @"%@ - nil character set argument", NSStringFromSelector(_cmd)]; + } + if (length > 0) + { + unichar (*caiImp)(NSString*, SEL, unsigned int); + BOOL (*mImp)(id, SEL, unichar); + unichar letter; + + caiImp = (unichar (*)())[self methodForSelector: caiSel]; + mImp = (BOOL(*)(id,SEL,unichar)) [aSet methodForSelector: cMemberSel]; + + while (end > 0) + { + letter = (*caiImp)(self, caiSel, end-1); + if ((*mImp)(aSet, cMemberSel, letter) == NO) + { + break; + } + end--; + } + while (start < end) + { + letter = (*caiImp)(self, caiSel, start); + if ((*mImp)(aSet, cMemberSel, letter) == NO) + { + break; + } + start++; + } + } + if (start == 0 && end == length) + { + return self; + } + if (start == end) + { + return @""; + } + return [self substringFromRange: NSMakeRange(start, end - start)]; +} + // private methods for Unicode level 3 implementation - (int) _baseLength {