[comp.sys.mac.programmer] Resource Fork data storage--related question

MAYER-A@RICEVM1.BITNET (David Mayer) (07/20/90)

In article <1990Jul17.172044.20361@Neon.Stanford.EDU>, commons@Sunburn.Stanford.EDU (Peter Commons) says:
>
>I'm currently working on a new multi-user game for the Mac. In thinking about
>how I would like my save file to look, it would be very convenient to have
>one resource with the main data and one resource with the data for each player
>(rather than have all the data sequentially laid out in the data fork) because
>the game will only need to look at one player's info at a time.
>
>Can I do this? If so, should I use my own (non-reserved) resource name? And if
>I define my own resource type, how do I specify it's length (or does it
>automatically make it as long as the handle I pass it when I call AddResource?
>
>Thanks in advance.


WELL,

I have a related question. It may be more of a Pascal question than a
Macintosh question, though.  I would like to retrieve the contents
of a (rather long) array.  A resource of my own type seems
like a logical structure for this.

I know how to load a resource into memory, but I don't see how then to
store the contents into an array I've declared...

I would appreciate any suggestions or better ideas.  Thanks!

    --David

souka@uh.msc.umn.edu (Omar Souka) (07/20/90)

> WELL,
> 
> I have a related question. It may be more of a Pascal question than a
> Macintosh question, though.  I would like to retrieve the contents
> of a (rather long) array.  A resource of my own type seems
> like a logical structure for this.
> 
> I know how to load a resource into memory, but I don't see how then to
> store the contents into an array I've declared...
> 
> I would appreciate any suggestions or better ideas.  Thanks!
> 
>     --David

The resource fork is a great place to store nearly any type of data. 
Here is a sketch of what many programs do.

1.  Create a new resource in Resedit.  It doesn't have to have anything
in it right now but a name (try to make the name unique) and a resource number.

Writing to the resource.

1.  Call GetResource to get a handle to your resource.

2.  If its the first time that your writing to it, you must call
SizeHandle to increase the size of the handle to the size of whatever
you are going to store.

3.  Then simply BlockMove the contents of your data structure into the
resource.  In C, it would look something like this:

	BlockMove(array,*ResourceHandle,number_of_bytes);
			or generically
	BlockMove(source pointer, destination pointer, # of bytes)

This operation will stick the raw bytes of your array into your resource.

4.  Call ChangedResource

5.  Call WriteResource

Reading from the resource

1.  Call GetResource

2.  If you need to know how big the handle is call HandleSize

3.  BlockMove from the resource into your array

	BlockMove(*ResourceHandle,array,number_of_bytes);

In Pascal it would look something like this (just a guess, I don't do Pascal)

	BlockMove(ResourceHandle^,@array,number_of_bytes)

What's great about this technique is that you can store very complicated
data structures this way and not really worry about what the structure
looks like.  If anyone is interested in seeing some actual source, just
E-Mail me.

philip@Minnie.Stanford.EDU (Philip Machanick) (07/23/90)

In article <2172@uc.msc.umn.edu>, souka@uh.msc.umn.edu (Omar Souka) writes:
> > I have a related question. It may be more of a Pascal question than a
> > Macintosh question, though.  I would like to retrieve the contents
> > of a (rather long) array.  A resource of my own type seems
> > like a logical structure for this.
> > 
> > I know how to load a resource into memory, but I don't see how then to
> > store the contents into an array I've declared...
> > 
> > I would appreciate any suggestions or better ideas.  Thanks!
[...]
> Reading from the resource
> 
> 1.  Call GetResource
> 
> 2.  If you need to know how big the handle is call HandleSize
> 
> 3.  BlockMove from the resource into your array
> 
> 	BlockMove(*ResourceHandle,array,number_of_bytes);
> 
> In Pascal it would look something like this (just a guess, I don't do Pascal)
> 
> 	BlockMove(ResourceHandle^,@array,number_of_bytes)
> 
Why not store the result of GetResource directly into the array? You would
have to use the array through a handle, e.g., in Pascal:
  type
    arrayPtr = ^arrayType;
    arrayHdl = ^arrayPtr;
  var
    data : arrayHdl;
  begin
    data := arrayHdl(GetResource(...));

Saves you a blockmove (why copy data unnecessarily?).

Philip Machanick
philip@pescadero.stanford.edu

boerned@mist.CS.ORST.EDU (Dan Boerner) (07/23/90)

In his response Philip asks 

> Why not store the result of GetResource directly into the array? 

I believe the answer is that GetResource allocates memory for a resource only
once.  The second time you call GetResource, it will return a handle to the
same memory block as it did the first time.  Therefore, you must copy the
results of GetResource into a different block of memory for each different
copy of the resource you want.  

Dan Boerner
boerned@cs.orst.edu
Oregon State University

sstorkel@dvlseq.oracle.com (Scott Storkel) (07/24/90)

In article <19475@orstcs.CS.ORST.EDU> boerned@mist.CS.ORST.EDU (Dan Boerner) writes:

>In his response Philip asks 
>
>> Why not store the result of GetResource directly into the array? 
>
>I believe the answer is that GetResource allocates memory for a resource only
>once.  The second time you call GetResource, it will return a handle to the
>same memory block as it did the first time.  Therefore, you must copy the
>results of GetResource into a different block of memory for each different
>copy of the resource you want.  
>

Sorry for jumping into the middle of this discussion. Did somebody say
something about multiple uses? The correct way to do what Philip
suggests is to call DetachResource and then use the handle as a handle
to an array. By calling DetachResource, you make the resource manager
"forget" about the resource. That way you could call GetResource again
to get a new copy of the resource (don't know why you'd want to do
that) and the resource manager won't release the memory out from under
you (if you close the resource file for example).


-- Scott Storkel