/* SequenceInputStream.java -- Reads multiple input streams in sequence
   Copyright (C) 1998, 1999, 2001, 2004, 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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, or (at your option)
any later version.
 
GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.io;

import java.util.Enumeration;

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
 * Status:  Believed complete and correct.
 */
 
/**
  * This class merges a sequence of multiple <code>InputStream</code>'s in
  * order to form a single logical stream that can be read by applications
  * that expect only one stream.
  * <p>
  * The streams passed to the constructor method are read in order until
  * they return -1 to indicate they are at end of stream.  When a stream
  * reports end of stream, it is closed, then the next stream is read.
  * When the last stream is closed, the next attempt to read from this
  * stream will return a -1 to indicate it is at end of stream.
  * <p>
  * If this stream is closed prior to all subordinate streams being read
  * to completion, all subordinate streams are closed.
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  * @author Warren Levy (warrenl@cygnus.com)
  */
public class SequenceInputStream extends InputStream
{
  /** The handle for the current input stream. */
  private InputStream in;

  /** Secondary input stream; not used if constructed w/ enumeration. */
  private InputStream in2;

  /**
   * The enumeration handle; not used if constructed w/ 2 explicit
   * input streams.
   */
  private Enumeration<? extends InputStream> e;

 /**
  * This method creates a new <code>SequenceInputStream</code> that obtains
  * its list of subordinate <code>InputStream</code>s from the specified
  * <code>Enumeration</code>
  *
  * @param e An <code>Enumeration</code> that will return a list of
  * <code>InputStream</code>s to read in sequence
  */
  public SequenceInputStream(Enumeration<? extends InputStream> e)
  {
    this.e = e;
    in = e.nextElement();
    in2 = null;
  }

 /**
  * This method creates a new <code>SequenceInputStream</code> that will read
  * the two specified subordinate <code>InputStream</code>s in sequence.
  *
  * @param s1 The first <code>InputStream</code> to read
  * @param s2 The second <code>InputStream</code> to read
  */
  public SequenceInputStream(InputStream s1, InputStream s2)
  {
    in = s1;
    in2 = s2;
  }

 /**
  * This method returns the number of bytes than can be read from the
  * currently being read subordinate stream before that stream could
  * block.  Note that it is possible more bytes than this can actually
  * be read without the stream blocking.  If a 0 is returned, then the
  * stream could block on the very next read.
  *
  * @return The number of bytes that can be read before blocking could occur
  *
  * @exception IOException If an error occurs
  */
  public int available() throws IOException
  {
    if (in == null)
      return 0;

    return in.available();
  }

 /**
  * Closes this stream.  This will cause any remaining unclosed subordinate
  * <code>InputStream</code>'s to be closed as well.  Subsequent attempts to 
  * read from this stream may cause an exception.
  *
  * @exception IOException If an error occurs
  */
  public void close() throws IOException
  {
    while (in != null)
      {
	in.close();
	in = getNextStream ();
      }
  }

 /**
  * This method reads an unsigned byte from the input stream and returns it
  * as an int in the range of 0-255.  This method also will return -1 if
  * the end of the stream has been reached.  This will only happen when
  * all of the subordinate streams have been read.
  * <p>
  * This method will block until the byte can be read.
  *
  * @return The byte read, or -1 if end of stream
  *
  * @exception IOException If an error occurs
  */
  public int read() throws IOException
  {
    int ch = -1;

    while (in != null && (ch = in.read()) < 0)
      {
	in.close();
        in = getNextStream();
      }

    return ch;
  }

 /**
  * This method reads bytes from a stream and stores them into a caller
  * supplied buffer.  It starts storing the data at index <code>offset</code>
  * into the buffer and attempts to read <code>len</code> bytes. This method
  * can return before reading the number of bytes requested. The actual number
  * of bytes read is returned as an int. A -1 is returend to indicate the
  * end of the stream. This will only happen when all of the subordinate
  * streams have been read.
  * <p>
  * This method will block until at least one byte can be read.
  *
  * @param b The array into which bytes read should be stored
  * @param off The offset into the array to start storing bytes
  * @param len The requested number of bytes to read
  *
  * @return The actual number of bytes read, or -1 if end of stream
  *
  * @exception IOException If an error occurs
  */
  public int read(byte[] b, int off, int len) throws IOException
  {
    int ch = -1;

    // The validity of the parameters will be checked by in.read so
    // don't bother doing it here.
    while (in != null && (ch = in.read(b, off, len)) < 0)
      {
	in.close();
        in = getNextStream();
      }

    return ch;
  }

 /**
  * This private method is used to get the next <code>InputStream</code> to
  * read from. Returns null when no more streams are available.
  */
  private InputStream getNextStream()
  {
    InputStream nextIn = null;

    if (e != null)
      {
        if (e.hasMoreElements())
	  nextIn = e.nextElement();
      }
    else if (in2 != null)
      {
	nextIn = in2;
	in2 = null;
      }

    return nextIn;
  }
}
