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