This is MiscStringComparing.m in view mode; [Download] [Up]
//
// MiscStringComparing.m
// Written by Don Yacktman (c) 1993 by Don Yacktman.
// Version 1.95 All rights reserved.
// This notice may not be removed from this source code.
//
// This object is included in the MiscKit by permission from the author
// and its use is governed by the MiscKit license, found in the file
// "LICENSE.rtf" in the MiscKit distribution. Please refer to that file
// for a list of all applicable permissions and restrictions.
//
#import <misckit/MiscString.h>
@implementation MiscString(Comparing)
// This category is composed of methods which compare
// MiscStrings with other strings.
- (BOOL)isEqual:anObject
{
if (anObject == self) return YES;
// doesn't have to be a MiscString object to be equal...
if ([anObject respondsTo:@selector(stringValue)]) {
if (!NXOrderStrings((unsigned char *)buffer,
(unsigned char *)[anObject stringValue],
YES, -1, orderTable)) return YES;
}
return NO;
}
- (unsigned int)hash
// Use the NextStep string hashing functiuon NXStrHash() instead of
// the pointer hashing function.
{
return NXStrHash(NULL, buffer);
}
- (int)compareTo:sender
{
return [self compareTo:sender n:(-1) caseSensitive:YES];
}
- (int)compareTo:sender n:(int)n
{
return [self compareTo:sender n:n caseSensitive:YES];
}
- (int)cmp:(const char *)aString
{
if (!aString && !buffer) return 0; // both NULL, so "equal"
if (!aString) return 1; // only one is NULL, so not equal
if (!buffer) return -1; // only one is NULL, so not equal
return strcmp(buffer, aString);
}
- (int)cmp:(const char *)aString n:(int)n
{
if (!aString && !buffer) return 0; // both NULL, so "equal"
if (!aString) return 1; // only one is NULL, so not equal
if (!buffer) return -1; // only one is NULL, so not equal
// we don't check n; use strncmp's behavior here.
return strncmp(buffer, aString, n);
}
- (int)compareTo:sender caseSensitive:(BOOL)sense
{
return [self compareTo:sender n:(-1) caseSensitive:sense];
}
- (int)compareTo:sender n:(int)n caseSensitive:(BOOL)sense
{
const char *s; int ret, senderLength, size = n;
if (!sender) {
if (!buffer) return 0;
return 1;
}
if (![sender respondsTo:@selector(stringValue)]) return 1; // !=
s = [sender stringValue];
if (!buffer && !s) return 0; // both are NULL
if (!buffer) return -1; // buffer is NULL
if (!s) return 1; // sender is NULL
if ([sender respondsTo:@selector(length)]) senderLength = [sender length];
else senderLength = strlen(s);
if ((size > length) || (size > senderLength)) {
size = MIN(length, senderLength);
if (!size) if (senderLength) return -1;
else if (length) return 1;
else return 0;
}
ret = NXOrderStrings((unsigned char *)buffer,
(unsigned char *)s, sense, size, orderTable);
if (((size > length) || (size > senderLength)) && (!ret)) {
if (length < senderLength) return -1;
if (length > senderLength) return 1;
}
return ret;
}
- (int)casecmp:(const char *)aString
{
if (!aString && !buffer) return 0; // both NULL, so "equal"
if (!aString || !buffer) return -1; // only one is NULL, so not equal
return strcasecmp(buffer, aString);
}
- (int)casecmp:(const char *)aString n:(int)n
{
if (!aString && !buffer) return 0; // both NULL, so "equal"
if (!aString || !buffer) return -1; // only one is NULL, so not equal
// we don't check n; use strncasecmp's behavior here.
return strncasecmp(buffer, aString, n);
}
- (int)endcmp:(const char *)aString
{
return [self endcmp:aString n:-1];
}
- (int)endcmp:(const char *)aString n:(int)n
{
id tempStr;
int retval;
if (!aString) return -1;
tempStr = [[self class] newWithString:aString];
retval = [self endCompareTo:tempStr n:n caseSensitive:YES];
[tempStr free];
return retval;
}
- (int)endcasecmp:(const char *)aString
{
return [self endcasecmp:aString n:-1];
}
- (int)endcasecmp:(const char *)aString n:(int)n
{
id tempStr;
int retval;
if (!aString) return -1;
tempStr = [[self class] newWithString:aString];
retval = [self endCompareTo:tempStr n:n caseSensitive:NO];
[tempStr free];
return retval;
}
- (int)endCompareTo:(id)sender
{
return [self endCompareTo:sender n:-1 caseSensitive:YES];
}
- (int)endCompareTo:(id)sender caseSensitive:(BOOL)sense
{
return [self endCompareTo:sender n:-1 caseSensitive:sense];
}
- (int)endCompareTo:(id)sender n:(int)n
{
return [self endCompareTo:sender n:n caseSensitive:YES];
}
- (int)endCompareTo:(id)sender n:(int)n caseSensitive:(BOOL)sense
{ // DAY: fixed it: sender doesn't have to be a MiscString anymore.
id tempStr, temp2, temp3;
int retval, smallLen, senderLength;
const char *s;
// unlike MOKit, we allow NULL/empty strings, and we adjust n if
// it is too big. also, this method is slower than MOKit complement.
if (!sender) {
if (!buffer) return 0;
return 1;
}
if (!([sender respondsTo:@selector(stringValue)])) return -1;
s = [sender stringValue];
if (!s || !buffer) return -1;
if ([sender respondsTo:@selector(length)]) senderLength = [sender length];
else senderLength = strlen(s);
// find the shorter of the two lengths
smallLen = ((length >= senderLength) ? senderLength : length);
if ((n == -1) || (n > smallLen)) n = smallLen;
tempStr = [self right:n];
if ([sender respondsTo:@selector(right:)]) temp2 = [sender right:n];
else {
temp3 = [[self class] newWithString:[sender stringValue]];
temp2 = [temp3 right:n];
[temp3 free];
}
retval = [tempStr compareTo:temp2 caseSensitive:sense];
[tempStr free];
[temp2 free];
return retval;
}
//--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
// Additions for the MiscCompare, MiscEndCompare protocols:
//--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
// We should eventually decide upon a single protocol rather than having
// both the above and these methods. This is an API bug in a big way.
- (int)compare:anObject length:(unsigned long)len ignoreCase:(BOOL)flag
{
return [self compareTo:anObject n:len
caseSensitive:(flag ? NO : YES)];
}
- (int)compareLiteral:(const char *)literal length:(unsigned long)len ignoreCase:(BOOL)flag
{
MiscString *aString = [[self class] newWithString:literal];
int ret = [self compareTo:aString n:len
caseSensitive:(flag ? NO : YES)];
[aString free];
return ret;
}
- (int)endCompare:anObject length:(unsigned long)len ignoreCase:(BOOL)flag
{
return [self endCompareTo:anObject n:len
caseSensitive:(flag ? NO : YES)];
}
- (int)endCompareLiteral:(const char *)literal length:(unsigned long)len ignoreCase:(BOOL)flag
{
MiscString *aString = [[self class] newWithString:literal];
int ret = [self endCompareTo:aString n:len
caseSensitive:(flag ? NO : YES)];
[aString free];
return ret;
}
//--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
// convenience methods of protocol that call the above four methods:
//--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
- (int)compare:anObject
{
return [self compare:anObject length:[self length] ignoreCase:NO];
}
- (int)compare:anObject ignoreCase:(BOOL)flag
{
return [self compare:anObject length:[self length] ignoreCase:flag];
}
- (int)compare:anObject length:(unsigned long)len
{
return [self compare:anObject length:len ignoreCase:NO];
}
- (int)compareLiteral:(const char *)literal
{
return [self compareLiteral:literal length:[self length] ignoreCase:NO];
}
- (int)compareLiteral:(const char *)literal ignoreCase:(BOOL)flag
{
return [self compareLiteral:literal length:[self length] ignoreCase:flag];
}
- (int)compareLiteral:(const char *)literal length:(unsigned long)len
{
return [self compareLiteral:literal length:len ignoreCase:NO];
}
- (int)endCompare:anObject
{
return [self endCompare:anObject length:[self length] ignoreCase:NO];
}
- (int)endCompare:anObject ignoreCase:(BOOL)flag
{
return [self endCompare:anObject length:[self length] ignoreCase:flag];
}
- (int)endCompare:anObject length:(unsigned long)len
{
return [self endCompare:anObject length:len ignoreCase:NO];
}
- (int)endCompareLiteral:(const char *)literal
{
return [self endCompareLiteral:literal length:[self length] ignoreCase:NO];
}
- (int)endCompareLiteral:(const char *)literal ignoreCase:(BOOL)flag
{
return [self endCompareLiteral:literal length:[self length]
ignoreCase:flag];
}
- (int)endCompareLiteral:(const char *)literal length:(unsigned long)len
{
return [self endCompareLiteral:literal length:len ignoreCase:NO];
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.