language-Modula2-0.1: examples/Modula-2_Libraries/PMOS/sources/notdone/streams2.mod
IMPLEMENTATION MODULE Streams2;
(********************************************************)
(* *)
(* I/O module: PMOS replacement for the *)
(* Streams module in the FTL library *)
(* *)
(* Programmer: P. Moylan *)
(* Last edited: 16 September 1991 *)
(* Status: Being tested *)
(* *)
(* Most operations are working. *)
(* Random-access operations not yet tested. *)
(* RenameFile not yet implemented. *)
(* DeleteFile not yet implemented. *)
(* *)
(* The immediate goal is to use this module as *)
(* a test bed for working out what features *)
(* should be added to the Files module. *)
(* *)
(* In the long term, this module is likely to *)
(* become obsolete (except as an interface for *)
(* programs which were using the FTL library *)
(* module), since it is probable that all desired *)
(* features will be included in module Files. *)
(* *)
(********************************************************)
FROM Trace IMPORT
(* proc *) NYI;
FROM SYSTEM IMPORT
(* proc *) ADR;
FROM Files IMPORT
(* type *) File,
(* proc *) OpenFile, CloseFile, EOF, ReadByte, ReadRecord,
WriteByte, WriteRecord, SetPosition, SavePosition,
FileSize;
FROM IOErrorCodes IMPORT
(* type *) ErrorCode;
FROM Logic IMPORT
(* proc *) MakeLong, HighWord, LowWord;
IMPORT HardDisk, Floppy;
(************************************************************************)
TYPE
STREAM = File;
(************************************************************************)
(* OPENING AND CLOSING FILES *)
(************************************************************************)
PROCEDURE Connect (VAR (*OUT*) s:STREAM; name: ARRAY OF CHAR;
dir: Direction): CARDINAL;
(* Opens a file. The function result is zero if successful, or *)
(* nonzero to indicate that the operation failed. *)
BEGIN
RETURN ORD (OpenFile (s, name, dir=output));
END Connect;
(************************************************************************)
PROCEDURE Disconnect (VAR (*INOUT*) s:STREAM; closefile:BOOLEAN);
(* Closes a file, if closefile is TRUE. The action when closefile *)
(* is FALSE has not yet been defined. *)
BEGIN
IF closefile THEN
CloseFile (s);
END (*IF*);
END Disconnect;
(************************************************************************)
(* INPUT *)
(************************************************************************)
PROCEDURE ReadChar (s: STREAM; VAR (*OUT*) ch:CHAR);
(* Read one byte. *)
BEGIN
ch := ReadByte (s);
END ReadChar;
(************************************************************************)
PROCEDURE ReadWord (s: STREAM; VAR (*OUT*) w: WORD);
(* Read two sequential bytes. *)
VAR reply: INTEGER;
BEGIN
ReadRec (s, ADR(w), 2, reply);
END ReadWord;
(************************************************************************)
PROCEDURE BufferAhead (s: STREAM; force: BOOLEAN);
(* So far, has no effect. In the long term the intention is to *)
(* allow line editing for keyboard input. *)
BEGIN
END BufferAhead;
(************************************************************************)
PROCEDURE ReadRec (s: STREAM; buffaddr: ADDRESS; count: CARDINAL;
VAR (*OUT*) reply: INTEGER);
(* Reads count bytes to memory location buffaddr. The last *)
(* parameter returns the number of bytes actually read. A reply *)
(* of -1 indicates an error, in which case an error code may be *)
(* found in variable IOResult. *)
VAR actualcount: CARDINAL; status: ErrorCode;
BEGIN
status := ReadRecord (s, buffaddr, count, actualcount);
IOResult := ORD(status);
IF status = OK THEN
reply := actualcount;
ELSE
reply := -1;
END (*IF*);
END ReadRec;
(************************************************************************)
(* OUTPUT *)
(************************************************************************)
PROCEDURE WriteWord (s: STREAM; w: WORD);
(* Output two bytes. *)
VAR dummy: INTEGER;
BEGIN
WriteRec (s, ADR(w), 2, dummy);
END WriteWord;
(************************************************************************)
PROCEDURE WriteChar (s: STREAM; ch: CHAR);
(* Output one byte. *)
BEGIN
IOResult := ORD (WriteByte (s, ch));
END WriteChar;
(************************************************************************)
PROCEDURE WriteRec (s:STREAM; buffaddr: ADDRESS; count: CARDINAL;
VAR (*OUT*) reply: INTEGER);
(* Writes count bytes from memory location buffaddr. The last *)
(* parameter returns the number of bytes actually written. *)
(* A reply of -1 indicates an error, in which case an error code *)
(* may be found in variable IOResult. *)
VAR status: ErrorCode;
BEGIN
status := WriteRecord (s, buffaddr, count);
IOResult := ORD(status);
IF status = OK THEN
reply := count;
ELSE
reply := -1;
END (*IF*);
END WriteRec;
(************************************************************************)
(* END-OF-FILE TEST *)
(************************************************************************)
PROCEDURE EOS (s: STREAM): BOOLEAN;
(* Returns TRUE iff at end of file. *)
BEGIN
RETURN EOF (s);
END EOS;
(************************************************************************)
(* RANDOM ACCESS *)
(************************************************************************)
PROCEDURE Reset (s: STREAM);
(* Goes to beginning of file. On list device, starts new page. *)
BEGIN
IOResult := ORD (SetPosition (s, 0));
END Reset;
(************************************************************************)
PROCEDURE SetLongPos (s: STREAM; Pos: LONGCARD);
(* Goes to byte position Pos in file. Start of file is position 0. *)
BEGIN
IOResult := ORD (SetPosition (s, Pos));
END SetLongPos;
(************************************************************************)
PROCEDURE SetPos (s: STREAM; high, low: CARDINAL);
(* Same as SetLongPos (s, MakeLong(high, low)) *)
BEGIN
IOResult := ORD (SetPosition (s, MakeLong (high, low)));
END SetPos;
(************************************************************************)
PROCEDURE GetLongPos (s: STREAM; VAR (*OUT*) Pos: LONGCARD);
(* Returns the current position, i.e. the byte number of the next *)
(* byte to be read or written. *)
BEGIN
Pos := SavePosition (s);
END GetLongPos;
(************************************************************************)
PROCEDURE GetPos (s: STREAM; VAR (*OUT*) high, low: CARDINAL);
(* Same as GetLongPos, but decomposes the result into two words. *)
VAR position: LONGCARD;
BEGIN
position := SavePosition (s);
high := HighWord (position); low := LowWord (position);
END GetPos;
(************************************************************************)
PROCEDURE StreamLength (s: STREAM): LONGCARD;
(* Returns the length of the file in bytes. *)
BEGIN
RETURN FileSize (s);
END StreamLength;
END Streams2.