/* * `gnu.iou' * Copyright (C) 2006 John Pritchard. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA */ package gnu.iou ; import java.io.IOException; import java.io.OutputStream; /** * Output stream <tt>`tee'</tt>. * * @author John Pritchard (john@syntelos.org) * * @see pte */ public class tee extends OutputStream { protected volatile OutputStream fir ; protected volatile OutputStream sec ; protected volatile OutputStream thi ; public tee ( OutputStream first, OutputStream second ){ super(); if ( null == first) throw new IllegalArgumentException("Constructing `tee(2)' with one stream?"); else this.fir = first; if ( null == second) throw new IllegalArgumentException("Constructing `tee(2)' with one stream?"); else this.sec = second; } public tee ( tee first, OutputStream third ){ this(first.fir,first.sec); if ( null == third) throw new IllegalArgumentException("Constructing `tee(3)' with two streams?"); else this.thi = third; } public OutputStream teeOrig(){ if ( this.fir instanceof tee) return ((tee)this.fir).teeOrig(); else return fir; } public boolean teeFull(){ return (null != this.thi);} public boolean teeEmpty(){ return (null == this.sec);} protected void teeAdd( OutputStream ps){ if ( null != ps){ if ( null == this.sec) this.sec = ps; else if ( null == this.thi) this.thi = ps; else if ( this.thi instanceof tee) ((tee)this.thi).teeAdd(ps); else { tee t = new tee( this.thi, ps); this.thi = t; } } } /** * @exception IllegalStateException Attempting to remove first * stream from tee (ie, when tee is empty -- only one stream in * it). */ protected void teeRemove( OutputStream ps){ if ( null != ps){ if ( ps == this.thi) this.thi = null; else if ( ps == this.sec){ if ( null != this.thi){ OutputStream t = this.thi; this.thi = null; this.sec = t; } else this.sec = null; } else if ( ps == this.fir){ if ( null != this.thi){ OutputStream t = this.thi; this.thi = null; OutputStream s = this.sec; this.sec = t; this.fir = s; } else if ( null != this.sec){ OutputStream s = this.sec; this.sec = null; this.fir = this.sec; } else throw new IllegalStateException("Removing root from tee."); } else if ( this.thi instanceof tee){ try { ((tee)this.thi).teeRemove(ps); } catch ( IllegalStateException mmt){ this.thi = null; // is empty } } } } public void write ( int b) throws IOException { fir.write(b); if ( null != sec) sec.write(b); if ( null != thi) thi.write(b); } public void write ( byte[] b) throws IOException { this.write(b,0,b.length); } public void write ( byte[] b, int ofs, int len) throws IOException { fir.write(b, ofs, len); if ( null != sec) sec.write(b, ofs, len); if ( null != thi) thi.write(b, ofs, len); } public void flush() throws IOException { fir.flush(); if ( null != sec) sec.flush(); if ( null != thi) thi.flush(); } /** * @exception IllegalStateException Can't use `close()' on a tee. */ public void close() throws IOException { throw new IllegalStateException("Close not available on output tee."); } }