home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1994 June / NEBULA_SE.ISO / SourceCode / MiscKit / Source / MiscStringCompat.m < prev    next >
Encoding:
Text File  |  1994-03-28  |  13.0 KB  |  524 lines

  1. //
  2. //    MiscStringCompat.m
  3. //        Written by Don Yacktman (c) 1993 by Don Yacktman.
  4. //                Version 1.7  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(Compat)
  16.  
  17. // This category includes methods to make the MiscString compatible
  18. // with other existing string classes.  This way, you can easily
  19. // replace your crufty old string class with a MiscString without
  20. // having to change the code.  Most methods are covers which simply
  21. // call the appropriate existing MiscString function.  The majority
  22. // of these methods actually add compatability with the MOString class,
  23. // but there is other stuff in here, too...
  24.  
  25. // None of the methods in this category add functionality; they are wrappers
  26. // around existing methods which allow programmers to use calls associated
  27. // with other string classes on the MiscString.  When I add compatability
  28. // with string classes, if there is a function that adds functionality, I
  29. // write a compatible method and place it into another category.  Only
  30. // redundant methods are in this category, which is why they are not
  31. // detailed in the documentation.
  32.  
  33. // If you have some _other_ string class, and would like to see
  34. // compatibility methods added to the MiscString to support that
  35. // class, too, let us know!
  36.  
  37. // Most of these methods are derived by Don Yacktman from code written
  38. // by Mike Ferris and David Lehn.
  39.  
  40. - takeStringValue:sender { return [self takeStringValueFrom:sender]; }
  41.  
  42. - clear
  43. {
  44.     [self freeString];
  45.     return self;
  46. }
  47.  
  48. - ( const char* ) string
  49. {
  50.    return [self stringValue];
  51. }
  52.  
  53. - setString: ( const char *) aString
  54. {
  55.     [self setStringValue:aString];
  56.     return self;
  57. }
  58.  
  59. - replaceChar: ( char ) aChar withChar: ( char ) replaceChar
  60. {
  61.     return [self replaceEveryInstanceOfChar:aChar withChar:replaceChar];
  62. }
  63.  
  64. - addToEndOfString: ( const char *) aString
  65. {
  66.     [self cat:aString];
  67.     return self;
  68. }
  69.  
  70. - addToFrontOfString: ( const char *) aString
  71. {
  72.     [self insert:aString at:0];
  73.     return self;
  74. }
  75.  
  76. - addCharToEndOfString: ( char ) aChar
  77. {
  78.     [self addChar:aChar];
  79.     return self;
  80. }
  81.  
  82. - addCharToFrontOfString: ( char ) aChar
  83. {
  84.     [self insertChar:aChar at:0];
  85.     return self;
  86. }
  87.  
  88. - ( int ) numberFields
  89. {
  90.     return [self numWords];
  91. }
  92.  
  93. - ( char * ) nthField: ( int ) fieldNumber useAsDelimiter: ( char ) c
  94. {
  95.     char * field;
  96.     id fieldString = [ self extractPart:(fieldNumber) useAsDelimiter:c ];
  97.     if (!fieldString) return NULL;
  98.     field = NXZoneMalloc( [ self zone ], [ fieldString length ] + 1 );
  99.     strcpy(field, [ fieldString stringValue ]);
  100.     [fieldString free];
  101.     return field;
  102. }
  103.  
  104. - ( char * ) nthField: ( int ) fieldNumber
  105. {
  106.     return [ self nthField:fieldNumber useAsDelimiter:' ' ];
  107. }
  108.  
  109. // this one kind of adds functionality, but by naming conventions it still
  110. // makes sense to put it here.
  111. - ( char * ) nthQuotedField: ( int ) fieldNumber
  112. {
  113.     return [ self nthField:fieldNumber*2 useAsDelimiter:'"' ];
  114. }
  115.  
  116. - ( char * ) lastField
  117. {
  118.     char * field;
  119.     id str = [ self extractPart:MISC_STRING_LAST useAsDelimiter:' ' ];
  120.     field = NXZoneMalloc([self zone], [str length] + 1);
  121.     strcpy(field, [str stringValue]);
  122.     [str free];
  123.     return field;
  124. }
  125.  
  126. - ( char * ) firstField
  127. {
  128.     char * field;
  129.     id str = [ self extractPart:MISC_STRING_FIRST useAsDelimiter:' ' ];
  130.     field = NXZoneMalloc([self zone], [str length] + 1);
  131.     strcpy(field, [str stringValue]);
  132.     [str free];
  133.     return field;
  134. }
  135.  
  136. - addStrings: ( const char *) fields,  ...
  137. {
  138.     va_list ptr;
  139.   
  140.     va_start( ptr, fields );
  141.     [self catStrings:fields, ptr];
  142.     va_end( ptr );       
  143.     return self;
  144. }
  145.  
  146. - replaceEveryInstanceOfChar:(char)aChar withChar:(char)replaceChar
  147. {
  148.     return [self replaceEveryOccurrenceOfChar:aChar
  149.             withChar:replaceChar caseSensitive:YES];
  150. }
  151.  
  152. - replaceEveryInstanceOfChar:(char)aChar with:(char)replaceChar
  153. {
  154.     return [self replaceEveryOccurrenceOfChar:aChar
  155.             withChar:replaceChar caseSensitive:YES];
  156. }
  157.  
  158. // The rest of the methods here are for compatability with the MOString
  159. // from the MOKit.
  160.  
  161. // warning:  the following MOString methods clash with MiscString methods
  162. //    of the same name.  You will have to check your code for uses of these
  163. //    methods and fix them appropriately to avoid serious problems.
  164. //    Group 1:  MOString wants string object, MiscString wants char *
  165. //        -insert:stringObject at:(int)position
  166. //        -cat:stringObject
  167. //    Note also that the MiscString doesn't support the unique string
  168. //    concept, so it cannot become a unique string.  Perhaps in the
  169. //    future there will be a MiscUniqueString class; I prefer that approach
  170. //    myself.  At any rate, this shouldn't affect the functionality when
  171. // using the MiscString compatibly.
  172.  
  173. - convertToUpper
  174. {
  175.     return [self toUpper];
  176. }
  177.  
  178. - convertToLower
  179. {
  180.     return [self toLower];
  181. }
  182.  
  183. - (size_t)recalcLength
  184. {
  185.     length = strlen(buffer);
  186.     return length;
  187. }
  188.  
  189. - (int)replaceAllOccurrencesOfChar:(char)oldChar with:(char)newChar
  190. {
  191.     [self replaceEveryOccurrenceOfChar:oldChar withChar:newChar];
  192.     return 0; // this information isn't available so we'll just return zero
  193. }
  194.  
  195. - (char)replaceCharAt:(int)index with:(char)newChar
  196. {
  197.     char tempChar = [self charAt:index];
  198.     [self replaceCharAt:index withChar:newChar];
  199.     return tempChar; 
  200. }
  201.  
  202. - insertStringValue:(const char *)s at:(int)position
  203. {
  204.     [self insert:s at:position];
  205.     return self;
  206. }
  207.  
  208. - preCatStringValue:(const char *)s
  209. {
  210.     return [self insert:s at:0];
  211. }
  212.  
  213. - preCat:stringObject
  214. {
  215.     return [self insertString:stringObject];
  216. }
  217.  
  218. - preCatFromFormat:(const char *)format, ...
  219. // Prepends the given format string after formatting before the contents
  220. // of the receiver.
  221. {
  222.     va_list param_list;
  223.  
  224.     va_start(param_list, format);
  225.     [self insertFromFormat:format, param_list];
  226.     va_end(param_list);
  227.     return self;
  228. }
  229.  
  230. - catStringValue:(const char *)s
  231. {
  232.     return [self cat:s];
  233. }
  234.  
  235. - (int)compare:stringObject
  236. {
  237.     return [self compare:stringObject caseSensitive:YES 
  238.                     length:-1 withTable:NULL];
  239. }
  240.  
  241. - (int)compare:stringObject caseSensitive:(BOOL)flag
  242. {
  243.     return [self compare:stringObject caseSensitive:flag 
  244.                     length:-1 withTable:NULL];
  245. }
  246.  
  247. - (int)compare:stringObject caseSensitive:(BOOL)flag length:(int)len
  248. {
  249.     return [self compare:stringObject caseSensitive:flag 
  250.                     length:len withTable:NULL];
  251. }
  252.  
  253. - (int)compare:stringObject caseSensitive:(BOOL)flag length:(int)len 
  254.             withTable:(NXStringOrderTable *)table
  255. {
  256.     int ret;
  257.     NXStringOrderTable *realTable = [self stringOrderTable]; // temp save
  258.     [self setStringOrderTable:table];
  259.     ret = [self compareTo:stringObject n:len caseSensitive:flag];
  260.     [self setStringOrderTable:realTable];
  261.     return ret;
  262. }
  263.  
  264. - (int)compareStr:(const char *)s
  265. {
  266.     return [self compareStr:s caseSensitive:YES length:-1 withTable:NULL];
  267. }
  268.  
  269. - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag
  270. {
  271.     return [self compareStr:s caseSensitive:flag length:-1 withTable:NULL];
  272. }
  273.  
  274. - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag length:(int)len
  275. {
  276.     return [self compareStr:s caseSensitive:flag length:len withTable:NULL];
  277. }
  278.  
  279. - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag length:(int)len
  280.             withTable:(NXStringOrderTable *)table
  281. {
  282.     id ss = [[self class] newWithString:s];
  283.     int ret = [self compare:ss caseSensitive:flag length:len withTable:table];
  284.     [ss free];
  285.     return ret;
  286. }
  287.  
  288. - (int)endCompare:stringObject
  289. {
  290.     return [self endCompare:stringObject 
  291.                     caseSensitive:YES length:-1 withTable:NULL];
  292. }
  293.  
  294. - (int)endCompare:stringObject caseSensitive:(BOOL)flag
  295. {
  296.     return [self endCompare:stringObject 
  297.                     caseSensitive:flag length:-1 withTable:NULL];
  298. }
  299.  
  300. - (int)endCompare:stringObject caseSensitive:(BOOL)flag length:(int)len
  301. {
  302.     return [self endCompare:stringObject 
  303.                     caseSensitive:flag length:len withTable:NULL];
  304. }
  305.  
  306. - (int)endCompare:stringObject caseSensitive:(BOOL)flag length:(int)len 
  307.             withTable:(NXStringOrderTable *)table
  308. {
  309.     int ret;
  310.     NXStringOrderTable *realTable = [self stringOrderTable]; // temp save
  311.     [self setStringOrderTable:table];
  312.     ret = [self endCompareTo:stringObject n:len caseSensitive:flag];
  313.     [self setStringOrderTable:realTable];
  314.     return ret;
  315. }
  316.  
  317. - (int)endCompareStr:(const char *)s
  318. {
  319.     return [self endCompareStr:s caseSensitive:YES 
  320.                 length:-1 withTable:NULL];
  321. }
  322.  
  323. - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag
  324. {
  325.     return [self endCompareStr:s caseSensitive:flag 
  326.                 length:-1 withTable:NULL];
  327. }
  328.  
  329. - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag 
  330.             length:(int)len
  331. {
  332.     return [self endCompareStr:s caseSensitive:flag 
  333.                 length:len withTable:NULL];
  334. }
  335.  
  336. - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag 
  337.             length:(int)len withTable:(NXStringOrderTable *)table
  338. {
  339.     id ss = [[self class] newWithString:s];
  340.     int ret = [self endCompare:ss caseSensitive:flag
  341.             length:len withTable:table];
  342.     [ss free];
  343.     return ret;
  344. }
  345.  
  346. - substringFrom:(int)start to:(int)end
  347. {
  348.     return [self midFrom:start to:end];
  349. }
  350.  
  351. - (int)positionOf:(char)aChar nthOccurrence:(int)n
  352. {
  353.     if (n<0) return [self rspotOf:aChar occurrenceNum:(-n) caseSensitive:YES];
  354.     return [self spotOf:aChar occurrenceNum:n caseSensitive:YES];
  355. }
  356.  
  357. - (int)countOccurrencesOf:(char)aChar
  358. {
  359.     return [self numOfChar:aChar caseSensitive:YES];
  360. }
  361.  
  362. - (size_t)strlen
  363. {
  364.     return length;
  365. }
  366.  
  367. - (const char *)strcpy:(const char *)s
  368. {
  369.     [self setStringValue:s];
  370.     return buffer;
  371. }
  372.  
  373. - (const char *)strncpy:(const char *)s :(size_t)n
  374. {
  375.     [self setStringValue:s n:(int)n fromZone:[self zone]];
  376.     return buffer;
  377. }
  378.  
  379. - (const char *)strcat:(const char *)s
  380. {
  381.     [self cat:s];
  382.     return buffer;
  383. }
  384.  
  385. - (const char *)strncat:(const char *)s :(size_t)n
  386. {
  387.     [self cat:s n:n fromZone:[self zone]];
  388.     return buffer;
  389. }
  390.  
  391. - (int)strcmp:(const char *)s
  392. {
  393.     if ((!buffer) || (!s)) return -2;
  394.     return strcmp(buffer, s);
  395. }
  396.  
  397. - (int)strncmp:(const char *)s :(size_t)n
  398. {
  399.     if ((!buffer) || (!s)) return -2;
  400.     return strncmp(buffer, s, n);
  401. }
  402.  
  403. - (const char *)strchr:(char)aChar
  404. {
  405.     if (buffer) return NULL;
  406.     return strchr(buffer, aChar);
  407. }
  408.  
  409. - (const char *)strrchr:(char)aChar
  410. {
  411.     if (!buffer) return NULL;
  412.     return strrchr(buffer, aChar);
  413. }
  414.  
  415. - (const char *)strpbrk:(const char *)breakChars
  416. {
  417.     if ((!buffer) || (!breakChars)) return NULL;
  418.     return strpbrk(buffer, breakChars);
  419. }
  420.  
  421. - (size_t)strspn:(const char *)acceptableChars
  422. {
  423.     if ((!buffer) || (!acceptableChars)) return -1;
  424.     return strspn(buffer, acceptableChars);
  425. }
  426.  
  427. - (size_t)strcspn:(const char *)breakChars
  428. {
  429.     if ((!buffer) || (!breakChars)) return 0;
  430.     return strcspn(buffer, breakChars);
  431. }
  432.  
  433. - initStringValue:(const char *)s
  434. {
  435.     return [self initString:s];
  436. }
  437.  
  438. - initStringValueNoCopy:(char *)s
  439. {    // we still copy it anyway; this could be implemented for effect a speedup
  440.     // if it makes that much difference...
  441.     return [self initString:s];
  442. }
  443.  
  444. - initStringValueNoCopy:(char *)s shouldFree:(BOOL)flag
  445. {
  446.     id ret = [self initString:s];
  447.     if (flag) NX_FREE(s);
  448.     return ret;
  449. }
  450.  
  451. - initStringValueUnique:(const char *)s
  452. {
  453.     return [self initString:s];
  454. }
  455.  
  456. - deepCopy
  457. {
  458.     return [self deepCopyFromZone:[self zone]];
  459. }
  460.  
  461. - deepCopyFromZone:(NXZone *)zone
  462. { // our copy from zone IS deep already...
  463.     return [self copyFromZone:zone];
  464. }
  465.  
  466. - shallowCopy
  467. {
  468.     return [self shallowCopyFromZone:[self zone]];
  469. }
  470.  
  471. - shallowCopyFromZone:(NXZone *)zone
  472. { // our copy from zone IS deep already...
  473.     return [self copyFromZone:zone];
  474. }
  475.  
  476. - setStringValueNoCopy:(const char *)s
  477. {    // we set the string value by copying anyway.
  478.     return [self setStringValue:s];
  479. }
  480.  
  481. - setStringValueNoCopy:(char *)s shouldFree:(BOOL)flag
  482. {
  483.     id ret = [self setStringValue:s];
  484.     if (flag) NX_FREE(s);
  485.     return ret;
  486. }
  487.  
  488. - setStringValueUnique:(const char *)s { return [self setStringValue:s]; }
  489. - setNull { return [self freeString]; }
  490. - makeUnique { return self; } // we don't support this at all.
  491. - setShouldFree:(BOOL)flag { return self; }
  492. - (unsigned int)count { return length; }
  493. - (BOOL)isNull { return [self emptyString]; }
  494. - (BOOL)isEmpty { return [self emptyString]; }
  495. - (BOOL)isUnique { return NO; }
  496. - (BOOL)shouldFree { return YES; }
  497.  
  498.  
  499.  
  500.  
  501. // MOPathString methods
  502. - (int)numberOfComponents { return [self numberOfPathComponents]; }
  503. - componentAt:(int)index { return [self pathComponentAt:index]; }
  504. - file { return [self fileName]; }
  505. - directory { return [self pathName]; }
  506. - (const char *)path { return [self stringValue]; }
  507. - (BOOL)isRelative { return [self isRelativePath]; }
  508. - (BOOL)isAbsolute { return [self isAbsolutePath]; }
  509. - (BOOL)isDirectory { return [self isFileOfType:Misc_Directory]; }
  510. - (BOOL)isPlainFile { return [self isFileOfType:Misc_PlainFile]; }
  511. - (BOOL)isSymbolicLink { return [self isFileOfType:Misc_SymbolicLink]; }
  512. - (BOOL)isCharacterSpecial { return [self isFileOfType:Misc_CharacterSpecial]; }
  513. - (BOOL)isBlockSpecial { return [self isFileOfType:Misc_BlockSpecial]; }
  514. - (BOOL)isSocket { return [self isFileOfType:Misc_Socket]; }
  515. - setPathSeparator:(char)c { return self; } // NO OP
  516. - setExtensionSeparator:(char)c { return self; } // NO OP
  517. - (char)pathSeparator { return '/'; }
  518. - (char)extensionSeparator { return '.'; }
  519. - setPath:(const char *)path { return [self setStringValue:path]; }
  520. - initPath:(const char *)path { return [self initStringValue:path]; }
  521. - (char *)buffer { return buffer; } // be careful with this!  don't muck it up!
  522.  
  523. @end
  524.