KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > zip > InflaterInputStream


1 /*
2  * @(#)InflaterInputStream.java 1.37 04/06/11
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.zip;
9
10 import java.io.FilterInputStream JavaDoc;
11 import java.io.InputStream JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.EOFException JavaDoc;
14
15 /**
16  * This class implements a stream filter for uncompressing data in the
17  * "deflate" compression format. It is also used as the basis for other
18  * decompression filters, such as GZIPInputStream.
19  *
20  * @see Inflater
21  * @version 1.37, 06/11/04
22  * @author David Connelly
23  */

24 public
25 class InflaterInputStream extends FilterInputStream JavaDoc {
26     /**
27      * Decompressor for this stream.
28      */

29     protected Inflater JavaDoc inf;
30
31     /**
32      * Input buffer for decompression.
33      */

34     protected byte[] buf;
35
36     /**
37      * Length of input buffer.
38      */

39     protected int len;
40
41     private boolean closed = false;
42     // this flag is set to true after EOF has reached
43
private boolean reachEOF = false;
44     
45     /**
46      * Check to make sure that this stream has not been closed
47      */

48     private void ensureOpen() throws IOException JavaDoc {
49     if (closed) {
50         throw new IOException JavaDoc("Stream closed");
51         }
52     }
53
54
55     /**
56      * Creates a new input stream with the specified decompressor and
57      * buffer size.
58      * @param in the input stream
59      * @param inf the decompressor ("inflater")
60      * @param size the input buffer size
61      * @exception IllegalArgumentException if size is <= 0
62      */

63     public InflaterInputStream(InputStream JavaDoc in, Inflater JavaDoc inf, int size) {
64     super(in);
65         if (in == null || inf == null) {
66             throw new NullPointerException JavaDoc();
67         } else if (size <= 0) {
68             throw new IllegalArgumentException JavaDoc("buffer size <= 0");
69         }
70     this.inf = inf;
71     buf = new byte[size];
72     }
73
74     /**
75      * Creates a new input stream with the specified decompressor and a
76      * default buffer size.
77      * @param in the input stream
78      * @param inf the decompressor ("inflater")
79      */

80     public InflaterInputStream(InputStream JavaDoc in, Inflater JavaDoc inf) {
81     this(in, inf, 512);
82     }
83
84     boolean usesDefaultInflater = false;
85
86     /**
87      * Creates a new input stream with a default decompressor and buffer size.
88      * @param in the input stream
89      */

90     public InflaterInputStream(InputStream JavaDoc in) {
91     this(in, new Inflater JavaDoc());
92         usesDefaultInflater = true;
93     }
94
95     private byte[] singleByteBuf = new byte[1];
96
97     /**
98      * Reads a byte of uncompressed data. This method will block until
99      * enough input is available for decompression.
100      * @return the byte read, or -1 if end of compressed input is reached
101      * @exception IOException if an I/O error has occurred
102      */

103     public int read() throws IOException JavaDoc {
104     ensureOpen();
105     return read(singleByteBuf, 0, 1) == -1 ? -1 : singleByteBuf[0] & 0xff;
106     }
107
108     /**
109      * Reads uncompressed data into an array of bytes. This method will
110      * block until some input can be decompressed.
111      * @param b the buffer into which the data is read
112      * @param off the start offset of the data
113      * @param len the maximum number of bytes read
114      * @return the actual number of bytes read, or -1 if the end of the
115      * compressed input is reached or a preset dictionary is needed
116      * @exception ZipException if a ZIP format error has occurred
117      * @exception IOException if an I/O error has occurred
118      */

119     public int read(byte[] b, int off, int len) throws IOException JavaDoc {
120     ensureOpen();
121         if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
122         throw new IndexOutOfBoundsException JavaDoc();
123     } else if (len == 0) {
124         return 0;
125     }
126     try {
127         int n;
128         while ((n = inf.inflate(b, off, len)) == 0) {
129         if (inf.finished() || inf.needsDictionary()) {
130                     reachEOF = true;
131             return -1;
132         }
133         if (inf.needsInput()) {
134             fill();
135         }
136         }
137         return n;
138     } catch (DataFormatException JavaDoc e) {
139         String JavaDoc s = e.getMessage();
140         throw new ZipException JavaDoc(s != null ? s : "Invalid ZLIB data format");
141     }
142     }
143
144     /**
145      * Returns 0 after EOF has been reached, otherwise always return 1.
146      * <p>
147      * Programs should not count on this method to return the actual number
148      * of bytes that could be read without blocking.
149      *
150      * @return 1 before EOF and 0 after EOF.
151      * @exception IOException if an I/O error occurs.
152      *
153      */

154     public int available() throws IOException JavaDoc {
155         ensureOpen();
156         if (reachEOF) {
157             return 0;
158         } else {
159             return 1;
160         }
161     }
162
163     private byte[] b = new byte[512];
164
165     /**
166      * Skips specified number of bytes of uncompressed data.
167      * @param n the number of bytes to skip
168      * @return the actual number of bytes skipped.
169      * @exception IOException if an I/O error has occurred
170      * @exception IllegalArgumentException if n < 0
171      */

172     public long skip(long n) throws IOException JavaDoc {
173         if (n < 0) {
174             throw new IllegalArgumentException JavaDoc("negative skip length");
175         }
176     ensureOpen();
177     int max = (int)Math.min(n, Integer.MAX_VALUE);
178     int total = 0;
179     while (total < max) {
180         int len = max - total;
181         if (len > b.length) {
182         len = b.length;
183         }
184         len = read(b, 0, len);
185         if (len == -1) {
186                 reachEOF = true;
187         break;
188         }
189         total += len;
190     }
191     return total;
192     }
193
194     /**
195      * Closes this input stream and releases any system resources associated
196      * with the stream.
197      * @exception IOException if an I/O error has occurred
198      */

199     public void close() throws IOException JavaDoc {
200         if (!closed) {
201             if (usesDefaultInflater)
202                 inf.end();
203         in.close();
204             closed = true;
205         }
206     }
207
208     /**
209      * Fills input buffer with more data to decompress.
210      * @exception IOException if an I/O error has occurred
211      */

212     protected void fill() throws IOException JavaDoc {
213     ensureOpen();
214     len = in.read(buf, 0, buf.length);
215     if (len == -1) {
216         throw new EOFException JavaDoc("Unexpected end of ZLIB input stream");
217     }
218     inf.setInput(buf, 0, len);
219     }
220
221     /**
222      * Tests if this input stream supports the <code>mark</code> and
223      * <code>reset</code> methods. The <code>markSupported</code>
224      * method of <code>InflaterInputStream</code> returns
225      * <code>false</code>.
226      *
227      * @return a <code>boolean</code> indicating if this stream type supports
228      * the <code>mark</code> and <code>reset</code> methods.
229      * @see java.io.InputStream#mark(int)
230      * @see java.io.InputStream#reset()
231      */

232     public boolean markSupported() {
233         return false;
234     }
235  
236     /**
237      * Marks the current position in this input stream.
238      *
239      * <p> The <code>mark</code> method of <code>InflaterInputStream</code>
240      * does nothing.
241      *
242      * @param readlimit the maximum limit of bytes that can be read before
243      * the mark position becomes invalid.
244      * @see java.io.InputStream#reset()
245      */

246     public synchronized void mark(int readlimit) {
247     }
248  
249     /**
250      * Repositions this stream to the position at the time the
251      * <code>mark</code> method was last called on this input stream.
252      *
253      * <p> The method <code>reset</code> for class
254      * <code>InflaterInputStream</code> does nothing except throw an
255      * <code>IOException</code>.
256      *
257      * @exception IOException if this method is invoked.
258      * @see java.io.InputStream#mark(int)
259      * @see java.io.IOException
260      */

261     public synchronized void reset() throws IOException JavaDoc {
262         throw new IOException JavaDoc("mark/reset not supported");
263     }
264 }
265
Popular Tags