KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)DeflaterInputStream.java 1.1 06/01/30
3  *
4  * Copyright 2006 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
14 /**
15  * Implements an input stream filter for compressing data in the "deflate"
16  * compression format.
17  *
18  * @version 1.1
19  * @since 1.6
20  * @author David R Tribble (david@tribble.com)
21  *
22  * @see DeflaterOutputStream
23  * @see InflaterOutputStream
24  * @see InflaterInputStream
25  */

26
27 public class DeflaterInputStream extends FilterInputStream JavaDoc {
28     /** Compressor for this stream. */
29     protected final Deflater JavaDoc def;
30
31     /** Input buffer for reading compressed data. */
32     protected final byte[] buf;
33
34     /** Temporary read buffer. */
35     private byte[] rbuf = new byte[1];
36
37     /** Default compressor is used. */
38     private boolean usesDefaultDeflater = false;
39
40     /** End of the underlying input stream has been reached. */
41     private boolean reachEOF = false;
42
43     /**
44      * Check to make sure that this stream has not been closed.
45      */

46     private void ensureOpen() throws IOException JavaDoc {
47         if (in == null) {
48             throw new IOException JavaDoc("Stream closed");
49         }
50     }
51
52     /**
53      * Creates a new input stream with a default compressor and buffer
54      * size.
55      *
56      * @param in input stream to read the uncompressed data to
57      * @throws NullPointerException if {@code in} is null
58      */

59     public DeflaterInputStream(InputStream JavaDoc in) {
60         this(in, new Deflater JavaDoc());
61         usesDefaultDeflater = true;
62     }
63
64     /**
65      * Creates a new input stream with the specified compressor and a
66      * default buffer size.
67      *
68      * @param in input stream to read the uncompressed data to
69      * @param defl compressor ("deflater") for this stream
70      * @throws NullPointerException if {@code in} or {@code defl} is null
71      */

72     public DeflaterInputStream(InputStream JavaDoc in, Deflater JavaDoc defl) {
73         this(in, defl, 512);
74     }
75
76     /**
77      * Creates a new input stream with the specified compressor and buffer
78      * size.
79      *
80      * @param in input stream to read the uncompressed data to
81      * @param defl compressor ("deflater") for this stream
82      * @param bufLen compression buffer size
83      * @throws IllegalArgumentException if {@code bufLen} is <= 0
84      * @throws NullPointerException if {@code in} or {@code defl} is null
85      */

86     public DeflaterInputStream(InputStream JavaDoc in, Deflater JavaDoc defl, int bufLen) {
87         super(in);
88
89         // Sanity checks
90
if (in == null)
91             throw new NullPointerException JavaDoc("Null input");
92         if (defl == null)
93             throw new NullPointerException JavaDoc("Null deflater");
94         if (bufLen < 1)
95             throw new IllegalArgumentException JavaDoc("Buffer size < 1");
96
97         // Initialize
98
def = defl;
99         buf = new byte[bufLen];
100     }
101
102     /**
103      * Closes this input stream and its underlying input stream, discarding
104      * any pending uncompressed data.
105      *
106      * @throws IOException if an I/O error occurs
107      */

108     public void close() throws IOException JavaDoc {
109         if (in != null) {
110             try {
111                 // Clean up
112
if (usesDefaultDeflater) {
113                     def.end();
114                 }
115
116                 in.close();
117             } finally {
118                 in = null;
119             }
120         }
121     }
122
123     /**
124      * Reads a single byte of compressed data from the input stream.
125      * This method will block until some input can be read and compressed.
126      *
127      * @return a single byte of compressed data, or -1 if the end of the
128      * uncompressed input stream is reached
129      * @throws IOException if an I/O error occurs or if this stream is
130      * already closed
131      */

132     public int read() throws IOException JavaDoc {
133         // Read a single byte of compressed data
134
int len = read(rbuf, 0, 1);
135         if (len <= 0)
136             return -1;
137         return (rbuf[0] & 0xFF);
138     }
139
140     /**
141      * Reads compressed data into a byte array.
142      * This method will block until some input can be read and compressed.
143      *
144      * @param b buffer into which the data is read
145      * @param off starting offset of the data within {@code b}
146      * @param len maximum number of compressed bytes to read into {@code b}
147      * @return the actual number of bytes read, or -1 if the end of the
148      * uncompressed input stream is reached
149      * @throws IndexOutOfBoundsException if {@code len} > {@code b.length -
150      * off}
151      * @throws IOException if an I/O error occurs or if this input stream is
152      * already closed
153      */

154     public int read(byte[] b, int off, int len) throws IOException JavaDoc {
155         // Sanity checks
156
ensureOpen();
157         if (b == null) {
158             throw new NullPointerException JavaDoc("Null buffer for read");
159         } else if (off < 0 || len < 0 || len > b.length - off) {
160             throw new IndexOutOfBoundsException JavaDoc();
161         } else if (len == 0) {
162             return 0;
163         }
164
165         // Read and compress (deflate) input data bytes
166
int cnt = 0;
167         while (len > 0 && !def.finished()) {
168             int n;
169
170             // Read data from the input stream
171
if (def.needsInput()) {
172                 n = in.read(buf, 0, buf.length);
173                 if (n < 0) {
174                     // End of the input stream reached
175
def.finish();
176                 } else if (n > 0) {
177                     def.setInput(buf, 0, n);
178                 }
179             }
180
181             // Compress the input data, filling the read buffer
182
n = def.deflate(b, off, len);
183             cnt += n;
184             off += n;
185             len -= n;
186         }
187         if (cnt == 0 && def.finished()) {
188             reachEOF = true;
189             cnt = -1;
190         }
191
192         return cnt;
193     }
194
195     /**
196      * Skips over and discards data from the input stream.
197      * This method may block until the specified number of bytes are read and
198      * skipped. <em>Note:</em> While {@code n} is given as a {@code long},
199      * the maximum number of bytes which can be skipped is
200      * {@code Integer.MAX_VALUE}.
201      *
202      * @param n number of bytes to be skipped
203      * @return the actual number of bytes skipped
204      * @throws IOException if an I/O error occurs or if this stream is
205      * already closed
206      */

207     public long skip(long n) throws IOException JavaDoc {
208         if (n < 0) {
209             throw new IllegalArgumentException JavaDoc("negative skip length");
210         }
211         ensureOpen();
212
213         // Skip bytes by repeatedly decompressing small blocks
214
if (rbuf.length < 512)
215             rbuf = new byte[512];
216
217         int total = (int)Math.min(n, Integer.MAX_VALUE);
218         long cnt = 0;
219         while (total > 0) {
220             // Read a small block of uncompressed bytes
221
int len = read(rbuf, 0, (total <= rbuf.length ? total : rbuf.length));
222
223             if (len < 0) {
224                 break;
225             }
226             cnt += len;
227             total -= len;
228         }
229         return cnt;
230     }
231
232     /**
233      * Returns 0 after EOF has been reached, otherwise always return 1.
234      * <p>
235      * Programs should not count on this method to return the actual number
236      * of bytes that could be read without blocking
237      * @return zero after the end of the underlying input stream has been
238      * reached, otherwise always returns 1
239      * @throws IOException if an I/O error occurs or if this stream is
240      * already closed
241      */

242     public int available() throws IOException JavaDoc {
243         ensureOpen();
244         if (reachEOF) {
245             return 0;
246         }
247         return 1;
248     }
249
250     /**
251      * Always returns {@code false} because this input stream does not support
252      * the {@link #mark mark()} and {@link #reset reset()} methods.
253      *
254      * @return false, always
255      */

256     public boolean markSupported() {
257         return false;
258     }
259
260     /**
261      * <i>This operation is not supported</i>.
262      *
263      * @param limit maximum bytes that can be read before invalidating the position marker
264      */

265     public void mark(int limit) {
266         // Operation not supported
267
}
268
269     /**
270      * <i>This operation is not supported</i>.
271      *
272      * @throws IOException always thrown
273      */

274     public void reset() throws IOException JavaDoc {
275         throw new IOException JavaDoc("mark/reset not supported");
276     }
277 }
278
Popular Tags