Deflater.java revision e31b37859051d3902e06e4ba384995df7188917f
1/*
2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.util.zip;
27
28import dalvik.annotation.optimization.ReachabilitySensitive;
29import dalvik.system.CloseGuard;
30
31/**
32 * This class provides support for general purpose compression using the
33 * popular ZLIB compression library. The ZLIB compression library was
34 * initially developed as part of the PNG graphics standard and is not
35 * protected by patents. It is fully described in the specifications at
36 * the <a href="package-summary.html#package_description">java.util.zip
37 * package description</a>.
38 *
39 * <p>The following code fragment demonstrates a trivial compression
40 * and decompression of a string using <tt>Deflater</tt> and
41 * <tt>Inflater</tt>.
42 *
43 * <blockquote><pre>
44 * try {
45 *     // Encode a String into bytes
46 *     String inputString = "blahblahblah";
47 *     byte[] input = inputString.getBytes("UTF-8");
48 *
49 *     // Compress the bytes
50 *     byte[] output = new byte[100];
51 *     Deflater compresser = new Deflater();
52 *     compresser.setInput(input);
53 *     compresser.finish();
54 *     int compressedDataLength = compresser.deflate(output);
55 *     compresser.end();
56 *
57 *     // Decompress the bytes
58 *     Inflater decompresser = new Inflater();
59 *     decompresser.setInput(output, 0, compressedDataLength);
60 *     byte[] result = new byte[100];
61 *     int resultLength = decompresser.inflate(result);
62 *     decompresser.end();
63 *
64 *     // Decode the bytes into a String
65 *     String outputString = new String(result, 0, resultLength, "UTF-8");
66 * } catch(java.io.UnsupportedEncodingException ex) {
67 *     // handle
68 * } catch (java.util.zip.DataFormatException ex) {
69 *     // handle
70 * }
71 * </pre></blockquote>
72 *
73 * @see         Inflater
74 * @author      David Connelly
75 */
76public
77class Deflater {
78
79    // Android-added: @ReachabilitySensitive
80    // Finalization clears zsRef, and thus can't be allowed to occur early.
81    // Unlike some other CloseGuard uses, the spec allows clients to rely on finalization
82    // here.  Thus dropping a deflater without calling close() should work correctly.
83    // It thus does not suffice to just rely on the CloseGuard annotation.
84    @ReachabilitySensitive
85    private final ZStreamRef zsRef;
86    private byte[] buf = new byte[0];
87    private int off, len;
88    private int level, strategy;
89    private boolean setParams;
90    private boolean finish, finished;
91    private long bytesRead;
92    private long bytesWritten;
93
94    // Android-changed: added close guard
95    @ReachabilitySensitive
96    private final CloseGuard guard = CloseGuard.get();
97
98    /**
99     * Compression method for the deflate algorithm (the only one currently
100     * supported).
101     */
102    public static final int DEFLATED = 8;
103
104    /**
105     * Compression level for no compression.
106     */
107    public static final int NO_COMPRESSION = 0;
108
109    /**
110     * Compression level for fastest compression.
111     */
112    public static final int BEST_SPEED = 1;
113
114    /**
115     * Compression level for best compression.
116     */
117    public static final int BEST_COMPRESSION = 9;
118
119    /**
120     * Default compression level.
121     */
122    public static final int DEFAULT_COMPRESSION = -1;
123
124    /**
125     * Compression strategy best used for data consisting mostly of small
126     * values with a somewhat random distribution. Forces more Huffman coding
127     * and less string matching.
128     */
129    public static final int FILTERED = 1;
130
131    /**
132     * Compression strategy for Huffman coding only.
133     */
134    public static final int HUFFMAN_ONLY = 2;
135
136    /**
137     * Default compression strategy.
138     */
139    public static final int DEFAULT_STRATEGY = 0;
140
141    /**
142     * Compression flush mode used to achieve best compression result.
143     *
144     * @see Deflater#deflate(byte[], int, int, int)
145     * @since 1.7
146     */
147    public static final int NO_FLUSH = 0;
148
149    /**
150     * Compression flush mode used to flush out all pending output; may
151     * degrade compression for some compression algorithms.
152     *
153     * @see Deflater#deflate(byte[], int, int, int)
154     * @since 1.7
155     */
156    public static final int SYNC_FLUSH = 2;
157
158    /**
159     * Compression flush mode used to flush out all pending output and
160     * reset the deflater. Using this mode too often can seriously degrade
161     * compression.
162     *
163     * @see Deflater#deflate(byte[], int, int, int)
164     * @since 1.7
165     */
166    public static final int FULL_FLUSH = 3;
167
168    /**
169     * Creates a new compressor using the specified compression level.
170     * If 'nowrap' is true then the ZLIB header and checksum fields will
171     * not be used in order to support the compression format used in
172     * both GZIP and PKZIP.
173     * @param level the compression level (0-9)
174     * @param nowrap if true then use GZIP compatible compression
175     */
176    public Deflater(int level, boolean nowrap) {
177        this.level = level;
178        this.strategy = DEFAULT_STRATEGY;
179        this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
180        // Android-changed: added close guard
181        guard.open("end");
182    }
183
184    /**
185     * Creates a new compressor using the specified compression level.
186     * Compressed data will be generated in ZLIB format.
187     * @param level the compression level (0-9)
188     */
189    public Deflater(int level) {
190        this(level, false);
191    }
192
193    /**
194     * Creates a new compressor with the default compression level.
195     * Compressed data will be generated in ZLIB format.
196     */
197    public Deflater() {
198        this(DEFAULT_COMPRESSION, false);
199    }
200
201    /**
202     * Sets input data for compression. This should be called whenever
203     * needsInput() returns true indicating that more input data is required.
204     * @param b the input data bytes
205     * @param off the start offset of the data
206     * @param len the length of the data
207     * @see Deflater#needsInput
208     */
209    public void setInput(byte[] b, int off, int len) {
210        if (b== null) {
211            throw new NullPointerException();
212        }
213        if (off < 0 || len < 0 || off > b.length - len) {
214            throw new ArrayIndexOutOfBoundsException();
215        }
216        synchronized (zsRef) {
217            this.buf = b;
218            this.off = off;
219            this.len = len;
220        }
221    }
222
223    /**
224     * Sets input data for compression. This should be called whenever
225     * needsInput() returns true indicating that more input data is required.
226     * @param b the input data bytes
227     * @see Deflater#needsInput
228     */
229    public void setInput(byte[] b) {
230        setInput(b, 0, b.length);
231    }
232
233    /**
234     * Sets preset dictionary for compression. A preset dictionary is used
235     * when the history buffer can be predetermined. When the data is later
236     * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
237     * in order to get the Adler-32 value of the dictionary required for
238     * decompression.
239     * @param b the dictionary data bytes
240     * @param off the start offset of the data
241     * @param len the length of the data
242     * @see Inflater#inflate
243     * @see Inflater#getAdler
244     */
245    public void setDictionary(byte[] b, int off, int len) {
246        if (b == null) {
247            throw new NullPointerException();
248        }
249        if (off < 0 || len < 0 || off > b.length - len) {
250            throw new ArrayIndexOutOfBoundsException();
251        }
252        synchronized (zsRef) {
253            ensureOpen();
254            setDictionary(zsRef.address(), b, off, len);
255        }
256    }
257
258    /**
259     * Sets preset dictionary for compression. A preset dictionary is used
260     * when the history buffer can be predetermined. When the data is later
261     * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
262     * in order to get the Adler-32 value of the dictionary required for
263     * decompression.
264     * @param b the dictionary data bytes
265     * @see Inflater#inflate
266     * @see Inflater#getAdler
267     */
268    public void setDictionary(byte[] b) {
269        setDictionary(b, 0, b.length);
270    }
271
272    /**
273     * Sets the compression strategy to the specified value.
274     *
275     * <p> If the compression strategy is changed, the next invocation
276     * of {@code deflate} will compress the input available so far with
277     * the old strategy (and may be flushed); the new strategy will take
278     * effect only after that invocation.
279     *
280     * @param strategy the new compression strategy
281     * @exception IllegalArgumentException if the compression strategy is
282     *                                     invalid
283     */
284    public void setStrategy(int strategy) {
285        switch (strategy) {
286          case DEFAULT_STRATEGY:
287          case FILTERED:
288          case HUFFMAN_ONLY:
289            break;
290          default:
291            throw new IllegalArgumentException();
292        }
293        synchronized (zsRef) {
294            if (this.strategy != strategy) {
295                this.strategy = strategy;
296                setParams = true;
297            }
298        }
299    }
300
301    /**
302     * Sets the compression level to the specified value.
303     *
304     * <p> If the compression level is changed, the next invocation
305     * of {@code deflate} will compress the input available so far
306     * with the old level (and may be flushed); the new level will
307     * take effect only after that invocation.
308     *
309     * @param level the new compression level (0-9)
310     * @exception IllegalArgumentException if the compression level is invalid
311     */
312    public void setLevel(int level) {
313        if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) {
314            throw new IllegalArgumentException("invalid compression level");
315        }
316        synchronized (zsRef) {
317            if (this.level != level) {
318                this.level = level;
319                setParams = true;
320            }
321        }
322    }
323
324    /**
325     * Returns true if the input data buffer is empty and setInput()
326     * should be called in order to provide more input.
327     * @return true if the input data buffer is empty and setInput()
328     * should be called in order to provide more input
329     */
330    public boolean needsInput() {
331        synchronized (zsRef) {
332            return len <= 0;
333        }
334    }
335
336    /**
337     * When called, indicates that compression should end with the current
338     * contents of the input buffer.
339     */
340    public void finish() {
341        synchronized (zsRef) {
342            finish = true;
343        }
344    }
345
346    /**
347     * Returns true if the end of the compressed data output stream has
348     * been reached.
349     * @return true if the end of the compressed data output stream has
350     * been reached
351     */
352    public boolean finished() {
353        synchronized (zsRef) {
354            return finished;
355        }
356    }
357
358    /**
359     * Compresses the input data and fills specified buffer with compressed
360     * data. Returns actual number of bytes of compressed data. A return value
361     * of 0 indicates that {@link #needsInput() needsInput} should be called
362     * in order to determine if more input data is required.
363     *
364     * <p>This method uses {@link #NO_FLUSH} as its compression flush mode.
365     * An invocation of this method of the form {@code deflater.deflate(b, off, len)}
366     * yields the same result as the invocation of
367     * {@code deflater.deflate(b, off, len, Deflater.NO_FLUSH)}.
368     *
369     * @param b the buffer for the compressed data
370     * @param off the start offset of the data
371     * @param len the maximum number of bytes of compressed data
372     * @return the actual number of bytes of compressed data written to the
373     *         output buffer
374     */
375    public int deflate(byte[] b, int off, int len) {
376        return deflate(b, off, len, NO_FLUSH);
377    }
378
379    /**
380     * Compresses the input data and fills specified buffer with compressed
381     * data. Returns actual number of bytes of compressed data. A return value
382     * of 0 indicates that {@link #needsInput() needsInput} should be called
383     * in order to determine if more input data is required.
384     *
385     * <p>This method uses {@link #NO_FLUSH} as its compression flush mode.
386     * An invocation of this method of the form {@code deflater.deflate(b)}
387     * yields the same result as the invocation of
388     * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}.
389     *
390     * @param b the buffer for the compressed data
391     * @return the actual number of bytes of compressed data written to the
392     *         output buffer
393     */
394    public int deflate(byte[] b) {
395        return deflate(b, 0, b.length, NO_FLUSH);
396    }
397
398    /**
399     * Compresses the input data and fills the specified buffer with compressed
400     * data. Returns actual number of bytes of data compressed.
401     *
402     * <p>Compression flush mode is one of the following three modes:
403     *
404     * <ul>
405     * <li>{@link #NO_FLUSH}: allows the deflater to decide how much data
406     * to accumulate, before producing output, in order to achieve the best
407     * compression (should be used in normal use scenario). A return value
408     * of 0 in this flush mode indicates that {@link #needsInput()} should
409     * be called in order to determine if more input data is required.
410     *
411     * <li>{@link #SYNC_FLUSH}: all pending output in the deflater is flushed,
412     * to the specified output buffer, so that an inflater that works on
413     * compressed data can get all input data available so far (In particular
414     * the {@link #needsInput()} returns {@code true} after this invocation
415     * if enough output space is provided). Flushing with {@link #SYNC_FLUSH}
416     * may degrade compression for some compression algorithms and so it
417     * should be used only when necessary.
418     *
419     * <li>{@link #FULL_FLUSH}: all pending output is flushed out as with
420     * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater
421     * that works on the compressed output data can restart from this point
422     * if previous compressed data has been damaged or if random access is
423     * desired. Using {@link #FULL_FLUSH} too often can seriously degrade
424     * compression.
425     * </ul>
426     *
427     * <p>In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if
428     * the return value is {@code len}, the space available in output
429     * buffer {@code b}, this method should be invoked again with the same
430     * {@code flush} parameter and more output space.
431     *
432     * @param b the buffer for the compressed data
433     * @param off the start offset of the data
434     * @param len the maximum number of bytes of compressed data
435     * @param flush the compression flush mode
436     * @return the actual number of bytes of compressed data written to
437     *         the output buffer
438     *
439     * @throws IllegalArgumentException if the flush mode is invalid
440     * @since 1.7
441     */
442    public int deflate(byte[] b, int off, int len, int flush) {
443        if (b == null) {
444            throw new NullPointerException();
445        }
446        if (off < 0 || len < 0 || off > b.length - len) {
447            throw new ArrayIndexOutOfBoundsException();
448        }
449        synchronized (zsRef) {
450            ensureOpen();
451            if (flush == NO_FLUSH || flush == SYNC_FLUSH ||
452                flush == FULL_FLUSH) {
453                int thisLen = this.len;
454                int n = deflateBytes(zsRef.address(), b, off, len, flush);
455                bytesWritten += n;
456                bytesRead += (thisLen - this.len);
457                return n;
458            }
459            throw new IllegalArgumentException();
460        }
461    }
462
463    /**
464     * Returns the ADLER-32 value of the uncompressed data.
465     * @return the ADLER-32 value of the uncompressed data
466     */
467    public int getAdler() {
468        synchronized (zsRef) {
469            ensureOpen();
470            return getAdler(zsRef.address());
471        }
472    }
473
474    /**
475     * Returns the total number of uncompressed bytes input so far.
476     *
477     * <p>Since the number of bytes may be greater than
478     * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now
479     * the preferred means of obtaining this information.</p>
480     *
481     * @return the total number of uncompressed bytes input so far
482     */
483    public int getTotalIn() {
484        return (int) getBytesRead();
485    }
486
487    /**
488     * Returns the total number of uncompressed bytes input so far.
489     *
490     * @return the total (non-negative) number of uncompressed bytes input so far
491     * @since 1.5
492     */
493    public long getBytesRead() {
494        synchronized (zsRef) {
495            ensureOpen();
496            return bytesRead;
497        }
498    }
499
500    /**
501     * Returns the total number of compressed bytes output so far.
502     *
503     * <p>Since the number of bytes may be greater than
504     * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now
505     * the preferred means of obtaining this information.</p>
506     *
507     * @return the total number of compressed bytes output so far
508     */
509    public int getTotalOut() {
510        return (int) getBytesWritten();
511    }
512
513    /**
514     * Returns the total number of compressed bytes output so far.
515     *
516     * @return the total (non-negative) number of compressed bytes output so far
517     * @since 1.5
518     */
519    public long getBytesWritten() {
520        synchronized (zsRef) {
521            ensureOpen();
522            return bytesWritten;
523        }
524    }
525
526    /**
527     * Resets deflater so that a new set of input data can be processed.
528     * Keeps current compression level and strategy settings.
529     */
530    public void reset() {
531        synchronized (zsRef) {
532            ensureOpen();
533            reset(zsRef.address());
534            finish = false;
535            finished = false;
536            off = len = 0;
537            bytesRead = bytesWritten = 0;
538        }
539    }
540
541    /**
542     * Closes the compressor and discards any unprocessed input.
543     * This method should be called when the compressor is no longer
544     * being used, but will also be called automatically by the
545     * finalize() method. Once this method is called, the behavior
546     * of the Deflater object is undefined.
547     */
548    public void end() {
549        synchronized (zsRef) {
550            // Android-changed: added close guard
551            guard.close();
552            long addr = zsRef.address();
553            zsRef.clear();
554            if (addr != 0) {
555                end(addr);
556                buf = null;
557            }
558        }
559    }
560
561    /**
562     * Closes the compressor when garbage is collected.
563     */
564    protected void finalize() {
565        // Android-changed: added close guard
566        if (guard != null) {
567            guard.warnIfOpen();
568        }
569        end();
570    }
571
572    private void ensureOpen() {
573        assert Thread.holdsLock(zsRef);
574        if (zsRef.address() == 0)
575            throw new NullPointerException("Deflater has been closed");
576    }
577
578    // Android-changed: initIDs handled in register method.
579    // private native static void initIDs();
580    private native static long init(int level, int strategy, boolean nowrap);
581    private native static void setDictionary(long addr, byte[] b, int off, int len);
582    private native int deflateBytes(long addr, byte[] b, int off, int len,
583                                    int flush);
584    private native static int getAdler(long addr);
585    private native static void reset(long addr);
586    private native static void end(long addr);
587}
588