home *** CD-ROM | disk | FTP | other *** search
- //
- // MiscStringModification.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(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;
- }
-
- // need a removePart:... series like the extract part stuff.
- @end
-