DEFINITION MODULE File; (* This module defines data types and procedures for performing *) (* DIRECT ACCESS file I/O with a user defined logical record. *) FROM SYSTEM IMPORT ADDRESS; IMPORT GEMDOS; CONST EOK = GEMDOS.EOK; UnknownError = GEMDOS.Error; InvalidHandle = GEMDOS.EIHndl; BadRequest = GEMDOS.EBadRq; SeekError = GEMDOS.ESeek; ReadFailure = GEMDOS.EReadF; WriteFailure = GEMDOS.EWritF; EndOfFile = -1000; TYPE RecordIdType = LONGCARD; (* Defines a type for uniquely identifying a single record. *) TYPE PossibleFields = (NextKey, PrevKey, NextRecord, PrevRecord); TYPE RecordHeaderType = RECORD NextKeyId : RecordIdType; (* Id of previous record with different primary key *) PrevKeyId : RecordIdType; (* Id of next record with different primary key *) NextRecordId : RecordIdType; (* Id of next logical record *) PrevRecordId : RecordIdType; (* Id of previous logical record *) END; (* This declaration, defining information required by the File *) (* module, is provided for inclusion in the user defined record *) (* as the first component. Immediately following this type, the *) (* user must declare two additional fields - a key and a subkey. *) (* Each field should be declared as ARRAY [0..n] OF CHAR, where *) (* n is the length of the key (or subkey). An example of a *) (* complete user defined record is : *) (* *) (* TYPE UserDefinedRecord = RECORD *) (* RecordHeader : File.RecordHeaderType; *) (* Key : ARRAY [0..3] OF CHAR; *) (* SubKey : ARRAY [0..5] OF CHAR; *) (* UserData : SomeUserDefinedType; *) (* END; *) TYPE GetKeyProc = PROCEDURE ( ADDRESS, VAR ARRAY OF CHAR ); (* Defines a type for retrieving the key from the user record. *) TYPE GetSubKeyProc = PROCEDURE ( ADDRESS, VAR ARRAY OF CHAR ); (* Defines a type for retrieving the subkey from the user record. *) TYPE FileIdType = RECORD Valid : BOOLEAN; (* True if valid file handle *) FileHandle : INTEGER; (* GEMDOS file handle *) FileSize : LONGCARD; (* "High Water" mark of file size *) FilePosition : RecordIdType; (* Id of current record *) RecordSize : CARDINAL; (* Size of user defined logical record *) NumberRecords : LONGCARD; (* Number of logical records in file *) GetKey : GetKeyProc; GetSubKey : GetSubKeyProc; FreeListId : RecordIdType; (* First free record id *) FirstRecordId : RecordIdType; (* First data record id *) NextRecordId : RecordIdType; (* Id of next record relative to current *) PrevRecordId : RecordIdType; (* Id of previous record relative to current *) END; (* Defines a type for uniquely identifying a single file. Note *) (* that this type is private to the File module, and as such *) (* must not be modified by other modules. However, information *) (* may be read from the record without adverse side effects. *) VAR Status : INTEGER; (* Contains the status of the last File operation. The possible *) (* values are documented in module GEMDOS. *) PROCEDURE DosError ( ErrorCode : INTEGER ); (* Display the Dos Error in an alert box. *) PROCEDURE GetField ( Field : (* IN *) PossibleFields; UserRecord : (* IN *) ADDRESS ) : RecordIdType; (* Retrieves the information from the record header *) (* field specified by Field. *) PROCEDURE Create ( VAR FileName : (* IN *) ARRAY OF CHAR; RecordSize : (* IN *) CARDINAL; GetKey : (* IN *) GetKeyProc; GetSubKey : (* IN *) GetSubKeyProc; VAR FileId : (* OUT *) FileIdType ); (* Creates a zero length disk file with name FileName. *) (* RecordSize contains the total size of the user defined *) (* record in bytes, and must be larger than the sum of the *) (* sizes of the record header, key, and subkey. If the *) (* routine was successful, FileId contains a value uniquely *) (* identifying the file for further access. *) PROCEDURE Open ( VAR FileName : (* IN *) ARRAY OF CHAR; GetKey : (* IN *) GetKeyProc; GetSubKey : (* IN *) GetSubKeyProc; VAR FileId : (* OUT *) FileIdType ); (* Opens the existing file named FileName. Note that since *) (* the file attributes are stored in the file (record size, *) (* key size, subkey size, etc), this information does not *) (* need to be specified by the user when invoking this *) (* routine. If the routine was successful, FileId contains *) (* a value uniquely identifying the file for further access. *) PROCEDURE Read ( VAR FileId : (* IN *) FileIdType; Data : (* OUT *) ADDRESS; VAR RecordId : (* OUT *) RecordIdType ); (* Reads the record located at the current file position *) (* into Data. If the routine is successful, the record id *) (* is placed in RecordId. Otherwise, the contents of *) (* RecordId is undefined. Upon completion of this routine, *) (* the current file position is advanced to the next logical *) (* record. *) PROCEDURE Write ( VAR FileId : (* IN *) FileIdType; Data : (* IN *) ADDRESS; VAR RecordId : (* OUT *) RecordIdType ); (* Writes the contents of Data into the record located at the *) (* current file position. If the routine is successful, the *) (* record id is placed in RecordId. Otherwise, the contents of *) (* RecordId is undefined. Upon completions of this routine, the *) (* current file position is advanced to the next logical record. *) (* Note that the contents of the key and subkey fields must not *) (* be changed since the record was last read. In order to *) (* modify the contents of the key or subkey, delete the record *) (* and then reinsert it. This will reinsert the record in the *) (* proper place in the file. *) PROCEDURE InsertRecord ( VAR FileId : (* IN *) FileIdType; VAR Key : (* IN *) ARRAY OF CHAR; VAR SubKey : (* IN *) ARRAY OF CHAR; Data : (* IN *) ADDRESS; WorkBuffer : (* IN *) ADDRESS; VAR RecordId : (* OUT *) RecordIdType ); (* Inserts the contents of Data into the file associated with *) (* FileId. The record is inserted into the file in ascending *) (* ASCII order (based on the contents of the key and subkey). *) (* If the routine is successful, RecordId contains a value *) (* uniquely identifying the record. Otherwise, the contents *) (* of RecordId is undefined. Note that the parameter *) (* WorkBuffer, used internally by the routine for temporary *) (* storage, must be of the same type as the user defined record. *) PROCEDURE DeleteRecord ( VAR FileId : (* IN *) FileIdType; RecordId : (* IN *) RecordIdType; WorkBuffer : (* IN *) ADDRESS ); (* Deletes the record identified by RecordId from the file *) (* associated with FileId. Note that the parameter WorkBuffer, *) (* used internally by the routine for temporary storage, must *) (* be of the same type as the user defined record. *) PROCEDURE Retreat ( VAR FileId : (* IN *) FileIdType; Data : (* OUT *) ADDRESS; VAR RecordId : (* OUT *) RecordIdType ); (* Moves the current file position to the previous logical *) (* record and then places the contents of the record in Data. *) (* If the routine is successful, the id of the record is *) (* placed in RecordId. Otherwise, the contents of RecordId *) (* is undefined. Note that the parameter WorkBuffer, used *) (* internally by the routine for temporary storage, must be *) (* of the same type as the user defined record. *) PROCEDURE Seek ( VAR FileId : (* IN *) FileIdType; RecordId : (* IN *) RecordIdType; Data : (* OUT *) ADDRESS ); (* Moves the current file position to the record identified by *) (* RecordId, and then places the contents of the record in Data. *) PROCEDURE Find ( VAR FileId : (* IN *) FileIdType; VAR Key : (* IN *) ARRAY OF CHAR; VAR SubKey : (* IN *) ARRAY OF CHAR; Data : (* OUT *) ADDRESS; VAR FoundKey : (* OUT *) BOOLEAN; VAR KeyId : (* OUT *) RecordIdType; VAR FoundRecord : (* OUT *) BOOLEAN; VAR RecordId : (* OUT *) RecordIdType ); (* Searches the file associated with FileId for a record *) (* containing the contents of Key and Subkey. Note that *) (* either of the keys may be a null string - matching any *) (* record. If a record was found, the contents of the record *) (* is placed in Data, and RecordId is set to a value uniquely *) (* identifying the record. The current file position is then *) (* set to the start of the next record. Otherwise, if the *) (* keys could not be found, the contents of RecordId are *) (* undefined, with KeyId and RecordId pointing to the last *) (* key and record read during the search, respectively. *) PROCEDURE Close ( VAR FileId : (* IN *) FileIdType ); (* Closes the file associated with FileId. *) PROCEDURE Copy; (* Copy one file to another. *) PROCEDURE Delete; (* Delete a file. *) END File. J4Pg& n&ÿþd:.ÿþ(n8.ÿþGùYr´P@Rnÿþ`Â:.ÿþIùYrB4PN^NuNV3ü8XhN^NuNV:9Xfºy