diff options
author | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 00:30:23 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 00:30:23 +0000 |
commit | f911ba985aa7fe0096c386c5be385ac5825ea527 (patch) | |
tree | a0b991cf5866ae1d616639b906ac001811d74508 /libjava/classpath/java/io/SequenceInputStream.java | |
parent | 6f4434b39b261de5317dc81ddfdd94d2e1d62b11 (diff) | |
download | gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.zip gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.gz gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.bz2 |
Initial revision
From-SVN: r102074
Diffstat (limited to 'libjava/classpath/java/io/SequenceInputStream.java')
-rw-r--r-- | libjava/classpath/java/io/SequenceInputStream.java | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/libjava/classpath/java/io/SequenceInputStream.java b/libjava/classpath/java/io/SequenceInputStream.java new file mode 100644 index 0000000..7fefe24 --- /dev/null +++ b/libjava/classpath/java/io/SequenceInputStream.java @@ -0,0 +1,221 @@ +/* SequenceInputStream.java -- Reads multiple input streams in sequence + Copyright (C) 1998, 1999, 2001, 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 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 e) + { + this.e = e; + in = (InputStream) 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 = (InputStream) e.nextElement(); + } + else + if (in2 != null) + { + nextIn = in2; + in2 = null; + } + + return nextIn; + } +} |