001: /*
002: *
003: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License version
008: * 2 only, as published by the Free Software Foundation.
009: *
010: * This program is distributed in the hope that it will be useful, but
011: * WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * General Public License version 2 for more details (a copy is
014: * included at /legal/license.txt).
015: *
016: * You should have received a copy of the GNU General Public License
017: * version 2 along with this work; if not, write to the Free Software
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019: * 02110-1301 USA
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
022: * Clara, CA 95054 or visit www.sun.com if you need additional
023: * information or have any questions.
024: */
025:
026: package com.sun.perseus.platform;
027:
028: import java.io.InputStream;
029:
030: import java.io.IOException;
031:
032: /**
033: * A <code>FilterInputStream</code> contains
034: * some other input stream, which it uses as
035: * its basic source of data, possibly transforming
036: * the data along the way or providing additional
037: * functionality. The class <code>FilterInputStream</code>
038: * itself simply overrides all methods of
039: * <code>InputStream</code> with versions that
040: * pass all requests to the contained input
041: * stream. Subclasses of <code>FilterInputStream</code>
042: * may further override some of these methods
043: * and may also provide additional methods
044: * and fields.
045: *
046: */
047: public class FilterInputStream extends InputStream {
048: /**
049: * The input stream to be filtered.
050: */
051: protected InputStream in;
052:
053: /**
054: * Creates a <code>FilterInputStream</code>
055: * by assigning the argument <code>in</code>
056: * to the field <code>this.in</code> so as
057: * to remember it for later use.
058: *
059: * @param in the underlying input stream, or <code>null</code> if
060: * this instance is to be created without an underlying stream.
061: */
062: protected FilterInputStream(InputStream in) {
063: this .in = in;
064: }
065:
066: /**
067: * Reads the next byte of data from this input stream. The value
068: * byte is returned as an <code>int</code> in the range
069: * <code>0</code> to <code>255</code>. If no byte is available
070: * because the end of the stream has been reached, the value
071: * <code>-1</code> is returned. This method blocks until input data
072: * is available, the end of the stream is detected, or an exception
073: * is thrown.
074: * <p>
075: * This method
076: * simply performs <code>in.read()</code> and returns the result.
077: *
078: * @return the next byte of data, or <code>-1</code> if the end of the
079: * stream is reached.
080: * @exception IOException if an I/O error occurs.
081: * @see java.io.FilterInputStream#in
082: */
083: public int read() throws IOException {
084: return in.read();
085: }
086:
087: /**
088: * Reads up to <code>byte.length</code> bytes of data from this
089: * input stream into an array of bytes. This method blocks until some
090: * input is available.
091: * <p>
092: * This method simply performs the call
093: * <code>read(b, 0, b.length)</code> and returns
094: * the result. It is important that it does
095: * <i>not</i> do <code>in.read(b)</code> instead;
096: * certain subclasses of <code>FilterInputStream</code>
097: * depend on the implementation strategy actually
098: * used.
099: *
100: * @param b the buffer into which the data is read.
101: * @return the total number of bytes read into the buffer, or
102: * <code>-1</code> if there is no more data because the end of
103: * the stream has been reached.
104: * @exception IOException if an I/O error occurs.
105: * @see java.io.FilterInputStream#read(byte[], int, int)
106: */
107: public int read(byte b[]) throws IOException {
108: return read(b, 0, b.length);
109: }
110:
111: /**
112: * Reads up to <code>len</code> bytes of data from this input stream
113: * into an array of bytes. This method blocks until some input is
114: * available.
115: * <p>
116: * This method simply performs <code>in.read(b, off, len)</code>
117: * and returns the result.
118: *
119: * @param b the buffer into which the data is read.
120: * @param off the start offset of the data.
121: * @param len the maximum number of bytes read.
122: * @return the total number of bytes read into the buffer, or
123: * <code>-1</code> if there is no more data because the end of
124: * the stream has been reached.
125: * @exception IOException if an I/O error occurs.
126: * @see java.io.FilterInputStream#in
127: */
128: public int read(byte b[], int off, int len) throws IOException {
129: return in.read(b, off, len);
130: }
131:
132: /**
133: * Skips over and discards <code>n</code> bytes of data from the
134: * input stream. The <code>skip</code> method may, for a variety of
135: * reasons, end up skipping over some smaller number of bytes,
136: * possibly <code>0</code>. The actual number of bytes skipped is
137: * returned.
138: * <p>
139: * This method
140: * simply performs <code>in.skip(n)</code>.
141: *
142: * @param n the number of bytes to be skipped.
143: * @return the actual number of bytes skipped.
144: * @exception IOException if an I/O error occurs.
145: */
146: public long skip(long n) throws IOException {
147: return in.skip(n);
148: }
149:
150: /**
151: * Returns the number of bytes that can be read from this input
152: * stream without blocking.
153: * <p>
154: * This method
155: * simply performs <code>in.available(n)</code> and
156: * returns the result.
157: *
158: * @return the number of bytes that can be read from the input stream
159: * without blocking.
160: * @exception IOException if an I/O error occurs.
161: * @see java.io.FilterInputStream#in
162: */
163: public int available() throws IOException {
164: return in.available();
165: }
166:
167: /**
168: * Closes this input stream and releases any system resources
169: * associated with the stream.
170: * This
171: * method simply performs <code>in.close()</code>.
172: *
173: * @exception IOException if an I/O error occurs.
174: * @see java.io.FilterInputStream#in
175: */
176: public void close() throws IOException {
177: in.close();
178: }
179:
180: /**
181: * Marks the current position in this input stream. A subsequent
182: * call to the <code>reset</code> method repositions this stream at
183: * the last marked position so that subsequent reads re-read the same bytes.
184: * <p>
185: * The <code>readlimit</code> argument tells this input stream to
186: * allow that many bytes to be read before the mark position gets
187: * invalidated.
188: * <p>
189: * This method simply performs <code>in.mark(readlimit)</code>.
190: *
191: * @param readlimit the maximum limit of bytes that can be read before
192: * the mark position becomes invalid.
193: * @see java.io.FilterInputStream#in
194: * @see java.io.FilterInputStream#reset()
195: */
196: public synchronized void mark(int readlimit) {
197: in.mark(readlimit);
198: }
199:
200: /**
201: * Repositions this stream to the position at the time the
202: * <code>mark</code> method was last called on this input stream.
203: * <p>
204: * This method
205: * simply performs <code>in.reset()</code>.
206: * <p>
207: * Stream marks are intended to be used in
208: * situations where you need to read ahead a little to see what's in
209: * the stream. Often this is most easily done by invoking some
210: * general parser. If the stream is of the type handled by the
211: * parse, it just chugs along happily. If the stream is not of
212: * that type, the parser should toss an exception when it fails.
213: * If this happens within readlimit bytes, it allows the outer
214: * code to reset the stream and try another parser.
215: *
216: * @exception IOException if the stream has not been marked or if the
217: * mark has been invalidated.
218: * @see java.io.FilterInputStream#in
219: * @see java.io.FilterInputStream#mark(int)
220: */
221: public synchronized void reset() throws IOException {
222: in.reset();
223: }
224:
225: /**
226: * Tests if this input stream supports the <code>mark</code>
227: * and <code>reset</code> methods.
228: * This method
229: * simply performs <code>in.markSupported()</code>.
230: *
231: * @return <code>true</code> if this stream type supports the
232: * <code>mark</code> and <code>reset</code> method;
233: * <code>false</code> otherwise.
234: * @see java.io.FilterInputStream#in
235: * @see java.io.InputStream#mark(int)
236: * @see java.io.InputStream#reset()
237: */
238: public boolean markSupported() {
239: return in.markSupported();
240: }
241: }
|