* EOControl/EONSAddOns.h (GDL2_BUFFER): Added experimental

macro.
        * EOControl/EOQualifier.m (_isLike): New static function to
        implement -isLike: and -isCaseInsensitiveLike:.
        (-[NSString isLike:]): Implemented.
        (-[NSString isCaseInsensitiveLike:]): Ditto.
        (-[NSArray filteredArrayUsingQualifier:]): Adapted to use
        experimental GDL2_BUFFER macro.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@17969 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
David Ayers 2003-10-24 16:30:49 +00:00
parent 6b82f558c1
commit b536cbb410
3 changed files with 125 additions and 21 deletions

View file

@ -1,3 +1,13 @@
2003-10-24 David Ayers <d.ayers@inode.at>
* EOControl/EONSAddOns.h (GDL2_BUFFER): Added experimental macro.
* EOControl/EOQualifier.m (_isLike): New static function to
implement -isLike: and -isCaseInsensitiveLike:.
(-[NSString isLike:]): Implemented.
(-[NSString isCaseInsensitiveLike:]): Ditto.
(-[NSArray filteredArrayUsingQualifier:]): Adapted to use
experimental GDL2_BUFFER macro.
2003-10-23 David Ayers <d.ayers@inode.at>
* EOControl/EOFetchSpecification.m

View file

@ -36,6 +36,16 @@
#include <EOControl/EODefines.h>
/**
* This define is experimental. Expect it to be replaced.
*/
#define GDL2_BUFFER(ID, SIZE, TYPE) \
unsigned ID##_size = (SIZE); \
TYPE ID##_obuf[(ID##_size) <= GS_MAX_OBJECTS_FROM_STACK ? (ID##_size) : 0]; \
TYPE *ID##_base = ((ID##_size) <= GS_MAX_OBJECTS_FROM_STACK) ? ID##_obuf \
: ( TYPE *)GSAutoreleasedBuffer((ID##_size) * sizeof( TYPE )); \
TYPE *ID = ID##_base;
@class NSLock;
@class NSRecursiveLock;

View file

@ -41,6 +41,7 @@ RCS_ID("$Id$")
#ifndef NeXT_Foundation_LIBRARY
#include <Foundation/NSDictionary.h>
#include <Foundation/NSSet.h>
#include <Foundation/NSScanner.h>
#include <Foundation/NSUtilities.h>
#include <Foundation/NSException.h>
#include <Foundation/NSValue.h>
@ -55,11 +56,11 @@ RCS_ID("$Id$")
#endif
#include <EOControl/EOQualifier.h>
#include <EOControl/EONSAddOns.h>
#include <EOControl/EODebug.h>
#include <GNUstepBase/GSObjCRuntime.h>
@implementation NSNumber (EOQualifierExtras)
- (id)initWithString: (NSString *)string
@ -682,7 +683,8 @@ static Class whichQualifier(const char **cFormat, const char **s)
+ (NSArray *)allQualifierOperators
{ // rivedere
return [NSArray arrayWithObjects:@"=", @"!=", @"<=", @"<", @">=", @">", @"doesContain", @"like", @"caseInsensitiveLike", nil];
return [NSArray arrayWithObjects: @"=", @"!=", @"<=", @"<", @">=", @">",
@"doesContain", @"like", @"caseInsensitiveLike", nil];
}
+ (NSArray *)relationalQualifierOperators
@ -955,25 +957,113 @@ static Class whichQualifier(const char **cFormat, const char **s)
@implementation NSString (EORelationalSelectors)
static NSCharacterSet *isLikeWildCardSet = nil;
static NSString *isLikeWildCardTokenQ = @"?";
static NSString *isLikeWildCardTokenS = @"*";
static inline BOOL
_isLike (NSString *self, NSString *regExpr, BOOL isCaseSensative)
{
NSScanner *regExScanner;
NSScanner *valueScanner;
NSString *scanned;
unsigned c = 0;
unsigned i = 0;
GDL2_BUFFER (tokens, [regExpr cStringLength], id);
if ([self isEqual: regExpr])
{
return YES;
}
if (isLikeWildCardSet == nil)
isLikeWildCardSet
= [[NSCharacterSet characterSetWithCharactersInString: @"?*"] retain];
regExScanner = [NSScanner scannerWithString: regExpr];
valueScanner = [NSScanner scannerWithString: self];
[valueScanner setCaseSensitive: isCaseSensative];
while ([regExScanner isAtEnd] == NO)
{
if ([regExScanner scanUpToCharactersFromSet: isLikeWildCardSet
intoString: &scanned])
{
tokens[c++] = scanned;
}
if ([regExScanner isAtEnd] == NO)
{
if ([regExScanner scanCharactersFromSet: isLikeWildCardSet
intoString: &scanned])
{
char *cScanned;
for (cScanned = [scanned cString]; *cScanned != 0; cScanned++)
{
if (*cScanned == '?'
&& tokens[c - 1] != isLikeWildCardTokenS)
{
tokens[c++] = isLikeWildCardTokenQ;
}
else if (*cScanned == '*'
&& tokens[c - 1] != isLikeWildCardTokenS)
{
tokens[c++] = isLikeWildCardTokenS;
}
}
}
}
}
for (i = 0; i < c; i++)
{
if (tokens[i] == isLikeWildCardTokenQ)
{
if ([valueScanner isAtEnd])
{
return NO;
}
[valueScanner setScanLocation: [valueScanner scanLocation] + 1];
}
else if (tokens[i] == isLikeWildCardTokenS)
{
if (i == c - 1)
{
return YES;
}
[valueScanner scanUpToString: tokens[i + 1]
intoString: 0];
}
else
{
if ([valueScanner isAtEnd])
{
return NO;
}
if ([valueScanner scanString: tokens[i] intoString: 0] == NO)
{
return NO;
}
}
}
return [valueScanner isAtEnd];
}
- (BOOL)isLike: (NSString *)object
{
NSEmitTODO(); //TODO
return [self isEqual: object] == NSOrderedSame;
return _isLike(self, object, YES);
}
- (BOOL)isCaseInsensitiveLike: (NSString *)object
{
NSEmitTODO(); //TODO
return [[self uppercaseString]
isEqual: [object uppercaseString]] == NSOrderedSame;
return _isLike(self, object, NO);
}
@end
@implementation NSArray (EOQualifierExtras)
#define MAX_STACK_OBJECTS 20
- (NSArray *)filteredArrayUsingQualifier: (EOQualifier *)qualifier
{
unsigned max = [self count];
@ -981,30 +1071,25 @@ static Class whichQualifier(const char **cFormat, const char **s)
if (max != 0)
{
unsigned i;
id obj[max>MAX_STACK_OBJECTS?0:max];
id *objPStart;
id *objP;
id anObject;
id object;
SEL oaiSEL = @selector(objectAtIndex:);
IMP oaiIMP = [self methodForSelector:oaiSEL];
SEL ewoSEL = @selector(evaluateWithObject:);
BOOL (*ewoIMP)(id, SEL, id);
GDL2_BUFFER(objP, max, id);
ewoIMP = (BOOL (*)(id, SEL, id))[qualifier methodForSelector:ewoSEL];
objPStart = objP = (max > MAX_STACK_OBJECTS)?
GSAutoreleasedBuffer(sizeof(id)*max):obj;
for(i=0; i < max; i++)
{
anObject = (*oaiIMP)(self, oaiSEL, i);
object = (*oaiIMP)(self, oaiSEL, i);
if((*ewoIMP)(qualifier, ewoSEL, anObject))
if((*ewoIMP)(qualifier, ewoSEL, object))
{
*objP++=anObject;
*objP++=object;
}
}
return [NSArray arrayWithObjects: objPStart count: objP - objPStart];
return [NSArray arrayWithObjects: objP_base count: objP - objP_base];
}
else
{
@ -1012,6 +1097,5 @@ static Class whichQualifier(const char **cFormat, const char **s)
}
}
#undef MAX_STACK_OBJECTS
@end