This is String.m in view mode; [Download] [Up]
//
// String.m -- a generic class to simplify manipulation of (char *)'s
// Written by Don Yacktman (c) 1993 by Don Yacktman.
// All rights reserved.
//
// You may use and copy this class freely as long as you
// comply with the following terms:
// (1) If you use this class in an application which you
// intend to sell commercially, as shareware, or otherwise,
// you may only do so with express written permission
// of the author. Use in applications which will
// be distributed free of charge is encouraged.
// (2) You must include the source code to this object and
// all accompanying documentation with your application,
// or provide it to users if requested, free of charge.
// (3) Do not remove the author's name or any of the
// copyright notices
//
#import "String.h"
#import <strings.h>
#import <appkit/appkit.h>
@implementation String
- init
{
[super init];
[self setStringOrderTable:NXDefaultStringOrderTable()];
buffer = NULL;
length = 0;
_length = 0;
return self;
}
- setStringOrderTable:(NXStringOrderTable *)table
{
orderTable = table;
return self;
}
- (NXStringOrderTable *)stringOrderTable
{
return orderTable;
}
- allocateBuffer:(int)size
{
return [self allocateBuffer:size fromZone:[self zone]];
}
- allocateBuffer:(int)size fromZone:(NXZone *)zone
{
if(size <= _length) return self;
[self freeString];
buffer = (char *)NXZoneMalloc(zone, size);
buffer[0] = 0;
_length = size;
return self;
}
- setString:(const char *)aString
{
return [self setString:aString fromZone:[self zone]];
}
- setString:(const char *)aString fromZone:(NXZone *)zone
{
if(!aString) return self;
[self allocateBuffer:strlen(aString)+1 fromZone:zone];
strcpy(buffer, aString);
length = strlen(buffer);
return self;
}
- setStringValue:sender
{
if (![sender respondsTo:@selector(stringValue)]) return self;
return [self setString:[sender stringValue] fromZone:[self zone]];
}
- setStringValue:sender fromZone:(NXZone *)zone
{
if (![sender respondsTo:@selector(stringValue)]) return self;
return [self setString:[sender stringValue] fromZone:zone];
}
- (const char *)stringValue
{
return buffer;
}
- read:(NXTypedStream *)stream
{
char *tmpStr;
[super read:stream];
NXReadType(stream, "i", &_length);
[self allocateBuffer:_length fromZone:[self zone]];
NXReadType(stream, "*", &tmpStr);
[self setString:tmpStr fromZone:[self zone]];
free(tmpStr);
return self;
}
- write:(NXTypedStream *)stream
{
[super write:stream];
NXWriteTypes(stream, "i*", &_length, &buffer);
return self;
}
- copyFromZone:(NXZone *)zone
{
String *myCopy = [super copyFromZone:zone];
// force child to have it's own copy of the string
[myCopy _unhookBuffer];
[myCopy allocateBuffer:_length fromZone:zone];
[myCopy setString:buffer fromZone:zone];
return myCopy;
}
- _unhookBuffer
{ // used by the copy method so that we don't free the buffer from orig.
buffer = NULL; _length = 0;
return self;
}
- freeString
{
if(buffer) free(buffer);
buffer = NULL;
length = 0;
_length = 0;
return self;
}
- free
{
[self freeString];
return [super free];
}
- cat:(const char *)aString
{
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
{
return [self cat:aString n:strlen(aString) fromZone:zone];
}
- cat:(const char *)aString n:(int)n fromZone:(NXZone *)zone
{
char *newBuffer; int newSize;
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
{
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];
}
- (const char *)rindex:(char)aChar
{
return rindex(buffer, aChar);
}
- (const char *)index:(char)aChar
{
return index(buffer, aChar);
}
- (int)length
{
return length;
}
- (BOOL)isEqual:anObject
{
if (anObject == self) return YES;
// doesn't have to be a String object to be equal...
if ([anObject respondsTo:@selector(stringValue)]) {
if (!NXOrderStrings(buffer, [anObject stringValue],
YES, -1, orderTable)) return YES;
}
return NO;
}
- (int)compareTo:sender
{
return [self compareTo:sender n:(-1) caseSensitive:YES];
}
- (int)compareTo:sender n:(int)n
{
return [self compareTo:sender n:n caseSensitive:YES];
}
- (int)cmp:(const char *)aString
{
return strcmp(buffer, aString);
}
- (int)cmp:(const char *)aString n:(int)n
{
return strncmp(buffer, aString, n);
}
- (int)compareTo:sender caseSensitive:(BOOL)sense
{
return [self compareTo:sender n:(-1) caseSensitive:sense];
}
- (int)compareTo:sender n:(int)n caseSensitive:(BOOL)sense
{
if (![sender respondsTo:@selector(stringValue)]) return 1; // !=
return NXOrderStrings(buffer, [sender stringValue], sense, n, orderTable);
}
- (int)casecmp:(const char *)aString
{
return strcasecmp(buffer, aString);
}
- (int)casecmp:(const char *)aString n:(int)n
{
return strncasecmp(buffer, aString, n);
}
- left:(int)count
{
return [self left:count fromZone:[self zone]];
}
- right:(int)count
{
return [self right:count fromZone:[self zone]];
}
- midFrom:(int)start to:(int)end
{
return [self midFrom:start to:end fromZone:[self zone]];
}
- midFrom:(int)start length:(int)len
{
return [self midFrom:start length:len fromZone:[self zone]];
}
- left:(int)count fromZone:(NXZone *)zone
{
char smash = buffer[count];
id newString = [[String allocFromZone:zone] init];
buffer[count] = '\0';
[newString setString:buffer fromZone:zone];
buffer[count] = smash;
return newString;
}
- right:(int)count fromZone:(NXZone *)zone
{
id newString = [[String allocFromZone:zone] init];
[newString setString:&buffer[length - count] fromZone:zone];
return newString;
}
- midFrom:(int)start to:(int)end fromZone:(NXZone *)zone
{
char smash = buffer[end];
id newString = [[String allocFromZone:zone] init];
buffer[end] = '\0'; // inclusive; end-1 is not.
[newString setString:&buffer[start - 1] fromZone:zone];
buffer[end] = smash;
return newString;
}
- midFrom:(int)start length:(int)len fromZone:(NXZone *)zone
{
register int spot = start + len - 1;
char smash = buffer[spot];
id newString = [[String allocFromZone:zone] init];
buffer[spot] = '\0';
[newString setString:&buffer[start - 1] fromZone:zone];
buffer[spot] = smash;
return newString;
}
//
// add ons
//
+ str:(const char *)strValue
{
if (strValue) {
self = [super new];
return self;
} else {
return [self new];
}
}
+ sprintf:(const char*)format,...
{
va_list ap;
char aBuffer[BUFSIZ];
va_start(ap,format);
vsprintf(aBuffer,format,ap);
va_end(ap);
return [self str:aBuffer];
}
- (double) asDouble
{
return atof([self str]);
}
- (int) asInt
{
return atoi([self str]);
}
- (long) asLong
{
return atol([self str]);
}
- (const char *)str
{
return [self stringValue];
}
- printToFile:(FILE *)aFile
{
fputs([self str],aFile);return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.