From 55d4f390aadda010ad729fdeb004b391f2746249 Mon Sep 17 00:00:00 2001 From: Richard Frith-MacDonald Date: Tue, 9 Feb 2010 06:07:10 +0000 Subject: [PATCH] re-instate cleaned up version of string proxy code. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29518 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 10 + Headers/Additions/GNUstepBase/GSCategories.h | 1 + Headers/Foundation/NSString.h | 9 + Source/Additions/GSCategories.m | 195 +++++++++++++++++++ Source/GSAttributedString.m | 106 +--------- 5 files changed, 220 insertions(+), 101 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3c4858c4..8210f5e93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-02-09 Richard Frith-Macdonald + + * Source/GSAttributedString.m: + * Source/Additions/GSCategories.m: + * Headers/Foundation/NSString.h: + * Headers/Additions/GNUstepBase/GSCategories.h: + Re-instated the immutableProxy mathod, but as a clean category on + NSMutableString in the additions library. + Use for the -string method of NSAttributedString + 2010-02-08 Richard Frith-Macdonald * Source/NSAttributedString.m: minor cosmetic change diff --git a/Headers/Additions/GNUstepBase/GSCategories.h b/Headers/Additions/GNUstepBase/GSCategories.h index 51a47ac9e..cf77183b2 100644 --- a/Headers/Additions/GNUstepBase/GSCategories.h +++ b/Headers/Additions/GNUstepBase/GSCategories.h @@ -237,6 +237,7 @@ typedef enum _NSGNUstepStringEncoding @interface NSMutableString (GSCategories) - (void) deleteSuffix: (NSString*)suffix; - (void) deletePrefix: (NSString*)prefix; +- (NSString*) immutableProxy; - (void) replaceString: (NSString*)replace withString: (NSString*)by; - (void) trimLeadSpaces; diff --git a/Headers/Foundation/NSString.h b/Headers/Foundation/NSString.h index 97b72f12f..1f78f022a 100644 --- a/Headers/Foundation/NSString.h +++ b/Headers/Foundation/NSString.h @@ -877,6 +877,15 @@ extern struct objc_class _NSConstantStringClassReference; */ - (void) deletePrefix: (NSString*)prefix; +/** + * Returns a proxy to the receiver which will allow access to the + * receiver as an NSString, but which will not allow any of the + * extra NSMutableString methods to be used. You can use this method + * to provide other code with read-only access to a mutable string + * you own. + */ +- (NSString*) immutableProxy; + /** * Replaces all occurrences of the string replace with the string by * in the receiver.
diff --git a/Source/Additions/GSCategories.m b/Source/Additions/GSCategories.m index 2ab3a9d89..7770b0f58 100644 --- a/Source/Additions/GSCategories.m +++ b/Source/Additions/GSCategories.m @@ -1126,6 +1126,189 @@ strerror_r(int eno, char *buf, int len) @end +/* This private cass is used for the -immutableProxy method in the category + * on NSMutableString. + * It is needed for [NSAttributedString-string] and [NSTextStorage-string] + */ +@interface GSImmutableString : NSString +{ + NSString *_parent; +} +- (id) initWithString: (NSString*)parent; +@end + +@implementation GSImmutableString + +- (BOOL) canBeConvertedToEncoding: (NSStringEncoding)enc +{ + return [_parent canBeConvertedToEncoding: enc]; +} + +- (unichar) characterAtIndex: (NSUInteger)index +{ + return [_parent characterAtIndex: index]; +} + +- (NSComparisonResult) compare: (NSString*)aString + options: (NSUInteger)mask + range: (NSRange)aRange +{ + return [_parent compare: aString options: mask range: aRange]; +} + +- (const char *) cString +{ + return [_parent cString]; +} + +- (const char *) cStringUsingEncoding: (NSStringEncoding)encoding +{ + return [_parent cStringUsingEncoding: encoding]; +} + +- (NSUInteger) cStringLength +{ + return [_parent cStringLength]; +} + +- (NSData*) dataUsingEncoding: (NSStringEncoding)encoding + allowLossyConversion: (BOOL)flag +{ + return [_parent dataUsingEncoding: encoding allowLossyConversion: flag]; +} + +- (void) dealloc +{ + RELEASE(_parent); + [super dealloc]; +} + +- (id) copyWithZone: (NSZone*)z +{ + return [_parent copyWithZone: z]; +} + +- (id) mutableCopyWithZone: (NSZone*)z +{ + return [_parent mutableCopyWithZone: z]; +} + +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + [_parent encodeWithCoder: aCoder]; +} + +- (NSStringEncoding) fastestEncoding +{ + return [_parent fastestEncoding]; +} + +- (void) getCharacters: (unichar*)buffer +{ + [_parent getCharacters: buffer]; +} + +- (void) getCharacters: (unichar*)buffer range: (NSRange)aRange +{ + [_parent getCharacters: buffer range: aRange]; +} + +- (void) getCString: (char*)buffer +{ + [_parent getCString: buffer]; +} + +- (void) getCString: (char*)buffer + maxLength: (NSUInteger)maxLength +{ + [_parent getCString: buffer maxLength: maxLength]; +} + +- (BOOL) getCString: (char*)buffer + maxLength: (NSUInteger)maxLength + encoding: (NSStringEncoding)encoding +{ + return [_parent getCString: buffer maxLength: maxLength encoding: encoding]; +} + +- (void) getCString: (char*)buffer + maxLength: (NSUInteger)maxLength + range: (NSRange)aRange + remainingRange: (NSRange*)leftoverRange +{ + [_parent getCString: buffer + maxLength: maxLength + range: aRange + remainingRange: leftoverRange]; +} + +- (NSUInteger) hash +{ + return [_parent hash]; +} + +- (id) initWithString: (NSString*)parent +{ + _parent = RETAIN(parent); + return self; +} + +- (BOOL) isEqual: (id)anObject +{ + return [_parent isEqual: anObject]; +} + +- (BOOL) isEqualToString: (NSString*)anObject +{ + return [_parent isEqualToString: anObject]; +} + +- (NSUInteger) length +{ + return [_parent length]; +} + +- (NSUInteger) lengthOfBytesUsingEncoding: (NSStringEncoding)encoding +{ + return [_parent lengthOfBytesUsingEncoding: encoding]; +} + +- (const char*) lossyCString +{ + return [_parent lossyCString]; +} + +- (NSUInteger) maximumLengthOfBytesUsingEncoding: (NSStringEncoding)encoding +{ + return [_parent maximumLengthOfBytesUsingEncoding: encoding]; +} + +- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (NSUInteger)anIndex +{ + return [_parent rangeOfComposedCharacterSequenceAtIndex: anIndex]; +} + +- (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet + options: (NSUInteger)mask + range: (NSRange)aRange +{ + return [_parent rangeOfCharacterFromSet: aSet options: mask range: aRange]; +} + +- (NSRange) rangeOfString: (NSString*)aString + options: (NSUInteger)mask + range: (NSRange)aRange +{ + return [_parent rangeOfString: aString options: mask range: aRange]; +} + +- (NSStringEncoding) smallestEncoding +{ + return [_parent smallestEncoding]; +} + +@end + /** * GNUstep specific (non-standard) additions to the NSString class. */ @@ -1321,6 +1504,18 @@ strerror_r(int eno, char *buf, int len) [self deleteCharactersInRange: NSMakeRange(0, [prefix length])]; } +/** + * Returns a proxy to the receiver which will allow access to the + * receiver as an NSString, but which will not allow any of the + * extra NSMutableString methods to be used. You can use this method + * to provide other code with read-only access to a mutable string + * you own. + */ +- (NSString*) immutableProxy +{ + return AUTORELEASE([[GSImmutableString alloc] initWithString: self]); +} + /** * Replaces all occurrences of the string replace with the string by * in the receiver.
diff --git a/Source/GSAttributedString.m b/Source/GSAttributedString.m index c2d88d875..577667cba 100644 --- a/Source/GSAttributedString.m +++ b/Source/GSAttributedString.m @@ -63,102 +63,6 @@ static NSDictionary *blank; -@interface GSAttributedStringProxy : NSProxy -{ - NSString *string; -} -- (id) _initWithString: (NSString*)s; -@end - -@implementation GSAttributedStringProxy - -static Class NSObjectClass = nil; -static Class NSStringClass = nil; - -+ (void) initialize -{ - NSObjectClass = [NSObject class]; - NSStringClass = [NSString class]; -} - -- (Class) class -{ - return NSStringClass; -} - -- (void) dealloc -{ - [string release]; - [super dealloc]; -} - -- (void) forwardInvocation: (NSInvocation*)anInvocation -{ - SEL aSel = [anInvocation selector]; - - if (YES == [NSStringClass instancesRespondToSelector: aSel]) - { - [anInvocation invokeWithTarget: string]; - } - else - { - [NSException raise: NSGenericException - format: @"NSString(instance) does not recognize %s", - aSel ? GSNameFromSelector(aSel) : "(null)"]; - } -} - -- (NSUInteger) hash -{ - return [string hash]; -} - -- (id) _initWithString: (NSString*)s -{ - string = [s retain]; - return self; -} - -- (BOOL) isEqual: (id)other -{ - return [string isEqual: other]; -} - -- (BOOL) isMemberOfClass: (Class)c -{ - return (c == NSStringClass) ? YES : NO; -} - -- (BOOL) isKindOfClass: (Class)c -{ - return (c == NSStringClass || c == NSObjectClass) ? YES : NO; -} - -- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector -{ - NSMethodSignature *sig; - - if (YES == [NSStringClass instancesRespondToSelector: aSelector]) - { - sig = [string methodSignatureForSelector: aSelector]; - } - else - { - sig = [super methodSignatureForSelector: aSelector]; - } - return sig; -} - -- (BOOL) respondsToSelector: (SEL)aSelector -{ - if (YES == [NSStringClass instancesRespondToSelector: aSelector]) - { - return YES; - } - return [super respondsToSelector: aSelector]; -} - -@end @interface GSAttributedString : NSAttributedString { @@ -178,7 +82,7 @@ static Class NSStringClass = nil; { NSMutableString *_textChars; NSMutableArray *_infoArray; - NSString *_proxy; + NSString *_textProxy; } - (id) initWithString: (NSString*)aString @@ -694,11 +598,11 @@ SANITY(); /* NB. This method is SUPPOSED to return a proxy to the mutable string! * This is a performance feature documented ifor OSX. */ - if (_proxy == nil) + if (_textProxy == nil) { - _proxy = [[GSAttributedStringProxy alloc] _initWithString: _textChars]; + _textProxy = [[_textChars immutableProxy] retain]; } - return _proxy; + return _textProxy; } - (NSDictionary*) attributesAtIndex: (unsigned)index @@ -988,7 +892,7 @@ SANITY(); - (void) dealloc { - [_proxy release]; + [_textProxy release]; RELEASE(_textChars); RELEASE(_infoArray); [super dealloc];