home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / sys / mac / programm / 15114 < prev    next >
Encoding:
Internet Message Format  |  1992-09-08  |  4.3 KB

  1. Path: sparky!uunet!wupost!waikato.ac.nz!ldo
  2. From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  3. Newsgroups: comp.sys.mac.programmer
  4. Subject: Re: Is a resource fork already open?
  5. Message-ID: <1992Sep8.153520.10687@waikato.ac.nz>
  6. Date: 8 Sep 92 15:35:20 +1200
  7. References: <39464@imag.imag.fr>
  8. Organization: University of Waikato, Hamilton, New Zealand
  9. Lines: 113
  10.  
  11. In article <39464@imag.imag.fr>, cinquin@imag.fr ( Philippe Cinquin) writes:
  12. > Sorry if this is a stupid question, but how do you know if the resource fork of
  13. > a file is already open?
  14.  
  15. If a file is already open by somebody else, you'll get an error if you try
  16. opening it in a mode that's incompatible with the other person's open mode.
  17.  
  18. But I suspect you're really asking what happens when you open a resource file
  19. twice from the same application. The answer is, you will get the same file
  20. refnum back the second time. So how do you tell that this is happened? It can
  21. be done, without too much low-level messing about.
  22.  
  23. The Resource Manager maintains a chain of currently-open resource files.
  24. It loads the "resource map" structure from each file into memory, and fills
  25. in a link field to chain all the resource maps together. There are two
  26. important low-memory globals that are used for this:
  27.  
  28.     TopMapHndl -- handle to the first resource map in the chain
  29.     CurMap -- refnum of the "current" resource file (returned by
  30.         CurResFile, can be changed with UseResFile to point anywhere
  31.         along the chain).
  32.  
  33. Supposing the state of your resource chain is like this:
  34.  
  35.     TopMapHndl --> map for res file 2 --> map for res file 1
  36.     CurMap -- don't care
  37.  
  38. And you open resource file 3, which wasn't previously open. The resource
  39. chain now becomes this:
  40.  
  41.     TopMapHndl --> map for res file 3 --> map for res file 2 -->
  42.                           map for res file 1
  43.     CurMap -- iorefnum for res file 3
  44.  
  45. If, on the other hand, you try reopening res file 2, you get this
  46. situation:
  47.  
  48.     TopMapHndl --> map for res file 2 --> map for res file 1
  49.     CurMap -- iorefnum for res file 2
  50.  
  51. And if you try reopening res file 1, you get this:
  52.  
  53.     TopMapHndl --> map for res file 2 --> map for res file 1
  54.     CurMap -- iorefnum for res file 1
  55.  
  56. In summary:
  57.  
  58.     * If you open a resource file that wasn't previously open, its
  59.       resource map gets prepended to the top of the chain, and TopMapHndl
  60.       is set to point to it.
  61.     * If you reopen a resource file that was already open, TopMapHndl
  62.       is unchanged.
  63.     * Every time you open a resource file, whether it was previously open
  64.       or not, CurMap is updated to hold the iorefnum of that resource file.
  65.  
  66. So here's how to tell, when you open a resource file, whether you really
  67. opened it or not. First, some useful definitions (this is all in Modula-2,
  68. by the way):
  69.  
  70.     TYPE
  71.     IORefNum = INTEGER;
  72.  
  73.     PROCEDURE GetTopMapHndl() : (*Handle*) ADDRESS;
  74.      (* returns the current value of TopMapHndl global. *)
  75.  
  76.     CODE
  77.         02EB8H, 00A50H; (* move.l TopMapHndl, (sp) *)
  78.  
  79.     PROCEDURE GetTopMap() : IORefNum;
  80.       (* returns the reference number of the last-opened resource file. *)
  81.  
  82.     VAR
  83.         TempHandle : Handle;
  84.         TempPtr : POINTER TO IORefNum;
  85.  
  86.     BEGIN
  87.     TempHandle := GetTopMapHndl();
  88.     TempPtr := TempHandle^ + 20;
  89.     RETURN
  90.         TempPtr^
  91.     END GetTopMap;
  92.  
  93. Now here's an example code fragment that opens a resource file:
  94.  
  95.       (* get information about current state of resource chain *)
  96.     PreviousResFile := CurResFile();
  97.     PreviousTop := GetTopMap();
  98.  
  99.       (* open resource file with OpenResFile, OpenRFPerm or whatever, e g *)
  100.     TheResFile := OpenRFPerm(FileName, VRefNum, Permission);
  101.  
  102.     ReallyOpened :=
  103.         (TheResFile = GetTopMap())
  104.         AND
  105.         (TheResFile <> PreviousTop)
  106.  
  107. And to close the resource file (but only if it was really opened by you) and
  108. leave things the way they were before:
  109.  
  110.     IF ReallyOpened THEN
  111.         CloseResFile(TheResFile)
  112.     END (*IF*);
  113.     UseResFile(PreviousResFile)
  114.  
  115. I have successfully used this code to do things to my running system file.
  116. And I haven't had a crash yet. crash yet. crash yet.
  117.  
  118. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  119. Computer Services Dept                     fax: +64-7-838-4066
  120. University of Waikato            electric mail: ldo@waikato.ac.nz
  121. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  122. "Well, perhaps that is because Apple has not yet released any future versions
  123. of the System software." -- Amanda Walker
  124.