[net.sources] OSSI: SIStreams

biagioni@unc.UUCP (Edoardo Biagioni) (11/06/86)

(***************************************************************************)
(***                                                                     ***)
(***                                                                     ***)
(***                        O  S  S  I                                   ***)
(***                        ==========                                   ***)
(***                                                                     ***)
(**)               DEFINITION MODULE SIStreams;                          (**)
(***               ===========================                           ***)
(***                                                                     ***)
(***   This module defines an interface to sequential files.             ***)
(***                                                                     ***)
(***---------------------------------------------------------------------***)
(***                                                                     ***)
(***   Hardware:             independent                                 ***)
(***   Operating System:     UNIX BSD 4.2                                ***)
(***   Compiler:             independent                                 ***)
(***                                                                     ***)
(***   Version:      3.0                                                 ***)
(***   Implemented:  see copyright                                       ***)
(***   Date:         1986-03-12                                          ***)
(***                                                                     ***)
(***---------------------------------------------------------------------***)
(***                                                                     ***)
(***   Copyright 1984, 1985, 1986 by                                     ***)
(***      E. S. Biagioni                                                 ***)
(***      G. Heiser                                                      ***)
(***      K. Hinrichs                                                    ***)
(***      C. Muller                                                      ***)
(***                                                                     ***)
(***   Institut fuer Informatik                                          ***)
(***   ETH Zuerich                                                       ***)
(***   CH 8092 Zuerich                                                   ***)
(***   Switzerland                                                       ***)
(***                                                                     ***)
(***   Department of Computer Science                                    ***)
(***   University of North Carolina                                      ***)
(***   Chapel Hill, North Carolina 27514                                 ***)
(***   U.S.A.                                                            ***)
(***                                                                     ***)
(*** Permission to copy without fee all of this material is granted      ***)
(*** provided that the copies are not made or distributed for direct     ***)
(*** commercial advantage, that this OSSI copyright notice is            ***)
(*** included in the copy, that the module is not modified in any way    ***)
(*** except where necessary for compilation on a particular system,      ***)
(*** and that the module is always distributed in its original form.     ***)
(*** Distribution of this module in a modified form without including    ***)
(*** the original version is a violation of this copyright notice.       ***)
(***                                                                     ***)
(***---------------------------------------------------------------------***)
(***                                                                     ***)
(***   Updates:                                                          ***)
(***                                                                     ***)
(***                                                                     ***)
(***************************************************************************)

(* This module allows for stream I/O to files.
   In order to access the data of a file, a stream must be connected to it.
   This is done using the procedure ConnectStream.
   After processing of the file's data is finished, the stream should be
   disconnected using DisconnectStream. An output stream left connected at
   program termination time is in an undefined state. Some data may be lost
   or corrupted.

   For handling of files as units, see the module SIFiles.

   A stream may be either a text stream (allowing character and line oriented
   operations) or a binary stream (allowing byte and record I/O). The type
   of the stream is specified at connection time and remains fixed until
   disconnected. A text stream is compatible with standard text editors.

   There may be an implementation limit on the maximum line length of a text
   stream. If a line longer than the limit is written, the system will
   automatically break it up in several lines not exceeding the line limit.
   On input, such an oversized line will be read as several lines.

   A stream may be used either for input or for output. The intended mode
   must be specified when connecting the stream and remains fixed until
   disconnected.

   Success or failure of an operation is indicated by a variable 'result'.
   After a successful operation, 'result' will be equal to 'SIDone',
   after an unsuccessful operation its value will be different from
   'SIDone'. The possible result values are system dependent and the
   error message corresponding to a particular value can be obtained by a
   call to 'SIMessage'.

   After successfully reading the last item of an input stream 'result' will
   be equal to 'SIDone', while 'EndOfStream' will return TRUE. A successive
   read operation on the same stream will result in a result value different
   from 'SIDone', while 'EndOfStream' will still return TRUE.

   If an attempt is made to read a record from a binary stream on which
   'EndOfStream' returns FALSE before the call but not enough data are
   left in the stream to fill the record, after the read operation the
   value of 'result' will be different from 'SIDone', while 'EndOfStream'
   will return TRUE. The contents of the record are undefined in this case.

   Whenever 'EndOfStream' returns FALSE, at least one more character or
   byte can be read from the stream, whenever 'EndOfStream' returns
   TRUE, nothing can be read from the stream.

   The table below gives the valid procedure calls for the possible
   combinations of StreamType and StreamMode. In addition to those listed,
   a call to DisconnectStream is always possible.
   ConnectStream may not be called if a stream is already connected to
   the specified file. If this is done, the result is undefined.
   DeleteFile may not be called for a file which is currently connected
   to a stream. If this is done, the result is undefined.

     StreamType     StreamMode      valid procedure calls
     -------------------------------------------------------------------
     textStream     inputStream     SRead, SReadString, EndOfStream
     textStream     outputStream    SWrite, SWriteString, SWriteLine
     binaryStream   inputStream     SReadByte, SReadRecord, EndOfStream
     binaryStream   outputStream    SWriteByte, SWriteRecord   *)

(* Additional remarks on the UNIX implementation:

   The following conventions hold for file names (as parameter to
   ConnectStream):

    - a leading tilde character is replaced by the path name of the user's
      home directory
    - after making this substitution the name must be an empty string or a
      valid UNIX path name
    - an empty file name as parameter to ConnectStream connects to standard
      input or standard output respectively.

   Note that an input stream connected to standard input will not behave
   correctly if the module UserIO is linked to the program.

   There is no special limit on the length of a line in a text stream. *)

FROM SYSTEM IMPORT
  WORD;

FROM SISystem IMPORT
  SIResult,
  BYTE;

EXPORT QUALIFIED
  StreamType,       (* TYPEs *)
  StreamMode,
  Stream,
  ConnectStream,    (* PROCEDUREs *)
  DisconnectStream,
  EndOfStream,
  SRead,
  SReadString,
  SWrite,
  SWriteString,
  SWriteLine,
  SReadRecord,
  SWriteRecord,
  SReadByte,
  SWriteByte;

TYPE StreamType = (textStream, binaryStream);
     StreamMode = (inputStream, outputStream);
     Stream;

PROCEDURE ConnectStream (VAR s: Stream; fileName: ARRAY OF CHAR;
                         type: StreamType; mode: StreamMode;
                         VAR result: SIResult);
(* connects the stream s to the file named fileName.
   ConnectStream will fail if mode = inputStream and the file does not
   exist or if mode = outputStream and the file does exist already *)

PROCEDURE DisconnectStream (VAR s: Stream; VAR result: SIResult);
(* disconnects the stream from the file and closes the file. *)

PROCEDURE EndOfStream (s: Stream; VAR eos: BOOLEAN; VAR result: SIResult);
(* eos returns TRUE if s is an input stream and the end of the file has
   been reached, i.e, no more data may be read from the stream. *)

PROCEDURE SRead (s: Stream; VAR ch: CHAR; VAR result: SIResult);
(* ch returns the next character from stream 's'. *)

PROCEDURE SReadString (s: Stream; VAR string: ARRAY OF CHAR;
                       VAR result: SIResult);
(* Reads a line from a text input stream (see also SRead) and stores
   it in the string. *)

PROCEDURE SReadRecord (s: Stream; VAR record: ARRAY OF WORD;
                       VAR result: SIResult);
(* read a record from stream 's'. The number of words is determined by
   the size of the actual parameter. *)

PROCEDURE SReadByte (s: Stream; VAR byte: BYTE; VAR result: SIResult);
(* read a single byte from stream 's'. *)

PROCEDURE SWrite (s: Stream; ch: CHAR; VAR result: SIResult);
(* write the character 'ch' to the stream 's'. Writing of non-printing
   ASCII characters may cause termination of the current line. *)

PROCEDURE SWriteString (s: Stream; string: ARRAY OF CHAR;
                        VAR result: SIResult);
(* write the string 'string' on the stream 's'. Equivalent to
   FOR index := 0 TO StringLength (string) - 1 DO
     SWrite (s, string [index])
   END
   but possibly more efficient. *)

PROCEDURE SWriteLine (s: Stream; VAR result: SIResult);
(* ends the line being written to the stream 's'. See also SReadString. *)

PROCEDURE SWriteRecord (s: Stream; VAR record: ARRAY OF WORD;
                        VAR result: SIResult);
(* write the 'record' to the stream 's'. The number of words written
   is equal to the size of the actual parameter. *)

PROCEDURE SWriteByte (s: Stream; byte: BYTE; VAR result: SIResult);
(* write the 'byte' to the stream 's'. Exactly one byte is written. *)

END SIStreams.