gm2-libs-iso/IOLink
DEFINITION MODULE IOLink;
(* Types and procedures for the standard implementation of channels *)
IMPORT IOChan, IOConsts, ChanConsts, SYSTEM;
TYPE
DeviceId;
(* Values of this type are used to identify new device modules,
and are normally obtained by them during their initialization.
*)
PROCEDURE AllocateDeviceId (VAR did: DeviceId);
(* Allocates a unique value of type DeviceId, and assigns this
value to did. *)
PROCEDURE MakeChan (did: DeviceId; VAR cid: IOChan.ChanId);
(* Attempts to make a new channel for the device module identified
by did. If no more channels can be made, the identity of
the invalid channel is assigned to cid. Otherwise, the identity
of a new channel is assigned to cid.
*)
PROCEDURE UnMakeChan (did: DeviceId; VAR cid: IOChan.ChanId);
(* If the device module identified by did is not the module that
made the channel identified by cid, the exception wrongDevice is
raised; otherwise the channel is deallocated, and the value
identifying the invalid channel is assigned to cid.
*)
TYPE
DeviceTablePtr = POINTER TO DeviceTable;
(* Values of this type are used to refer to device tables *)
TYPE
LookProc = PROCEDURE (DeviceTablePtr, VAR CHAR, VAR IOConsts.ReadResults) ;
SkipProc = PROCEDURE (DeviceTablePtr) ;
SkipLookProc = PROCEDURE (DeviceTablePtr, VAR CHAR, VAR IOConsts.ReadResults) ;
WriteLnProc = PROCEDURE (DeviceTablePtr) ;
TextReadProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL, VAR CARDINAL) ;
TextWriteProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL) ;
RawReadProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL, VAR CARDINAL) ;
RawWriteProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL) ;
GetNameProc = PROCEDURE (DeviceTablePtr, VAR ARRAY OF CHAR) ;
ResetProc = PROCEDURE (DeviceTablePtr) ;
FlushProc = PROCEDURE (DeviceTablePtr) ;
FreeProc = PROCEDURE (DeviceTablePtr) ;
(* Carry out the operations involved in closing the corresponding
channel, including flushing buffers, but do not unmake the
channel.
*)
TYPE
DeviceData = SYSTEM.ADDRESS;
DeviceTable =
RECORD (* Initialized by MakeChan to: *)
cd: DeviceData; (* the value NIL *)
did: DeviceId; (* the value given in the call of MakeChan *)
cid: IOChan.ChanId; (* the identity of the channel *)
result: IOConsts.ReadResults;(* the value notKnown *)
errNum: IOChan.DeviceErrNum; (* undefined *)
flags: ChanConsts.FlagSet; (* ChanConsts.FlagSet{} *)
doLook: LookProc; (* raise exception notAvailable *)
doSkip: SkipProc; (* raise exception notAvailable *)
doSkipLook: SkipLookProc; (* raise exception notAvailable *)
doLnWrite: WriteLnProc; (* raise exception notAvailable *)
doTextRead: TextReadProc; (* raise exception notAvailable *)
doTextWrite: TextWriteProc; (* raise exception notAvailable *)
doRawRead: RawReadProc; (* raise exception notAvailable *)
doRawWrite: RawWriteProc; (* raise exception notAvailable *)
doGetName: GetNameProc; (* return the empty string *)
doReset: ResetProc; (* do nothing *)
doFlush: FlushProc; (* do nothing *)
doFree: FreeProc; (* do nothing *)
END;
(* The pointer to the device table for a channel is obtained using the
following procedure: *)
(*
If the device module identified by did is not the module that made
the channel identified by cid, the exception wrongDevice is raised.
*)
PROCEDURE DeviceTablePtrValue (cid: IOChan.ChanId; did: DeviceId): DeviceTablePtr;
(*
Tests if the device module identified by did is the module
that made the channel identified by cid.
*)
PROCEDURE IsDevice (cid: IOChan.ChanId; did: DeviceId) : BOOLEAN;
TYPE
DevExceptionRange = IOChan.ChanExceptions;
(*
ISO standard states defines
DevExceptionRange = [IOChan.notAvailable .. IOChan.textParseError];
however this must be a bug as other modules need to raise
IOChan.wrongDevice exceptions.
*)
PROCEDURE RAISEdevException (cid: IOChan.ChanId; did: DeviceId;
x: DevExceptionRange; s: ARRAY OF CHAR);
(* If the device module identified by did is not the module that made the channel
identified by cid, the exception wrongDevice is raised; otherwise the given exception
is raised, and the string value in s is included in the exception message.
*)
PROCEDURE IsIOException () : BOOLEAN;
(* Returns TRUE if the current coroutine is in the exceptional execution state
because of the raising af an exception from ChanExceptions;
otherwise FALSE.
*)
PROCEDURE IOException () : IOChan.ChanExceptions;
(* If the current coroutine is in the exceptional execution state because of the
raising af an exception from ChanExceptions, returns the corresponding
enumeration value, and otherwise raises an exception.
*)
END IOLink.