home *** CD-ROM | disk | FTP | other *** search
- //
- // MiscStringInsertion.m
- // Written by Don Yacktman (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) return [self setStringValue:aString fromZone:zone];
- 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
-