This is MiscStringInsertion.m in view mode; [Download] [Up]
//
// MiscStringInsertion.m
// Written by Don Yacktman Copyright (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(Insertion)
// This category is composed of methods which insert characters or
// strings into a MiscString.
- cat:(const char *)aString
{
if (!aString) return nil; // so strlen() stays sane. Thanks Steve Hayman!
return [self cat:aString n:strlen(aString) fromZone:[self zone]];
}
- cat:(const char *)aString n:(int)n
{
return [self cat:aString n:n fromZone:[self zone]];
}
- cat:(const char *)aString fromZone:(NXZone *)zone
{
if (!aString) return nil; // so strlen() stays sane. Thanks Steve Hayman!
return [self cat:aString n:strlen(aString) fromZone:zone];
}
- cat:(const char *)aString n:(int)n fromZone:(NXZone *)zone
{
char *newBuffer; int newSize;
if (!(aString || buffer)) return nil;
if (!buffer) { // Not very efficient, but safer.
char *tempBuffer = (char *)NXZoneMalloc(zone, n+1);
if (!tempBuffer) return nil;
strncpy(tempBuffer, aString, n);
tempBuffer[n] = '\0';
[self setStringValue:tempBuffer fromZone:zone];
free(tempBuffer);
return self;
}
if (!aString) return self;
if (n > strlen(aString)) n = strlen(aString);
newSize = length + n + 1;
if (newSize > _length) {
newBuffer = (char *)NXZoneMalloc(zone, newSize);
_length = newSize;
newBuffer[0] = '\0';
strcat(newBuffer, buffer);
strncat(newBuffer, aString, n);
free(buffer);
buffer = newBuffer;
} else strncat(buffer, aString, n);
length = strlen(buffer);
return self;
}
- concatenate:sender
{ // note return self here; assume that there's nothing to add...
if (![sender respondsTo:@selector(stringValue)]) return self;
return [self cat:[sender stringValue]
n:strlen([sender stringValue])
fromZone:[self zone]];
}
- concatenate:sender n:(int)n
{
if (![sender respondsTo:@selector(stringValue)]) return self;
return [self cat:[sender stringValue] n:n fromZone:[self zone]];
}
- concatenate:sender fromZone:(NXZone *)zone
{
if (![sender respondsTo:@selector(stringValue)]) return self;
return [self cat:[sender stringValue]
n:strlen([sender stringValue]) fromZone:zone];
}
- concatenate:sender n:(int)n fromZone:(NXZone *)zone
{
if (![sender respondsTo:@selector(stringValue)]) return self;
return [self cat:[sender stringValue] n:n fromZone:zone];
}
- insert:(const char *)aString at:(int)index
// inserts given string into buffer starting at index.
// (the first character is position #0)
{
id temp1;
id temp2;
if ((aString == NULL) || (strlen(aString)<=0)) return self;
if (index < 0) index = 0;
if (index >= length) return [self cat:aString];
temp1 = [self left:index];
if (!temp1) temp1 = [[[self class] alloc] init];
temp2 = [self right:length-index];
[[temp1 cat:aString] concatenate:temp2];
[self setStringValue:[temp1 stringValue]];
[temp1 free];
[temp2 free];
return self;
}
- insertString:(id)sender at:(int)index
// cover for insert:at: for a String object
{
if (![sender respondsTo:@selector(stringValue)]) return self;
return [self insert:[sender stringValue] at:index];
}
- insertChar:(char)aChar at:(int)index
{
id tempStr;
id retval;
if (aChar == 0) return self; // or should this return nil? DAY: leave it
tempStr = [[[[[self class] alloc] init] allocateBuffer:2] addChar:aChar];
retval = [self insert:[tempStr stringValue] at:index];
[tempStr free];
return retval;
}
- insertChar:(char)aChar // does an insert at the front (for chars)
{ // added for convenience; as you see it is redundant.
return [self insertChar:aChar at:0];
}
// catStrings: - a convenience function to append a list of strings
// to a string object.
// use like this:
// [aString addStrings:string0, string1, string2, string3, string4, NULL];
// make sure to have the ending NULL!
//
// Note from Don: I've decided to use a version sent in by David Moffett
// since it is a bit more concise.
- catStrings: ( const char *) strings, ...;
{
const char *aString;
va_list ptr;
va_start( ptr, strings );
aString = strings;
while (aString) {
[self cat:aString n:strlen(aString) fromZone:[self zone]];
aString = va_arg(ptr, char *);
}
va_end( ptr );
return self;
}
// and here's one modified to handle MiscStrings -- don
- concatenateStrings:(id)strings, ...
{
id aString;
va_list ptr;
va_start(ptr, strings);
aString = strings;
while (aString) {
if ([aString respondsTo:@selector(stringValue)]) {
const char *sptr = [aString stringValue];
[self cat:sptr
n:([aString respondsTo:@selector(length)] ?
[aString length] : strlen(sptr))
fromZone:[self zone]];
}
aString = va_arg(ptr, id);
}
va_end( ptr );
return self;
}
- insert:(const char *)aString // does an insert at the front (for char *'s)
{ // added for convenience; as you see it is redundant.
return [self insert:aString at:0];
}
- insertString:aString // does an insert at the front (for objects)
{ // added for convenience; as you see it is redundant.
return [self insertString:aString at:0];
}
- addChar:(char)aChar
{
if (aChar) [self cat:&aChar n:1];
return self;
}
// The following methods are from the MOString by Mike Ferris:
- insertFromFormat:(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 insertAt:0 fromFormat:format, param_list];
va_end(param_list);
return self;
}
- insertAt:(int)index fromFormat:(const char *)format, ...
{
char *buf;
va_list param_list;
va_start(param_list, format);
buf = MiscBuildStringFromFormatV(format, param_list);
[self insert:buf at:index];
NX_FREE(buf);
va_end(param_list);
return self;
}
- catFromFormat:(const char *)format, ...
// Appends to the string from the printf style format string and arguments.
{
char *buf;
va_list param_list;
va_start(param_list, format);
buf = MiscBuildStringFromFormatV(format, param_list);
[self cat:buf];
NX_FREE(buf);
va_end(param_list);
return self;
}
// Here's an alternative way to catFromFormat, courtesy of Steve Hayman.
// For now, we're keeping everything in the MiscBuildStringFromFormatV
// function for simplicity.
/* This method is currently commented out and not compiled.
- printf:(const char *)fmt, ...
{
NXStream *mem;
char *streambuf;
int len, maxlen;
va_list ap;
va_start(ap, fmt);
// open a memory stream ...
mem = NXOpenMemory( NULL, 0, NX_WRITEONLY );
// printf everything to the memory stream ...
NXVPrintf( mem, fmt, ap );
// and make sure it's null terminated
NXPutc( mem, '\0' );
// and get pointers to the buffer where the stream is ...
NXGetMemoryBuffer( mem, &streambuf, &len, &maxlen );
// and append the text to ourself
[self cat:streambuf];
// and free the memory stream.
NXCloseMemory(mem, NX_FREEBUFFER);
va_end(ap);
return self;
}
*/
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.