MuxOutputStream.java :  » Web-Server » Jigsaw » org » w3c » www » mux » Java Open Source

Java Open Source » Web Server » Jigsaw 
Jigsaw » org » w3c » www » mux » MuxOutputStream.java
// MuxOutputStream.java
// $Id: MuxOutputStream.java,v 1.9 2000/08/16 21:38:01 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.www.mux;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

public class MuxOutputStream extends OutputStream {
    protected static final boolean debug = false;

    /**
     * The session this stream is attached to.
     */
    protected MuxSession session = null;
    /**
     * The identifier of above session (fast access).
     */
    protected int sessid = -1;
    /**
     * The writer instance for the multiplexed stream.
     */
    protected MuxWriter writer = null;
    /**
     * The current max allowed fragment size.
     */
    protected int fragsz = MUX.SENDER_DEFAULT_FRAGMENT_SIZE;
    /**
     * The currently available credit.
     */
    protected int avail_credit = MUX.SENDER_DEFAULT_CREDIT;
    /**
     * Has this stream been closed ?
     */
    protected boolean closed = false;

    /**
     * Callback notifying that more credit is available for that stream.
     * @param credit The credit we are getting from our peer.
     */

    protected synchronized void notifyCredit(int credit) {
  if ( debug )
      System.out.println("> notifyCredit["+sessid+"]: "+credit);
  avail_credit += credit;
  notifyAll();
    }

    /**
     * Callback notifying the the frgament size has changed.
     * @param control The new fragment size.
     */

    protected synchronized void notifyControl(int control) {
  if ( debug )
      System.out.println("notifyControl: "+control);
  fragsz = control;
    }

    /**
     * Emit the given data on current session.
     * @param b The buffer containing the data to be emitted.
     * @param off Offset of data within above buffer.
     * @param len Length of data to be written,
     */

    private synchronized void send(byte b[], int off, int len) 
  throws IOException
    {
  // Otherwise perform:
  while (len > 0) {
      // Make sure we have some remaining credit:
      while ( avail_credit <= 0 ) {
    // If closed, trigger an error:
    if ( closed ) 
        throw new IOException("Broken pipe");
    writer.flush();
    try {
        wait();
    } catch (InterruptedException ex) {
        throw new IOException("Interrupted IO !");
    }
      }
      // Chunk (if needed) until all available credit has been consumed
      while ( avail_credit > 0 ) {
    if ( fragsz <= 0 ) {
        int sz = Math.min(avail_credit, len);
        writer.writeData(sessid, b, off, sz);
        len -= sz;
        off += sz;
        avail_credit -= sz;
    } else if (len < fragsz ) {
        // No fragmentation needed, we can sink all our data:
        writer.writeData(sessid, b, off, len);
        avail_credit -= len;
        return;
    } else {
        // Emit only one single chunk:
        writer.writeData(sessid, b, off, fragsz);
        len -= fragsz;
        off += fragsz;
        avail_credit -= fragsz;
    }
      }
  }
    }

    /**
     * Writes a byte. This method will block until the byte is actually
     * written.
     * It is <em>highly</em> recomended that you use a buffered output
     * stream on top of that stream, or that you don't use that method.
     * @param b  the byte
     * @exception IOException If an I/O error has occurred.
     */

    public void write(int b) 
  throws IOException
    {
  byte bits[] = new byte[1];
  bits[0] = (byte) (b&0xff);
  write(bits, 0, 1);
    }

    /**
     * Writes a sub array of bytes. 
     * @param b  the data to be written
     * @param off  the start offset in the data
     * @param len  the number of bytes that are written
     * @exception IOException If an I/O error has occurred.
     */

    public void write(byte b[], int off, int len) 
  throws IOException
    {
  send(b, off, len);
    }

    /**
     * Flush that output stream, blocking all data has been sent.
     * @exception IOException If some IO errors occur.
     */

    public void flush() 
  throws IOException
    {
  writer.flush();
    }

    /**
     * Close that session output stream.
     * @exception IOException If some IO errors occur.
     */

    public synchronized void close()
  throws IOException
    {
  if ( closed )
      return;
  closed = true;
  session.sendFIN();
  notifyAll();
  return ;
    }

    protected MuxOutputStream(MuxSession session) {
  this.session = session;
  this.sessid  = session.getIdentifier();
  this.writer  = session.getMuxStream().getMuxWriter();
    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.