home *** CD-ROM | disk | FTP | other *** search
- //
- // MiscStringCompat.m
- // Written by Don Yacktman (c) 1993 by Don Yacktman.
- // Version 1.7 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(Compat)
-
- // This category includes methods to make the MiscString compatible
- // with other existing string classes. This way, you can easily
- // replace your crufty old string class with a MiscString without
- // having to change the code. Most methods are covers which simply
- // call the appropriate existing MiscString function. The majority
- // of these methods actually add compatability with the MOString class,
- // but there is other stuff in here, too...
-
- // None of the methods in this category add functionality; they are wrappers
- // around existing methods which allow programmers to use calls associated
- // with other string classes on the MiscString. When I add compatability
- // with string classes, if there is a function that adds functionality, I
- // write a compatible method and place it into another category. Only
- // redundant methods are in this category, which is why they are not
- // detailed in the documentation.
-
- // If you have some _other_ string class, and would like to see
- // compatibility methods added to the MiscString to support that
- // class, too, let us know!
-
- // Most of these methods are derived by Don Yacktman from code written
- // by Mike Ferris and David Lehn.
-
- - takeStringValue:sender { return [self takeStringValueFrom:sender]; }
-
- - clear
- {
- [self freeString];
- return self;
- }
-
- - ( const char* ) string
- {
- return [self stringValue];
- }
-
- - setString: ( const char *) aString
- {
- [self setStringValue:aString];
- return self;
- }
-
- - replaceChar: ( char ) aChar withChar: ( char ) replaceChar
- {
- return [self replaceEveryInstanceOfChar:aChar withChar:replaceChar];
- }
-
- - addToEndOfString: ( const char *) aString
- {
- [self cat:aString];
- return self;
- }
-
- - addToFrontOfString: ( const char *) aString
- {
- [self insert:aString at:0];
- return self;
- }
-
- - addCharToEndOfString: ( char ) aChar
- {
- [self addChar:aChar];
- return self;
- }
-
- - addCharToFrontOfString: ( char ) aChar
- {
- [self insertChar:aChar at:0];
- return self;
- }
-
- - ( int ) numberFields
- {
- return [self numWords];
- }
-
- - ( char * ) nthField: ( int ) fieldNumber useAsDelimiter: ( char ) c
- {
- char * field;
- id fieldString = [ self extractPart:(fieldNumber) useAsDelimiter:c ];
- if (!fieldString) return NULL;
- field = NXZoneMalloc( [ self zone ], [ fieldString length ] + 1 );
- strcpy(field, [ fieldString stringValue ]);
- [fieldString free];
- return field;
- }
-
- - ( char * ) nthField: ( int ) fieldNumber
- {
- return [ self nthField:fieldNumber useAsDelimiter:' ' ];
- }
-
- // this one kind of adds functionality, but by naming conventions it still
- // makes sense to put it here.
- - ( char * ) nthQuotedField: ( int ) fieldNumber
- {
- return [ self nthField:fieldNumber*2 useAsDelimiter:'"' ];
- }
-
- - ( char * ) lastField
- {
- char * field;
- id str = [ self extractPart:MISC_STRING_LAST useAsDelimiter:' ' ];
- field = NXZoneMalloc([self zone], [str length] + 1);
- strcpy(field, [str stringValue]);
- [str free];
- return field;
- }
-
- - ( char * ) firstField
- {
- char * field;
- id str = [ self extractPart:MISC_STRING_FIRST useAsDelimiter:' ' ];
- field = NXZoneMalloc([self zone], [str length] + 1);
- strcpy(field, [str stringValue]);
- [str free];
- return field;
- }
-
- - addStrings: ( const char *) fields, ...
- {
- va_list ptr;
-
- va_start( ptr, fields );
- [self catStrings:fields, ptr];
- va_end( ptr );
- return self;
- }
-
- - replaceEveryInstanceOfChar:(char)aChar withChar:(char)replaceChar
- {
- return [self replaceEveryOccurrenceOfChar:aChar
- withChar:replaceChar caseSensitive:YES];
- }
-
- - replaceEveryInstanceOfChar:(char)aChar with:(char)replaceChar
- {
- return [self replaceEveryOccurrenceOfChar:aChar
- withChar:replaceChar caseSensitive:YES];
- }
-
- // The rest of the methods here are for compatability with the MOString
- // from the MOKit.
-
- // warning: the following MOString methods clash with MiscString methods
- // of the same name. You will have to check your code for uses of these
- // methods and fix them appropriately to avoid serious problems.
- // Group 1: MOString wants string object, MiscString wants char *
- // -insert:stringObject at:(int)position
- // -cat:stringObject
- // Note also that the MiscString doesn't support the unique string
- // concept, so it cannot become a unique string. Perhaps in the
- // future there will be a MiscUniqueString class; I prefer that approach
- // myself. At any rate, this shouldn't affect the functionality when
- // using the MiscString compatibly.
-
- - convertToUpper
- {
- return [self toUpper];
- }
-
- - convertToLower
- {
- return [self toLower];
- }
-
- - (size_t)recalcLength
- {
- length = strlen(buffer);
- return length;
- }
-
- - (int)replaceAllOccurrencesOfChar:(char)oldChar with:(char)newChar
- {
- [self replaceEveryOccurrenceOfChar:oldChar withChar:newChar];
- return 0; // this information isn't available so we'll just return zero
- }
-
- - (char)replaceCharAt:(int)index with:(char)newChar
- {
- char tempChar = [self charAt:index];
- [self replaceCharAt:index withChar:newChar];
- return tempChar;
- }
-
- - insertStringValue:(const char *)s at:(int)position
- {
- [self insert:s at:position];
- return self;
- }
-
- - preCatStringValue:(const char *)s
- {
- return [self insert:s at:0];
- }
-
- - preCat:stringObject
- {
- return [self insertString:stringObject];
- }
-
- - preCatFromFormat:(const char *)format, ...
- // Prepends the given format string after formatting before the contents
- // of the receiver.
- {
- va_list param_list;
-
- va_start(param_list, format);
- [self insertFromFormat:format, param_list];
- va_end(param_list);
- return self;
- }
-
- - catStringValue:(const char *)s
- {
- return [self cat:s];
- }
-
- - (int)compare:stringObject
- {
- return [self compare:stringObject caseSensitive:YES
- length:-1 withTable:NULL];
- }
-
- - (int)compare:stringObject caseSensitive:(BOOL)flag
- {
- return [self compare:stringObject caseSensitive:flag
- length:-1 withTable:NULL];
- }
-
- - (int)compare:stringObject caseSensitive:(BOOL)flag length:(int)len
- {
- return [self compare:stringObject caseSensitive:flag
- length:len withTable:NULL];
- }
-
- - (int)compare:stringObject caseSensitive:(BOOL)flag length:(int)len
- withTable:(NXStringOrderTable *)table
- {
- int ret;
- NXStringOrderTable *realTable = [self stringOrderTable]; // temp save
- [self setStringOrderTable:table];
- ret = [self compareTo:stringObject n:len caseSensitive:flag];
- [self setStringOrderTable:realTable];
- return ret;
- }
-
- - (int)compareStr:(const char *)s
- {
- return [self compareStr:s caseSensitive:YES length:-1 withTable:NULL];
- }
-
- - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag
- {
- return [self compareStr:s caseSensitive:flag length:-1 withTable:NULL];
- }
-
- - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag length:(int)len
- {
- return [self compareStr:s caseSensitive:flag length:len withTable:NULL];
- }
-
- - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag length:(int)len
- withTable:(NXStringOrderTable *)table
- {
- id ss = [[self class] newWithString:s];
- int ret = [self compare:ss caseSensitive:flag length:len withTable:table];
- [ss free];
- return ret;
- }
-
- - (int)endCompare:stringObject
- {
- return [self endCompare:stringObject
- caseSensitive:YES length:-1 withTable:NULL];
- }
-
- - (int)endCompare:stringObject caseSensitive:(BOOL)flag
- {
- return [self endCompare:stringObject
- caseSensitive:flag length:-1 withTable:NULL];
- }
-
- - (int)endCompare:stringObject caseSensitive:(BOOL)flag length:(int)len
- {
- return [self endCompare:stringObject
- caseSensitive:flag length:len withTable:NULL];
- }
-
- - (int)endCompare:stringObject caseSensitive:(BOOL)flag length:(int)len
- withTable:(NXStringOrderTable *)table
- {
- int ret;
- NXStringOrderTable *realTable = [self stringOrderTable]; // temp save
- [self setStringOrderTable:table];
- ret = [self endCompareTo:stringObject n:len caseSensitive:flag];
- [self setStringOrderTable:realTable];
- return ret;
- }
-
- - (int)endCompareStr:(const char *)s
- {
- return [self endCompareStr:s caseSensitive:YES
- length:-1 withTable:NULL];
- }
-
- - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag
- {
- return [self endCompareStr:s caseSensitive:flag
- length:-1 withTable:NULL];
- }
-
- - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag
- length:(int)len
- {
- return [self endCompareStr:s caseSensitive:flag
- length:len withTable:NULL];
- }
-
- - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag
- length:(int)len withTable:(NXStringOrderTable *)table
- {
- id ss = [[self class] newWithString:s];
- int ret = [self endCompare:ss caseSensitive:flag
- length:len withTable:table];
- [ss free];
- return ret;
- }
-
- - substringFrom:(int)start to:(int)end
- {
- return [self midFrom:start to:end];
- }
-
- - (int)positionOf:(char)aChar nthOccurrence:(int)n
- {
- if (n<0) return [self rspotOf:aChar occurrenceNum:(-n) caseSensitive:YES];
- return [self spotOf:aChar occurrenceNum:n caseSensitive:YES];
- }
-
- - (int)countOccurrencesOf:(char)aChar
- {
- return [self numOfChar:aChar caseSensitive:YES];
- }
-
- - (size_t)strlen
- {
- return length;
- }
-
- - (const char *)strcpy:(const char *)s
- {
- [self setStringValue:s];
- return buffer;
- }
-
- - (const char *)strncpy:(const char *)s :(size_t)n
- {
- [self setStringValue:s n:(int)n fromZone:[self zone]];
- return buffer;
- }
-
- - (const char *)strcat:(const char *)s
- {
- [self cat:s];
- return buffer;
- }
-
- - (const char *)strncat:(const char *)s :(size_t)n
- {
- [self cat:s n:n fromZone:[self zone]];
- return buffer;
- }
-
- - (int)strcmp:(const char *)s
- {
- if ((!buffer) || (!s)) return -2;
- return strcmp(buffer, s);
- }
-
- - (int)strncmp:(const char *)s :(size_t)n
- {
- if ((!buffer) || (!s)) return -2;
- return strncmp(buffer, s, n);
- }
-
- - (const char *)strchr:(char)aChar
- {
- if (buffer) return NULL;
- return strchr(buffer, aChar);
- }
-
- - (const char *)strrchr:(char)aChar
- {
- if (!buffer) return NULL;
- return strrchr(buffer, aChar);
- }
-
- - (const char *)strpbrk:(const char *)breakChars
- {
- if ((!buffer) || (!breakChars)) return NULL;
- return strpbrk(buffer, breakChars);
- }
-
- - (size_t)strspn:(const char *)acceptableChars
- {
- if ((!buffer) || (!acceptableChars)) return -1;
- return strspn(buffer, acceptableChars);
- }
-
- - (size_t)strcspn:(const char *)breakChars
- {
- if ((!buffer) || (!breakChars)) return 0;
- return strcspn(buffer, breakChars);
- }
-
- - initStringValue:(const char *)s
- {
- return [self initString:s];
- }
-
- - initStringValueNoCopy:(char *)s
- { // we still copy it anyway; this could be implemented for effect a speedup
- // if it makes that much difference...
- return [self initString:s];
- }
-
- - initStringValueNoCopy:(char *)s shouldFree:(BOOL)flag
- {
- id ret = [self initString:s];
- if (flag) NX_FREE(s);
- return ret;
- }
-
- - initStringValueUnique:(const char *)s
- {
- return [self initString:s];
- }
-
- - deepCopy
- {
- return [self deepCopyFromZone:[self zone]];
- }
-
- - deepCopyFromZone:(NXZone *)zone
- { // our copy from zone IS deep already...
- return [self copyFromZone:zone];
- }
-
- - shallowCopy
- {
- return [self shallowCopyFromZone:[self zone]];
- }
-
- - shallowCopyFromZone:(NXZone *)zone
- { // our copy from zone IS deep already...
- return [self copyFromZone:zone];
- }
-
- - setStringValueNoCopy:(const char *)s
- { // we set the string value by copying anyway.
- return [self setStringValue:s];
- }
-
- - setStringValueNoCopy:(char *)s shouldFree:(BOOL)flag
- {
- id ret = [self setStringValue:s];
- if (flag) NX_FREE(s);
- return ret;
- }
-
- - setStringValueUnique:(const char *)s { return [self setStringValue:s]; }
- - setNull { return [self freeString]; }
- - makeUnique { return self; } // we don't support this at all.
- - setShouldFree:(BOOL)flag { return self; }
- - (unsigned int)count { return length; }
- - (BOOL)isNull { return [self emptyString]; }
- - (BOOL)isEmpty { return [self emptyString]; }
- - (BOOL)isUnique { return NO; }
- - (BOOL)shouldFree { return YES; }
-
-
-
-
- // MOPathString methods
- - (int)numberOfComponents { return [self numberOfPathComponents]; }
- - componentAt:(int)index { return [self pathComponentAt:index]; }
- - file { return [self fileName]; }
- - directory { return [self pathName]; }
- - (const char *)path { return [self stringValue]; }
- - (BOOL)isRelative { return [self isRelativePath]; }
- - (BOOL)isAbsolute { return [self isAbsolutePath]; }
- - (BOOL)isDirectory { return [self isFileOfType:Misc_Directory]; }
- - (BOOL)isPlainFile { return [self isFileOfType:Misc_PlainFile]; }
- - (BOOL)isSymbolicLink { return [self isFileOfType:Misc_SymbolicLink]; }
- - (BOOL)isCharacterSpecial { return [self isFileOfType:Misc_CharacterSpecial]; }
- - (BOOL)isBlockSpecial { return [self isFileOfType:Misc_BlockSpecial]; }
- - (BOOL)isSocket { return [self isFileOfType:Misc_Socket]; }
- - setPathSeparator:(char)c { return self; } // NO OP
- - setExtensionSeparator:(char)c { return self; } // NO OP
- - (char)pathSeparator { return '/'; }
- - (char)extensionSeparator { return '.'; }
- - setPath:(const char *)path { return [self setStringValue:path]; }
- - initPath:(const char *)path { return [self initStringValue:path]; }
- - (char *)buffer { return buffer; } // be careful with this! don't muck it up!
-
- @end
-