mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 08:41:03 +00:00
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:
parent
6d55a1db69
commit
47ea9f8642
5 changed files with 340 additions and 262 deletions
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue