home *** CD-ROM | disk | FTP | other *** search
- //
- // 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;
- }
-
- @end
-