-- edited by Teitelman March 24, 1982 7:45 pm
DIRECTORY
ViewersIOStream, IOStream, Rope,
ViewerClasses, TypeScript;
ViewersIOStreamImpl: PROGRAM
IMPORTS IOStream, TypeScript
EXPORTS ViewersIOStream
SHARES IOStream =
BEGIN
Viewer: TYPE = ViewerClasses.Viewer;
ViewerStreamData: TYPE = REF ViewerStreamDataRecord;
ViewerStreamDataRecord: TYPE = RECORD[
viewer: Viewer,
echoTo: IOStream.Handle ← NIL
];
ViewerInStreamProcs: REF IOStream.StreamProcs ← IOStream.CreateRefStreamProcs[
getChar: ViewerGetChar,
close: ViewerClose,
endOf: ViewerEndOf,
charsAvail: ViewerCharsAvail,
setEcho: ViewerSetEcho,
name: "Viewers Input"
];
ViewerOutStreamProcs: REF IOStream.StreamProcs ← IOStream.CreateRefStreamProcs[
putChar: ViewerPutChar,
putBlock: ViewerPutBlock,
close: ViewerClose,
endOf: ViewerEndOf,
eraseChar: ViewerEraseChar,
name: "Viewers Output"
];
CreateViewerStreams: PUBLIC PROC [name: Rope.ROPE ← NIL, viewer: Viewer ← NIL] RETURNS [in: IOStream.Handle, out: IOStream.Handle] =
{OPEN IOStream;
IF viewer = NIL THEN viewer ← TypeScript.Create[info: [name: name]];
{in ← CreateProcsStream[streamProcs: ViewerInStreamProcs, streamData: NEW[ViewerStreamDataRecord ← [viewer: viewer]] ];
out ← CreateProcsStream[streamProcs: ViewerOutStreamProcs, streamData: NEW[ViewerStreamDataRecord ← [viewer: viewer]] ];
[] ← SetEcho[in, out]; -- do the echoing at the level of handle, since this permits echoing to an arbitrary handle.
};
};
ViewerGetChar: PROCEDURE [self: IOStream.Handle] RETURNS [char: CHARACTER] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IOStream.Error[StreamClosed];
char ← TypeScript.GetChar[data.viewer];
IF data.echoTo # NIL THEN IOStream.PutChar[data.echoTo, char];
END; -- of ViewerGetChar
ViewerPutChar: PROCEDURE[self: IOStream.Handle, char: CHARACTER] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IOStream.Error[StreamClosed];
TypeScript.PutChar[data.viewer, char];
END; -- of ViewerPutChar
ViewerPutBlock: PROCEDURE[self: IOStream.Handle, block: REF READONLY TEXT, startIndex: NAT, stopIndexPlusOne: NAT] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IOStream.Error[StreamClosed];
TypeScript.PutText[ts: data.viewer, text: block, start: startIndex, stopPlusOne: stopIndexPlusOne];
END; -- of ViewerPutChar
ViewerReset: PROCEDURE[self: IOStream.Handle] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
TypeScript.Reset[data.viewer];
END; -- of ViewerClose
ViewerClose: PROCEDURE[self: IOStream.Handle, abort: BOOLEAN] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF ~data.viewer.destroyed THEN TypeScript.Destroy[data.viewer];
END; -- of ViewerClose
ViewerEndOf: PROCEDURE[self: IOStream.Handle] RETURNS [BOOLEAN] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IOStream.Error[StreamClosed];
RETURN[FALSE];
END; -- ViewerEndOf
ViewerCharsAvail: PROCEDURE[self: IOStream.Handle] RETURNS [BOOLEAN] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IOStream.Error[StreamClosed];
RETURN[TypeScript.CharsAvailable[data.viewer]];
END; -- ViewerCharsAvail
ViewerEraseChar: PROCEDURE[self: IOStream.Handle, char: CHARACTER] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IOStream.Error[StreamClosed];
TypeScript.BackSpace[data.viewer];
END; -- of ViewerEraseChar
ViewerSetEcho: PROCEDURE[self: IOStream.Handle, echoTo: IOStream.Handle] RETURNS[oldEcho: IOStream.Handle] =
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IOStream.Error[StreamClosed];
oldEcho ← data.echoTo;
data.echoTo ← echoTo;
END; -- of ViewerSetEcho
DefaultCreateIn: PROC RETURNS [IOStream.Handle] =
-- creates a viewer. sets defaultOut to same window.
{in, out: IOStream.Handle;
[in, out] ← CreateViewerStreams[];
IOStream.SetDefaultStreams[out: out];
RETURN[in];
};
DefaultCreateError, DefaultCreateOut: PROC RETURNS [IOStream.Handle] =
{in, out: IOStream.Handle;
[in, out] ← CreateViewerStreams[];
IOStream.SetDefaultStreams[in: in];
RETURN[out];
};
CreateViewerStream1: PROC [name: Rope.ROPE ← NIL] RETURNS [in: IOStream.Handle, out: IOStream.Handle] = {[in, out] ← CreateViewerStreams[name]};
IOStream.SetTTYCreate[CreateViewerStream1];
IOStream.SetDefaultStreams[createIn: DefaultCreateIn, createOut: DefaultCreateOut, createError: DefaultCreateError];
END.
March 24, 1982 7:46 pm W. Teitelman. Fixed Close to check if viewer already destroyed. Added name argument to CreateRefStreamProcs.
13-Apr-82 14:05:22 W. Teitelman. Added checks for whether viewer was destroyed, and if so, raised IOStream error.