home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / MiscKit1.2.6 / Source / MiscStringModification.m < prev    next >
Encoding:
Text File  |  1994-05-19  |  9.2 KB  |  389 lines

  1. //
  2. //    MiscStringModification.m
  3. //        Written by Don Yacktman (c) 1993 by Don Yacktman.
  4. //                Version 1.95  All rights reserved.
  5. //        This notice may not be removed from this source code.
  6. //
  7. //    This object is included in the MiscKit by permission from the author
  8. //    and its use is governed by the MiscKit license, found in the file
  9. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  10. //    for a list of all applicable permissions and restrictions.
  11. //    
  12.  
  13. #import <misckit/MiscString.h>
  14.  
  15. @implementation MiscString(Modification)
  16.  
  17. // This category is composed of methods which modify a MiscString in
  18. // various ways (case conversion, trimming whitespace, deleting portions
  19. // of the string, and so on).
  20.  
  21. - setStringValue:(const char *)aString
  22. {
  23.     return [self setStringValue:aString fromZone:[self zone]];
  24. }
  25.  
  26. - setStringValue:(const char *)aString fromZone:(NXZone *)zone
  27. {
  28.     if (!aString) return self; // use -freeString to set to "NULL"
  29.     // Note that I could have used NXCopyStringBufferFromZone() here
  30.     // instead.  This works just as well, but it may be slower...
  31.     // I haven't checked that out, though.  It might be worth doing.
  32.     [self allocateBuffer:(strlen(aString)+1) fromZone:zone];
  33.     strcpy(buffer, aString);
  34.     length = strlen(buffer);
  35.     return self;
  36. }
  37.  
  38. - setStringValue:(const char *)aString n:(int)n
  39. {
  40.     return [self setStringValue:aString n:n fromZone:[self zone]];
  41. }
  42.  
  43. - setStringValue:(const char *)aString n:(int)n fromZone:(NXZone *)zone
  44. {
  45.     char *buf = NULL;
  46.     if ((aString) && (n > 0))  {
  47.         NX_MALLOC(buf, char, n + 1);
  48.         strncpy(buf, aString, n);
  49.         buf[n]='\0';
  50.     }
  51.     [self setStringValue:buf fromZone:zone];
  52.     NX_FREE(buf);
  53.     return self;
  54. }
  55.  
  56. - setFromFormat:(const char *)formatStr, ...
  57. // Sets the string from and printf style format string and arguments.
  58. {
  59.     va_list param_list;
  60.     char *buf;
  61.  
  62.     va_start(param_list, formatStr);
  63.     buf = MiscBuildStringFromFormatV(formatStr, param_list);
  64.     va_end(param_list);
  65.     [self setStringValue:buf];
  66.     NX_FREE(buf);
  67.     return self;
  68. }
  69.  
  70. - setIntValue:(int)val
  71. // Sets the string by converting the given int to a string.
  72. {
  73.     return [self setFromFormat:"%d", val];
  74. }
  75.  
  76. - setFloatValue:(float)val
  77. // Sets the string by converting the given float to a string.
  78. {
  79.     return [self setFromFormat:"%f", val];
  80. }
  81.  
  82. - setDoubleValue:(double)val
  83. // Sets the string by converting the given double to a string.
  84. {
  85.     return [self setFromFormat:"%f", val];
  86. }
  87.  
  88. - sprintf:(const char *)formatStr, ...
  89. // Sets the strings contents as the result of printf'ing with the
  90. // given format string and arguments.  Same as setFromFormat:, ...
  91. {
  92.     va_list param_list;
  93.     char *buf;
  94.     
  95.     va_start(param_list, formatStr);
  96.     buf = MiscBuildStringFromFormatV(formatStr, param_list);
  97.     va_end(param_list);
  98.     [self setStringValue:buf];
  99.     NX_FREE(buf);
  100.     return self;
  101. }
  102.  
  103. - takeStringValueFrom:sender
  104. { // if no string value, return nil; the user is expecting a changed string
  105.     if (!sender) return [self freeString]; // this seems reasonable...
  106.         // but maybe I should just return nil instead...
  107.     if (![sender respondsTo:@selector(stringValue)]) return nil;
  108.     return [self setStringValue:[sender stringValue] fromZone:[self zone]];
  109. }
  110.  
  111. - takeStringValueFrom:sender fromZone:(NXZone *)zone
  112. {
  113.     if (![sender respondsTo:@selector(stringValue)]) return nil;
  114.     return [self setStringValue:[sender stringValue] fromZone:zone];
  115. }
  116.  
  117. - takeIntValueFrom:sender
  118. {
  119.     if (![sender respondsTo:@selector(intValue)]) return nil;
  120.     [self setIntValue:[sender intValue]];
  121.     return self;
  122. }
  123.  
  124. - takeFloatValueFrom:sender
  125. {
  126.     if (![sender respondsTo:@selector(floatValue)]) return nil;
  127.     [self setFloatValue:[sender floatValue]];
  128.     return self;
  129. }
  130.  
  131. - takeDoubleValueFrom:sender
  132. {
  133.     if (![sender respondsTo:@selector(doubleValue)]) return nil;
  134.     [self setDoubleValue:[sender doubleValue]];
  135.     return self;
  136. }
  137.  
  138. - trimLeadSpaces
  139. { // removes any leading spaces from buffer
  140.     int i = 0;
  141.     id tmpStr;
  142.  
  143.     if (!buffer) return self;
  144.     if (length < 1) return self;
  145.     while (buffer[i] == ' ') i++;
  146.     if (i==0) return self;
  147.     tmpStr = [self right:length-i];
  148.     [self takeStringValueFrom:tmpStr];
  149.     [tmpStr free];
  150.     return self;
  151. }
  152.  
  153. - trimTailSpaces
  154. // removes any trailing spaces from buffer
  155. {
  156.     int i = length;
  157.     id tmpStr;
  158.  
  159.     if (!buffer) return self;
  160.     if (i < 1) return self;
  161.     while (buffer[i-1] == ' ') i--;
  162.     if (i==length) return self;
  163.     tmpStr = [self left:i];
  164.     [self takeStringValueFrom:tmpStr];
  165.     [tmpStr free];
  166.     return self;
  167. }
  168.  
  169. - trimSpaces
  170. // takes off leading and trailing spaces of the buffer
  171. {
  172.     return [[self trimLeadSpaces] trimTailSpaces];
  173. }
  174.  
  175. - trimLeadWhiteSpaces
  176. // removes any leading white space from buffer
  177.     int i = 0;
  178.     id tmpStr;
  179.     
  180.     if (!buffer) return self;
  181.     if (length < 1) return self;
  182.     while (NXIsSpace(buffer[i])) i++;
  183.     if (i==0) return self;
  184.     tmpStr = [self right:length-i];
  185.     [self takeStringValueFrom:tmpStr];
  186.     [tmpStr free];
  187.     return self;
  188. }
  189.  
  190. - trimTailWhiteSpaces
  191. // removes any leading white space from buffer
  192.     int i = length;
  193.     id tmpStr;
  194.     
  195.     if (!buffer) return self;
  196.     if (i < 1) return self;
  197.     while (NXIsSpace(buffer[i-1])) i--;
  198.     if (i==length) return self;
  199.     tmpStr = [self left:i];
  200.     [self takeStringValueFrom:tmpStr];
  201.     [tmpStr free];
  202.     return self;
  203. }
  204.  
  205. - trimWhiteSpaces
  206. // takes off leading and trailing spaces of the buffer
  207. {
  208.     return [[self trimLeadWhiteSpaces] trimTailWhiteSpaces];
  209. }
  210.  
  211. - squashSpaces
  212. {
  213.   int count = 0;
  214.   id tempStr;
  215.   
  216.   if (!buffer) return self;
  217.   [self trimSpaces];
  218.   tempStr = [[[[self class] alloc] init] allocateBuffer:length];
  219.   while (count<length) {
  220.     while ((count<length) && (buffer[count]!=' ')) {
  221.       [tempStr addChar:buffer[count]];
  222.       count++;
  223.      }
  224.     if ((count<length) && (buffer[count] == ' ')) {
  225.       [tempStr addChar:buffer[count]];
  226.       count++;
  227.      }
  228.     if ((count<length) && (buffer[count]==' ') && 
  229.        ((buffer[count-2] == ':') || (buffer[count-2] =='.'))) {
  230.          [tempStr addChar:buffer[count]];
  231.          count++;
  232.      }
  233.     while (buffer[count]==' ') count++;
  234.    }
  235.   [self takeStringValueFrom:tempStr];
  236.   [tempStr free];
  237.   return self;
  238. }
  239.  
  240. - reverse
  241. // reverses the characters in the buffer.  If it's a palindrome, you won't
  242. // notice much of a difference :-)
  243. {
  244.     char tmp[length+1];
  245.     int i, j=0;
  246.   
  247.     if (length <= 1) return self;
  248.     for (i=length-1; i>=0; i--) {
  249.         tmp[j] = buffer[i];
  250.         j++;
  251.     }
  252.     tmp[length] = 0;
  253.     if (length != 0) [self setStringValue:tmp];
  254.     return self;
  255. }
  256.  
  257. - toUpper
  258. // converts any lowercase characters in buffer to uppercase
  259. {
  260.     int i;
  261.     for (i=0; i<length; i++) {
  262.         if (NXIsLower(buffer[i])) buffer[i] = NXToUpper(buffer[i]);
  263.     }
  264.     return self;
  265. }
  266.  
  267. - toLower
  268. // converts any uppercase chars in buffer to lowercase
  269. {
  270.     int i;
  271.     for (i=0; i<length; i++) {
  272.         if (NXIsUpper(buffer[i])) buffer[i] = NXToLower(buffer[i]);
  273.     }
  274.     return self;
  275. }
  276.  
  277. - invertCases
  278. {
  279.     int i;
  280.     for (i=0; i<length; i++) {
  281.         if (NXIsUpper(buffer[i])) buffer[i] = NXToLower(buffer[i]);
  282.         else buffer[i] = NXToUpper(buffer[i]);
  283.     }
  284.     return self;
  285. }
  286.  
  287. - capitalizeEachWord
  288. { // ***** it might be nice to NOT capitalize words like "a" "an" and "the"
  289.     // so that capitalizations follw the style of titles, etc.
  290.     int i = 0;
  291.     if (!buffer) return 0;  
  292.     while (i <= length) {
  293.         while ((NXIsSpace(buffer[i])) && (i <= length)) i++;
  294.         if (i < length) buffer[i] = NXToUpper(buffer[i]);
  295.         while ((!NXIsSpace(buffer[i])) && (i <= length)) i++;
  296.     }
  297.     return self;
  298. }
  299.  
  300. - removeFrom:(int)index length:(int)len
  301. { // to avoid memory leaks, this should NEVER return nil!
  302.   id temp1,temp2;
  303.   
  304.   if (!buffer) return self;    // everything's already gone
  305.   if (len <= 0) return self; // noting to remove
  306.   // DAY: should I presume to fix index<0 like so? or just index = 0?
  307.   // or just return self?
  308.   if (index < 0) { len += index; index = 0; if (len <= 0) return self; }
  309.   if (index > length - 1) return self; // nothing out there
  310.   temp1 = [self left:index];
  311.   if (!temp1) temp1 = [[[self class] alloc] init];
  312.   temp2 = [self midFrom:index+len to:length];
  313.   [temp1 concatenate:temp2];
  314.   [self takeStringValueFrom:temp1];
  315.   [temp1 free];
  316.   [temp2 free];
  317.   return self;
  318. }
  319.  
  320. - removeFrom:(int)start to:(int)end
  321. {
  322.   return [self removeFrom:start length:end-start+1];
  323. }
  324.  
  325. - (int)gets
  326. {
  327.   char c;
  328.   [self setStringValue:""];
  329.   
  330.   while (((c = getchar()) != '\n') && (c != EOF)) {
  331.     if (length == _length-1) [self setCapacity:length*2];
  332.     [self addChar:c];
  333.    }
  334.   return (c == '\n')? 0:EOF;
  335. }
  336.  
  337. - (int)fgets:(FILE *)fd keepNewline:(BOOL)keepit
  338. {
  339.   char c;
  340.   [self setStringValue:""];
  341.   
  342.   while (((c = fgetc(fd)) != '\n') && (c != EOF)) {
  343.     if (length == _length-1) [self setCapacity:length*2];
  344.     [self addChar:c];
  345.    }
  346.   if (keepit && (c == '\n')) [self addChar:'\n']; //don't add EOF
  347.   return (c == '\n')? 0:EOF;
  348. }
  349.  
  350. - (int)fgets:(FILE *)fd
  351. {
  352.   return [self fgets:fd keepNewline:YES];
  353. }
  354.  
  355.  
  356. - (int)streamGets:(NXStream *)stream keepNewline:(BOOL)keepit
  357. {
  358.   char c = '\0';
  359.   [self setStringValue:""];
  360.   
  361.   while (!NXAtEOS(stream) && ((c = NXGetc(stream)) != '\n') && (c != EOF)) {
  362.     if (length == _length-1) [self setCapacity:length*2];
  363.     [self addChar:c];
  364.    }
  365.   if (keepit && (c == '\n')) [self addChar:'\n']; //don't add EOF
  366.   return (c == '\n')? 0:EOF;
  367. }
  368.  
  369. - (int)streamGets:(NXStream *)stream
  370. {
  371.   return [self streamGets:stream keepNewline:YES];
  372. }
  373.  
  374. - padToLength:(int)len withChar:(char)aChar
  375. {
  376.   int i;
  377.   
  378.   for (i=length;i<len;i++) {
  379.     if (length == _length-1) [self setCapacity:length*2];
  380.     [self addChar:aChar];
  381.    }
  382.   return self;
  383. }
  384.  
  385. // need a removePart:... series like the extract part stuff.
  386. @end
  387.