[comp.sys.apple] GS/OS file copying

JWANKERL@UTCVM.BITNET ("Josef W. Wankerl") (11/18/89)

     I am in the process of writing a program in assembly language that
will be able to copy GS/OS extended files.  I want to be able to copy
either the data fork, resource fork, or both.  I've run into a blank wall
on a few major points so I'm about to list a few technical questions.
Oh yeah, my GS/OS reference book is not the Apple one(s), it's Gary
Litle's Exploring Apple GS/OS and ProDOS 8.  So here are a few questions:

 * How would I go about allocating memory for the copy?  I have an idea to
find the maximum block size and if it's not enough then compact memory and
try again, and if it's still not enough then I'll have to ask for the new
maximum block size and then read in chunks of that size.  I haven't done
this yet because I think there might be a beter way.  Is there?

 * How do I actually copy the file?  I seem to remember a few messages back
an algorithm to OPEN source file data READ source file data CREATE target file
Write target file data CLOSE source file data OPEN source file resource
READ source file resource CLOSE source file resource OPEN target file resource
WRITE target file resource SETFILEINFO on target file CLOSE target resource
CLOSE target data.  Is that even close?  I think I remember you have to have
the target file open and set the file attributes when it's open because
when it is closed on an AppleTalk drop folder then it's not accessable
anymore.  Will my algorithm work correctly?

If you know the answers to any or all of the above questions, please
let me know as I'm anxious to finish up my project and move on to
another part of it.

Oh yes, one more question before I go (not related to file copying)

 * Is there a method for a NDA to open some windows that are controlled
by the NDA?  I don't believe I've ever seen this done before so I'm not
sure if it can be.  I guess I'd have to make the window a system window
but I'm now sure how things would react if the application it's running
under closes it.  Any answers to this one, either?

  -Gonzo

/**********************************************************************\
|*      Joe "Gonzo" Wankerl       |*|  The views expressed here are   *|
|* BITNET =>  JWANKERL@UTCVM      |*|  not necessarily yours...       *|
|*                                |*|         ...but they should be.  *|
\**********************************************************************/

mattd@Apple.COM (Matt Deatherage) (11/19/89)

JWANKERL@UTCVM.BITNET ("Josef W. Wankerl") writes:

(I deleted some attribution to make that line less than 80 columns, but it's
going to take some time for me to get used to INFO-APPLE messages posted
to comp.sys.apple as XXXXXX@apple.com!)

>     I am in the process of writing a program in assembly language that
>will be able to copy GS/OS extended files.  I want to be able to copy
>either the data fork, resource fork, or both.  I've run into a blank wall
>on a few major points so I'm about to list a few technical questions.
>Oh yeah, my GS/OS reference book is not the Apple one(s), it's Gary
>Litle's Exploring Apple GS/OS and ProDOS 8.  So here are a few questions:
>

No, no you don't.  If you are *copying* files (and not manipulating them),
you want to copy them exactly as they are.  Only programmers have an interest
in merging or changing resource and data forks, and if users try it the
results could be disastrous.  APW already has a "duplicate" tool which will
do this for programmers, so unless you're writing something similar (or more
powerful), I suggest you exactly duplicate the file to avoid lots of problems.

I've said before (and will probably say again) ... don't be writing programs
you're going to release without Apple's manuals.  Gary Little's book is a
very fine book and a great tutorial (my actions as technical editor for it and
my name in the preface have nothing to do with this endorsement :), but it can
*not* replace Apple manuals for guaranteed advice and information.  Fo
example, Gary lists some things about the ProDOS 8 global page which are true
but are not guaranteed (like the fact that QUIT currently vectors throug
JSPARE at $BF03).  If you release a program that depends on this, you're going
to regret it in a big way when Apple uses that vector for something else an
your program patches it out.  So get the GS/OS Reference.

> * How would I go about allocating memory for the copy?  I have an idea to
>find the maximum block size and if it's not enough then compact memory and
>try again, and if it's still not enough then I'll have to ask for the new
>maximum block size and then read in chunks of that size.  I haven't done
>this yet because I think there might be a beter way.  Is there?

I would venture there's really no need to compact memory.  This could give
you lots of things you don't want, like kicking out the disk cache or at least
the purgeable blocks within it.  Just use _MaxBlock to find out what th
biggest chunk currently available is, subtract about 10K from it for GS/OS
overhead (if necessary) and use that.

> * How do I actually copy the file?  I seem to remember a few messages back
>an algorithm to OPEN source file data READ source file data CREATE target file
>Write target file data CLOSE source file data OPEN source file resource
>READ source file resource CLOSE source file resource OPEN target file resource
>WRITE target file resource SETFILEINFO on target file CLOSE target resource
>CLOSE target data.  Is that even close?  I think I remember you have to have
>the target file open and set the file attributes when it's open because
>when it is closed on an AppleTalk drop folder then it's not accessable
>anymore.  Will my algorithm work correctly?
>

Carriage returns would definitely help between steps.  :)

Try this, using Class 1 GS/OS calls.

1.  OPEN source file with extended parameters, basically doing a GetFileInfo
    for you at the same time.  Be sure to open BOTH FORKS at this time, which
    will give you two reference numbers after two OPEN calls.

2.  CREATE target file, with or without extended parameters (this is explained
    later).

3.  OPEN destination file -- BOTH FORKS.  The trick is in an AppleShare Drop
    Folder, you can't open a file (or a fork) if either fork has any data in
    it.  So open them both while both forks are still empty.

4.  READ source fork #1 (in chunks as necessary).

5.  WRITE destination fork #1 (in chunks as necessary).

Loop between #4 and #5 until fork #1 is fully copied.

6.  READ source fork #2 (in chunks as necessary).

7.  WRITE destination fork #2 (in chunks as necessary).

Loop between #6 and #7 until fork #2 is fully copied.

8.  [optional]  Using the parameters from the OPEN in step #1, do a SET FIL
    INFO (actually "SetFileInfo", but I've been using all caps) to set the
    parameters of the copied file.

    You can use the CREATE call in step 2 to set the parameters of the
    destination file, but the "modified" date of the destination will become
    the present date and time, not the time the contents of the file were last
    modified.  Also note that if you do a SetFileInfo on an open file, GS/OS
    does not guarantee that GetFileInfo will return the correct results until
    you close the file.

9.  CLOSE all four open forks.

The file is now copied.  When copying the extended parameters (using Open or
Create or SetFileInfo), be *sure* to include the GS/OS option_list field for
future file system compatibility.  See GS/OS Technical Note #4.  Also, if you
know what you're doing, you can use GS/OS sessions to speed multiple file
copies dramatically.  See GS/OS Reference for more details.

> * Is there a method for a NDA to open some windows that are controlled
>by the NDA?  I don't believe I've ever seen this done before so I'm not
>sure if it can be.  I guess I'd have to make the window a system window
>but I'm now sure how things would react if the application it's running
>under closes it.  Any answers to this one, either?
>
It is not possible (to my knowledge; if it is, it's DEFINITELY not supported)
for an NDA to have more than one modeless window open at once.  A DA can put
up a modal dialog (using the Dialog Manager or, preferably, not), but it can't
have more than one "normal" modeless, movable window.  (And for the people
who keep asking this, stop trying to make your one NDA window a modeless
dialog.  :)

>  -Gonzo

-- 
-----------------------------------------------------------------------------
Matt Deatherage, Apple Computer, Inc. | "The opinions expressed in this tome
Send PERSONAL mail ONLY (please) to:  | should not be construed to imply that
Amer. Online: Matt DTS                | Apple Computer, Inc., or any of its
ThisNet: mattd@apple.com              | subsidiaries, in whole or in part,
ThatNet: (stuff)!ames!apple!mattd     | have any opinion on any subject."
Other mail by request only, please.   | "So there."
-----------------------------------------------------------------------------

dlyons@Apple.COM (David Lyons) (11/19/89)

Josef Wankerl asks how to copy extended files under GS/OS, and Matt
Deatherage answers.  (By the way, today is Matt's birthday.  He's 17
years old today, if you use the right number base.)

Matt sez it wouldn't be a great idea to provide an option for copying
only one of the forks of an extended file.  But as long as the default
is always to copy both forks, it wouldn't hurt--there are times when
it comes in very handy.  (For example, when Apple ships APW interface
files that are extended with empty resource forks, and you want to
be able to read them under ProDOS 8.)


J> * How would I go about allocating memory for the copy? [...]

M>I would venture there's really no need to compact memory.  This could give
M>you lots of things you don't want, like kicking out the disk cache or at
M>least the purgeable blocks within it.  Just use _MaxBlock to find out what
M>the biggest chunk currently available is, subtract about 10K from it for
M>GS/OS overhead (if necessary) and use that.

There's no *best* way to decide how much memory to allocate in a case like
this.  First, Matt is correct that there's no need to CompactMem and try
your NewHandle call again, because compacting memory is one of the things
the Memory Manager does automatically before it gives up and gives you an
error from NewHandle.

(Note that CompactMem *doesn't* purge anything.  It just moves unlocked
not-fixed blocks to try to make MaxBlock bigger.)

In a lot of cases, using MaxBlock-xxK will work fine.  In the worst case,
MaxBlock is very small, and there are several megs of purgable memory
(dormant applications, cached images of menus, toolsets that aren't being
used any more) and more stuff that Out-of-memory-queue routines are
willing to dispose of for you (like GS/OS's cache).  (The cache is nice,
but it's not so nice that you want to force the user to do extra disk
swaps to copy a file!  The cache will dump itself *before* any purgable
memory blocks are purged.  It's very humble and self-sacrificing.)

I say try to allocate as much memory as you have a use for--if you can't
get that much, then ask for less.  You might try asking for X, then X/2,
X/3, X/4, etc--this will mean you can do it in the minimum number of
passes possible in the avilable memory.

To guarantee that there's a bit of memory around for the OS to play with,
you might want to allocate a (say) 10K block right before you allocate
the big block, and then dispose of the 10K block before the OS calls.

>[...] you can use GS/OS sessions to speed multiple file
>copies dramatically.  See GS/OS Reference for more details.

True (although if all the files are huge it won't be dramatic).
Using a session means none of the updated "system" blocks (bitmap and
directory blocks, for example) will be written out to disk until the
whole thing is done--this way they get written once at the end instead
of several times.  This can save a lot of disks seeks.
-- 

 --Dave Lyons, Apple Computer, Inc.          |   DAL Systems
   AppleLink--Apple Edition: DAVE.LYONS      |   P.O. Box 875
   America Online: Dave Lyons                |   Cupertino, CA 95015-0875
   GEnie: D.LYONS2 or DAVE.LYONS         CompuServe: 72177,3233
   Internet/BITNET:  dlyons@apple.com    UUCP:  ...!ames!apple!dlyons

   My opinions are my own, not Apple's.

JWANKERL@UTCVM.BITNET ("Josef W. Wankerl") (11/19/89)

Thanks Matt and Dave -- I'll give it a try!

/**********************************************************************\
|*      Joe "Gonzo" Wankerl       |*|  The views expressed here are   *|
|* BITNET =>  JWANKERL@UTCVM      |*|  not necessarily yours...       *|
|*                                |*|         ...but they should be.  *|
\**********************************************************************/