🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.mac
Article #23651

Re: Adding to STR# resources

#23651
From: Earle R. Horton
Date: Fri, 15 Jan 1988 08:02
118 lines
4793 bytes
In article <6554@jade.BERKELEY.EDU>,
>        jmm@thoth6.berkeley.edu.BERKELEY.EDU writes:
> How does one add strings onto the end of a STR# resource from
>               inside a program?

----------------------cut here----------------------
/*	(Sorry if you wanted Pascal.)
There is no ToolBox call to do this (correct me if I am wrong) so you have
to do the following:
        a)  Resize the handle to the resource.
        b)  Manipulate the STR# resource data structure to make desired
            changes.
        c)  Write out the modified resource.

My printer driver article (MacTutor, December, 1987) gives an example of
changing the contents of a string list, which is not very far different from
this problem.  If you have it, you can just modify that code for the task
(it's on page 62).

A string list is composed of a WORD which contains the number of strings
in the list, followed by that number of Pascal strings, lined up one after
the other.  (A WORD is a two-byte integer.)  The length of the string list in
memory is found from the formula:

String_list_length = 2 + value_of_header_word + sum_of_length_bytes + PAD

2 accounts for the header word, the value of the header word accounts for
the length bytes, and the sum of the length bytes accounts for the actual
string characters.  A conservative value for "PAD" is 24.  The first byte of 
a Pascal string gives the length in characters of the rest of the string.

The following code will illustrate how we:
        a)  Read in the string list from disk.
        b)  Determine the desired new handle size.
        c)  Modify the string list to contain another string.
        d)  Write out the modified string list.

The example is in LightSpeedC, where an 'int' is worth 2 bytes.
If you want to test the example program, put it in a project, add
a string list, ID #100, with ResEdit or something, and run it a 
few times to see what you get.  You don't need any libraries.
*/
typedef struct{
	unsigned int len;
	unsigned char text[1];
}stringlist,*pStrLst,**hStrLst;
#define nil 0L
#define FALSE 0
#define TRUE  1
#define PAD 24
/*
 * Tacks another Pascal string onto the end of a string list.
 * Returns FALSE on error, TRUE on success.  Could check for more
 * errors!
 */
int tackstring(idnum,newstr)
int     idnum;
unsigned char *newstr;
{
        hStrLst   TheList;
        unsigned char *strptr;
        int     numstrings,i;
        long	length,result;
        TheList = (hStrLst)GetResource('STR#',idnum);
        if (TheList == nil) return FALSE;	/* Error handler time! */
        LoadResource(TheList);
        asm{
        	move.l	TheList,a0	; I'm doing this so I don't
        	HLock			; need the MacTraps library.
        }
        numstrings = (**TheList).len;	/* How many? */
        strptr = &(**TheList).text[0];	/* Point to first one. */
        length = 2 + PAD + numstrings;	/* Compute the length. */
        for(i = numstrings; i-- ; ){
        	length += *(strptr += (*strptr) +1);
        }
       	/* Now we point at one past the end. */
        length += *newstr;		/* Allow for expansion. */
        /* Resize the handle, error could occur here! */
        asm{
        	move.l	TheList,a0	;MM calls use regs.
        	move.l	length,d0	;Resize the handle.
        	SetHandleSize
        	move.l	TheList,a0	;How much did we get?
        	GetHandleSize
        	move.l	d0,result	;Tell C.
        }
        if( result != length) return FALSE;	/* Error, give up. */
        pstrcpy(strptr,newstr);		/* Tack on the new one. */
        (**TheList).len++;		/* Don't forget to say one more. */
        ChangedResource(TheList);	/* Tell the Mac. */
        WriteResource(TheList);		/* Write out the resource. */
        return TRUE;
}
pstrcpy(dst,src)	/* Copy a pascal string, simple. */
unsigned char *src,*dst;
{
	asm{
		clr.l	d0
		move.l	src,a0
		move.l	dst,a1
		move.b	(a0),d0
loop:
		move.b	(a0)+,(a1)+
		dbra	d0,@loop
	}
}
/*
 * Very boring main() program.  I assume you have a more interesting one
 * than this!
 */
main(){
	tackstring(100,"\pNew Test String");
}
-- 
*********************************************************************
*Earle R. Horton, H.B. 8000, Dartmouth College, Hanover, NH 03755   *
*********************************************************************
Technical Details
Message-ID: <7927@eleazar.Dartmouth.EDU>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!water!watmath!clyde!rutgers!gatech!mcnc!decvax!dartvax!eleazar!earleh
References: <6554@jade.BERKELEY.EDU>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!water!watmath!clyde!rutgers!gatech!mcnc!decvax!dartvax!eleazar!earleh
From: earleh@eleazar.Dartmouth.EDU (Earle R. Horton)
Newsgroups: comp.sys.mac
Subject: Re: Adding to STR# resources
Summary: This works.
Message-ID: <7927@eleazar.Dartmouth.EDU>
Date: 15 Jan 88 08:02:23 GMT
References: <6554@jade.BERKELEY.EDU>
Organization: Dartmouth College, Hanover, NH
Lines: 118