-*- Mode: Modula-3 -*-
*
* For information about this program, contact Blair MacIntyre
* (bm@cs.columbia.edu) or Steven Feiner (feiner@cs.columbia.edu)
* at the Computer Science Dept., Columbia University,
* 1214 Amsterdam Ave. Mailstop 0401, New York, NY, 10027.
*
* Copyright (C) 1995, 1996 by The Trustees of Columbia University in the
* City of New York. Blair MacIntyre, Computer Science Department.
* See file COPYRIGHT-COLUMBIA for details.
*
* Author : Blair MacIntyre
* Created On : Wed Mar 1 20:13:22 1995
* Last Modified By: Blair MacIntyre
* Last Modified On: Sat Aug 9 13:49:52 1997
* Update Count : 24
*
* $Source: /opt/cvs/cm3/doc/help/gen_html/rdwr/src/TeeWr.m3.html,v $
* $Date: 2010-04-29 17:19:52 $
* $Author: wagner $
* $Revision: 1.5 $
*
* $Log: not supported by cvs2svn $
* Revision 1.4.2.1 2010-04-15 21:00:21 wagner
* update generated HTML doc to RC5
*
* Revision 1.2 2001/12/02 00:35:21 wagner
* add copyright notes and fix overrides for cm3
*
* added: rdwr/COPYRIGHT-COLUMBIA
* added: rdwr/src/COPYRIGHT-COLUMBIA
* added: rdwr/src/m3overrides
* modified: rdwr/src/RdWrPipe.i3
* modified: rdwr/src/RdWrPipe.m3
* modified: rdwr/src/SimpleMsgRW.i3
* modified: rdwr/src/SimpleMsgRW.m3
* modified: rdwr/src/TeeWr.i3
* modified: rdwr/src/TeeWr.m3
*
* Revision 1.1.1.1 2001/12/02 00:29:10 wagner
* Blair MacIntyre's rdwr library
*
* Revision 1.3 1997/08/11 20:36:24 bm
* Various fixes
*
*
* HISTORY
MODULE TeeWr;
IMPORT WrClass, RefanyTbl, Text, Wr, Refany, Atom, AtomList;
FROM Wr IMPORT Failure;
FROM Thread IMPORT Alerted;
CONST
BuffSize = 1024;
REVEAL
T = Public BRANDED "TeeWr.T" OBJECT
wrs: RefanyTbl.T := NIL;
OVERRIDES
init := Init;
seek:= Seek;
putString := PutString;
flush := Flush;
close := Close;
tee := Tee;
untee := Untee;
END;
PROCEDURE Init (self: T): T =
BEGIN
IF (self.wrs = NIL) THEN
self.wrs := NEW(RefanyTbl.Default).init();
END;
self.st := 0;
self.lo := 0;
self.cur := 0;
self.hi := BuffSize;
IF (self.buff = NIL) THEN
self.buff := NEW(REF ARRAY OF CHAR, BuffSize);
END;
self.closed := FALSE;
self.seekable := FALSE;
self.buffered := TRUE;
RETURN self;
END Init;
EXCEPTION Error; <*FATAL Error*>
PROCEDURE Seek (self: T; n: CARDINAL) RAISES {Failure, Alerted} =
BEGIN
(* This file is not seekable, so only handle the special case. *)
IF n # self.hi OR n # self.cur THEN RAISE Error; END;
(* first, flush the output *)
self.flush();
(* now, mark the buffer as available *)
self.lo := n;
self.cur := n;
self.hi := n + BuffSize;
END Seek;
write the current buffered amount to a writer
PROCEDURE EmptyBuffer(self: T; wr: Wr.T) RAISES {Failure, Alerted} =
VAR n := self.cur - self.lo;
BEGIN
<*ASSERT self.st = 0*>
wr.putString(SUBARRAY(self.buff^, 0, n));
END EmptyBuffer;
PROCEDURE PutString (self: T; READONLY a: ARRAY OF CHAR)
RAISES {Failure, Alerted} =
VAR
key: Text.T;
val: Refany.T;
BEGIN
WITH i = self.wrs.iterate() DO
WHILE i.next(key, val) DO
WITH wr = NARROW(val, Wr.T) DO
EmptyBuffer(self, wr);
wr.putString(a);
END;
END;
END;
INC(self.cur, NUMBER(a));
INC(self.hi, NUMBER(a));
self.lo := self.cur;
END PutString;
PROCEDURE Flush (self: T) RAISES {Failure, Alerted} =
VAR
key: Text.T;
val: Refany.T;
BEGIN
WITH i = self.wrs.iterate() DO
WHILE i.next(key, val) DO
WITH wr = NARROW(val, Wr.T) DO
EmptyBuffer(self, wr);
END;
END;
END;
self.lo := self.cur;
END Flush;
PROCEDURE Close(self: T) =
BEGIN
self.wrs := NIL;
END Close;
PROCEDURE Tee(self: T; name: Text.T; wr: Wr.T) RAISES {Failure} =
VAR
val: Refany.T;
BEGIN
IF self.wrs.get(name, val) THEN
RAISE Wr.Failure(AtomList.List1(Atom.FromText(
"writer already teed")));
END;
val := wr;
IF NOT self.wrs.put(name, val) THEN
RAISE Wr.Failure(AtomList.List1(Atom.FromText(
"writer couldn't be added to tee")));
END;
END Tee;
PROCEDURE Untee(self: T; name: Text.T): Wr.T RAISES {Failure} =
VAR wr: Refany.T;
BEGIN
IF NOT self.wrs.delete(name, wr) THEN
RAISE Wr.Failure(AtomList.List1(Atom.FromText("writer not in tee")));
END;
RETURN NARROW(wr, Wr.T);
END Untee;
BEGIN
END TeeWr.