This is MOStringParsing.m in view mode; [Download] [Up]
// MOStringParsing.m // // by Mike Ferris // Part of MOKit // Copyright 1993, all rights reserved. // ABOUT MOKit // by Mike Ferris (mike@lorax.com) // // MOKit is a collection of useful and general objects. Permission is // granted by the author to use MOKit in your own programs in any way // you see fit. All other rights pertaining to the kit are reserved by the // author including the right to sell these objects as objects, as part // of a LIBRARY, or as SOURCE CODE. In plain English, I wish to retain // rights to these objects as objects, but allow the use of the objects // as pieces in a fully functional program. Permission is also granted to // redistribute the source code of MOKit for FREE as long as this copyright // notice is left intact and unchanged. NO WARRANTY is expressed or implied. // The author will under no circumstances be held responsible for ANY // consequences from the use of these objects. Since you don't have to pay // for them, and full source is provided, I think this is perfectly fair. #import "MOKit/MOString.h" extern char *MOBuildStringFromFormatV(const char *formatStr, va_list param_list); @implementation MOString(Parsing) // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // =-=-=-=-=-=-=-=-=-=-=-=-=-= Parsing MOStrings =-=-=-=-=-=-=-=-=-=-=-=-=-= // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - (char)charAt:(int)index // Returns the character at index. Returns '\0' if str is NULL or index // is beyond the end of the str. { if ((index<0) || (isUnique?!uStr:!str) || (index>=len)) { return '\0'; } return (isUnique?uStr[index]:str[index]); } - substringFrom:(int)start to:(int)end // Returns a new String object containing the specified substring of the // receiver's contents. Returns nil if the indexes are bad or the receiving // String is empty. The new string is NOT unique regardless of whether the // receiver is or not. // // Note that the string object returned is always the receiving object's // class even if the receiving object is a subclass! { id newStr; char *buf; int i,j; if ((start<0) || (end<0) || (start>end) || (isUnique?!uStr:!str) || (end>len)) { return nil; } NX_MALLOC(buf, char, end-start+2); for (i=start, j=0; i<=end; i++, j++) { buf[j]=(isUnique?uStr[i]:str[i]); } buf[j]='\0'; newStr = [[[self class] allocFromZone:[self zone]] initStringValueNoCopy:buf shouldFree:YES]; return newStr; } - (int)positionOf:(char)aChar nthOccurrence:(int)n // Returns the index of the nth occurrence of aChar in the string. // If n is negative it counts backwards from the end of the string. // If there is no nth occurrence of aChar or the string is NULL this // returns -1. This won't work for aChar=='\0' unless n==1. { int numFound=0, i; BOOL fromBack = (n<0); if ((isUnique?!uStr:!str) || (n==0)) { return -1; } n = abs(n); for (i=(fromBack?len:0); (fromBack?i>=0:i<=len); (fromBack?i--:i++)) { if ((isUnique?uStr[i]:str[i])==aChar) { numFound++; if (numFound==n) { return i; } } } return -1; } - (int)countOccurrencesOf:(char)aChar { int i; int count = 0; for (i=0; i<len; i++) { if ((isUnique?uStr:str)[i] == aChar) { count++; } } return count; } - tokenize:(const char *)breakChars into:aList // Uses strtok() on a COPY of the strings contents to break the string // into tokens. Fills aList with MOString objects containing (in order) // the tokens from strtok. If aList is nil a list is allocated, but the // caller is still responsible for freeing it. This is a "safe" usage of // strtok() (although not "thread-safe"). strtok() relies on static // variables to keep track of where it is in between calls. This is "safe" // in that we parse the whole damn thing before returning, so no one // in this thread will start parsing another string with strtok() while // we're in the middle of ours. // // Note that the string object returned is always the receiving object's // class even if the receiving object is a subclass! { char *toker, *token; // Allocate the list if we need to. if (aList == nil) { aList = [[List allocFromZone:[self zone]] init]; } // Copy our contents into a scratch buffer. NX_MALLOC(toker, char, len+1); strcpy(toker, (isUnique?uStr:str)); // Start toking on it. token = strtok(toker, breakChars); while (token) { [aList addObject:[[[self class] allocFromZone:[self zone]] initStringValue:token]]; token = strtok(NULL, breakChars); } // As you allocate, so shall ye free. NX_FREE(toker); return aList; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.