This is MiscStringModification.m in view mode; [Download] [Up]
//
// MiscStringModification.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(Modification)
// This category is composed of methods which modify a MiscString in
// various ways (case conversion, trimming whitespace, deleting portions
// of the string, and so on).
- setStringValue:(const char *)aString
{
return [self setStringValue:aString fromZone:[self zone]];
}
- setStringValue:(const char *)aString fromZone:(NXZone *)zone
{
if (!aString) return self; // use -freeString to set to "NULL"
// Note that I could have used NXCopyStringBufferFromZone() here
// instead. This works just as well, but it may be slower...
// I haven't checked that out, though. It might be worth doing.
[self allocateBuffer:(strlen(aString)+1) fromZone:zone];
strcpy(buffer, aString);
length = strlen(buffer);
return self;
}
- setStringValue:(const char *)aString n:(int)n
{
return [self setStringValue:aString n:n fromZone:[self zone]];
}
- setStringValue:(const char *)aString n:(int)n fromZone:(NXZone *)zone
{
char *buf = NULL;
if ((aString) && (n > 0)) {
NX_MALLOC(buf, char, n + 1);
strncpy(buf, aString, n);
buf[n]='\0';
}
[self setStringValue:buf fromZone:zone];
NX_FREE(buf);
return self;
}
- setFromFormat:(const char *)formatStr, ...
// Sets the string from and printf style format string and arguments.
{
va_list param_list;
char *buf;
va_start(param_list, formatStr);
buf = MiscBuildStringFromFormatV(formatStr, param_list);
va_end(param_list);
[self setStringValue:buf];
NX_FREE(buf);
return self;
}
- setIntValue:(int)val
// Sets the string by converting the given int to a string.
{
return [self setFromFormat:"%d", val];
}
- setFloatValue:(float)val
// Sets the string by converting the given float to a string.
{
return [self setFromFormat:"%f", val];
}
- setDoubleValue:(double)val
// Sets the string by converting the given double to a string.
{
return [self setFromFormat:"%f", val];
}
- sprintf:(const char *)formatStr, ...
// Sets the strings contents as the result of printf'ing with the
// given format string and arguments. Same as setFromFormat:, ...
{
va_list param_list;
char *buf;
va_start(param_list, formatStr);
buf = MiscBuildStringFromFormatV(formatStr, param_list);
va_end(param_list);
[self setStringValue:buf];
NX_FREE(buf);
return self;
}
- takeStringValueFrom:sender
{ // if no string value, return nil; the user is expecting a changed string
if (!sender) return [self freeString]; // this seems reasonable...
// but maybe I should just return nil instead...
if (![sender respondsTo:@selector(stringValue)]) return nil;
return [self setStringValue:[sender stringValue] fromZone:[self zone]];
}
- takeStringValueFrom:sender fromZone:(NXZone *)zone
{
if (![sender respondsTo:@selector(stringValue)]) return nil;
return [self setStringValue:[sender stringValue] fromZone:zone];
}
- takeIntValueFrom:sender
{
if (![sender respondsTo:@selector(intValue)]) return nil;
[self setIntValue:[sender intValue]];
return self;
}
- takeFloatValueFrom:sender
{
if (![sender respondsTo:@selector(floatValue)]) return nil;
[self setFloatValue:[sender floatValue]];
return self;
}
- takeDoubleValueFrom:sender
{
if (![sender respondsTo:@selector(doubleValue)]) return nil;
[self setDoubleValue:[sender doubleValue]];
return self;
}
- trimLeadSpaces
{ // removes any leading spaces from buffer
int i = 0;
id tmpStr;
if (!buffer) return self;
if (length < 1) return self;
while (buffer[i] == ' ') i++;
if (i==0) return self;
tmpStr = [self right:length-i];
[self takeStringValueFrom:tmpStr];
[tmpStr free];
return self;
}
- trimTailSpaces
// removes any trailing spaces from buffer
{
int i = length;
id tmpStr;
if (!buffer) return self;
if (i < 1) return self;
while (buffer[i-1] == ' ') i--;
if (i==length) return self;
tmpStr = [self left:i];
[self takeStringValueFrom:tmpStr];
[tmpStr free];
return self;
}
- trimSpaces
// takes off leading and trailing spaces of the buffer
{
return [[self trimLeadSpaces] trimTailSpaces];
}
- trimLeadWhiteSpaces
// removes any leading white space from buffer
{
int i = 0;
id tmpStr;
if (!buffer) return self;
if (length < 1) return self;
while (NXIsSpace(buffer[i])) i++;
if (i==0) return self;
tmpStr = [self right:length-i];
[self takeStringValueFrom:tmpStr];
[tmpStr free];
return self;
}
- trimTailWhiteSpaces
// removes any leading white space from buffer
{
int i = length;
id tmpStr;
if (!buffer) return self;
if (i < 1) return self;
while (NXIsSpace(buffer[i-1])) i--;
if (i==length) return self;
tmpStr = [self left:i];
[self takeStringValueFrom:tmpStr];
[tmpStr free];
return self;
}
- trimWhiteSpaces
// takes off leading and trailing spaces of the buffer
{
return [[self trimLeadWhiteSpaces] trimTailWhiteSpaces];
}
- squashSpaces
{
int count = 0;
id tempStr;
if (!buffer) return self;
[self trimSpaces];
tempStr = [[[[self class] alloc] init] allocateBuffer:length];
while (count<length) {
while ((count<length) && (buffer[count]!=' ')) {
[tempStr addChar:buffer[count]];
count++;
}
if ((count<length) && (buffer[count] == ' ')) {
[tempStr addChar:buffer[count]];
count++;
}
if ((count<length) && (buffer[count]==' ') &&
((buffer[count-2] == ':') || (buffer[count-2] =='.'))) {
[tempStr addChar:buffer[count]];
count++;
}
while (buffer[count]==' ') count++;
}
[self takeStringValueFrom:tempStr];
[tempStr free];
return self;
}
- reverse
// reverses the characters in the buffer. If it's a palindrome, you won't
// notice much of a difference :-)
{
char tmp[length+1];
int i, j=0;
if (length <= 1) return self;
for (i=length-1; i>=0; i--) {
tmp[j] = buffer[i];
j++;
}
tmp[length] = 0;
if (length != 0) [self setStringValue:tmp];
return self;
}
- toUpper
// converts any lowercase characters in buffer to uppercase
{
int i;
for (i=0; i<length; i++) {
if (NXIsLower(buffer[i])) buffer[i] = NXToUpper(buffer[i]);
}
return self;
}
- toLower
// converts any uppercase chars in buffer to lowercase
{
int i;
for (i=0; i<length; i++) {
if (NXIsUpper(buffer[i])) buffer[i] = NXToLower(buffer[i]);
}
return self;
}
- invertCases
{
int i;
for (i=0; i<length; i++) {
if (NXIsUpper(buffer[i])) buffer[i] = NXToLower(buffer[i]);
else buffer[i] = NXToUpper(buffer[i]);
}
return self;
}
- capitalizeEachWord
{ // ***** it might be nice to NOT capitalize words like "a" "an" and "the"
// so that capitalizations follw the style of titles, etc.
int i = 0;
if (!buffer) return 0;
while (i <= length) {
while ((NXIsSpace(buffer[i])) && (i <= length)) i++;
if (i < length) buffer[i] = NXToUpper(buffer[i]);
while ((!NXIsSpace(buffer[i])) && (i <= length)) i++;
}
return self;
}
- removeFrom:(int)index length:(int)len
{ // to avoid memory leaks, this should NEVER return nil!
id temp1,temp2;
if (!buffer) return self; // everything's already gone
if (len <= 0) return self; // noting to remove
// DAY: should I presume to fix index<0 like so? or just index = 0?
// or just return self?
if (index < 0) { len += index; index = 0; if (len <= 0) return self; }
if (index > length - 1) return self; // nothing out there
temp1 = [self left:index];
if (!temp1) temp1 = [[[self class] alloc] init];
temp2 = [self midFrom:index+len to:length];
[temp1 concatenate:temp2];
[self takeStringValueFrom:temp1];
[temp1 free];
[temp2 free];
return self;
}
- removeFrom:(int)start to:(int)end
{
return [self removeFrom:start length:end-start+1];
}
- (int)gets
{
char c;
[self setStringValue:""];
while (((c = getchar()) != '\n') && (c != EOF)) {
if (length == _length-1) [self setCapacity:length*2];
[self addChar:c];
}
return (c == '\n')? 0:EOF;
}
- (int)fgets:(FILE *)fd keepNewline:(BOOL)keepit
{
char c;
[self setStringValue:""];
while (((c = fgetc(fd)) != '\n') && (c != EOF)) {
if (length == _length-1) [self setCapacity:length*2];
[self addChar:c];
}
if (keepit && (c == '\n')) [self addChar:'\n']; //don't add EOF
return (c == '\n')? 0:EOF;
}
- (int)fgets:(FILE *)fd
{
return [self fgets:fd keepNewline:YES];
}
- (int)streamGets:(NXStream *)stream keepNewline:(BOOL)keepit
{
char c = '\0';
[self setStringValue:""];
while (!NXAtEOS(stream) && ((c = NXGetc(stream)) != '\n') && (c != EOF)) {
if (length == _length-1) [self setCapacity:length*2];
[self addChar:c];
}
if (keepit && (c == '\n')) [self addChar:'\n']; //don't add EOF
return (c == '\n')? 0:EOF;
}
- (int)streamGets:(NXStream *)stream
{
return [self streamGets:stream keepNewline:YES];
}
- padToLength:(int)len withChar:(char)aChar
{
int i;
for (i=length;i<len;i++) {
if (length == _length-1) [self setCapacity:length*2];
[self addChar:aChar];
}
return self;
}
- padFrontToLength:(int)len withChar:(char)aChar
{
if (len > length) {
id string = [[[[self class] alloc] initCapacity:len-length+1]
padToLength:len-length withChar:aChar];
[self insertString:string];
[string free];
}
return self;
}
// need a removePart:... series like the extract part stuff.
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.