Home | History | Annotate | Download | only in zip
      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 
     26 package java.util.zip;
     27 
     28 import dalvik.annotation.optimization.ReachabilitySensitive;
     29 import 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  */
     76 public
     77 class 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