(*
    Title: 	StreamRep - Definitions
    LastEdit:	"Mon Sep 17 14:06:45 1984"
    Author: 	Mick Jordan
		Acorn Research Centre
*)

DEFINITION MODULE StreamRep;
(*  This module defines the interface between the generic operations
    on a Stream and the implementation of a particular stream class.
*)

FROM SYSTEM IMPORT WORD, ADDRESS;
FROM SystemTypes IMPORT LongCARDINAL, LongINTEGER;
FROM Streams IMPORT 
    Stream, StreamProcs,
    OptionalFunction, SeekMode, StreamErrorCodeType;

EXPORT QUALIFIED
    Procs,
    PutProc, GetProc, BackspaceProc, FlushProc, DeleteProc,
    ImplementsProc, PutNProc, GetNProc, SeekProc, TellProc,
    DefaultProcs, SetStreamError, NullFlush;

(*  procedures which correspond to the generic operations exported
    by the `Streams' module.
*)

TYPE
    PutProc = PROCEDURE(Stream, WORD);
    GetProc = PROCEDURE(Stream): WORD;
    BackspaceProc = PROCEDURE(Stream);
    FlushProc = PROCEDURE(Stream);
    DeleteProc = PROCEDURE(Stream);
    ImplementsProc = PROCEDURE(Stream, OptionalFunction): BOOLEAN;

(* optional procedures *)

    PutNProc = PROCEDURE(Stream, ADDRESS, CARDINAL): CARDINAL;
    GetNProc = PROCEDURE(Stream, ADDRESS, CARDINAL): CARDINAL;
    SeekProc = PROCEDURE(Stream, SeekMode, LongINTEGER);
    TellProc = PROCEDURE(Stream, VAR LongCARDINAL);

TYPE Procs = POINTER TO RECORD
(*  Each stream class must provide this vector of procedures
    which implement the individual functions.  A pointer to
    the record is stored in a stream instance when it is created.
    The size of the stream element is recorded to allow an
    implementation of PutN and GetN.
*)
        elementSize: CARDINAL;
        Put: PutProc;
        Get: GetProc;
        Backspace: BackspaceProc;
        Flush: FlushProc;
        Delete: DeleteProc;
        Implements: ImplementsProc;
        PutN: PutNProc;
        GetN: GetNProc;
        Seek: SeekProc;     (* random access *)
        Tell: TellProc;
    END (* record *);

PROCEDURE DefaultProcs(elementSize: CARDINAL): Procs;
(*  
    'elementSize' defines the size (in bits) of an element
    on the stream.  The procedure 
    returns a pointer to a new instance of a 'Procs',
    with all the entries pointing to a procedures which
    RAISEs FunctionNotImplemented if called, 
    except PutN and GetN.  The latter
    procedures provide a default implementation for
    streams with 'elementSize=8', by calling
    Put and Get the appropriate number of times.  
    Other values of 'elementSize'
    cause the exception to be generated.

    A stream instance should update those
    fields which it explicitly implements,
    and then use the pointer as an argument to 
    Stream.CreateStream.  It is necessary to coerce
    the value to a StreamProcs, since the equivalence
    of Procs and StreamProcs is not exposed.
*)

PROCEDURE SetStreamError(s: Stream; error: StreamErrorCodeType);
(*  standard way of doing:
        s^.status = StreamError; s^.streamError := error;
*)

(*  Stream procedures which have widespread utility  *)
    
PROCEDURE NullFlush(s: Stream);
(*  does nothing, for streams where Flush is not required.
*)
END StreamRep .
