TokenIO.mesa
Copyright © 1983, 1984, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, August 24, 1983 3:10 pm
Last edited by: Christian Jacobi, October 28, 1986 6:31:00 pm PST
DIRECTORY
IO, Properties, Rope;
TokenIO: CEDAR DEFINITIONS =
BEGIN
Input output in tokenized form. Allows grouping of tokens to clusters with a push and a popflag. No monitoring is provided.
All procedures may raise ERROR Stopped
All input procedures may raise "ERROR" EncodingError
The routines may generate standard IO signals and errors, however:
most input errors are mapped into raising EncodingError.
Stopped: ERROR;
-- Raised if any process calls Stop
EncodingError: SIGNAL;
-- All read procedures SIGNAL EncodingError if read token is not as expected;
-- for emergeny error bypassing or debugging, the state may be changed in
-- the debugger and the computation continued; however, normal computation
-- considers EncodingError to be an ERROR, not a SIGNAL.
--
-- The read routines do not have changed the state of the input stream.
Handle: TYPE = REF HandleRec;
HandleRec: TYPE = --READONLY-- RECORD [
stop: REF BOOL ←,   --never NIL; stop^ is not considered READONLY
--private implementor fields which need to be fast
s: PRIVATE IO.STREAMNIL,  --reserved for the implementor
funny: PRIVATE BOOLFALSE,  --reserved for the implementor
imp: PRIVATE REF ImpRec ← NIL,  --reserved for the implementor
--client fields
stream: IO.STREAMNIL,  --for clients, but not automatically initialized
clientKey: REFNIL,   --for clients; represents a key put on properties
clientData: REFNIL,   --for clients; represents context
oldVersion: BOOLFALSE,  --for client: client may switch it to true only
truth: --readonly-- BOOLTRUE,  --for client: truth/versus cache
properties: REF Properties.PropList ← NIL --don't PutProp from forked processes
];   --[certain features to speed up ChipNDale's io only]
Mark: TYPE = REF;
ImpRec: TYPE;
Write: PROC [h: Handle, t: Token];
WritePush: PROC [h: Handle, a: ATOM];
WritePush2: PROC [h: Handle, a: ATOM];
WritePop: PROC [h: Handle];
WriteAtom: PROC [h: Handle, a: ATOM];
WriteRope: PROC [h: Handle, r: Rope.ROPE];
WriteInt: PROC [h: Handle, i: INT];
WriteReal: PROC [h: Handle, r: REAL];
WriteStream: PROC [h: Handle] RETURNS [s: IO.STREAM];
-- Next writes can be in stream mode
-- Usage of any other write procs finishes stream mode and switches back to token mode
-- Returns always same stream h.stream for same handle !
-- Do not close, do not use random access
MarkAndWriteInt: PROC [h: Handle, value: INT←-1] RETURNS [Mark];
-- WriteInt and remembers position for later updates
UpdateMark: PROC [h: Handle, mark: Mark, value: INT];
-- Updates value of integer written before
TType: TYPE = {push, push2, pop, atom, rope, int, real, streamed, endOfStream, error};
Token: TYPE = RECORD [
SELECT type: TType FROM
push => [value: ATOM],
push2 => [value: ATOM],
pop => [value: ATOM],
atom => [value: ATOM],
rope => [value: Rope.ROPE],
int => [value: INT],
real => [value: REAL],
streamed => [value: REF],
endOfStream => [],
error => [value: REF],
ENDCASE
];
Read: PROC [h: Handle] RETURNS [Token];
ReadAgain: PROC [h: Handle, t: Token];
--Causes next call of Read to get t
--Do not use in stream mode except before any real input from stream
ReadInt: PROC [h: Handle] RETURNS [INT];
ReadAtom: PROC [h: Handle] RETURNS [ATOM];
ReadRope: PROC [h: Handle] RETURNS [Rope.ROPE];
ReadReal: PROC [h: Handle] RETURNS [REAL];
ReadPush: PROC [h: Handle] RETURNS [ATOM];
ReadPush2: PROC [h: Handle] RETURNS [ATOM];
ReadPop: PROC [h: Handle];
ReadStream: PROC [h: Handle] RETURNS [s: IO.STREAM];
--Next reads can use stream
--Returns always the same read stream h.stream for the same handle
--Do not close, do not use random access
--It is not possible to read from stream anything which was not written in stream mode
Skip: PROC [h: Handle];
--if the next token is a pop: no-op
--if the next token is not a pop
-- skips forward on the stream until the next pop is read
-- pairs of push and pop: calls the catcher;
-- pairs of push2 and pop are skipped.
--In stream mode: skips started stream
--Attaching TokenIO to STREAMS
-- while TokenIO is attached to a stream no other operations on this stream must occur
-- otherwise, TokenIO might not be able to read back the clobbered stream.
CreateReader: PROC [stream: IO.STREAM, stop: REF BOOLNIL, catcher: PROC [Handle]←NIL] RETURNS [Handle];
--EncodingError if stream was not written and closed with TokenIO
--stop: set stop^ to TRUE to stop the reading
--catcher: called implicitely by Skip
CreateWriter: PROC [stream: IO.STREAM, stop: REF BOOLNIL, truth: BOOLTRUE] RETURNS [Handle];
--EncodingError if stream does not provide random access
--stop: set stop^ to TRUE to stop the writing
Close: PROC [h: Handle, closeStream: BOOLTRUE];
--Closes TokenIO stream
--closeStream: implicit call of IO.Close
--Calling Close is not necessary if writing is supposed to fail
END.