home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / ColorSync SDK / Sample Code / CSDemo 2.1 / ShellSources / stringUtils.c < prev    next >
Encoding:
Text File  |  1997-06-13  |  12.2 KB  |  365 lines  |  [TEXT/CWIE]

  1. // This file contains useful routines for converting
  2. // various data type into human-readable strings.
  3. // 
  4. // 9/16/94    david    first cut
  5. // 9/20/95    david    improved comments
  6.  
  7. #include <TextEdit.h>
  8. #include <Errors.h>
  9. #include <TextUtils.h>
  10. #include <Resources.h>
  11. #include <Script.h>
  12.  
  13. #include "stringUtils.h"
  14.  
  15.  
  16. /**\
  17. |**| ==============================================================================
  18. |**| PRIVATE TYPEDEFS
  19. |**| ==============================================================================
  20. \**/
  21. typedef struct xtnd80
  22. {
  23.     short                            exp;
  24.     short                            man[4];
  25. } xtnd80 ;
  26.  
  27.  
  28. /**\
  29. |**| ==============================================================================
  30. |**| PUBLIC FUNCTIONS
  31. |**| ==============================================================================
  32. \**/
  33.  
  34.  
  35. /*------------------------------------------------------------------------------*\
  36.     StringToString
  37.  *------------------------------------------------------------------------------*
  38.         This routine copies one pstring into another.
  39.         It assumes that the dest string is long enough to hold the source string.
  40. \*------------------------------------------------------------------------------*/
  41. void StringToString ( StringPtr src, StringPtr dest )
  42. {
  43.     BlockMove(src, dest, src[0]+1) ;
  44. }
  45.  
  46.  
  47. /*------------------------------------------------------------------------------*\
  48.     OSTypeToString
  49.  *------------------------------------------------------------------------------*
  50.         This routine converts a 4-byte OSType into a pascal string.
  51.         It assumes that the dest string (which will be 6 chars)
  52.         is long enough to hold the result.
  53. \*------------------------------------------------------------------------------*/
  54. void OSTypeToString ( OSType type, StringPtr dest )
  55. {
  56.     dest[0] = 6 ;
  57.     dest[1] = dest[6] = '\'' ;        // put single quotes aroung the ostype
  58.     BlockMove(&type, &dest[2], 4) ;
  59. }
  60.  
  61.  
  62. /*------------------------------------------------------------------------------*\
  63.     FSSpecToString
  64.  *------------------------------------------------------------------------------*
  65.         This routine converts the full path of a FSSpec into a pascal string.
  66.         If the appendName parameter is true then the FSSpec's filenam is
  67.         appended to the path.
  68.         It assumes that the dest string (which can be up to 255 chars)
  69.         is long enough to hold the result.
  70. \*------------------------------------------------------------------------------*/
  71. void FSSpecToString ( FSSpec spec, StringPtr dest, Boolean appendName )
  72. {
  73.     CInfoPBRec    pb;
  74.     Str255        dirName;
  75.     OSErr        err ;
  76.  
  77.     dest[0] = 0;                                    // initialize full pathname
  78.     
  79.     if (appendName)
  80.         pStrCat(dest, spec.name, 255) ;
  81.  
  82.     pb.dirInfo.ioNamePtr = dirName;
  83.     pb.dirInfo.ioVRefNum = spec.vRefNum;            // indicat target volume
  84.     pb.dirInfo.ioDrParID = spec.parID;                // initialize parent directory ID
  85.     pb.dirInfo.ioFDirIndex = -1;                    // get info about a directory
  86.  
  87.     do
  88.     {
  89.         pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
  90.         err = PBGetCatInfoSync(&pb) ;                // needs error cheching...
  91.         pStrCat(dirName, "\p:", 255) ;
  92.         pStrIns(dest, dirName, 255) ;                // assume fullPathName is a Str255
  93.     } while (pb.dirInfo.ioDrDirID != fsRtDirID) ;
  94. }
  95.  
  96.  
  97. /*------------------------------------------------------------------------------*\
  98.     LongHexToString
  99.  *------------------------------------------------------------------------------*
  100.         This routine converts a long into a pascal string in hex format.
  101.         It assumes that the dest string (which will be 10 chars)
  102.         is long enough to hold the result.
  103. \*------------------------------------------------------------------------------*/
  104. void LongHexToString ( long num, StringPtr dest )
  105. {
  106.     long  n ;
  107.     short i ;
  108.     
  109.     dest[0] = 10 ;
  110.     dest[1] = '0' ;
  111.     dest[2] = 'x' ;
  112.     
  113.     for (i=0; i<8; i++)
  114.     {
  115.         n = ( num & 15 ) ;
  116.         dest[10-i] = (n<=9) ? ('0'+n) : ('A'+n-10) ;
  117.         num >>= 4 ;
  118.     }
  119. }
  120.  
  121.  
  122. /*------------------------------------------------------------------------------*\
  123.     VersionToString
  124.  *------------------------------------------------------------------------------*
  125.         This routine converts a long into a pascal string according to the 
  126.         convention for encoding version numbers.
  127.         It assumes that the dest string (which may be from 4 to 9 chars)
  128.         is long enough to hold the result.
  129. \*------------------------------------------------------------------------------*/
  130. void VersionToString ( long vers, StringPtr dest )
  131. {
  132.     register unsigned char len = 0 ;
  133.     register unsigned char digit ;
  134.     
  135.     digit = (vers & 0xF0000000) >> 28 ;
  136.     if (digit)
  137.         dest[ ++len ] = '0' + digit ;
  138.     
  139.     digit = (vers & 0x0F000000) >> 24 ;
  140.     dest[ ++len ] = '0' + digit ;
  141.     
  142.     dest[ ++len ] = '.' ;
  143.     
  144.     digit = (vers & 0x00F00000) >> 20 ;
  145.     dest[ ++len ] = '0' + digit ;
  146.     
  147.     
  148.     digit = (vers & 0x000F0000) >> 16 ;
  149.     if (digit)
  150.     {
  151.         dest[ ++len ] = '.' ;
  152.         dest[ ++len ] = '0' + digit ;
  153.     }
  154.     
  155.     digit = (vers & 0x0000FF00) >> 8 ;
  156.     switch (digit)
  157.     {
  158.         case 0x20: dest[ ++len ] = 'd'; break;
  159.         case 0x40: dest[ ++len ] = 'a'; break;
  160.         case 0x60: dest[ ++len ] = 'b'; break;
  161.     }
  162.     
  163.     digit = (vers & 0x000000F0) >> 4 ;
  164.     if (digit)
  165.         dest[ ++len ] = '0' + digit ;
  166.         
  167.     digit = (vers & 0x0000000F) >> 0 ;
  168.     if (digit)
  169.         dest[ ++len ] = '0' + digit ;
  170.     
  171.     dest[0] = len;
  172. }
  173.  
  174.  
  175. /*------------------------------------------------------------------------------*\
  176.     pStrCat
  177.  *------------------------------------------------------------------------------*
  178.         This routine concatonates the src pstring to the end of the dest pstring.
  179.         It will not make the dst string longer than the size parameter.
  180. \*------------------------------------------------------------------------------*/
  181. void pStrCat ( StringPtr dst, StringPtr src, unsigned char size )
  182. {
  183.     if (*dst + *src > size)                                // make sure were not too big
  184.         *src = size - *dst;
  185.     BlockMove(src + 1, dst + *dst + 1, *src) ;            // copy string in
  186.     *dst += *src;                                        // adjust length byte
  187. }
  188.  
  189.  
  190. /*------------------------------------------------------------------------------*\
  191.     pStrIns
  192.  *------------------------------------------------------------------------------*
  193.         This routine inserts the src pstring at the beginning of the dest pstring.
  194.         It will not make the dst string longer than the size parameter.
  195. \*------------------------------------------------------------------------------*/
  196. void pStrIns ( StringPtr dst, StringPtr src, unsigned char size )
  197. {
  198.     if (*dst + *src > size)                                // make sure were not too big
  199.         *dst = size - *src;
  200.     BlockMove(dst + 1, dst + *src + 1, *dst) ;            // make room for new string
  201.     BlockMove(src + 1, dst + 1, *src) ;                    // copy new string in
  202.     *dst += *src;                                        // adjust length byte
  203. }
  204.  
  205.  
  206. /*------------------------------------------------------------------------------*\
  207.     MyReplaceText
  208.  *------------------------------------------------------------------------------*
  209.         This routine provides a slightly different way to call ReplaceText()
  210.         The only difference is that the parameter that contains the replacement
  211.         text is a StringPtr instead of a handle.
  212.         If the result of this routine is negative, then it is an error code.
  213.         If positive, then it indicates the number of substitutions.
  214. \*------------------------------------------------------------------------------*/
  215. short MyReplaceText ( Handle dest, StringPtr rplc, Str15 key )
  216. {
  217.     Size    rplcLen ;
  218.     Handle    rplcHandle ;
  219.     short    returnVal ;
  220.     OSErr    err ;
  221.     
  222.     rplcLen = rplc[0];
  223.     err = PtrToHand( &rplc[1], &rplcHandle, rplcLen ) ;
  224.     if (err) return err ;
  225.     
  226.     returnVal = ReplaceText( dest, rplcHandle, key ) ;
  227.     DisposeHandle( rplcHandle ) ;
  228.     return returnVal ;
  229. }
  230.  
  231.  
  232. /*------------------------------------------------------------------------------*\
  233.     MyTETextBox
  234.  *------------------------------------------------------------------------------*
  235.         This routine provides an alternative to calling TETextBox()
  236.         The difference is that this routine expicitly allocate a TEHandle so that
  237.         it can use the text mode of the current GrafPort.
  238. \*------------------------------------------------------------------------------*/
  239. void MyTETextBox ( Ptr text, long length, Rect *box, short justType)
  240. {
  241.     TEHandle hTE ;
  242.     
  243.     hTE = TENew( box, box ) ;
  244.     
  245.     TESetAlignment( justType, hTE ) ;
  246.     TESetText( text, length, hTE ) ;
  247.     
  248.     (**hTE).txMode = (qd.thePort)->txMode ;
  249.     
  250.     TEUpdate( box, hTE ) ;
  251.     TEDispose(hTE) ;
  252. }
  253.  
  254.  
  255.  
  256. /*------------------------------------------------------------------------------*\
  257.     FormatExtd80
  258.  *------------------------------------------------------------------------------*
  259.         This routine converts an extended80 number into a pascal string using
  260.         a 'FMAT' resource and the ExtendedToString() call so that the resulting
  261.         string will be formatted accrding to the user's setting in the Numbers
  262.         control panel.
  263.         It assumes that the dest string (which can be up to 255 chars)
  264.         is long enough to hold the result.
  265. \*------------------------------------------------------------------------------*/
  266. OSErr FormatExtd80 ( extended80 *x, short formatID, StringPtr dest )
  267. {
  268.     NumberParts            parts;
  269.     NumFormatString        **format;
  270.     Intl0Hndl            itl4;
  271.     long                offset, length;
  272.     FormatStatus        status;
  273.  
  274.     /* Just in case! */
  275.     dest[0] = 0;
  276.  
  277.     /* Get default Number Parts resource/offset/length */
  278.     GetIntlResourceTable( iuCurrentScript, iuNumberPartsTable,
  279.                             (Handle*)&itl4, &offset, &length ) ;
  280.     if ( itl4==nil ) return paramErr ;
  281.  
  282.     /* Retrieve default Number Parts Table */
  283.     parts = *( NumberPartsPtr )( *((Handle)itl4) + offset ) ;
  284.  
  285.     /* Retrieve canonical format */
  286.     format = ( NumFormatString ** )GetResource( 'FMAT', formatID ) ;
  287.     if ( format==nil ) return resNotFound;
  288.  
  289.     /* Lock it */
  290.     HLock(( Handle )format ) ;
  291.  
  292.     /* Format it! */
  293.     status = ExtendedToString( x, *format, &parts, dest ) ;
  294.  
  295.     /* Unlock and release the canonical format */
  296.     HUnlock( (Handle)format ) ;
  297.     ReleaseResource( (Handle)format ) ; 
  298.     
  299.     return status;
  300. }
  301.  
  302.  
  303. /*------------------------------------------------------------------------------*\
  304.     FormatLong
  305.  *------------------------------------------------------------------------------*
  306.         This routine converts a long integer into a pascal string using
  307.         a 'FMAT' resource and the ExtendedToString() call so that the resulting
  308.         string will be formatted accrding to the user's setting in the Numbers
  309.         control panel.  It does this by converting the long into an extended80
  310.         and then calling FormatExtd80.
  311.         It assumes that the dest string (which can be up to 255 chars)
  312.         is long enough to hold the result.
  313. \*------------------------------------------------------------------------------*/
  314. OSErr FormatLong ( long num, short formatID, StringPtr dest)
  315. {
  316.     xtnd80        x80 = {0,{0,0,0,0}} ;
  317.     x80.man[0] = HiWord(num) ;
  318.     x80.man[1] = LoWord(num) ;
  319.     x80.exp = 0x4000 + 32 - 2 ;        // 16414
  320.     return FormatExtd80( (extended80*)&x80, formatID, dest ) ;
  321. }
  322.  
  323.  
  324. /*------------------------------------------------------------------------------*\
  325.     FormatFixed
  326.  *------------------------------------------------------------------------------*
  327.         This routine converts a Fixed number into a pascal string using
  328.         a 'FMAT' resource and the ExtendedToString() call so that the resulting
  329.         string will be formatted accrding to the user's setting in the Numbers
  330.         control panel.  It does this by converting the Fixed into an extended80
  331.         and then calling FormatExtd80.
  332.         It assumes that the dest string (which can be up to 255 chars)
  333.         is long enough to hold the result.
  334. \*------------------------------------------------------------------------------*/
  335. OSErr FormatFixed ( Fixed num, short formatID, StringPtr dest)
  336. {
  337.     xtnd80        x80 = {0,{0,0,0,0}} ;
  338.     x80.man[0] = HiWord(num) ;
  339.     x80.man[1] = LoWord(num) ;
  340.     x80.exp = 0x4000 + 16 - 2 ;        // 16398
  341.     return FormatExtd80( (extended80*)&x80, formatID, dest ) ;
  342. }
  343.  
  344.  
  345. /*------------------------------------------------------------------------------*\
  346.     FormatSmallFract
  347.  *------------------------------------------------------------------------------*
  348.         This routine converts a SmallFract number into a pascal string using
  349.         a 'FMAT' resource and the ExtendedToString() call so that the resulting
  350.         string will be formatted accrding to the user's setting in the Numbers
  351.         control panel.  It does this by converting the SmallFract into an extended80
  352.         and then calling FormatExtd80.
  353.         It assumes that the dest string (which can be up to 255 chars)
  354.         is long enough to hold the result.
  355. \*------------------------------------------------------------------------------*/
  356. OSErr FormatSmallFract ( short num, short formatID, StringPtr dest)
  357. {
  358.     xtnd80        x80 = {0,{0,0,0,0}} ;
  359.     x80.man[0] = num;
  360.     x80.exp = 0x4000 + 1 - 2 ;        // 16384
  361.     return FormatExtd80( (extended80*)&x80, formatID, dest ) ;
  362. }
  363.  
  364.  
  365.