Make most functions inline for performance.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4030 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1999-04-05 07:07:03 +00:00
parent 6d55a1db69
commit 47ea9f8642
5 changed files with 340 additions and 262 deletions

View file

@ -1,3 +1,11 @@
Mopn Apr 5 7:33:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSRange.m: Moved most functions into header file, while
including header to generate linkable versions.
* Source/include/NSGeometry.h: Define MIN and MAX if required.
* Source/include/NSRange.h: Define MIN and MAX if required and make
most range functions a efficiency.
e
Thu Mar 11 10:30:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Thu Mar 11 10:30:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSDebug.m: Added two new functions for logging messags. * Source/NSDebug.m: Added two new functions for logging messags.

View file

@ -2,7 +2,7 @@
* Copyright (C) 1995 Free Software Foundation, Inc. * Copyright (C) 1995 Free Software Foundation, Inc.
* *
* Written by: Adam Fedor <fedor@boulder.colorado.edu> * Written by: Adam Fedor <fedor@boulder.colorado.edu>
* Date: 1995 * Date: 1995,199
* *
* This file is part of the GNUstep Base Library. * This file is part of the GNUstep Base Library.
* *
@ -32,6 +32,18 @@
/**** Type, Constant, and Macro Definitions **********************************/ /**** Type, Constant, and Macro Definitions **********************************/
#ifndef MAX
#define MAX(a,b) \
({typeof(a) _MAX_a = (a); typeof(b) _MAX_b = (b); \
_MAX_a > _MAX_b ? _MAX_a : _MAX_b; })
#endif
#ifndef MIN
#define MIN(a,b) \
({typeof(a) _MIN_a = (a); typeof(b) _MIN_b = (b); \
_MIN_a < _MIN_b ? _MIN_a : _MIN_b; })
#endif
/* Point definition. */ /* Point definition. */
typedef struct _NSPoint NSPoint; typedef struct _NSPoint NSPoint;
struct _NSPoint struct _NSPoint

View file

@ -1,5 +1,5 @@
/* Interface for NSObject for GNUStep /* Interface for NSObject for GNUStep
* Copyright (C) 1995 Free Software Foundation, Inc. * Copyright (C) 1995,199 Free Software Foundation, Inc.
* *
* Written by: Adam Fedor <fedor@boulder.colorado.edu> * Written by: Adam Fedor <fedor@boulder.colorado.edu>
* Date: 1995 * Date: 1995
@ -29,6 +29,18 @@
/**** Type, Constant, and Macro Definitions **********************************/ /**** Type, Constant, and Macro Definitions **********************************/
#ifndef MAX
#define MAX(a,b) \
({typeof(a) _MAX_a = (a); typeof(b) _MAX_b = (b); \
_MAX_a > _MAX_b ? _MAX_a : _MAX_b; })
#endif
#ifndef MIN
#define MIN(a,b) \
({typeof(a) _MIN_a = (a); typeof(b) _MIN_b = (b); \
_MIN_a < _MIN_b ? _MIN_a : _MIN_b; })
#endif
typedef struct _NSRange NSRange; typedef struct _NSRange NSRange;
struct _NSRange struct _NSRange
{ {
@ -38,19 +50,34 @@ struct _NSRange
/**** Function Prototypes ****************************************************/ /**** Function Prototypes ****************************************************/
static inline unsigned /*
NSMaxRange(NSRange range) __attribute__ ((unused)); * All but the most complex functions are declared static inline in this
* header file so that they are maximally efficient. In order to provide
* true functions (for code modules that don't have this header) this
* header is included in NSGeometry.m where the functions are no longer
* declared inline.
*/
#ifdef IN_NSRANGE_M
#define GS_RANGE_SCOPE extern
#define GS_RANGE_ATTR
#else
#define GS_RANGE_SCOPE static inline
#define GS_RANGE_ATTR __attribute__((unused))
#endif
static inline unsigned GS_RANGE_SCOPE unsigned
NSMaxRange(NSRange range) GS_RANGE_ATTR;
GS_RANGE_SCOPE unsigned
NSMaxRange(NSRange range) NSMaxRange(NSRange range)
{ {
return range.location + range.length; return range.location + range.length;
} }
static inline BOOL GS_RANGE_SCOPE BOOL
NSLocationInRange(unsigned location, NSRange range) __attribute__ ((unused)); NSLocationInRange(unsigned location, NSRange range) GS_RANGE_ATTR;
static inline BOOL GS_RANGE_SCOPE BOOL
NSLocationInRange(unsigned location, NSRange range) NSLocationInRange(unsigned location, NSRange range)
{ {
return (location >= range.location) && (location < NSMaxRange(range)); return (location >= range.location) && (location < NSMaxRange(range));
@ -60,11 +87,48 @@ NSLocationInRange(unsigned location, NSRange range)
extern NSRange extern NSRange
NSMakeRange(unsigned int location, unsigned int length); NSMakeRange(unsigned int location, unsigned int length);
extern NSRange GS_RANGE_SCOPE BOOL
NSUnionRange(NSRange range1, NSRange range2); NSEqualRanges(NSRange range1, NSRange range2) GS_RANGE_ATTR;
GS_RANGE_SCOPE BOOL
NSEqualRanges(NSRange range1, NSRange range2)
{
return ((range1.location == range2.location)
&& (range1.length == range2.length));
}
GS_RANGE_SCOPE NSRange
NSUnionRange(NSRange range1, NSRange range2) GS_RANGE_ATTR;
GS_RANGE_SCOPE NSRange
NSUnionRange(NSRange aRange, NSRange bRange)
{
NSRange range;
range.location = MIN(aRange.location, bRange.location);
range.length = MAX(NSMaxRange(aRange), NSMaxRange(bRange))
- range.location;
return range;
}
GS_RANGE_SCOPE NSRange
NSIntersectionRange(NSRange range1, NSRange range2) GS_RANGE_ATTR;
GS_RANGE_SCOPE NSRange
NSIntersectionRange (NSRange aRange, NSRange bRange)
{
NSRange range;
if (NSMaxRange(aRange) < bRange.location
|| NSMaxRange(bRange) < aRange.location)
return NSMakeRange(0, 0);
range.location = MAX(aRange.location, bRange.location);
range.length = MIN(NSMaxRange(aRange), NSMaxRange(bRange))
- range.location;
return range;
}
extern NSRange
NSIntersectionRange(NSRange range1, NSRange range2);
@class NSString; @class NSString;

View file

@ -3,9 +3,9 @@
Implementation of concrete subclass of a string class with attributes Implementation of concrete subclass of a string class with attributes
Copyright (C) 1997 Free Software Foundation, Inc. Copyright (C) 1997, 1999 Free Software Foundation, Inc.
Written by: ANOQ of the sun <anoq@vip.cybercity.dk> Written by: ANOQ of the sun < anoq@vip.cybercity.dk >
Date: November 1997 Date: November 1997
This file is part of GNUStep-base This file is part of GNUStep-base
@ -15,13 +15,13 @@
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
If you are interested in a warranty or support for this source code, If you are interested in a warranty or support for this source code,
contact Scott Christley <scottc@net-community.com> for more information. contact Scott Christley < scottc@net-community.com > for more information.
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
@ -32,15 +32,15 @@
// in NSMutableAttributedString is NOT tracked for changes to update // in NSMutableAttributedString is NOT tracked for changes to update
// NSMutableAttributedString's attributes as it should. // NSMutableAttributedString's attributes as it should.
//FIXME: 2) If out-of-memory exceptions are raised in some methods, //FIXME: 2) If out-of-memory exceptions are raised in some methods,
// inconsistencies may develop, because the two internal arrays in // inconsistencies may develop, because the two internal arrays in
// NSGAttributedString and NSGMutableAttributedString called // NSGAttributedString and NSGMutableAttributedString called
// attributeArray and locateArray must always be syncronized. // attributeArray and locateArray must always be syncronized.
//FIXME: 3) The method _setAttributesFrom: must be overridden by //FIXME: 3) The method _setAttributesFrom: must be overridden by
// concrete subclasses of NSAttributedString which is WRONG and // concrete subclasses of NSAttributedString which is WRONG and
// VERY bad! I haven't found any other way to make // VERY bad ! I haven't found any other way to make
// - initWithString:attributes: the designated initializer // - initWithString: attributes: the designated initializer
// in NSAttributedString and still implement // in NSAttributedString and still implement
// - initWithAttributedString: without having to override it // - initWithAttributedString: without having to override it
// in the concrete subclass. // in the concrete subclass.
@ -49,142 +49,154 @@
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
#include <Foundation/NSValue.h> #include <Foundation/NSValue.h>
@interface GSAttrInfo : NSObject
{
@public
NSDictionary *attr;
unsigned loc;
}
@end
@implementation NSGAttributedString @implementation NSGAttributedString
void _setAttributesFrom( void _setAttributesFrom(
NSAttributedString *attributedString, NSAttributedString *attributedString,
NSRange aRange, NSRange aRange,
NSMutableArray *attributeArray, NSMutableArray *attributeArray,
NSMutableArray *locateArray) NSMutableArray *locateArray)
{ {
//always called immediately after -initWithString:attributes: //always called immediately after -initWithString: attributes:
NSRange effectiveRange; NSRange effectiveRange;
NSDictionary *attributeDict; NSDictionary *attributeDict;
if(aRange.length <= 0) if (aRange.length <= 0)
return;//No attributes return;//No attributes
attributeDict = [attributedString attributesAtIndex:aRange.location attributeDict = [attributedString attributesAtIndex: aRange.location
effectiveRange:&effectiveRange]; effectiveRange: &effectiveRange];
[attributeArray replaceObjectAtIndex:0 withObject:attributeDict]; [attributeArray replaceObjectAtIndex: 0 withObject: attributeDict];
while (NSMaxRange(effectiveRange) < NSMaxRange(aRange)) while (NSMaxRange(effectiveRange) < NSMaxRange(aRange))
{ {
attributeDict = attributeDict =
[attributedString attributesAtIndex:NSMaxRange(effectiveRange) [attributedString attributesAtIndex: NSMaxRange(effectiveRange)
effectiveRange:&effectiveRange]; effectiveRange: &effectiveRange];
[attributeArray addObject:attributeDict]; [attributeArray addObject: attributeDict];
[locateArray addObject: [locateArray addObject:
[NSNumber numberWithUnsignedInt:effectiveRange.location-aRange.location]]; [NSNumber numberWithUnsignedInt:
} effectiveRange.location-aRange.location]];
}
return; return;
} }
void _initWithString( void _initWithString(
NSString *aString, NSString *aString,
NSDictionary *attributes, NSDictionary *attributes,
NSString **textChars, NSString **textChars,
NSMutableArray **attributeArray, NSMutableArray **attributeArray,
NSMutableArray **locateArray) NSMutableArray **locateArray)
{ {
if (aString) if (aString)
*textChars = [(*textChars) initWithString:aString]; *textChars = [(*textChars) initWithString: aString];
else else
*textChars = [(*textChars) init]; *textChars = [(*textChars) init];
*attributeArray = [[NSMutableArray alloc] init]; *attributeArray = [[NSMutableArray alloc] init];
*locateArray = [[NSMutableArray alloc] init]; *locateArray = [[NSMutableArray alloc] init];
if(!attributes) if (! attributes)
attributes = [[[NSDictionary alloc] init] autorelease]; attributes = [[NSDictionary alloc] init];
[(*attributeArray) addObject:attributes]; [(*attributeArray) addObject: attributes];
[(*locateArray) addObject:[NSNumber numberWithUnsignedInt:0]]; [attributes release];
[(*locateArray) addObject: [NSNumber numberWithUnsignedInt: 0]];
} }
NSDictionary *_attributesAtIndexEffectiveRange( NSDictionary *_attributesAtIndexEffectiveRange(
unsigned int index, unsigned int index,
NSRange *aRange, NSRange *aRange,
unsigned int tmpLength, unsigned int tmpLength,
NSMutableArray *attributeArray, NSMutableArray *attributeArray,
NSMutableArray *locateArray, NSMutableArray *locateArray,
unsigned int *foundIndex) unsigned int *foundIndex)
{ {
unsigned int low,high,used,cnt,foundLoc,nextLoc; unsigned int low, high, used, cnt, foundLoc, nextLoc;
NSDictionary *foundDict; NSDictionary *foundDict;
if(index<0 || index >= tmpLength) if (index <0 || index >= tmpLength)
{ {
[NSException raise:NSRangeException format: [NSException raise: NSRangeException
@"index is out of range in function _attributesAtIndexEffectiveRange()"]; format: @"index is out of range in function "
} @"_attributesAtIndexEffectiveRange()"];
}
//Binary search for efficiency in huge attributed strings //Binary search for efficiency in huge attributed strings
used = [attributeArray count]; used = [attributeArray count];
low=0; low = 0;
high = used - 1; high = used - 1;
while(low<=high) while (low <= high)
{
cnt=(low+high)/2;
foundDict = [attributeArray objectAtIndex:cnt];
foundLoc = [[locateArray objectAtIndex:cnt] unsignedIntValue];
if(foundLoc > index)
{ {
high = cnt-1; cnt = (low+high)/2;
} foundDict = [attributeArray objectAtIndex: cnt];
else foundLoc = [[locateArray objectAtIndex: cnt] unsignedIntValue];
{ if (foundLoc > index)
if(cnt >= used -1) {
nextLoc = tmpLength; high = cnt-1;
}
else else
nextLoc = [[locateArray objectAtIndex:cnt+1] unsignedIntValue]; {
if(foundLoc == index || if (cnt >= used -1)
index < nextLoc) nextLoc = tmpLength;
{ else
//Found nextLoc = [[locateArray objectAtIndex: cnt+1] unsignedIntValue];
if(aRange) if (foundLoc == index || index < nextLoc)
{ {
aRange->location = foundLoc; //Found
aRange->length = nextLoc - foundLoc; if (aRange)
} {
if(foundIndex) aRange->location = foundLoc;
*foundIndex = cnt; aRange->length = nextLoc - foundLoc;
return foundDict; }
} if (foundIndex)
else *foundIndex = cnt;
low = cnt+1; return foundDict;
}
else
low = cnt+1;
}
} }
} NSCAssert(NO, @"Error in binary search algorithm");
NSCAssert(NO,@"Error in binary search algorithm");
return nil; return nil;
} }
- (void) encodeWithCoder: aCoder - (void) encodeWithCoder: aCoder
{ {
[super encodeWithCoder:aCoder]; [super encodeWithCoder: aCoder];
[aCoder encodeObject:textChars]; [aCoder encodeObject: textChars];
[aCoder encodeObject:attributeArray]; [aCoder encodeObject: attributeArray];
[aCoder encodeObject:locateArray]; [aCoder encodeObject: locateArray];
} }
- initWithCoder: aCoder - initWithCoder: aCoder
{ {
self = [super initWithCoder:aCoder]; self = [super initWithCoder: aCoder];
[aCoder decodeValueOfObjCType: @encode(id) at: &textChars]; [aCoder decodeValueOfObjCType: @encode(id) at: &textChars];
[aCoder decodeValueOfObjCType: @encode(id) at: &attributeArray]; [aCoder decodeValueOfObjCType: @encode(id) at: &attributeArray];
[aCoder decodeValueOfObjCType: @encode(id) at: &locateArray]; [aCoder decodeValueOfObjCType: @encode(id) at: &locateArray];
return self; return self;
} }
- _setAttributesFrom:(NSAttributedString *)attributedString range:(NSRange)aRange - _setAttributesFrom: (NSAttributedString *)attributedString
range: (NSRange)aRange
{ {
//always called immediately after -initWithString:attributes: //always called immediately after -initWithString: attributes:
_setAttributesFrom(attributedString,aRange,attributeArray,locateArray); _setAttributesFrom(attributedString, aRange, attributeArray, locateArray);
return self; return self;
} }
- (id)initWithString:(NSString *)aString attributes:(NSDictionary *)attributes - (id)initWithString: (NSString *)aString attributes: (NSDictionary *)attributes
{ {
self = [super initWithString:aString attributes:attributes]; self = [super initWithString: aString attributes: attributes];
textChars = [NSString alloc]; textChars = [NSString alloc];
_initWithString(aString,attributes,&textChars,&attributeArray,&locateArray); _initWithString(aString, attributes, &textChars, &attributeArray, &locateArray);
return self; return self;
} }
@ -193,10 +205,10 @@ NSDictionary *_attributesAtIndexEffectiveRange(
return textChars; return textChars;
} }
- (NSDictionary *)attributesAtIndex:(unsigned int)index effectiveRange:(NSRange *)aRange - (NSDictionary *)attributesAtIndex: (unsigned int)index effectiveRange: (NSRange *)aRange
{ {
return _attributesAtIndexEffectiveRange( return _attributesAtIndexEffectiveRange(
index,aRange,[self length],attributeArray,locateArray,NULL); index, aRange, [self length], attributeArray, locateArray, NULL);
} }
- (void)dealloc - (void)dealloc
@ -214,33 +226,34 @@ NSDictionary *_attributesAtIndexEffectiveRange(
- (void) encodeWithCoder: aCoder - (void) encodeWithCoder: aCoder
{ {
[super encodeWithCoder:aCoder]; [super encodeWithCoder: aCoder];
[aCoder encodeObject:textChars]; [aCoder encodeObject: textChars];
[aCoder encodeObject:attributeArray]; [aCoder encodeObject: attributeArray];
[aCoder encodeObject:locateArray]; [aCoder encodeObject: locateArray];
} }
- initWithCoder: aCoder - initWithCoder: aCoder
{ {
self = [super initWithCoder:aCoder]; self = [super initWithCoder: aCoder];
[aCoder decodeValueOfObjCType: @encode(id) at: &textChars]; [aCoder decodeValueOfObjCType: @encode(id) at: &textChars];
[aCoder decodeValueOfObjCType: @encode(id) at: &attributeArray]; [aCoder decodeValueOfObjCType: @encode(id) at: &attributeArray];
[aCoder decodeValueOfObjCType: @encode(id) at: &locateArray]; [aCoder decodeValueOfObjCType: @encode(id) at: &locateArray];
return self; return self;
} }
- _setAttributesFrom:(NSAttributedString *)attributedString range:(NSRange)aRange - _setAttributesFrom: (NSAttributedString *)attributedString
range: (NSRange)aRange
{ {
//always called immediately after -initWithString:attributes: //always called immediately after -initWithString: attributes:
_setAttributesFrom(attributedString,aRange,attributeArray,locateArray); _setAttributesFrom(attributedString, aRange, attributeArray, locateArray);
return self; return self;
} }
- (id)initWithString:(NSString *)aString attributes:(NSDictionary *)attributes - (id)initWithString: (NSString *)aString attributes: (NSDictionary *)attributes
{ {
self = [super initWithString:aString attributes:attributes]; self = [super initWithString: aString attributes: attributes];
textChars = [NSMutableString alloc]; textChars = [NSMutableString alloc];
_initWithString(aString,attributes,&textChars,&attributeArray,&locateArray); _initWithString(aString, attributes, &textChars, &attributeArray, &locateArray);
return self; return self;
} }
@ -254,145 +267,154 @@ NSDictionary *_attributesAtIndexEffectiveRange(
return textChars; return textChars;
} }
- (NSDictionary *)attributesAtIndex:(unsigned int)index effectiveRange:(NSRange *)aRange - (NSDictionary *)attributesAtIndex: (unsigned int)index effectiveRange: (NSRange *)aRange
{ {
return _attributesAtIndexEffectiveRange( return _attributesAtIndexEffectiveRange(
index,aRange,[self length],attributeArray,locateArray,NULL); index, aRange, [self length], attributeArray, locateArray, NULL);
} }
- (void)setAttributes:(NSDictionary *)attributes range:(NSRange)range - (void)setAttributes: (NSDictionary *)attributes range: (NSRange)range
{ {
unsigned int tmpLength,arrayIndex,arraySize,location; unsigned int tmpLength, arrayIndex, arraySize, location;
NSRange effectiveRange; NSRange effectiveRange;
NSNumber *afterRangeLocation,*beginRangeLocation; NSNumber *afterRangeLocation, *beginRangeLocation;
NSDictionary *attrs; NSDictionary *attrs;
if(!attributes) if (! attributes)
attributes = [NSDictionary dictionary]; attributes = [NSDictionary dictionary];
tmpLength = [self length]; tmpLength = [self length];
if(range.location < 0 || NSMaxRange(range) > tmpLength) if (range.location < 0 || NSMaxRange(range) > tmpLength)
{ {
[NSException raise:NSRangeException [NSException raise: NSRangeException
format:@"RangeError in method -replaceCharactersInRange:withString: in class NSMutableAttributedString"]; format: @"RangeError in method -replaceCharactersInRange: "
} @"withString: in class NSMutableAttributedString"];
}
arraySize = [locateArray count]; arraySize = [locateArray count];
if(NSMaxRange(range) < tmpLength) if (NSMaxRange(range) < tmpLength)
{ {
attrs = _attributesAtIndexEffectiveRange( attrs = _attributesAtIndexEffectiveRange(
NSMaxRange(range),&effectiveRange,tmpLength,attributeArray,locateArray,&arrayIndex); NSMaxRange(range), &effectiveRange, tmpLength,
attributeArray, locateArray, &arrayIndex);
afterRangeLocation = afterRangeLocation =
[NSNumber numberWithUnsignedInt:NSMaxRange(range)]; [NSNumber numberWithUnsignedInt: NSMaxRange(range)];
if(effectiveRange.location > range.location) if (effectiveRange.location > range.location)
{ {
[locateArray replaceObjectAtIndex:arrayIndex [locateArray replaceObjectAtIndex: arrayIndex
withObject:afterRangeLocation]; withObject: afterRangeLocation];
}
else
{
arrayIndex++;
//There shouldn't be anything wrong in putting an object (attrs) in
//an array more than once should there? The object will not change.
[attributeArray insertObject: attrs atIndex: arrayIndex];
[locateArray insertObject: afterRangeLocation atIndex: arrayIndex];
}
arrayIndex--;
} }
else
{
arrayIndex++;
//There shouldn't be anything wrong in putting an object (attrs) in
//an array more than once should there? The object will not change.
[attributeArray insertObject:attrs atIndex:arrayIndex];
[locateArray insertObject:afterRangeLocation atIndex:arrayIndex];
}
arrayIndex--;
}
else else
arrayIndex = arraySize - 1; arrayIndex = arraySize - 1;
while(arrayIndex > 0 && while (arrayIndex > 0 &&
[[locateArray objectAtIndex:arrayIndex-1] unsignedIntValue] >= range.location) [[locateArray objectAtIndex: arrayIndex-1] unsignedIntValue]
{ >= range.location)
[locateArray removeObjectAtIndex:arrayIndex];
[attributeArray removeObjectAtIndex:arrayIndex];
arrayIndex--;
}
beginRangeLocation = [NSNumber numberWithUnsignedInt:range.location];
location = [[locateArray objectAtIndex:arrayIndex] unsignedIntValue];
if(location >= range.location)
{
if(location > range.location)
{ {
[locateArray replaceObjectAtIndex:arrayIndex [locateArray removeObjectAtIndex: arrayIndex];
withObject:beginRangeLocation]; [attributeArray removeObjectAtIndex: arrayIndex];
arrayIndex--;
}
beginRangeLocation = [NSNumber numberWithUnsignedInt: range.location];
location = [[locateArray objectAtIndex: arrayIndex] unsignedIntValue];
if (location >= range.location)
{
if (location > range.location)
{
[locateArray replaceObjectAtIndex: arrayIndex
withObject: beginRangeLocation];
}
[attributeArray replaceObjectAtIndex: arrayIndex
withObject: attributes];
} }
[attributeArray replaceObjectAtIndex:arrayIndex
withObject:attributes];
}
else else
{ {
arrayIndex++; arrayIndex++;
[attributeArray insertObject:attributes atIndex:arrayIndex]; [attributeArray insertObject: attributes atIndex: arrayIndex];
[locateArray insertObject:beginRangeLocation atIndex:arrayIndex]; [locateArray insertObject: beginRangeLocation atIndex: arrayIndex];
} }
/* Primitive method! Sets attributes and values for a given range of characters, replacing any previous attributes /* Primitive method ! Sets attributes and values for a given range of
and values for that range.*/ * characters, replacing any previous attributes and values for that range.
*/
/*Sets the attributes for the characters in aRange to attributes. These new attributes replace any attributes /* Sets the attributes for the characters in aRange to attributes.
previously associated with the characters in aRange. Raises an NSRangeException if any part of aRange lies beyond * These new attributes replace any attributes previously associated with
the end of the receiver's characters. * the characters in aRange. Raises an NSRangeException if any part of
See also: - addAtributes:range:, - removeAttributes:range:*/ * aRange lies beyond the end of the receiver's characters.
* See also: - addAtributes: range: , - removeAttributes: range:
*/
} }
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString - (void)replaceCharactersInRange: (NSRange)range withString: (NSString *)aString
{ {
unsigned int tmpLength,arrayIndex,arraySize,cnt,location,moveLocations; unsigned int tmpLength, arrayIndex, arraySize, cnt, location, moveLocations;
NSRange effectiveRange; NSRange effectiveRange;
NSDictionary *attrs; NSDictionary *attrs;
NSNumber *afterRangeLocation; NSNumber *afterRangeLocation;
if(!aString) if (! aString)
aString = @""; aString = @"";
tmpLength = [self length]; tmpLength = [self length];
if(range.location < 0 || NSMaxRange(range) > tmpLength) if (range.location < 0 || NSMaxRange(range) > tmpLength)
{ {
[NSException raise:NSRangeException [NSException raise: NSRangeException
format:@"RangeError in method -replaceCharactersInRange:withString: in class NSMutableAttributedString"]; format: @"RangeError in method -replaceCharactersInRange: "
} @"withString: in class NSMutableAttributedString"];
}
arraySize = [locateArray count]; arraySize = [locateArray count];
if(NSMaxRange(range) < tmpLength) if (NSMaxRange(range) < tmpLength)
{
attrs = _attributesAtIndexEffectiveRange(
NSMaxRange(range),&effectiveRange,tmpLength,attributeArray,locateArray,&arrayIndex);
moveLocations = [aString length] - range.length;
afterRangeLocation =
[NSNumber numberWithUnsignedInt:NSMaxRange(range)+moveLocations];
if(effectiveRange.location > range.location)
{ {
[locateArray replaceObjectAtIndex:arrayIndex attrs = _attributesAtIndexEffectiveRange(
withObject:afterRangeLocation]; NSMaxRange(range), &effectiveRange, tmpLength,
attributeArray, locateArray, &arrayIndex);
moveLocations = [aString length] - range.length;
afterRangeLocation =
[NSNumber numberWithUnsignedInt: NSMaxRange(range)+moveLocations];
if (effectiveRange.location > range.location)
{
[locateArray replaceObjectAtIndex: arrayIndex
withObject: afterRangeLocation];
}
else
{
arrayIndex++;
//There shouldn't be anything wrong in putting an object (attrs) in
//an array more than once should there? The object will not change.
[attributeArray insertObject: attrs atIndex: arrayIndex];
[locateArray insertObject: afterRangeLocation atIndex: arrayIndex];
}
for (cnt = arrayIndex+1;cnt < arraySize;cnt++)
{
location = [[locateArray objectAtIndex: cnt] unsignedIntValue]
+ moveLocations;
[locateArray replaceObjectAtIndex: cnt
withObject: [NSNumber numberWithUnsignedInt: location]];
}
arrayIndex--;
} }
else
{
arrayIndex++;
//There shouldn't be anything wrong in putting an object (attrs) in
//an array more than once should there? The object will not change.
[attributeArray insertObject:attrs atIndex:arrayIndex];
[locateArray insertObject:afterRangeLocation atIndex:arrayIndex];
}
for(cnt=arrayIndex+1;cnt<arraySize;cnt++)
{
location = [[locateArray objectAtIndex:cnt] unsignedIntValue] + moveLocations;
[locateArray replaceObjectAtIndex:cnt
withObject:[NSNumber numberWithUnsignedInt:location]];
}
arrayIndex--;
}
else else
arrayIndex = arraySize - 1; arrayIndex = arraySize - 1;
while(arrayIndex > 0 && while (arrayIndex > 0 &&
[[locateArray objectAtIndex:arrayIndex] unsignedIntValue] > range.location) [[locateArray objectAtIndex: arrayIndex] unsignedIntValue] > range.location)
{ {
[locateArray removeObjectAtIndex:arrayIndex]; [locateArray removeObjectAtIndex: arrayIndex];
[attributeArray removeObjectAtIndex:arrayIndex]; [attributeArray removeObjectAtIndex: arrayIndex];
arrayIndex--; arrayIndex--;
} }
[textChars replaceCharactersInRange:range withString:aString]; [textChars replaceCharactersInRange: range withString: aString];
} }
- (void)dealloc - (void)dealloc

View file

@ -3,62 +3,34 @@
*/ */
#include <config.h> #include <config.h>
#include <Foundation/NSString.h>
#include <Foundation/NSException.h>
NSRange #define IN_NSRANGE_M 1
#include <Foundation/NSException.h>
#include <Foundation/NSString.h>
#include <Foundation/NSRange.h>
@class NSString;
NSRange
NSMakeRange(unsigned int location, unsigned int length) NSMakeRange(unsigned int location, unsigned int length)
{ {
NSRange range; NSRange range;
unsigned int end = location + length; unsigned int end = location + length;
if (end < location || end < length) { if (end < location || end < length)
[NSException raise:NSRangeException {
format:@"Range location + length too great"]; [NSException raise: NSRangeException
format: @"Range location + length too great"];
} }
range.location = location; range.location = location;
range.length = length; range.length = length;
return range; return range;
}
/* Query a Range */
BOOL
NSEqualRanges(NSRange range1, NSRange range2)
{
return ((range1.location == range2.location)
&& (range1.length == range2.length));
}
/* Compute a Range from Two Other Ranges */
NSRange
NSUnionRange(NSRange aRange, NSRange bRange)
{
NSRange range;
range.location = MIN(aRange.location, bRange.location);
range.length = MAX(NSMaxRange(aRange), NSMaxRange(bRange))
- range.location;
return range;
}
NSRange
NSIntersectionRange (NSRange aRange, NSRange bRange)
{
NSRange range;
if (NSMaxRange(aRange) < bRange.location
|| NSMaxRange(bRange) < aRange.location)
return NSMakeRange(0, 0);
range.location = MAX(aRange.location, bRange.location);
range.length = MIN(NSMaxRange(aRange), NSMaxRange(bRange))
- range.location;
return range;
} }
NSString * NSString *
NSStringFromRange(NSRange range) NSStringFromRange(NSRange range)
{ {
return [NSString stringWithFormat:@"{location = %d, length = %d}", return [NSString stringWithFormat: @"{location = %d, length = %d}",
range.location, range.length]; range.location, range.length];
} }