home *** CD-ROM | disk | FTP | other *** search
- #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
-