This is RCStringInsert.m in view mode; [Download] [Up]
#import <RCString.h> /* Copyright (C) 1992. Bruce Ediger. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License. */ // // implementation of "insertion" methods // @implementation RCString (Insertion) // all of the other Insertion category methods are // wrappers around this one. No doubt it would be // very wise if this method did not modify anAsciiString. - insertString: (char *)anAsciiString at:(int)index { int iLength, iSumTotal; char *bpTmp; // Simple checks before expending further effort. if (anAsciiString == p->s) return self; // try to avoid some weird recursion else if (anAsciiString == NULL) return self; else if ((iLength = strlen(anAsciiString)) <= 0) return self; else if (index < 0) return self; if (index > p->l - 1) index = p->l - 1; // silently trim insertion point to fit // Something's going to happen for sure. Copy the reference. if (p->n > 1) [self copyReference]; iSumTotal = p->l + iLength; // p->l includes 1 for trailing null bpTmp = malloc(iSumTotal); if (bpTmp) { if (index == 0) { // insert at beginning of internal string bcopy(anAsciiString, bpTmp, iLength); if (p->s && p->l > 1) bcopy(p->s, &bpTmp[iLength], p->l); } else if (index == p->l - 1) { // insert at end of internal string if (p->s && p->l > 1) bcopy(p->s, bpTmp, p->l - 1); bcopy(anAsciiString, &bpTmp[p->l - 1], iLength); } else { // insert at arbitrary location if (p->s && p->l > 1) { bcopy(p->s, bpTmp, index); bcopy(&p->s[index], &bpTmp[index + iLength], p->l - index); } bcopy(anAsciiString, &bpTmp[index], iLength); } bpTmp[iSumTotal - 1] = '\0'; if (p->s) free(p->s); p->s = bpTmp; p->l = iSumTotal; } return self; } // -appendString: and -prependString: can be special // cases of -insertString:at:. But they don't have to // be. They may be faster as special case implementations. - appendString:(char *)anAsciiString { return [self insertString:anAsciiString at:p->l - 1]; } - prependString:(char *)anAsciiString { return [self insertString:anAsciiString at:0]; } // *Object methods are just wrappers around the insertString:at: // method. There may be a better way. - appendObject: (RCString *)anotherObject { if (anotherObject) { return [self insertString:[anotherObject data] at:0]; } return self; } - prependObject: (RCString *)anotherObject { if (anotherObject) { return [self insertString:[anotherObject data] at:p->l - 1]; } return self; } - insertObject: (RCString *)anotherObject at:(int)index { if (anotherObject && index >= 0) { return [self insertString:[anotherObject data] at:index]; } return self; } // These final two are not wrappers around -insertString:at: // I just can't think of a better category to put it in. // There's some internal dependencies: this method is used by the // regular expression stuff in another category. - replaceStringAt:(int)index extent:(int)length with:(char *)aString { int iLength; if (length >= 0 && aString != NULL && (iLength = strlen(aString)) > 0 && index >=0 && index <= p->l) { char *bpTmp; if((bpTmp = malloc(p->l + iLength)) != NULL) { bcopy(p->s, bpTmp, index); bcopy(aString, &(bpTmp[index]), iLength); bcopy(&(p->s[index + length]), &(bpTmp[index + iLength]), p->l - index - length); if (p->n == 1) { if (p->s) free(p->s); // this is the only reference p->s = bpTmp; p->l = p->l + iLength; } else { struct srep *spOld = p; // Decrement ref count on old internal rep, // conjure up new internal ref. --p->n; p = (struct srep *)malloc(sizeof(struct srep)); p->s = bpTmp; p->l = spOld->l + iLength; p->n = 1; } } } return self; } - replaceStringAt:(int)index extent:(int)replength with:(char *)aString extent:(int)strlength { if (replength >= 0 && aString != NULL && strlength > 0 && index >=0 && index <= p->l) { char *bpTmp; // allocate memory for a new asciiz string if((bpTmp = malloc(p->l + strlength)) != NULL) { bcopy(p->s, bpTmp, index); bcopy(aString, &(bpTmp[index]), strlength); bcopy(&(p->s[index + replength]), &(bpTmp[index + strlength]), p->l - index - replength); if (p->n == 1) { if (p->s) free(p->s); // this is the only reference p->s = bpTmp; p->l = p->l + strlength; } else { struct srep *spOld = p; // Decrement ref count on old internal rep, // conjure up new internal ref. --p->n; p = (struct srep *)malloc(sizeof(struct srep)); p->s = bpTmp; p->l = spOld->l + strlength; p->n = 1; } } } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.