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.