packages feed

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.