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.