home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / code / c_addstr.sit < prev    next >
Encoding:
Text File  |  1988-06-20  |  4.7 KB  |  132 lines

  1. 18-Jun-88 14:23:29-MDT,4941;000000000001
  2. Return-Path: <u-lchoqu%sunset@cs.utah.edu>
  3. Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:23:21 MDT
  4. Received: by cs.utah.edu (5.54/utah-2.0-cs)
  5.     id AA22081; Sat, 18 Jun 88 14:23:24 MDT
  6. Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
  7.     id AA24478; Sat, 18 Jun 88 14:23:20 MDT
  8. Date: Sat, 18 Jun 88 14:23:20 MDT
  9. From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
  10. Message-Id: <8806182023.AA24478@sunset.utah.edu>
  11. To: rthum@simtel20.arpa
  12. Subject: AddSTRInd.c
  13.  
  14. /************************************************************************
  15. In article <6554@jade.BERKELEY.EDU>,
  16.         jmm@thoth6.berkeley.edu.BERKELEY.EDU writes:
  17. > How does one add strings onto the end of a STR# resource from
  18. >               inside a program?
  19.  
  20. There is no ToolBox call to do this (correct me if I am wrong) so you have
  21. to do the following:
  22.         a)  Resize the handle to the resource.
  23.         b)  Manipulate the STR# resource data structure to make desired
  24.             changes.
  25.         c)  Write out the modified resource.
  26.  
  27. My printer driver article (MacTutor, December, 1987) gives an example of
  28. changing the contents of a string list, which is not very far different from
  29. this problem.  If you have it, you can just modify that code for the task
  30. (it's on page 62).
  31.  
  32. A string list is composed of a WORD which contains the number of strings
  33. in the list, followed by that number of Pascal strings, lined up one after
  34. the other.  (A WORD is a two-byte integer.)  The length of the string list in
  35. memory is found from the formula:
  36.  
  37. String_list_length = 2 + value_of_header_word + sum_of_length_bytes + PAD
  38.  
  39. 2 accounts for the header word, the value of the header word accounts for
  40. the length bytes, and the sum of the length bytes accounts for the actual
  41. string characters.  A conservative value for "PAD" is 24.  The first byte of 
  42. a Pascal string gives the length in characters of the rest of the string.
  43.  
  44. The following code will illustrate how we:
  45.         a)  Read in the string list from disk.
  46.         b)  Determine the desired new handle size.
  47.         c)  Modify the string list to contain another string.
  48.         d)  Write out the modified string list.
  49.  
  50. The example is in LightSpeedC, where an 'int' is worth 2 bytes.
  51. If you want to test the example program, put it in a project, add
  52. a string list, ID #100, with ResEdit or something, and run it a 
  53. few times to see what you get.  You don't need any libraries.
  54. ************************************************************************/
  55.  
  56. typedef struct{
  57.     unsigned int len;
  58.     unsigned char text[1];
  59. }stringlist,*pStrLst,**hStrLst;
  60. #define nil 0L
  61. #define FALSE 0
  62. #define TRUE  1
  63. #define PAD 24
  64. /*
  65.  * Tacks another Pascal string onto the end of a string list.
  66.  * Returns FALSE on error, TRUE on success.  Could check for more
  67.  * errors!
  68.  */
  69. int tackstring(idnum,newstr)
  70. int     idnum;
  71. unsigned char *newstr;
  72. {
  73.         hStrLst   TheList;
  74.         unsigned char *strptr;
  75.         int     numstrings,i;
  76.         long    length,result;
  77.         TheList = (hStrLst)GetResource('STR#',idnum);
  78.         if (TheList == nil) return FALSE;    /* Error handler time! */
  79.         LoadResource(TheList);
  80.         asm{
  81.             move.l    TheList,a0    ; I'm doing this so I don't
  82.             HLock            ; need the MacTraps library.
  83.         }
  84.         numstrings = (**TheList).len;    /* How many? */
  85.         strptr = &(**TheList).text[0];    /* Point to first one. */
  86.         length = 2 + PAD + numstrings;    /* Compute the length. */
  87.         for(i = numstrings; i-- ; ){
  88.             length += *(strptr += (*strptr) +1);
  89.         }
  90.            /* Now we point at one past the end. */
  91.         length += *newstr;        /* Allow for expansion. */
  92.         /* Resize the handle, error could occur here! */
  93.         asm{
  94.             move.l    TheList,a0    ;MM calls use regs.
  95.             move.l    length,d0    ;Resize the handle.
  96.             SetHandleSize
  97.             move.l    TheList,a0    ;How much did we get?
  98.             GetHandleSize
  99.             move.l    d0,result    ;Tell C.
  100.         }
  101.         if( result != length) return FALSE;    /* Error, give up. */
  102.         pstrcpy(strptr,newstr);        /* Tack on the new one. */
  103.         (**TheList).len++;        /* Don't forget to say one more. */
  104.         ChangedResource(TheList);    /* Tell the Mac. */
  105.         WriteResource(TheList);        /* Write out the resource. */
  106.         return TRUE;
  107. }
  108. pstrcpy(dst,src)    /* Copy a pascal string, simple. */
  109. unsigned char *src,*dst;
  110. {
  111.     asm{
  112.         clr.l    d0
  113.         move.l    src,a0
  114.         move.l    dst,a1
  115.         move.b    (a0),d0
  116. loop:
  117.         move.b    (a0)+,(a1)+
  118.         dbra    d0,@loop
  119.     }
  120. }
  121. /*
  122.  * Very boring main() program.  I assume you have a more interesting one
  123.  * than this!
  124.  */
  125. main(){
  126.     tackstring(100,"\pNew Test String");
  127. }
  128.  
  129. /********************************************************************
  130. *Earle R. Horton, H.B. 8000, Dartmouth College, Hanover, NH 03755   *
  131. ********************************************************************/
  132.