[comp.sys.mac.programmer] Writing resources to a file

dhare%integral@Sun.COM (Dwight Hare) (04/30/88)

I am writing resources to files for the first time.  The interface for
this is extremely clumsy.  In short, I do the following:

1) Do a GetFInfo of the file to see if it already exists
2) if it doesn't, do a PBCreate
3) do an openresfile of the file
4) do a Get1Resource of the resource I intend to write
5) if the get fails, allocate a handle and do an AddResource
6) change the resource
7) call ChangedResource with the resource
8) do a CloseResFile.

Two questions:  Is this right?  Do I need to deallocate the handles if I
allocated them, and if so, how? (DisposHandle or DisposeResource?)

Thanks,
Dwight

markw@kinetics.UUCP (Mark Wittenberg) (05/05/88)

From article <51379@sun.uucp>, by dhare%integral@Sun.COM (Dwight Hare):
> I am writing resources to files for the first time.  The interface for
> this is extremely clumsy.  In short, I do the following:
> 
> 1) Do a GetFInfo of the file to see if it already exists
> 2) if it doesn't, do a PBCreate
> 3) do an openresfile of the file
> 4) do a Get1Resource of the resource I intend to write
> 5) if the get fails, allocate a handle and do an AddResource
> 6) change the resource
> 7) call ChangedResource with the resource
> 8) do a CloseResFile.
> 
> Two questions:  Is this right?  Do I need to deallocate the handles if I
> allocated them, and if so, how? (DisposHandle or DisposeResource?)
> 
> Thanks,
> Dwight

You must DisposeResource, not DisposHandle.  The latter will cause a later
NewHandle (the next one?) to appear to be a resource ... with interesting
consequences.  BTW, if the Get1Resource succeeds I usually just RemoveResource
it, and then always AddResource.  Be careful that your output resource file
isn't currently open (mustn't close it if it is -- like, the system, your
application, ...).  If you're running on the old ROMs and don't have
Get1Resource, you have to use GetResource and check to see if it's in the
right resource file.  If not, you have to DisposeResource it UNLESS it had
already been gotten.

So, we have two open questions:

1.  How do you tell if a resource file is already open?
    OK, I know you can run through the FCB list, but this doesn't seem like
    a very good idea, from the compatibility point of view.
2.  How do you tell if a resource has already been loaded?  I'd prefer to know
    without loading it, but I'll settle for just knowing whether or not I
    should unload it.  It's not sufficient to call SetResLoad(FALSE) before
    the GetResource, and check to see if the handle was NULL.

Any answers out there?


Mark Wittenberg
Kinetics, Inc.
2500 Camino Diablo
Walnut Creek, CA 94596
(415) 945-3645
UUCP: ucbvax!mtxinu!kinetics!markw

oster@dewey.soe.berkeley.edu (David Phillip Oster) (05/08/88)

In article <600@kinetics.UUCP> markw@kinetics.UUCP (Mark Wittenberg) writes:
>1.  How do you tell if a resource file is already open?
>    OK, I know you can run through the FCB list, but this doesn't seem like
>    a very good idea, from the compatibility point of view.
Well, one easy way to do it is, before opening the file with
OpenResFile(), try opening it with PBOpenRF(). If it is already open,
since you are opening it for read/write you get back the vRef of the
existing access path and an "already open" error code. Close the file in
either case and open it with OpenResFile().  There probably is a better
way to solve this problem.

Another good thing to do is forbid you r application to open files of type
ZSYS or APPL. (This makes sense for many applications like MacPaint or
MacWrite, but not for applications like ResEdit.)  That way, when the
reviewer from InfoWorld trys to save-as on top of his System file, your
prgram won't clobber it. (They are beginning to give programs demerits
that don't include this bit of foolproofing.)

>2.  How do you tell if a resource has already been loaded?  I'd prefer to know
>    without loading it, but I'll settle for just knowing whether or not I
>    should unload it.  It's not sufficient to call SetResLoad(FALSE) before
>    the GetResource, and check to see if the handle was NULL.
Why isn't this sufficient? According to the Resource manager
documentation, this should work just fine.  (Though, for this application
you may want to use Get1Resource()).

--- David Phillip Oster            --When you asked me to live in sin with you
Arpa: oster@dewey.soe.berkeley.edu --I didn't know you meant sloth.
Uucp: {uwvax,decvax,ihnp4}!ucbvax!oster%dewey.soe.berkeley.edu

kaufman@polya.STANFORD.EDU (Marc T. Kaufman) (05/08/88)

In article <600@kinetics.UUCP> markw@kinetics.UUCP (Mark Wittenberg) writes:

>2.  How do you tell if a resource has already been loaded?  I'd prefer to know
>    without loading it, but I'll settle for just knowing whether or not I
>    should unload it.  It's not sufficient to call SetResLoad(FALSE) before
>    the GetResource, and check to see if the handle was NULL.

Why is this?  (since I seem to remember seeing the technique in some Tech
Note or other).  [actually you look for Handle^ being NIL, not Handle.
If Handle is NIL, there is no such resource.  If Handle^ is NIL, the
resource exists but was not loaded.  If the resource is already loaded,
Handle^ will point to it even if SetResLoad is FALSE -- or so I thought].

Marc Kaufman (kaufman@polya.stanford.edu)

han@Apple.COM (Byron Han) (05/09/88)

In article <600@kinetics.UUCP> markw@kinetics.UUCP (Mark Wittenberg) writes:
>
>You must DisposeResource, not DisposHandle.  The latter will cause a later

ReleaseResource, NOT DisposeResource.


-- 
Byron Han,  Communications Tool            "OS/2 - Half of an operating system."
Apple Computer, Inc. MS 27Y                -------------------------------------
ATTnet:408-973-6450     applelink:HAN1     domain:han@apple.COM       MacNET:HAN
GENIE:BYRONHAN    COMPUSERVE:72167,1664    UUCP:{sun,voder,nsc,decwrl}!apple!han

lsr@Apple.COM (Larry Rosenstein) (05/11/88)

In article <51379@sun.uucp> dhare@sun.UUCP (Dwight Hare) writes:
>
>1) Do a GetFInfo of the file to see if it already exists
>2) if it doesn't, do a PBCreate
>3) do an openresfile of the file

There are 2 things wrong here.

First, on the Hierarchical File System, certain calls (including GetFInfo)
will automatically search the System Folder if the file is not found in the
first place you specify.  So step 1 could actually find a file with the same
name in the System Folder.

You can always suppress the searching by specifying a dirID and using the
HFS-specific calls (eg, PBHGetFInfo).  

In this particular case, you can also do the Create first, and look at the
result.  Create does not use the search path.  If Create returns an
dupFNErr, then the file exists.

The second problem is that after the Create, you have to call CreateResFile.
CreateResFile initializes the resource fork, which is different than a
resource fork with nothing in it.

>Two questions:  Is this right?  Do I need to deallocate the handles if I
>allocated them, and if so, how? (DisposHandle or DisposeResource?)

There is no DisposeResource.  ReleaseResource frees the data taken by a
resource.  DetachResource disassociates a handle from its resource file, but
doesn't free the storage.  (Such a handle could be added to another resource
file, and should be freed with a call to DisposHandle.)

-- 
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 27-AJ  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr

markw@kinetics.UUCP (Mark Wittenberg) (05/12/88)

From article <9415@apple.Apple.Com>, by han@Apple.COM (Byron Han):
> In article <600@kinetics.UUCP> markw@kinetics.UUCP (Mark Wittenberg) writes:
>>
>>You must DisposeResource, not DisposHandle.  The latter will cause a later
> 
> ReleaseResource, NOT DisposeResource.
> 
> 
> -- 
> Byron Han,  Communications Tool            "OS/2 - Half of an operating system."
Yeah, I wrote that from memory, and noticed my mistake later; I figured
everyone would know what I meant, though.

Mark Wittenberg

lsr@Apple.COM (Larry Rosenstein) (05/26/88)

In article <23980@ucbvax.BERKELEY.EDU> oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster) writes:
>In article <600@kinetics.UUCP> markw@kinetics.UUCP (Mark Wittenberg) writes:
>>1.  How do you tell if a resource file is already open?
>Well, one easy way to do it is, before opening the file with
>OpenResFile(), try opening it with PBOpenRF(). If it is already open,
>since you are opening it for read/write you get back the vRef of the
>existing access path and an "already open" error code. Close the file in

Tech Note 185 mentions a problem with this under MultiFinder.  The the file
is opened by another process and you ask for read/write permission (or use
OpenResFile) then you will get back -1 as the refnum and ResError will be
-49.  You need to check for this case as well.

I think you can also do a PBGetFInfo, since that returns the refnum of an
access path if the file is open.  (I don't think it distinguishes the data
and resource forks.)  Also, on 64K ROMs, I think you have to zero the refnum
field before the call.

-- 
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 27-AJ  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr