Copyright 1992 Digital Equipment Corporation.
Distributed only by permission.
Created on Sat Jan 11 15:49:00 PST 1992 by gnelson
Last modified on Wed Aug 31 11:45:59 PDT 1994 by wobber
modified on Tue Aug 4 16:19:31 PDT 1992 by tomr
modified on Tue Jan 28 15:19:47 PST 1992 by muller
modified on Sun Jan 12 16:17:03 PST 1992 by meehan
MODULE ConnRW;
IMPORT
Rd, StreamRd, Wr, StreamWr, RdClass, StreamRdClass, WrClass,
StreamWrClass, Thread;
IMPORT ConnFD;
TYPE
RdT = StreamRd.T BRANDED OBJECT
fd: ConnFD.T;
OVERRIDES
seek := RdSeek;
close := RdClose
END;
WrT = StreamWr.T BRANDED OBJECT
fd: ConnFD.T;
OVERRIDES
seek := WrSeek;
flush := WrFlush;
close := WrClose
END;
CONST BufferSize = 8192;
PROCEDURE NewRd(fd: ConnFD.T) : StreamRd.T =
BEGIN
RETURN NEW(RdT, fd := fd,
buff := NEW(REF ARRAY OF CHAR, BufferSize),
st := 0,
lo := 0,
hi := 0,
cur := 0,
intermittent := TRUE,
seekable := FALSE,
closed := FALSE);
END NewRd;
PROCEDURE NewWr(fd: ConnFD.T) : StreamWr.T =
BEGIN
RETURN NEW(WrT, fd := fd,
buff := NEW(REF ARRAY OF CHAR, BufferSize),
st := 0,
lo := 0,
hi := 0,
cur := 0,
buffered := TRUE,
seekable := FALSE,
closed := FALSE);
END NewWr;
PROCEDURE RdSeek(rd: RdT; <*UNUSED*> pos: CARDINAL;
dontBlock: BOOLEAN): RdClass.SeekResult
RAISES {Rd.Failure, Thread.Alerted} =
VAR
len: CARDINAL;
timer: LONGREAL;
BEGIN
IF dontBlock THEN timer := 0.0D0; ELSE timer := -1.0D0; END;
TRY
len := rd.fd.get(rd.buff^, timer);
EXCEPT
| ConnFD.TimedOut => RETURN RdClass.SeekResult.WouldBlock;
(* | ConnFD.Error => RETURN RdClass.SeekResult.Eof; *)
END;
IF len > 0 THEN
rd.lo := rd.cur;
rd.hi := rd.cur + len;
StreamRdClass.DontOverflow(rd);
RETURN RdClass.SeekResult.Ready
ELSE
RETURN RdClass.SeekResult.Eof;
END;
END RdSeek;
PROCEDURE RdClose(rd: RdT) RAISES {Rd.Failure} =
BEGIN
rd.buff := NIL;
rd.fd.shutdownIn();
END RdClose;
PROCEDURE WrSeek(wr: WrT; <*UNUSED*> n: CARDINAL)
RAISES {Wr.Failure, Thread.Alerted} =
BEGIN WrFlush(wr) END WrSeek;
PROCEDURE WrFlush(wr: WrT) RAISES {Wr.Failure, Thread.Alerted} =
BEGIN
wr.fd.put(SUBARRAY(wr.buff^, 0, wr.cur-wr.lo));
wr.lo := wr.cur;
wr.hi := wr.lo + NUMBER(wr.buff^);
StreamWrClass.DontOverflow(wr);
END WrFlush;
PROCEDURE WrClose(wr: WrT) RAISES {Wr.Failure} =
BEGIN
wr.buff := NIL;
wr.fd.shutdownOut();
END WrClose;
BEGIN END ConnRW.