KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)Deflater.java 1.43 05/11/11
3  *
4  * Copyright 2005 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 /**
11  * This class provides support for general purpose compression using the
12  * popular ZLIB compression library. The ZLIB compression library was
13  * initially developed as part of the PNG graphics standard and is not
14  * protected by patents. It is fully described in the specifications at
15  * the <a HREF="package-summary.html#package_description">java.util.zip
16  * package description</a>.
17  *
18  * <p>The following code fragment demonstrates a trivial compression
19  * and decompression of a string using <tt>Deflater</tt> and
20  * <tt>Inflater</tt>.
21  *
22  * <blockquote><pre>
23  * // Encode a String into bytes
24  * String inputString = "blahblahblah€€";
25  * byte[] input = inputString.getBytes("UTF-8");
26  *
27  * // Compress the bytes
28  * byte[] output = new byte[100];
29  * Deflater compresser = new Deflater();
30  * compresser.setInput(input);
31  * compresser.finish();
32  * int compressedDataLength = compresser.deflate(output);
33  *
34  * // Decompress the bytes
35  * Inflater decompresser = new Inflater();
36  * decompresser.setInput(output, 0, compressedDataLength);
37  * byte[] result = new byte[100];
38  * int resultLength = decompresser.inflate(result);
39  * decompresser.end();
40  *
41  * // Decode the bytes into a String
42  * String outputString = new String(result, 0, resultLength, "UTF-8");
43  * </pre></blockquote>
44  *
45  * @see Inflater
46  * @version 1.43, 11/11/05
47  * @author David Connelly
48  */

49 public
50 class Deflater {
51     private long strm;
52     private byte[] buf = new byte[0];
53     private int off, len;
54     private int level, strategy;
55     private boolean setParams;
56     private boolean finish, finished;
57
58     /**
59      * Compression method for the deflate algorithm (the only one currently
60      * supported).
61      */

62     public static final int DEFLATED = 8;
63
64     /**
65      * Compression level for no compression.
66      */

67     public static final int NO_COMPRESSION = 0;
68
69     /**
70      * Compression level for fastest compression.
71      */

72     public static final int BEST_SPEED = 1;
73
74     /**
75      * Compression level for best compression.
76      */

77     public static final int BEST_COMPRESSION = 9;
78
79     /**
80      * Default compression level.
81      */

82     public static final int DEFAULT_COMPRESSION = -1;
83
84     /**
85      * Compression strategy best used for data consisting mostly of small
86      * values with a somewhat random distribution. Forces more Huffman coding
87      * and less string matching.
88      */

89     public static final int FILTERED = 1;
90
91     /**
92      * Compression strategy for Huffman coding only.
93      */

94     public static final int HUFFMAN_ONLY = 2;
95
96     /**
97      * Default compression strategy.
98      */

99     public static final int DEFAULT_STRATEGY = 0;
100
101     static {
102     /* Zip library is loaded from System.initializeSystemClass */
103     initIDs();
104     }
105
106     /**
107      * Creates a new compressor using the specified compression level.
108      * If 'nowrap' is true then the ZLIB header and checksum fields will
109      * not be used in order to support the compression format used in
110      * both GZIP and PKZIP.
111      * @param level the compression level (0-9)
112      * @param nowrap if true then use GZIP compatible compression
113      */

114     public Deflater(int level, boolean nowrap) {
115     this.level = level;
116     this.strategy = DEFAULT_STRATEGY;
117     strm = init(level, DEFAULT_STRATEGY, nowrap);
118     }
119
120     /**
121      * Creates a new compressor using the specified compression level.
122      * Compressed data will be generated in ZLIB format.
123      * @param level the compression level (0-9)
124      */

125     public Deflater(int level) {
126     this(level, false);
127     }
128
129     /**
130      * Creates a new compressor with the default compression level.
131      * Compressed data will be generated in ZLIB format.
132      */

133     public Deflater() {
134     this(DEFAULT_COMPRESSION, false);
135     }
136
137     /**
138      * Sets input data for compression. This should be called whenever
139      * needsInput() returns true indicating that more input data is required.
140      * @param b the input data bytes
141      * @param off the start offset of the data
142      * @param len the length of the data
143      * @see Deflater#needsInput
144      */

145     public synchronized void setInput(byte[] b, int off, int len) {
146     if (b== null) {
147         throw new NullPointerException JavaDoc();
148     }
149         if (off < 0 || len < 0 || off > b.length - len) {
150         throw new ArrayIndexOutOfBoundsException JavaDoc();
151     }
152     this.buf = b;
153     this.off = off;
154     this.len = len;
155     }
156
157     /**
158      * Sets input data for compression. This should be called whenever
159      * needsInput() returns true indicating that more input data is required.
160      * @param b the input data bytes
161      * @see Deflater#needsInput
162      */

163     public void setInput(byte[] b) {
164     setInput(b, 0, b.length);
165     }
166
167     /**
168      * Sets preset dictionary for compression. A preset dictionary is used
169      * when the history buffer can be predetermined. When the data is later
170      * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
171      * in order to get the Adler-32 value of the dictionary required for
172      * decompression.
173      * @param b the dictionary data bytes
174      * @param off the start offset of the data
175      * @param len the length of the data
176      * @see Inflater#inflate
177      * @see Inflater#getAdler
178      */

179     public synchronized void setDictionary(byte[] b, int off, int len) {
180     if (strm == 0 || b == null) {
181         throw new NullPointerException JavaDoc();
182     }
183         if (off < 0 || len < 0 || off > b.length - len) {
184         throw new ArrayIndexOutOfBoundsException JavaDoc();
185     }
186     setDictionary(strm, b, off, len);
187     }
188
189     /**
190      * Sets preset dictionary for compression. A preset dictionary is used
191      * when the history buffer can be predetermined. When the data is later
192      * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
193      * in order to get the Adler-32 value of the dictionary required for
194      * decompression.
195      * @param b the dictionary data bytes
196      * @see Inflater#inflate
197      * @see Inflater#getAdler
198      */

199     public void setDictionary(byte[] b) {
200     setDictionary(b, 0, b.length);
201     }
202
203     /**
204      * Sets the compression strategy to the specified value.
205      * @param strategy the new compression strategy
206      * @exception IllegalArgumentException if the compression strategy is
207      * invalid
208      */

209     public synchronized void setStrategy(int strategy) {
210     switch (strategy) {
211       case DEFAULT_STRATEGY:
212       case FILTERED:
213       case HUFFMAN_ONLY:
214         break;
215       default:
216         throw new IllegalArgumentException JavaDoc();
217     }
218     if (this.strategy != strategy) {
219         this.strategy = strategy;
220         setParams = true;
221     }
222     }
223
224     /**
225      * Sets the current compression level to the specified value.
226      * @param level the new compression level (0-9)
227      * @exception IllegalArgumentException if the compression level is invalid
228      */

229     public synchronized void setLevel(int level) {
230     if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) {
231         throw new IllegalArgumentException JavaDoc("invalid compression level");
232     }
233     if (this.level != level) {
234         this.level = level;
235         setParams = true;
236     }
237     }
238
239     /**
240      * Returns true if the input data buffer is empty and setInput()
241      * should be called in order to provide more input.
242      * @return true if the input data buffer is empty and setInput()
243      * should be called in order to provide more input
244      */

245     public boolean needsInput() {
246     return len <= 0;
247     }
248
249     /**
250      * When called, indicates that compression should end with the current
251      * contents of the input buffer.
252      */

253     public synchronized void finish() {
254     finish = true;
255     }
256
257     /**
258      * Returns true if the end of the compressed data output stream has
259      * been reached.
260      * @return true if the end of the compressed data output stream has
261      * been reached
262      */

263     public synchronized boolean finished() {
264     return finished;
265     }
266
267     /**
268      * Fills specified buffer with compressed data. Returns actual number
269      * of bytes of compressed data. A return value of 0 indicates that
270      * needsInput() should be called in order to determine if more input
271      * data is required.
272      * @param b the buffer for the compressed data
273      * @param off the start offset of the data
274      * @param len the maximum number of bytes of compressed data
275      * @return the actual number of bytes of compressed data
276      */

277     public synchronized int deflate(byte[] b, int off, int len) {
278     if (b == null) {
279         throw new NullPointerException JavaDoc();
280     }
281         if (off < 0 || len < 0 || off > b.length - len) {
282         throw new ArrayIndexOutOfBoundsException JavaDoc();
283     }
284     return deflateBytes(b, off, len);
285     }
286
287     /**
288      * Fills specified buffer with compressed data. Returns actual number
289      * of bytes of compressed data. A return value of 0 indicates that
290      * needsInput() should be called in order to determine if more input
291      * data is required.
292      * @param b the buffer for the compressed data
293      * @return the actual number of bytes of compressed data
294      */

295     public int deflate(byte[] b) {
296     return deflate(b, 0, b.length);
297     }
298
299     /**
300      * Returns the ADLER-32 value of the uncompressed data.
301      * @return the ADLER-32 value of the uncompressed data
302      */

303     public synchronized int getAdler() {
304     ensureOpen();
305     return getAdler(strm);
306     }
307
308     /**
309      * Returns the total number of uncompressed bytes input so far.
310      *
311      * <p>Since the number of bytes may be greater than
312      * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now
313      * the preferred means of obtaining this information.</p>
314      *
315      * @return the total number of uncompressed bytes input so far
316      */

317     public int getTotalIn() {
318     return (int) getBytesRead();
319     }
320
321     /**
322      * Returns the total number of uncompressed bytes input so far.</p>
323      *
324      * @return the total (non-negative) number of uncompressed bytes input so far
325      */

326     public synchronized long getBytesRead() {
327     ensureOpen();
328     return getBytesRead(strm);
329     }
330
331     /**
332      * Returns the total number of compressed bytes output so far.
333      *
334      * <p>Since the number of bytes may be greater than
335      * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now
336      * the preferred means of obtaining this information.</p>
337      *
338      * @return the total number of compressed bytes output so far
339      */

340     public int getTotalOut() {
341     return (int) getBytesWritten();
342     }
343
344     /**
345      * Returns the total number of compressed bytes output so far.</p>
346      *
347      * @return the total (non-negative) number of compressed bytes output so far
348      */

349     public synchronized long getBytesWritten() {
350     ensureOpen();
351     return getBytesWritten(strm);
352     }
353
354     /**
355      * Resets deflater so that a new set of input data can be processed.
356      * Keeps current compression level and strategy settings.
357      */

358     public synchronized void reset() {
359     ensureOpen();
360     reset(strm);
361     finish = false;
362     finished = false;
363     off = len = 0;
364     }
365
366     /**
367      * Closes the compressor and discards any unprocessed input.
368      * This method should be called when the compressor is no longer
369      * being used, but will also be called automatically by the
370      * finalize() method. Once this method is called, the behavior
371      * of the Deflater object is undefined.
372      */

373     public synchronized void end() {
374     if (strm != 0) {
375         end(strm);
376         strm = 0;
377         buf = null;
378     }
379     }
380
381     /**
382      * Closes the compressor when garbage is collected.
383      */

384     protected void finalize() {
385     end();
386     }
387
388     private void ensureOpen() {
389     if (strm == 0)
390         throw new NullPointerException JavaDoc();
391     }
392
393     private static native void initIDs();
394     private native static long init(int level, int strategy, boolean nowrap);
395     private native static void setDictionary(long strm, byte[] b, int off,
396                          int len);
397     private native int deflateBytes(byte[] b, int off, int len);
398     private native static int getAdler(long strm);
399     private native static long getBytesRead(long strm);
400     private native static long getBytesWritten(long strm);
401     private native static void reset(long strm);
402     private native static void end(long strm);
403 }
404
Popular Tags