{ ----------------------------------------------------------------------------- NOTICE: THESE MATERIALS are UNSUPPORTED by OSS! If you do not understand how to use them do not contact OSS for help! We will not teach you how to program in Pascal. If you find an error in these materials, feel free to SEND US A LETTER explaining the error, and how to fix it. THE BOTTOM LINE: Use it, enjoy it, but you are on your own when using these materials! DISCLAIMER: OSS makes no representations or warranties with respect to the contents hereof and specifically disclaim all warranties of merchantability or fitness for any particular purpose. This document is subject to change without notice. OSS provides these materials for use with Personal Pascal. Use them in any way you wish. -------------------------------------------------------------------------- } Disk File Functions Page 1 Disk File Operations There may be times when you want to perform operations not supported by the standard Personal Pascal I/O library. Until such time as equivalent routines are added to the Personal Pascal library, you can use direct GEMDOS calls to achieve the results you want. For all calls described in this section, we're going to assume the following TYPE declarations are present in your program: TYPE Path_Chars = PACKED ARRAY [ 1..80 ] OF Char ; Notice that the maximum length of a GEMDOS pathname is 80 characters. The reason we are using a packed array and not a Pascal STRING type is that GEMDOS is expecting path and file names in the "C language" string format. In other words, GEMDOS normally wants a string in which the first byte is the first data character, and it expects the string to be terminated by a zero byte (Chr( 0 ), in Pascal). You can't pass a Pascal STRING to GEMDOS directly, since the first character in a Pascal string (s[0]) is the length byte for the string, and the string is not null-terminated. In order to pass a Pascal string to GEMDOS, you have to copy it into a "C-type" string by calling a procedure like the following: PROCEDURE Make_Path( VAR ps : Str255 ; VAR cs : Path_Chars ) ; VAR i : Integer ; BEGIN FOR i := 1 TO Length( ps ) DO cs[i] := ps[i] ; cs[ length(ps)+1 ] := Chr(0) ; END ; Now that we know what type of names to pass to GEMDOS, we can get on with presenting the calls you can use: Create and open a file. Sometimes, you may want open a file with special properties that Pascal doesn't support. For this purpose, you can use the following routine: FUNCTION f_create( VAR name : Path_Chars ; attributes : Integer ) : Integer ; GEMDOS( $3c ) ; This call creates a new file with the specified name and the specified attributes. The bits in the attributes parameter have the following assignments: bit meaning --- ------- $01 file is read-only $02 file is hidden from directory search $04 file is a system file, hidden from directory search $08 file contains a volume label in the first 8 data bytes The return value is a valid GEMDOS file handle, if greater than or equal to Disk File Functions Page 2 zero, or an error number, if negative. You should use this call to open a file for output, if you want to open a new file, or if you want to first erase the previous contents. If you want to write to an existing file, without erasing the contents, use the f_open call, below. Open a file. You might also want to open an existing file (or one you created with f_create) without using the built-in procedure Reset. You can use this GEMDOS call: FUNCTION f_open( VAR name : Path_Chars ; mode : Integer ) : Integer ; GEMDOS( $3d ) ; Use this call to open a file for reading, writing, or updating. If you want to open a file for writing, but you want to first erase the previous contents, use the f_create call, instead. The valid values for mode are: 0 open for reading only 1 open for writing only 2 open for reading or writing The return value is a GEMDOS handle, if greater than or equal to zero, or an error number, if negative. Notice that this call does not have a parameter to specify the attributes of the file. Those attributes are set by the f_create call and are not changed by this call. If you want to change the attributes of a file, you can use the f_attrib call, below. Close an open file. If you used f_create or f_open to ready a file for access, you should use the following call to close it when you're finished reading or writing to the file: FUNCTION f_close( handle : Integer ) : Integer ; GEMDOS( $3e ) ; The parameter handle should be the same as that returned by the appropriate open call. Zero is returned, if the file was closed successfully, or a negative error number, otherwise. Read bytes from a file. Pascal supports reading from and writing to files one item at a time, where the size of the item is the size of the file pointer variable. Occasionally you may want to read or write in larger chunks, especially if your item size is small, since GEMDOS isn't very fast for single-byte transfers. The following call allows you to read a block of characters into memory: FUNCTION f_read( handle : Integer ; count : Long_Integer ; VAR buf : Buf_Type ) : Long_Integer ; GEMDOS( $3f ) ; This call reads an arbitrary number of bytes from a file into a desired Disk File Functions Page 3 buffer. The number of bytes actually read is returned, if the function was successful, or a negative error number, if something went wrong. Note that the number of bytes actually read may be shorter than the number of bytes requested, if the end-of-file position was reached. The Buf_Type mentioned above may be almost any type. For example, to read 100 two-byte values into an array, you might use a program segment like this: TYPE Hundred_Integers = ARRAY [ 1..100 ] OF Integer ; VAR a : Hundred_Integers ; bytes_read : Long_Integer ; PROCEDURE f_read( handle : Integer ; count : Long_Integer ; VAR buf : Hundred_Integers ) : Long_Integer ; GEMDOS( $3f ) ; BEGIN bytes_read := f_read( handle, 200, a ) ; END ; Note that 200 was passed as the number of bytes to read, since we wanted 100 two-byte values! The handle parameter should be that value returned by either the f_create or f_open call. If you want to use the f_read call to read from a file which was opened using the built-in procedure Reset, you can use the function Handle to find out the handle associated with the file. If you are reading from a file just opened using Reset, you must be aware, however, that the first item has already been read from the file and put into the file buffer variable. Write bytes to a file. Similarly, you may want to write an arbitrary number of bytes to a file. The following call supports block writing: FUNCTION f_write( handle : Integer ; count : Long_Integer ; VAR buf : Buf_Type ) : Long_Integer ; GEMDOS( $40 ) ; This call is the counterpart of the f_read function described above. It takes an arbitrary number of bytes from a buffer and outputs them to a previously opened file. The handle parameter must be that which was returned by a previous f_open or f_create call. You can also use the Handle function to get the handle of a file which was opened using the Rewrite built-in procedure. The value returned by f_write is the number of bytes written, if the operation was successful, or a negative error number. In general, if the number of bytes returned does not equal the number requested, something went wrong! Delete a file. There is no standard procedure in Pascal to remove a file from a disk, so if you want to erase files, you need the following call: FUNCTION f_delete( VAR name : Path_Chars ) : Integer ; GEMDOS( $41 ) ; Disk File Functions Page 4 Zero is returned, if the delete was successful, or a negative error value, otherwise. Seek within a file. Personal Pascal supports random access to files using the built-in procedures Get, Put, and Seek. If you want to use instead the underlying GEMDOS routine to position within a file, here it is: FUNCTION f_seek( offset : Long_Integer ; handle, mode : Integer ) : Long_Integer ; GEMDOS( $42 ) ; Use this call to point to a particular byte position within a file. The offset parameter specifies the desired byte position, and the mode parameter specifies which file position the offset parameter is relative to: mode relative to ---- ----------- 0 the beginning of the file 1 the current location 2 the end of the file The offset parameter is signed, so you could, for example, move 10 bytes backwards in the file by specifying offset and mode parameters of -10 and 1, respectively. Get/Set file attributes. As mentioned above, the f_create call sets a file's attributes. These attributes are never changed when the file is subsequently opened. If you ever want to change the attributes of a file, you should use the following call: FUNCTION f_attrib( VAR name : Path_Chars ; mode, attributes : Integer ) : Integer ; GEMDOS( $43 ) ; The mode parameter specifies whether to get the file attributes, if 0, or to set the attributes, if 1. The attributes parameter is specified in the same way as for the f_create call, above, with the following two additions: bit meaning --- ------- $10 file is a subdirectory $20 file is written and closed correctly. These two attributes only refer to subdirectories.