This is MiscStringCompat.m in view mode; [Download] [Up]
// // MiscStringCompat.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(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 { // have to do all this garbage to make sure we (1) don't leak memory // and (2) we don't smash the stringValueAndFree buffer. (Otherwise // I would just use it, but that would make the MiscString badly // non-reentrant.) This works, anyway...though the obvious // implementation would be this: // // return [[self wordNum:fieldNumber] stringValueAndFree]; static id tempBuffer = nil; id temp; if (!tempBuffer) tempBuffer = [MiscString new]; temp = [self wordNum:fieldNumber]; [tempBuffer setStringValue:[temp stringValue]]; [temp free]; return (char *)[tempBuffer stringValue]; } // 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 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 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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.