mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Performance improvements
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4273 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
f2d8bc8b52
commit
5063e7bbfc
6 changed files with 1021 additions and 734 deletions
|
@ -1,3 +1,11 @@
|
|||
Thu May 20 10:40:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/GSeq.h: Add support for comparison and search.
|
||||
* Source/NSString.m: Use comparison and search functions from GSeq.h
|
||||
* Source/NSGString.m: Use comparison and search functions from GSeq.h
|
||||
* Source/NSGCString.m: Use comparison and search functions from GSeq.h
|
||||
* Source/Makefile.postamble: Make all string files depend on GSeq.h
|
||||
|
||||
Wed May 19 21:25:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/GSeq.h: New file to replace NSGSequence stuff
|
||||
|
|
853
Source/GSeq.h
853
Source/GSeq.h
|
@ -23,21 +23,57 @@
|
|||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Warning - this contains hairy code - handle with care.
|
||||
* The first part of this file contains variable and constant definitions
|
||||
* plus inline function definitions for handling sequences of unicode
|
||||
* characters. It is bracketed in preprocessor conditionals so that it
|
||||
* is only ever included once.
|
||||
* The second part of the file contains inline function definitions that
|
||||
* are designed to be modified depending on the defined macros at the
|
||||
* point where they are included. This is meant to be included multiple
|
||||
* times so the same code can be used for NSString, NSGString, and
|
||||
* NSGCString objects.
|
||||
*/
|
||||
|
||||
#ifndef __GSeq_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __GSeq_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
/*
|
||||
* Some standard selectors for frequently used methods.
|
||||
*/
|
||||
static SEL caiSel = @selector(characterAtIndex:);
|
||||
static SEL gcrSel = @selector(getCharacters:range:);
|
||||
static SEL ranSel = @selector(rangeOfComposedCharacterSequenceAtIndex:);
|
||||
|
||||
/*
|
||||
* The maximum decompostion level for composite unicode characters.
|
||||
*/
|
||||
#define MAXDEC 18
|
||||
|
||||
/*
|
||||
* The structure definition for handling a unicode character sequence
|
||||
* for a single character.
|
||||
*/
|
||||
typedef struct {
|
||||
unichar *chars;
|
||||
unsigned count;
|
||||
unsigned capacity;
|
||||
BOOL normalized;
|
||||
} GSeqStruct;
|
||||
|
||||
typedef GSeqStruct *GSeq;
|
||||
|
||||
/*
|
||||
* A macro to define a GSeqStruct variable capable of holding a
|
||||
* unicode character sequence of the specified length.
|
||||
*/
|
||||
#define GSEQ_MAKE(BUF, SEQ, LEN) \
|
||||
unichar BUF[LEN * MAXDEC + 1]; \
|
||||
GSeqStruct SEQ = { BUF, LEN, LEN * MAXDEC, 0 }
|
||||
|
||||
/*
|
||||
* A function to normalize a unicode character sequence.
|
||||
*/
|
||||
static inline void GSeq_normalize(GSeq seq)
|
||||
{
|
||||
unsigned count = seq->count;
|
||||
|
@ -123,6 +159,10 @@ static inline void GSeq_normalize(GSeq seq)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A function to compare two unicode character sequences normalizing if
|
||||
* required.
|
||||
*/
|
||||
static inline NSComparisonResult GSeq_compare(GSeq s0, GSeq s1)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -176,3 +216,814 @@ static inline void GSeq_uppercase(GSeq seq)
|
|||
s[i] = uni_toupper(s[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify NSString, NSGString or NSGCString
|
||||
*/
|
||||
#define GSEQ_NS 0
|
||||
#define GSEQ_US 1
|
||||
#define GSEQ_CS 2
|
||||
|
||||
/*
|
||||
* Structures to access NSGString and NSGCString ivars.
|
||||
*/
|
||||
typedef struct {
|
||||
@defs(NSGString)
|
||||
} NSGStringStruct;
|
||||
|
||||
typedef struct {
|
||||
@defs(NSGCString)
|
||||
} NSGCStringStruct;
|
||||
|
||||
/*
|
||||
* Definitions for bitmask of search options. These MUST match the
|
||||
* enumeration in NSString.h
|
||||
*/
|
||||
#define FCLS 3
|
||||
#define BCLS 7
|
||||
#define FLS 2
|
||||
#define BLS 6
|
||||
#define FCS 1
|
||||
#define BCS 5
|
||||
#define FS 0
|
||||
#define BS 4
|
||||
#define FCLAS 11
|
||||
#define BCLAS 15
|
||||
#define FLAS 10
|
||||
#define BLAS 14
|
||||
#define FCAS 9
|
||||
#define BCAS 13
|
||||
#define FAS 8
|
||||
#define BAS 12
|
||||
|
||||
#endif /* __GSeq_h_GNUSTEP_BASE_INCLUDE */
|
||||
|
||||
/*
|
||||
* Set up macros for dealing with 'self' on the basis of GSQ_S
|
||||
*/
|
||||
#if GSEQ_S == GSEQ_US
|
||||
#define GSEQ_ST NSGStringStruct*
|
||||
#define GSEQ_SLEN s->_count
|
||||
#define GSEQ_SGETC(I) s->_contents_chars[I]
|
||||
#define GSEQ_SGETR(B,R) memcpy(B, &s->_contents_chars[R.location], 2*(R).length)
|
||||
#define GSEQ_SRANGE(I) (*srImp)((id)s, ranSel, I)
|
||||
#else
|
||||
#if GSEQ_S == GSEQ_CS
|
||||
#define GSEQ_ST NSGCStringStruct*
|
||||
#define GSEQ_SLEN s->_count
|
||||
#define GSEQ_SGETC(I) (unichar)s->_contents_chars[I]
|
||||
#define GSEQ_SGETR(B,R) ( { \
|
||||
unsigned _lcount = 0; \
|
||||
while (_lcount < (R).length) \
|
||||
{ \
|
||||
(B)[_lcount] = (unichar)s->_contents_chars[(R).location + _lcount]; \
|
||||
_lcount++; \
|
||||
} \
|
||||
} )
|
||||
#define GSEQ_SRANGE(I) (NSRange){I,1}
|
||||
#else
|
||||
#define GSEQ_ST NSString*
|
||||
#define GSEQ_SLEN [s length]
|
||||
#define GSEQ_SGETC(I) (*scImp)(s, caiSel, I)
|
||||
#define GSEQ_SGETR(B,R) (*sgImp)(s, gcrSel, B, R)
|
||||
#define GSEQ_SRANGE(I) (*srImp)(s, ranSel, I)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up macros for dealing with 'other' string on the basis of GSQ_O
|
||||
*/
|
||||
#if GSEQ_O == GSEQ_US
|
||||
#define GSEQ_OT NSGStringStruct*
|
||||
#define GSEQ_OLEN o->_count
|
||||
#define GSEQ_OGETC(I) o->_contents_chars[I]
|
||||
#define GSEQ_OGETR(B,R) memcpy(B, &o->_contents_chars[R.location], 2*(R).length)
|
||||
#define GSEQ_ORANGE(I) (*orImp)((id)o, ranSel, I)
|
||||
#else
|
||||
#if GSEQ_O == GSEQ_CS
|
||||
#define GSEQ_OT NSGCStringStruct*
|
||||
#define GSEQ_OLEN o->_count
|
||||
#define GSEQ_OGETC(I) (unichar)o->_contents_chars[I]
|
||||
#define GSEQ_OGETR(B,R) ( { \
|
||||
unsigned _lcount = 0; \
|
||||
while (_lcount < (R).length) \
|
||||
{ \
|
||||
(B)[_lcount] = (unichar)o->_contents_chars[(R).location + _lcount]; \
|
||||
_lcount++; \
|
||||
} \
|
||||
} )
|
||||
#define GSEQ_ORANGE(I) (NSRange){I,1}
|
||||
#else
|
||||
#define GSEQ_OT NSString*
|
||||
#define GSEQ_OLEN [o length]
|
||||
#define GSEQ_OGETC(I) (*ocImp)(o, caiSel, I)
|
||||
#define GSEQ_OGETR(B,R) (*ogImp)(o, gcrSel, B, R)
|
||||
#define GSEQ_ORANGE(I) (*orImp)(o, ranSel, I)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If a string comparison function is required, implement it.
|
||||
*/
|
||||
#ifdef GSEQ_STRCOMP
|
||||
static inline NSComparisonResult
|
||||
GSEQ_STRCOMP(NSString *ss, NSString *os, unsigned mask, NSRange aRange)
|
||||
{
|
||||
GSEQ_ST s = (GSEQ_ST)ss;
|
||||
GSEQ_OT o = (GSEQ_OT)os;
|
||||
unsigned oLength; /* Length of other. */
|
||||
unsigned sLength = GSEQ_SLEN;
|
||||
|
||||
if (aRange.location > sLength)
|
||||
[NSException raise: NSRangeException format: @"Invalid location."];
|
||||
if (aRange.length > (sLength - aRange.location))
|
||||
[NSException raise: NSRangeException format: @"Invalid location+length."];
|
||||
|
||||
oLength = GSEQ_OLEN;
|
||||
if (sLength - aRange.location == 0)
|
||||
{
|
||||
if (oLength == 0)
|
||||
{
|
||||
return NSOrderedSame;
|
||||
}
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
else if (oLength == 0)
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
|
||||
if (mask & NSLiteralSearch)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned sLen = aRange.length;
|
||||
unsigned oLen = oLength;
|
||||
unsigned end;
|
||||
#if GSEQ_S == GSEQ_NS
|
||||
void (*sgImp)(NSString*, SEL, unichar*, NSRange);
|
||||
unichar sBuf[sLen];
|
||||
#else
|
||||
#if GSEQ_S == GSEQ_US
|
||||
unichar *sBuf;
|
||||
#else
|
||||
char *sBuf;
|
||||
#endif
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS
|
||||
void (*ogImp)(NSString*, SEL, unichar*, NSRange);
|
||||
unichar oBuf[oLen];
|
||||
#else
|
||||
#if GSEQ_O == GSEQ_US
|
||||
unichar *oBuf;
|
||||
#else
|
||||
char *oBuf;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if GSEQ_S == GSEQ_NS
|
||||
sgImp = (void (*)())[(id)s methodForSelector: gcrSel];
|
||||
GSEQ_SGETR(sBuf, aRange);
|
||||
#else
|
||||
sBuf = &s->_contents_chars[aRange.location];
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS
|
||||
ogImp = (void (*)())[(id)o methodForSelector: gcrSel];
|
||||
GSEQ_OGETR(oBuf, NSMakeRange(0, oLen));
|
||||
#else
|
||||
oBuf = o->_contents_chars;
|
||||
#endif
|
||||
|
||||
if (oLen < sLen)
|
||||
end = oLen;
|
||||
else
|
||||
end = sLen;
|
||||
|
||||
if (mask & NSCaseInsensitiveSearch)
|
||||
{
|
||||
for (i = 0; i < end; i++)
|
||||
{
|
||||
unichar c1 = uni_tolower((unichar)sBuf[i]);
|
||||
unichar c2 = uni_tolower((unichar)oBuf[i]);
|
||||
|
||||
if (c1 < c2)
|
||||
return NSOrderedAscending;
|
||||
if (c1 > c2)
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < end; i++)
|
||||
{
|
||||
if ((unichar)sBuf[i] < (unichar)oBuf[i])
|
||||
return NSOrderedAscending;
|
||||
if ((unichar)sBuf[i] > (unichar)oBuf[i])
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
}
|
||||
if (sLen > oLen)
|
||||
return NSOrderedDescending;
|
||||
else if (sLen < oLen)
|
||||
return NSOrderedAscending;
|
||||
else
|
||||
return NSOrderedSame;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned start = aRange.location;
|
||||
unsigned end = start + aRange.length;
|
||||
unsigned sCount = start;
|
||||
unsigned oCount = 0;
|
||||
NSComparisonResult result;
|
||||
#if GSEQ_S == GSEQ_NS || GSEQ_S == GSEQ_US
|
||||
NSRange (*srImp)(NSString*, SEL, unsigned);
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS || GSEQ_O == GSEQ_US
|
||||
NSRange (*orImp)(NSString*, SEL, unsigned);
|
||||
#endif
|
||||
#if GSEQ_S == GSEQ_NS
|
||||
void (*sgImp)(NSString*, SEL, unichar*, NSRange);
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS
|
||||
void (*ogImp)(NSString*, SEL, unichar*, NSRange);
|
||||
#endif
|
||||
|
||||
#if GSEQ_S == GSEQ_NS || GSEQ_S == GSEQ_US
|
||||
srImp = (NSRange (*)())[(id)s methodForSelector: ranSel];
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS || GSEQ_O == GSEQ_US
|
||||
orImp = (NSRange (*)())[(id)o methodForSelector: ranSel];
|
||||
#endif
|
||||
#if GSEQ_S == GSEQ_NS
|
||||
sgImp = (void (*)())[(id)s methodForSelector: gcrSel];
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS
|
||||
ogImp = (void (*)())[(id)o methodForSelector: gcrSel];
|
||||
#endif
|
||||
|
||||
|
||||
while (sCount < end)
|
||||
{
|
||||
if (oCount >= oLength)
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
else if (sCount >= sLength)
|
||||
{
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRange sRange = GSEQ_SRANGE(sCount);
|
||||
NSRange oRange = GSEQ_ORANGE(oCount);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
GSEQ_MAKE(oBuf, oSeq, oRange.length);
|
||||
|
||||
GSEQ_SGETR(sBuf, sRange);
|
||||
GSEQ_OGETR(oBuf, oRange);
|
||||
|
||||
result = GSeq_compare(&sSeq, &oSeq);
|
||||
|
||||
if (result != NSOrderedSame)
|
||||
{
|
||||
if (mask & NSCaseInsensitiveSearch)
|
||||
{
|
||||
GSeq_lowercase(&oSeq);
|
||||
GSeq_lowercase(&sSeq);
|
||||
result = GSeq_compare(&sSeq, &oSeq);
|
||||
if (result != NSOrderedSame)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
sCount += sRange.length;
|
||||
oCount += oRange.length;
|
||||
}
|
||||
}
|
||||
if (oCount < oLength)
|
||||
return NSOrderedAscending;
|
||||
return NSOrderedSame;
|
||||
}
|
||||
}
|
||||
#undef GSEQ_STRCOMP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If a string search function is required, implement it.
|
||||
*/
|
||||
#ifdef GSEQ_STRRANGE
|
||||
static inline NSRange
|
||||
GSEQ_STRRANGE(NSString *ss, NSString *os, unsigned mask, NSRange aRange)
|
||||
{
|
||||
GSEQ_ST s = (GSEQ_ST)ss;
|
||||
GSEQ_OT o = (GSEQ_OT)os;
|
||||
unsigned myLength;
|
||||
unsigned myIndex;
|
||||
unsigned myEndIndex;
|
||||
unsigned strLength;
|
||||
#if GSEQ_S == GSEQ_NS
|
||||
unichar (*scImp)(NSString*, SEL, unsigned);
|
||||
void (*sgImp)(NSString*, SEL, unichar*, NSRange);
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS
|
||||
unichar (*ocImp)(NSString*, SEL, unsigned);
|
||||
void (*ogImp)(NSString*, SEL, unichar*, NSRange);
|
||||
#endif
|
||||
#if GSEQ_S == GSEQ_NS || GSEQ_S == GSEQ_US
|
||||
NSRange (*srImp)(NSString*, SEL, unsigned);
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS || GSEQ_O == GSEQ_US
|
||||
NSRange (*orImp)(NSString*, SEL, unsigned);
|
||||
#endif
|
||||
|
||||
/* Check that the search range is reasonable */
|
||||
myLength = GSEQ_SLEN;
|
||||
if (aRange.location > myLength)
|
||||
[NSException raise: NSRangeException format: @"Invalid location."];
|
||||
if (aRange.length > (myLength - aRange.location))
|
||||
[NSException raise: NSRangeException format: @"Invalid location+length."];
|
||||
|
||||
|
||||
/* Ensure the string can be found */
|
||||
strLength = GSEQ_OLEN;
|
||||
if (strLength > aRange.length || strLength == 0)
|
||||
return (NSRange){0, 0};
|
||||
|
||||
/*
|
||||
* Cache method implementations for getting characters and ranges
|
||||
*/
|
||||
#if GSEQ_S == GSEQ_NS
|
||||
scImp = (unichar (*)())[(id)s methodForSelector: caiSel];
|
||||
sgImp = (void (*)())[(id)s methodForSelector: gcrSel];
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS
|
||||
ocImp = (unichar (*)())[(id)o methodForSelector: caiSel];
|
||||
ogImp = (void (*)())[(id)o methodForSelector: gcrSel];
|
||||
#endif
|
||||
#if GSEQ_S == GSEQ_NS || GSEQ_S == GSEQ_US
|
||||
srImp = (NSRange (*)())[(id)s methodForSelector: ranSel];
|
||||
#endif
|
||||
#if GSEQ_O == GSEQ_NS || GSEQ_O == GSEQ_US
|
||||
orImp = (NSRange (*)())[(id)o methodForSelector: ranSel];
|
||||
#endif
|
||||
|
||||
switch (mask)
|
||||
{
|
||||
case FCLS :
|
||||
case FCLAS :
|
||||
{
|
||||
unichar strFirstCharacter = GSEQ_OGETC(0);
|
||||
|
||||
myIndex = aRange.location;
|
||||
myEndIndex = aRange.location + aRange.length - strLength;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i = 1;
|
||||
unichar myCharacter = GSEQ_SGETC(myIndex);
|
||||
unichar strCharacter = strFirstCharacter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((myCharacter != strCharacter) &&
|
||||
((uni_tolower(myCharacter) != uni_tolower(strCharacter))))
|
||||
break;
|
||||
if (i == strLength)
|
||||
return (NSRange){myIndex, strLength};
|
||||
myCharacter = GSEQ_SGETC(myIndex + i);
|
||||
strCharacter = GSEQ_OGETC(i);
|
||||
i++;
|
||||
}
|
||||
if (myIndex == myEndIndex)
|
||||
break;
|
||||
myIndex++;
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case BCLS :
|
||||
case BCLAS :
|
||||
{
|
||||
unichar strFirstCharacter = GSEQ_OGETC(0);
|
||||
|
||||
myIndex = aRange.location + aRange.length - strLength;
|
||||
myEndIndex = aRange.location;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i = 1;
|
||||
unichar myCharacter = GSEQ_SGETC(myIndex);
|
||||
unichar strCharacter = strFirstCharacter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((myCharacter != strCharacter) &&
|
||||
((uni_tolower(myCharacter) != uni_tolower(strCharacter))))
|
||||
break;
|
||||
if (i == strLength)
|
||||
return (NSRange){myIndex, strLength};
|
||||
myCharacter = GSEQ_SGETC(myIndex + i);
|
||||
strCharacter = GSEQ_OGETC(i);
|
||||
i++;
|
||||
}
|
||||
if (myIndex == myEndIndex)
|
||||
break;
|
||||
myIndex--;
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case FLS :
|
||||
case FLAS :
|
||||
{
|
||||
unichar strFirstCharacter = GSEQ_OGETC(0);
|
||||
|
||||
myIndex = aRange.location;
|
||||
myEndIndex = aRange.location + aRange.length - strLength;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i = 1;
|
||||
unichar myCharacter = GSEQ_SGETC(myIndex);
|
||||
unichar strCharacter = strFirstCharacter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (myCharacter != strCharacter)
|
||||
break;
|
||||
if (i == strLength)
|
||||
return (NSRange){myIndex, strLength};
|
||||
myCharacter = GSEQ_SGETC(myIndex + i);
|
||||
strCharacter = GSEQ_OGETC(i);
|
||||
i++;
|
||||
}
|
||||
if (myIndex == myEndIndex)
|
||||
break;
|
||||
myIndex++;
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case BLS :
|
||||
case BLAS :
|
||||
{
|
||||
unichar strFirstCharacter = GSEQ_OGETC(0);
|
||||
|
||||
myIndex = aRange.location + aRange.length - strLength;
|
||||
myEndIndex = aRange.location;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i = 1;
|
||||
unichar myCharacter = GSEQ_SGETC(myIndex);
|
||||
unichar strCharacter = strFirstCharacter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (myCharacter != strCharacter)
|
||||
break;
|
||||
if (i == strLength)
|
||||
return (NSRange){myIndex, strLength};
|
||||
myCharacter = GSEQ_SGETC(myIndex + i);
|
||||
strCharacter = GSEQ_OGETC(i);
|
||||
i++;
|
||||
}
|
||||
if (myIndex == myEndIndex)
|
||||
break;
|
||||
myIndex--;
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case FCS :
|
||||
case FCAS :
|
||||
{
|
||||
unsigned strBaseLength;
|
||||
NSRange iRange;
|
||||
|
||||
strBaseLength = [(NSString*)o _baseLength];
|
||||
|
||||
myIndex = aRange.location;
|
||||
myEndIndex = aRange.location + aRange.length - strBaseLength;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
iRange = GSEQ_ORANGE(0);
|
||||
if (iRange.length)
|
||||
{
|
||||
GSEQ_MAKE(iBuf, iSeq, iRange.length);
|
||||
|
||||
GSEQ_OGETR(iBuf, iRange);
|
||||
GSeq_lowercase(&iSeq);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSRange sRange = GSEQ_SRANGE(myIndex);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
|
||||
GSEQ_SGETR(sBuf, sRange);
|
||||
GSeq_lowercase(&sSeq);
|
||||
|
||||
if (GSeq_compare(&iSeq, &sSeq) == NSOrderedSame)
|
||||
{
|
||||
unsigned myCount = sRange.length;
|
||||
unsigned strCount = iRange.length;
|
||||
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
NSRange r0 = GSEQ_SRANGE(myIndex + myCount);
|
||||
GSEQ_MAKE(b0, s0, r0.length);
|
||||
NSRange r1 = GSEQ_ORANGE(strCount);
|
||||
GSEQ_MAKE(b1, s1, r1.length);
|
||||
|
||||
GSEQ_SGETR(b0, r0);
|
||||
GSEQ_OGETR(b1, r1);
|
||||
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
GSeq_lowercase(&s0);
|
||||
GSeq_lowercase(&s1);
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
myCount += r0.length;
|
||||
strCount += r1.length;
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
}
|
||||
}
|
||||
myIndex += sRange.length;
|
||||
if (myIndex >= myEndIndex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case BCS :
|
||||
case BCAS :
|
||||
{
|
||||
unsigned strBaseLength;
|
||||
NSRange iRange;
|
||||
|
||||
strBaseLength = [(NSString*)o _baseLength];
|
||||
|
||||
myIndex = aRange.location + aRange.length - strBaseLength;
|
||||
myEndIndex = aRange.location;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
iRange = GSEQ_ORANGE(0);
|
||||
if (iRange.length)
|
||||
{
|
||||
GSEQ_MAKE(iBuf, iSeq, iRange.length);
|
||||
|
||||
GSEQ_OGETR(iBuf, iRange);
|
||||
GSeq_lowercase(&iSeq);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSRange sRange = GSEQ_SRANGE(myIndex);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
|
||||
GSEQ_SGETR(sBuf, sRange);
|
||||
GSeq_lowercase(&sSeq);
|
||||
|
||||
if (GSeq_compare(&iSeq, &sSeq) == NSOrderedSame)
|
||||
{
|
||||
unsigned myCount = sRange.length;
|
||||
unsigned strCount = iRange.length;
|
||||
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
NSRange r0 = GSEQ_SRANGE(myIndex + myCount);
|
||||
GSEQ_MAKE(b0, s0, r0.length);
|
||||
NSRange r1 = GSEQ_ORANGE(strCount);
|
||||
GSEQ_MAKE(b1, s1, r1.length);
|
||||
|
||||
GSEQ_SGETR(b0, r0);
|
||||
GSEQ_OGETR(b1, r1);
|
||||
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
GSeq_lowercase(&s0);
|
||||
GSeq_lowercase(&s1);
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
myCount += r0.length;
|
||||
strCount += r1.length;
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myIndex <= myEndIndex)
|
||||
break;
|
||||
myIndex--;
|
||||
while (uni_isnonsp(GSEQ_SGETC(myIndex))
|
||||
&& (myIndex > 0))
|
||||
myIndex--;
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case BS :
|
||||
case BAS :
|
||||
{
|
||||
unsigned strBaseLength;
|
||||
NSRange iRange;
|
||||
|
||||
strBaseLength = [(NSString*)o _baseLength];
|
||||
|
||||
myIndex = aRange.location + aRange.length - strBaseLength;
|
||||
myEndIndex = aRange.location;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
iRange = GSEQ_ORANGE(0);
|
||||
if (iRange.length)
|
||||
{
|
||||
GSEQ_MAKE(iBuf, iSeq, iRange.length);
|
||||
|
||||
GSEQ_OGETR(iBuf, iRange);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSRange sRange = GSEQ_SRANGE(myIndex);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
|
||||
GSEQ_SGETR(sBuf, sRange);
|
||||
|
||||
if (GSeq_compare(&iSeq, &sSeq) == NSOrderedSame)
|
||||
{
|
||||
unsigned myCount = sRange.length;
|
||||
unsigned strCount = iRange.length;
|
||||
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
NSRange r0 = GSEQ_SRANGE(myIndex + myCount);
|
||||
GSEQ_MAKE(b0, s0, r0.length);
|
||||
NSRange r1 = GSEQ_ORANGE(strCount);
|
||||
GSEQ_MAKE(b1, s1, r1.length);
|
||||
|
||||
GSEQ_SGETR(b0, r0);
|
||||
GSEQ_OGETR(b1, r1);
|
||||
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
myCount += r0.length;
|
||||
strCount += r1.length;
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myIndex <= myEndIndex)
|
||||
break;
|
||||
myIndex--;
|
||||
while (uni_isnonsp(GSEQ_SGETC(myIndex))
|
||||
&& (myIndex > 0))
|
||||
myIndex--;
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case FS :
|
||||
case FAS :
|
||||
default :
|
||||
{
|
||||
unsigned strBaseLength;
|
||||
NSRange iRange;
|
||||
|
||||
strBaseLength = [(NSString*)o _baseLength];
|
||||
|
||||
myIndex = aRange.location;
|
||||
myEndIndex = aRange.location + aRange.length - strBaseLength;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
iRange = GSEQ_ORANGE(0);
|
||||
if (iRange.length)
|
||||
{
|
||||
GSEQ_MAKE(iBuf, iSeq, iRange.length);
|
||||
|
||||
GSEQ_OGETR(iBuf, iRange);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSRange sRange = GSEQ_SRANGE(myIndex);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
|
||||
GSEQ_SGETR(sBuf, sRange);
|
||||
|
||||
if (GSeq_compare(&iSeq, &sSeq) == NSOrderedSame)
|
||||
{
|
||||
unsigned myCount = sRange.length;
|
||||
unsigned strCount = iRange.length;
|
||||
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
NSRange r0 = GSEQ_SRANGE(myIndex + myCount);
|
||||
GSEQ_MAKE(b0, s0, r0.length);
|
||||
NSRange r1 = GSEQ_ORANGE(strCount);
|
||||
GSEQ_MAKE(b1, s1, r1.length);
|
||||
|
||||
GSEQ_SGETR(b0, r0);
|
||||
GSEQ_OGETR(b1, r1);
|
||||
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
myCount += r0.length;
|
||||
strCount += r1.length;
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
}
|
||||
}
|
||||
myIndex += sRange.length;
|
||||
if (myIndex >= myEndIndex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
#undef GSEQ_STRRANGE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clean up macro namespace
|
||||
*/
|
||||
#ifdef GSEQ_S
|
||||
#undef GSEQ_SLEN
|
||||
#undef GSEQ_SGETC
|
||||
#undef GSEQ_SGETR
|
||||
#undef GSEQ_SRANGE
|
||||
#undef GSEQ_ST
|
||||
#undef GSEQ_S
|
||||
#endif
|
||||
|
||||
#ifdef GSEQ_O
|
||||
#undef GSEQ_OLEN
|
||||
#undef GSEQ_OGETC
|
||||
#undef GSEQ_OGETR
|
||||
#undef GSEQ_ORANGE
|
||||
#undef GSEQ_OT
|
||||
#undef GSEQ_O
|
||||
#endif
|
||||
|
||||
|
|
|
@ -258,6 +258,8 @@ $(GNUSTEP_OBJ_DIR)/NSGCString.o \
|
|||
# Files that include GSeq.h will need a rebuild if it is changed.
|
||||
#
|
||||
$(GNUSTEP_OBJ_DIR)/NSString.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSGString.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSGCString.o \
|
||||
: GSeq.h
|
||||
|
||||
#
|
||||
|
|
|
@ -41,6 +41,28 @@
|
|||
#include <base/Unicode.h>
|
||||
#include <base/fast.x>
|
||||
|
||||
/*
|
||||
* Include sequence handling code with instructions to generate search
|
||||
* and compare functions for NSString objects.
|
||||
*/
|
||||
#define GSEQ_STRCOMP strCompCsNs
|
||||
#define GSEQ_STRRANGE strRangeCsNs
|
||||
#define GSEQ_O GSEQ_NS
|
||||
#define GSEQ_S GSEQ_CS
|
||||
#include <GSeq.h>
|
||||
|
||||
#define GSEQ_STRCOMP strCompCsUs
|
||||
#define GSEQ_STRRANGE strRangeCsUs
|
||||
#define GSEQ_O GSEQ_US
|
||||
#define GSEQ_S GSEQ_CS
|
||||
#include <GSeq.h>
|
||||
|
||||
#define GSEQ_STRCOMP strCompCsCs
|
||||
#define GSEQ_STRRANGE strRangeCsCs
|
||||
#define GSEQ_O GSEQ_CS
|
||||
#define GSEQ_S GSEQ_CS
|
||||
#include <GSeq.h>
|
||||
|
||||
/*
|
||||
* Include property-list parsing code configured for ascii characters.
|
||||
*/
|
||||
|
@ -418,7 +440,8 @@ static IMP msInitImp; /* designated initialiser for mutable */
|
|||
return NO;
|
||||
c = fastClassOfInstance(anObject);
|
||||
|
||||
if (c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString || c == _fastCls._NXConstantString)
|
||||
if (c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString
|
||||
|| c == _fastCls._NXConstantString)
|
||||
{
|
||||
NSGCString *other = (NSGCString*)anObject;
|
||||
|
||||
|
@ -434,6 +457,12 @@ static IMP msInitImp; /* designated initialiser for mutable */
|
|||
return NO;
|
||||
return YES;
|
||||
}
|
||||
else if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString)
|
||||
{
|
||||
if (strCompCsUs(self, anObject, 0, (NSRange){0,_count}) == NSOrderedSame)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
else if (c == nil)
|
||||
return NO;
|
||||
else if (fastClassIsKindOfClass(c, _fastCls._NSString))
|
||||
|
@ -452,7 +481,8 @@ static IMP msInitImp; /* designated initialiser for mutable */
|
|||
if (aString == nil)
|
||||
return NO;
|
||||
c = fastClassOfInstance(aString);
|
||||
if (c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString || c == _fastCls._NXConstantString)
|
||||
if (c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString
|
||||
|| c == _fastCls._NXConstantString)
|
||||
{
|
||||
NSGCString *other = (NSGCString*)aString;
|
||||
|
||||
|
@ -468,6 +498,12 @@ static IMP msInitImp; /* designated initialiser for mutable */
|
|||
return NO;
|
||||
return YES;
|
||||
}
|
||||
else if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString)
|
||||
{
|
||||
if (strCompCsUs(self, aString, 0, (NSRange){0,_count}) == NSOrderedSame)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
else if (c == nil)
|
||||
return NO;
|
||||
else if (fastClassIsKindOfClass(c, _fastCls._NSString))
|
||||
|
@ -656,6 +692,35 @@ static IMP msInitImp; /* designated initialiser for mutable */
|
|||
return NSMakeRange(anIndex, 1);
|
||||
}
|
||||
|
||||
- (NSComparisonResult) compare: (NSString*)aString
|
||||
options: (unsigned int)mask
|
||||
range: (NSRange)aRange
|
||||
{
|
||||
Class c = fastClass(aString);
|
||||
|
||||
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString)
|
||||
return strCompCsUs(self, aString, mask, aRange);
|
||||
else if (c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString
|
||||
|| c == _fastCls._NXConstantString)
|
||||
return strCompCsCs(self, aString, mask, aRange);
|
||||
else
|
||||
return strCompCsNs(self, aString, mask, aRange);
|
||||
}
|
||||
|
||||
- (NSRange) rangeOfString: (NSString *) aString
|
||||
options: (unsigned int) mask
|
||||
range: (NSRange) aRange
|
||||
{
|
||||
Class c = fastClass(aString);
|
||||
|
||||
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString)
|
||||
return strRangeCsUs(self, aString, mask, aRange);
|
||||
else if (c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString
|
||||
|| c == _fastCls._NXConstantString)
|
||||
return strRangeCsCs(self, aString, mask, aRange);
|
||||
else
|
||||
return strRangeCsNs(self, aString, mask, aRange);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -47,6 +47,28 @@
|
|||
#include <base/fast.x>
|
||||
#include <base/Unicode.h>
|
||||
|
||||
/*
|
||||
* Include sequence handling code with instructions to generate search
|
||||
* and compare functions for NSString objects.
|
||||
*/
|
||||
#define GSEQ_STRCOMP strCompUsNs
|
||||
#define GSEQ_STRRANGE strRangeUsNs
|
||||
#define GSEQ_O GSEQ_NS
|
||||
#define GSEQ_S GSEQ_US
|
||||
#include <GSeq.h>
|
||||
|
||||
#define GSEQ_STRCOMP strCompUsUs
|
||||
#define GSEQ_STRRANGE strRangeUsUs
|
||||
#define GSEQ_O GSEQ_US
|
||||
#define GSEQ_S GSEQ_US
|
||||
#include <GSeq.h>
|
||||
|
||||
#define GSEQ_STRCOMP strCompUsCs
|
||||
#define GSEQ_STRRANGE strRangeUsCs
|
||||
#define GSEQ_O GSEQ_CS
|
||||
#define GSEQ_S GSEQ_US
|
||||
#include <GSeq.h>
|
||||
|
||||
/*
|
||||
* Include property-list parsing code configured for unicode characters.
|
||||
*/
|
||||
|
@ -91,20 +113,37 @@
|
|||
if (anObject == nil)
|
||||
return NO;
|
||||
c = fastClassOfInstance(anObject);
|
||||
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString ||
|
||||
c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString ||
|
||||
c == _fastCls._NXConstantString)
|
||||
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString
|
||||
|| c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString
|
||||
|| c == _fastCls._NXConstantString)
|
||||
{
|
||||
NSGString *other = (NSGString*)anObject;
|
||||
NSRange r = {0, _count};
|
||||
|
||||
/*
|
||||
* First see if the has is the same - if not, we can't be equal.
|
||||
*/
|
||||
if (_hash == 0)
|
||||
_hash = _fastImp._NSString_hash(self, @selector(hash));
|
||||
if (other->_hash == 0)
|
||||
other->_hash = _fastImp._NSString_hash(other, @selector(hash));
|
||||
if (_hash != other->_hash)
|
||||
return NO;
|
||||
return _fastImp._NSString_isEqualToString_(self,
|
||||
@selector(isEqualToString:), other);
|
||||
|
||||
/*
|
||||
* Do a compare depending on the type of the other string.
|
||||
*/
|
||||
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString)
|
||||
{
|
||||
if (strCompUsUs(self, other, 0, r) == NSOrderedSame)
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strCompUsCs(self, other, 0, r) == NSOrderedSame)
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
else if (c == nil)
|
||||
return NO;
|
||||
|
@ -387,6 +426,36 @@
|
|||
return NSMakeRange(start, end-start);
|
||||
}
|
||||
|
||||
- (NSComparisonResult) compare: (NSString*)aString
|
||||
options: (unsigned int)mask
|
||||
range: (NSRange)aRange
|
||||
{
|
||||
Class c = fastClass(aString);
|
||||
|
||||
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString)
|
||||
return strCompUsUs(self, aString, mask, aRange);
|
||||
else if (c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString
|
||||
|| c == _fastCls._NXConstantString)
|
||||
return strCompUsCs(self, aString, mask, aRange);
|
||||
else
|
||||
return strCompUsNs(self, aString, mask, aRange);
|
||||
}
|
||||
|
||||
- (NSRange) rangeOfString: (NSString *) aString
|
||||
options: (unsigned int) mask
|
||||
range: (NSRange) aRange
|
||||
{
|
||||
Class c = fastClass(aString);
|
||||
|
||||
if (c == _fastCls._NSGString || c == _fastCls._NSGMutableString)
|
||||
return strRangeUsUs(self, aString, mask, aRange);
|
||||
else if (c == _fastCls._NSGCString || c == _fastCls._NSGMutableCString
|
||||
|| c == _fastCls._NXConstantString)
|
||||
return strRangeUsCs(self, aString, mask, aRange);
|
||||
else
|
||||
return strRangeUsNs(self, aString, mask, aRange);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
#include <base/GetDefEncoding.h>
|
||||
#include <base/NSGString.h>
|
||||
#include <base/NSGCString.h>
|
||||
#include <GSeq.h>
|
||||
|
||||
#include <base/fast.x>
|
||||
|
||||
|
@ -101,9 +100,15 @@
|
|||
|
||||
static Class NSString_class; /* For speed */
|
||||
|
||||
static SEL caiSel = @selector(characterAtIndex:);
|
||||
static SEL gcrSel = @selector(getCharacters:range:);
|
||||
static SEL ranSel = @selector(rangeOfComposedCharacterSequenceAtIndex:);
|
||||
/*
|
||||
* Include sequence handling code with instructions to generate search
|
||||
* and compare functions for NSString objects.
|
||||
*/
|
||||
#define GSEQ_STRCOMP strCompNsNs
|
||||
#define GSEQ_STRRANGE strRangeNsNs
|
||||
#define GSEQ_O GSEQ_NS
|
||||
#define GSEQ_S GSEQ_NS
|
||||
#include <GSeq.h>
|
||||
|
||||
/*
|
||||
* Include property-list parsing code configured for unicode characters.
|
||||
|
@ -649,7 +654,7 @@ handle_printf_atsign (FILE *stream,
|
|||
|
||||
/* Inefficient. Should be overridden */
|
||||
- (void) getCharacters: (unichar*)buffer
|
||||
range: (NSRange)aRange
|
||||
range: (NSRange)aRange
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < aRange.length; i++)
|
||||
|
@ -764,7 +769,7 @@ handle_printf_atsign (FILE *stream,
|
|||
}
|
||||
|
||||
- (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet
|
||||
options: (unsigned int)mask
|
||||
options: (unsigned int)mask
|
||||
{
|
||||
NSRange all = NSMakeRange(0, [self length]);
|
||||
return [self rangeOfCharacterFromSet: aSet
|
||||
|
@ -834,514 +839,10 @@ handle_printf_atsign (FILE *stream,
|
|||
}
|
||||
|
||||
- (NSRange) rangeOfString: (NSString *) aString
|
||||
options: (unsigned int) mask
|
||||
range: (NSRange) aRange
|
||||
options: (unsigned int) mask
|
||||
range: (NSRange) aRange
|
||||
{
|
||||
#define FCLS 3
|
||||
#define BCLS 7
|
||||
#define FLS 2
|
||||
#define BLS 6
|
||||
#define FCS 1
|
||||
#define BCS 5
|
||||
#define FS 0
|
||||
#define BS 4
|
||||
#define FCLAS 11
|
||||
#define BCLAS 15
|
||||
#define FLAS 10
|
||||
#define BLAS 14
|
||||
#define FCAS 9
|
||||
#define BCAS 13
|
||||
#define FAS 8
|
||||
#define BAS 12
|
||||
|
||||
unsigned myLength;
|
||||
unsigned myIndex;
|
||||
unsigned myEndIndex;
|
||||
unsigned strLength;
|
||||
unichar (*scImp)(NSString*, SEL, unsigned);
|
||||
unichar (*ocImp)(NSString*, SEL, unsigned);
|
||||
void (*sgImp)(NSString*, SEL, unichar*, NSRange);
|
||||
void (*ogImp)(NSString*, SEL, unichar*, NSRange);
|
||||
NSRange (*srImp)(NSString*, SEL, unsigned);
|
||||
NSRange (*orImp)(NSString*, SEL, unsigned);
|
||||
|
||||
/* Check that the search range is reasonable */
|
||||
myLength = [self length];
|
||||
if (aRange.location > myLength)
|
||||
[NSException raise: NSRangeException format: @"Invalid location."];
|
||||
if (aRange.length > (myLength - aRange.location))
|
||||
[NSException raise: NSRangeException format: @"Invalid location+length."];
|
||||
|
||||
|
||||
/* Ensure the string can be found */
|
||||
strLength = [aString length];
|
||||
if (strLength > aRange.length || strLength == 0)
|
||||
return (NSRange){0, 0};
|
||||
|
||||
/*
|
||||
* Cache method implementations fo getting characters and ranges
|
||||
*/
|
||||
scImp = (unichar (*)())[self methodForSelector: caiSel];
|
||||
ocImp = (unichar (*)())[aString methodForSelector: caiSel];
|
||||
sgImp = (void (*)())[self methodForSelector: gcrSel];
|
||||
ogImp = (void (*)())[aString methodForSelector: gcrSel];
|
||||
srImp = (NSRange (*)())[self methodForSelector: ranSel];
|
||||
orImp = (NSRange (*)())[aString methodForSelector: ranSel];
|
||||
|
||||
switch (mask)
|
||||
{
|
||||
case FCLS :
|
||||
case FCLAS :
|
||||
{
|
||||
unichar strFirstCharacter = (*ocImp)(aString, caiSel, 0);
|
||||
|
||||
myIndex = aRange.location;
|
||||
myEndIndex = aRange.location + aRange.length - strLength;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i = 1;
|
||||
unichar myCharacter = (*scImp)(self, caiSel, myIndex);
|
||||
unichar strCharacter = strFirstCharacter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((myCharacter != strCharacter) &&
|
||||
((uni_tolower(myCharacter) != uni_tolower(strCharacter))))
|
||||
break;
|
||||
if (i == strLength)
|
||||
return (NSRange){myIndex, strLength};
|
||||
myCharacter = (*scImp)(self, caiSel, myIndex + i);
|
||||
strCharacter = (*ocImp)(aString, caiSel, i);
|
||||
i++;
|
||||
}
|
||||
if (myIndex == myEndIndex)
|
||||
break;
|
||||
myIndex++;
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case BCLS :
|
||||
case BCLAS :
|
||||
{
|
||||
unichar strFirstCharacter = (*ocImp)(aString, caiSel, 0);
|
||||
|
||||
myIndex = aRange.location + aRange.length - strLength;
|
||||
myEndIndex = aRange.location;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i = 1;
|
||||
unichar myCharacter = (*scImp)(self, caiSel, myIndex);
|
||||
unichar strCharacter = strFirstCharacter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((myCharacter != strCharacter) &&
|
||||
((uni_tolower(myCharacter) != uni_tolower(strCharacter))))
|
||||
break;
|
||||
if (i == strLength)
|
||||
return (NSRange){myIndex, strLength};
|
||||
myCharacter = (*scImp)(self, caiSel, myIndex + i);
|
||||
strCharacter = (*ocImp)(aString, caiSel, i);
|
||||
i++;
|
||||
}
|
||||
if (myIndex == myEndIndex)
|
||||
break;
|
||||
myIndex--;
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case FLS :
|
||||
case FLAS :
|
||||
{
|
||||
unichar strFirstCharacter = (*ocImp)(aString, caiSel, 0);
|
||||
|
||||
myIndex = aRange.location;
|
||||
myEndIndex = aRange.location + aRange.length - strLength;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i = 1;
|
||||
unichar myCharacter = (*scImp)(self, caiSel, myIndex);
|
||||
unichar strCharacter = strFirstCharacter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (myCharacter != strCharacter)
|
||||
break;
|
||||
if (i == strLength)
|
||||
return (NSRange){myIndex, strLength};
|
||||
myCharacter = (*scImp)(self, caiSel, myIndex + i);
|
||||
strCharacter = (*ocImp)(aString, caiSel, i);
|
||||
i++;
|
||||
}
|
||||
if (myIndex == myEndIndex)
|
||||
break;
|
||||
myIndex++;
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case BLS :
|
||||
case BLAS :
|
||||
{
|
||||
unichar strFirstCharacter = (*ocImp)(aString, caiSel, 0);
|
||||
|
||||
myIndex = aRange.location + aRange.length - strLength;
|
||||
myEndIndex = aRange.location;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned i = 1;
|
||||
unichar myCharacter = (*scImp)(self, caiSel, myIndex);
|
||||
unichar strCharacter = strFirstCharacter;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (myCharacter != strCharacter)
|
||||
break;
|
||||
if (i == strLength)
|
||||
return (NSRange){myIndex, strLength};
|
||||
myCharacter = (*scImp)(self, caiSel, myIndex + i);
|
||||
strCharacter = (*ocImp)(aString, caiSel, i);
|
||||
i++;
|
||||
}
|
||||
if (myIndex == myEndIndex)
|
||||
break;
|
||||
myIndex--;
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case FCS :
|
||||
case FCAS :
|
||||
{
|
||||
unsigned strBaseLength;
|
||||
NSRange iRange;
|
||||
|
||||
strBaseLength = [aString _baseLength];
|
||||
|
||||
myIndex = aRange.location;
|
||||
myEndIndex = aRange.location + aRange.length - strBaseLength;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
iRange = (*orImp)(aString, ranSel, 0);
|
||||
if (iRange.length)
|
||||
{
|
||||
GSEQ_MAKE(iBuf, iSeq, iRange.length);
|
||||
|
||||
(*ogImp)(aString, gcrSel, iBuf, iRange);
|
||||
GSeq_normalize(&iSeq);
|
||||
GSeq_lowercase(&iSeq);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSRange sRange = (*srImp)(self, ranSel, myIndex);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, sBuf, sRange);
|
||||
GSeq_normalize(&sSeq);
|
||||
GSeq_lowercase(&sSeq);
|
||||
|
||||
if (GSeq_compare(&iSeq, &sSeq) == NSOrderedSame)
|
||||
{
|
||||
unsigned myCount = sRange.length;
|
||||
unsigned strCount = iRange.length;
|
||||
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
NSRange r0 =
|
||||
(*srImp)(self, ranSel, myIndex + myCount);
|
||||
GSEQ_MAKE(b0, s0, r0.length);
|
||||
NSRange r1 =
|
||||
(*orImp)(aString, ranSel, strCount);
|
||||
GSEQ_MAKE(b1, s1, r1.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, b0, r0);
|
||||
(*ogImp)(aString, gcrSel, b1, r1);
|
||||
|
||||
GSeq_normalize(&s0);
|
||||
GSeq_normalize(&s1);
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
GSeq_lowercase(&s0);
|
||||
GSeq_lowercase(&s1);
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
myCount += r0.length;
|
||||
strCount += r1.length;
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
}
|
||||
}
|
||||
myIndex += sRange.length;
|
||||
if (myIndex >= myEndIndex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case BCS :
|
||||
case BCAS :
|
||||
{
|
||||
unsigned strBaseLength;
|
||||
NSRange iRange;
|
||||
|
||||
strBaseLength = [aString _baseLength];
|
||||
|
||||
myIndex = aRange.location + aRange.length - strBaseLength;
|
||||
myEndIndex = aRange.location;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
iRange = (*orImp)(aString, ranSel, 0);
|
||||
if (iRange.length)
|
||||
{
|
||||
GSEQ_MAKE(iBuf, iSeq, iRange.length);
|
||||
|
||||
(*ogImp)(aString, gcrSel, iBuf, iRange);
|
||||
GSeq_normalize(&iSeq);
|
||||
GSeq_lowercase(&iSeq);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSRange sRange = (*srImp)(self, ranSel, myIndex);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, sBuf, sRange);
|
||||
GSeq_normalize(&sSeq);
|
||||
GSeq_lowercase(&sSeq);
|
||||
|
||||
if (GSeq_compare(&iSeq, &sSeq) == NSOrderedSame)
|
||||
{
|
||||
unsigned myCount = sRange.length;
|
||||
unsigned strCount = iRange.length;
|
||||
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
NSRange r0 =
|
||||
(*srImp)(self, ranSel, myIndex + myCount);
|
||||
GSEQ_MAKE(b0, s0, r0.length);
|
||||
NSRange r1 =
|
||||
(*orImp)(aString, ranSel, strCount);
|
||||
GSEQ_MAKE(b1, s1, r1.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, b0, r0);
|
||||
(*ogImp)(aString, gcrSel, b1, r1);
|
||||
|
||||
GSeq_normalize(&s0);
|
||||
GSeq_normalize(&s1);
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
GSeq_lowercase(&s0);
|
||||
GSeq_lowercase(&s1);
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
myCount += r0.length;
|
||||
strCount += r1.length;
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myIndex <= myEndIndex)
|
||||
break;
|
||||
myIndex--;
|
||||
while (uni_isnonsp((*scImp)(self, caiSel, myIndex))
|
||||
&& (myIndex > 0))
|
||||
myIndex--;
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case BS :
|
||||
case BAS :
|
||||
{
|
||||
unsigned strBaseLength;
|
||||
NSRange iRange;
|
||||
|
||||
strBaseLength = [aString _baseLength];
|
||||
|
||||
myIndex = aRange.location + aRange.length - strBaseLength;
|
||||
myEndIndex = aRange.location;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
iRange = (*orImp)(aString, ranSel, 0);
|
||||
if (iRange.length)
|
||||
{
|
||||
GSEQ_MAKE(iBuf, iSeq, iRange.length);
|
||||
|
||||
(*ogImp)(aString, gcrSel, iBuf, iRange);
|
||||
GSeq_normalize(&iSeq);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSRange sRange = (*srImp)(self, ranSel, myIndex);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, sBuf, sRange);
|
||||
GSeq_normalize(&sSeq);
|
||||
|
||||
if (GSeq_compare(&iSeq, &sSeq) == NSOrderedSame)
|
||||
{
|
||||
unsigned myCount = sRange.length;
|
||||
unsigned strCount = iRange.length;
|
||||
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
NSRange r0 =
|
||||
(*srImp)(self, ranSel, myIndex + myCount);
|
||||
GSEQ_MAKE(b0, s0, r0.length);
|
||||
NSRange r1 =
|
||||
(*orImp)(aString, ranSel, strCount);
|
||||
GSEQ_MAKE(b1, s1, r1.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, b0, r0);
|
||||
(*ogImp)(aString, gcrSel, b1, r1);
|
||||
|
||||
GSeq_normalize(&s0);
|
||||
GSeq_normalize(&s1);
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
myCount += r0.length;
|
||||
strCount += r1.length;
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myIndex <= myEndIndex)
|
||||
break;
|
||||
myIndex--;
|
||||
while (uni_isnonsp((*scImp)(self, caiSel, myIndex))
|
||||
&& (myIndex > 0))
|
||||
myIndex--;
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
|
||||
case FS :
|
||||
case FAS :
|
||||
default :
|
||||
{
|
||||
unsigned strBaseLength;
|
||||
NSRange iRange;
|
||||
|
||||
strBaseLength = [aString _baseLength];
|
||||
|
||||
myIndex = aRange.location;
|
||||
myEndIndex = aRange.location + aRange.length - strBaseLength;
|
||||
|
||||
if (mask & NSAnchoredSearch)
|
||||
myEndIndex = myIndex;
|
||||
|
||||
iRange = (*orImp)(aString, ranSel, 0);
|
||||
if (iRange.length)
|
||||
{
|
||||
GSEQ_MAKE(iBuf, iSeq, iRange.length);
|
||||
|
||||
(*ogImp)(aString, gcrSel, iBuf, iRange);
|
||||
GSeq_normalize(&iSeq);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSRange sRange = (*srImp)(self, ranSel, myIndex);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, sBuf, sRange);
|
||||
GSeq_normalize(&sSeq);
|
||||
|
||||
if (GSeq_compare(&iSeq, &sSeq) == NSOrderedSame)
|
||||
{
|
||||
unsigned myCount = sRange.length;
|
||||
unsigned strCount = iRange.length;
|
||||
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
NSRange r0 =
|
||||
(*srImp)(self, ranSel, myIndex + myCount);
|
||||
GSEQ_MAKE(b0, s0, r0.length);
|
||||
NSRange r1 =
|
||||
(*orImp)(aString, ranSel, strCount);
|
||||
GSEQ_MAKE(b1, s1, r1.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, b0, r0);
|
||||
(*ogImp)(aString, gcrSel, b1, r1);
|
||||
|
||||
GSeq_normalize(&s0);
|
||||
GSeq_normalize(&s1);
|
||||
if (GSeq_compare(&s0, &s1) != NSOrderedSame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
myCount += r0.length;
|
||||
strCount += r1.length;
|
||||
if (strCount >= strLength)
|
||||
{
|
||||
return (NSRange){myIndex, myCount};
|
||||
}
|
||||
}
|
||||
}
|
||||
myIndex += sRange.length;
|
||||
if (myIndex >= myEndIndex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
}
|
||||
}
|
||||
return (NSRange){0, 0};
|
||||
return strRangeNsNs(self, aString, mask, aRange);
|
||||
}
|
||||
|
||||
// Determining Composed Character Sequences
|
||||
|
@ -1383,144 +884,7 @@ handle_printf_atsign (FILE *stream,
|
|||
options: (unsigned int)mask
|
||||
range: (NSRange)aRange
|
||||
{
|
||||
unsigned oLength; /* Length of other. */
|
||||
unsigned sLength = [self length];
|
||||
|
||||
if (aRange.location > sLength)
|
||||
[NSException raise: NSRangeException format: @"Invalid location."];
|
||||
if (aRange.length > (sLength - aRange.location))
|
||||
[NSException raise: NSRangeException format: @"Invalid location+length."];
|
||||
|
||||
oLength = [aString length];
|
||||
if (sLength - aRange.location == 0)
|
||||
{
|
||||
if (oLength == 0)
|
||||
{
|
||||
return NSOrderedSame;
|
||||
}
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
else if (oLength == 0)
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
|
||||
if (mask & NSLiteralSearch)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned sLen = aRange.length;
|
||||
unsigned oLen = oLength;
|
||||
unsigned end;
|
||||
unichar s[sLen+1];
|
||||
unichar o[oLen+1];
|
||||
|
||||
[self getCharacters: s range: aRange];
|
||||
s[sLen] = (unichar)0;
|
||||
[aString getCharacters: o];
|
||||
o[oLen] = (unichar)0;
|
||||
if (oLen < sLen)
|
||||
end = oLen + 1;
|
||||
else
|
||||
end = sLen + 1;
|
||||
|
||||
if (mask & NSCaseInsensitiveSearch)
|
||||
{
|
||||
for (i = 0; i < end; i++)
|
||||
{
|
||||
unichar c1 = uni_tolower(s[i]);
|
||||
unichar c2 = uni_tolower(o[i]);
|
||||
|
||||
if (c1 < c2)
|
||||
return NSOrderedAscending;
|
||||
if (c1 > c2)
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < end; i++)
|
||||
{
|
||||
if (s[i] < o[i])
|
||||
return NSOrderedAscending;
|
||||
if (s[i] > o[i])
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
}
|
||||
if (sLen > oLen)
|
||||
return NSOrderedDescending;
|
||||
else if (sLen < oLen)
|
||||
return NSOrderedAscending;
|
||||
else
|
||||
return NSOrderedSame;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned start = aRange.location;
|
||||
unsigned end = start + aRange.length;
|
||||
unsigned sCount = start;
|
||||
unsigned oCount = 0;
|
||||
void (*sgImp)(NSString*, SEL, unichar*, NSRange);
|
||||
void (*ogImp)(NSString*, SEL, unichar*, NSRange);
|
||||
NSRange (*srImp)(NSString*, SEL, unsigned);
|
||||
NSRange (*orImp)(NSString*, SEL, unsigned);
|
||||
NSComparisonResult result;
|
||||
|
||||
sgImp = (void (*)())[self methodForSelector: gcrSel];
|
||||
ogImp = (void (*)())[aString methodForSelector: gcrSel];
|
||||
srImp = (NSRange (*)())[self methodForSelector: ranSel];
|
||||
orImp = (NSRange (*)())[aString methodForSelector: ranSel];
|
||||
|
||||
while (sCount < end)
|
||||
{
|
||||
if (oCount >= oLength)
|
||||
{
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
else if (sCount >= sLength)
|
||||
{
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRange sRange = (*srImp)(self, ranSel, sCount);
|
||||
NSRange oRange = (*orImp)(aString, ranSel, oCount);
|
||||
GSEQ_MAKE(sBuf, sSeq, sRange.length);
|
||||
GSEQ_MAKE(oBuf, oSeq, oRange.length);
|
||||
|
||||
(*sgImp)(self, gcrSel, sBuf, sRange);
|
||||
(*ogImp)(aString, gcrSel, oBuf, oRange);
|
||||
|
||||
GSeq_normalize(&sSeq);
|
||||
GSeq_normalize(&oSeq);
|
||||
|
||||
result = GSeq_compare(&sSeq, &oSeq);
|
||||
|
||||
if (result != NSOrderedSame)
|
||||
{
|
||||
if (mask & NSCaseInsensitiveSearch)
|
||||
{
|
||||
GSeq_lowercase(&oSeq);
|
||||
GSeq_lowercase(&sSeq);
|
||||
result = GSeq_compare(&sSeq, &oSeq);
|
||||
if (result != NSOrderedSame)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
sCount += sRange.length;
|
||||
oCount += oRange.length;
|
||||
}
|
||||
}
|
||||
if (oCount < oLength)
|
||||
return NSOrderedAscending;
|
||||
return NSOrderedSame;
|
||||
}
|
||||
return strCompNsNs(self, aString, mask, aRange);
|
||||
}
|
||||
|
||||
- (BOOL) hasPrefix: (NSString*)aString
|
||||
|
@ -1556,82 +920,12 @@ handle_printf_atsign (FILE *stream,
|
|||
|
||||
- (BOOL) isEqualToString: (NSString*)aString
|
||||
{
|
||||
unsigned myLength;
|
||||
unsigned strLength;
|
||||
unsigned myIndex = 0;
|
||||
unsigned strIndex = 0;
|
||||
unichar (*scImp)(NSString*, SEL, unsigned);
|
||||
unichar (*ocImp)(NSString*, SEL, unsigned);
|
||||
void (*sgImp)(NSString*, SEL, unichar*, NSRange);
|
||||
void (*ogImp)(NSString*, SEL, unichar*, NSRange);
|
||||
NSRange (*srImp)(NSString*, SEL, unsigned);
|
||||
NSRange (*orImp)(NSString*, SEL, unsigned);
|
||||
BOOL gotRangeImps = NO;
|
||||
BOOL gotFetchImps = NO;
|
||||
|
||||
if ([self hash] != [aString hash])
|
||||
return NO;
|
||||
myLength = [self length];
|
||||
strLength = [aString length];
|
||||
if ((!myLength) && (!strLength))
|
||||
if (strCompNsNs(self, aString, 0, (NSRange){0, [self length]})
|
||||
== NSOrderedSame)
|
||||
return YES;
|
||||
if (!myLength)
|
||||
return NO;
|
||||
if (!strLength)
|
||||
return NO;
|
||||
|
||||
scImp = (unichar (*)())[self methodForSelector: caiSel];
|
||||
ocImp = (unichar (*)())[aString methodForSelector: caiSel];
|
||||
|
||||
while ((myIndex < myLength) && (strIndex < strLength))
|
||||
if ((*scImp)(self, caiSel, myIndex) == (*ocImp)(aString, caiSel, strIndex))
|
||||
{
|
||||
myIndex++;
|
||||
strIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRange r0;
|
||||
NSRange r1;
|
||||
|
||||
if (gotRangeImps == NO)
|
||||
{
|
||||
gotRangeImps = YES;
|
||||
srImp = (NSRange (*)())[self methodForSelector: ranSel];
|
||||
orImp = (NSRange (*)())[aString methodForSelector: ranSel];
|
||||
}
|
||||
r0 = (*srImp)(self, ranSel, myIndex);
|
||||
r1 = (*orImp)(aString, ranSel, strIndex);
|
||||
if ((r0.length < 2) || (r1.length < 2))
|
||||
return NO;
|
||||
else
|
||||
{
|
||||
unichar buf0[r0.length * MAXDEC + 1];
|
||||
unichar buf1[r1.length * MAXDEC + 1];
|
||||
GSeqStruct s0 = { buf0, r0.length, r0.length * MAXDEC, 0 };
|
||||
GSeqStruct s1 = { buf1, r1.length, r1.length * MAXDEC, 0 };
|
||||
|
||||
if (gotFetchImps == NO)
|
||||
{
|
||||
gotFetchImps = YES;
|
||||
sgImp = (void (*)())[self methodForSelector: gcrSel];
|
||||
ogImp = (void (*)())[aString methodForSelector: gcrSel];
|
||||
}
|
||||
(*sgImp)(self, gcrSel, buf0, r0);
|
||||
(*ogImp)(aString, gcrSel, buf1, r1);
|
||||
if (GSeq_compare(&s0, &s1) == NSOrderedSame)
|
||||
{
|
||||
myIndex += r0.length;
|
||||
strIndex += r1.length;
|
||||
}
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
if ((myIndex == myLength) && (strIndex == strLength))
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (unsigned int) hash
|
||||
|
@ -1781,8 +1075,6 @@ handle_printf_atsign (FILE *stream,
|
|||
(*sgImp)(self, gcrSel, sBuf, sRange);
|
||||
(*ogImp)(aString, gcrSel, oBuf, oRange);
|
||||
|
||||
GSeq_normalize(&sSeq);
|
||||
GSeq_normalize(&oSeq);
|
||||
if (GSeq_compare(&sSeq, &oSeq) == NSOrderedSame)
|
||||
{
|
||||
sIndex += sRange.length;
|
||||
|
|
Loading…
Reference in a new issue