Save This Page
Home » openjdk-7 » java » util » zip » [javadoc | source]
    1   /*
    2    * Copyright 1996-2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package java.util.zip;
   27   
   28   /**
   29    * This class provides support for general purpose compression using the
   30    * popular ZLIB compression library. The ZLIB compression library was
   31    * initially developed as part of the PNG graphics standard and is not
   32    * protected by patents. It is fully described in the specifications at
   33    * the <a href="package-summary.html#package_description">java.util.zip
   34    * package description</a>.
   35    *
   36    * <p>The following code fragment demonstrates a trivial compression
   37    * and decompression of a string using <tt>Deflater</tt> and
   38    * <tt>Inflater</tt>.
   39    *
   40    * <blockquote><pre>
   41    * try {
   42    *     // Encode a String into bytes
   43    *     String inputString = "blahblahblah\u20AC\u20AC";
   44    *     byte[] input = inputString.getBytes("UTF-8");
   45    *
   46    *     // Compress the bytes
   47    *     byte[] output = new byte[100];
   48    *     Deflater compresser = new Deflater();
   49    *     compresser.setInput(input);
   50    *     compresser.finish();
   51    *     int compressedDataLength = compresser.deflate(output);
   52    *
   53    *     // Decompress the bytes
   54    *     Inflater decompresser = new Inflater();
   55    *     decompresser.setInput(output, 0, compressedDataLength);
   56    *     byte[] result = new byte[100];
   57    *     int resultLength = decompresser.inflate(result);
   58    *     decompresser.end();
   59    *
   60    *     // Decode the bytes into a String
   61    *     String outputString = new String(result, 0, resultLength, "UTF-8");
   62    * } catch(java.io.UnsupportedEncodingException ex) {
   63    *     // handle
   64    * } catch (java.util.zip.DataFormatException ex) {
   65    *     // handle
   66    * }
   67    * </pre></blockquote>
   68    *
   69    * @see         Inflater
   70    * @author      David Connelly
   71    */
   72   public
   73   class Deflater {
   74       private long strm;
   75       private byte[] buf = new byte[0];
   76       private int off, len;
   77       private int level, strategy;
   78       private boolean setParams;
   79       private boolean finish, finished;
   80   
   81       /**
   82        * Compression method for the deflate algorithm (the only one currently
   83        * supported).
   84        */
   85       public static final int DEFLATED = 8;
   86   
   87       /**
   88        * Compression level for no compression.
   89        */
   90       public static final int NO_COMPRESSION = 0;
   91   
   92       /**
   93        * Compression level for fastest compression.
   94        */
   95       public static final int BEST_SPEED = 1;
   96   
   97       /**
   98        * Compression level for best compression.
   99        */
  100       public static final int BEST_COMPRESSION = 9;
  101   
  102       /**
  103        * Default compression level.
  104        */
  105       public static final int DEFAULT_COMPRESSION = -1;
  106   
  107       /**
  108        * Compression strategy best used for data consisting mostly of small
  109        * values with a somewhat random distribution. Forces more Huffman coding
  110        * and less string matching.
  111        */
  112       public static final int FILTERED = 1;
  113   
  114       /**
  115        * Compression strategy for Huffman coding only.
  116        */
  117       public static final int HUFFMAN_ONLY = 2;
  118   
  119       /**
  120        * Default compression strategy.
  121        */
  122       public static final int DEFAULT_STRATEGY = 0;
  123   
  124       static {
  125           /* Zip library is loaded from System.initializeSystemClass */
  126           initIDs();
  127       }
  128   
  129       /**
  130        * Creates a new compressor using the specified compression level.
  131        * If 'nowrap' is true then the ZLIB header and checksum fields will
  132        * not be used in order to support the compression format used in
  133        * both GZIP and PKZIP.
  134        * @param level the compression level (0-9)
  135        * @param nowrap if true then use GZIP compatible compression
  136        */
  137       public Deflater(int level, boolean nowrap) {
  138           this.level = level;
  139           this.strategy = DEFAULT_STRATEGY;
  140           strm = init(level, DEFAULT_STRATEGY, nowrap);
  141       }
  142   
  143       /**
  144        * Creates a new compressor using the specified compression level.
  145        * Compressed data will be generated in ZLIB format.
  146        * @param level the compression level (0-9)
  147        */
  148       public Deflater(int level) {
  149           this(level, false);
  150       }
  151   
  152       /**
  153        * Creates a new compressor with the default compression level.
  154        * Compressed data will be generated in ZLIB format.
  155        */
  156       public Deflater() {
  157           this(DEFAULT_COMPRESSION, false);
  158       }
  159   
  160       /**
  161        * Sets input data for compression. This should be called whenever
  162        * needsInput() returns true indicating that more input data is required.
  163        * @param b the input data bytes
  164        * @param off the start offset of the data
  165        * @param len the length of the data
  166        * @see Deflater#needsInput
  167        */
  168       public synchronized void setInput(byte[] b, int off, int len) {
  169           if (b== null) {
  170               throw new NullPointerException();
  171           }
  172           if (off < 0 || len < 0 || off > b.length - len) {
  173               throw new ArrayIndexOutOfBoundsException();
  174           }
  175           this.buf = b;
  176           this.off = off;
  177           this.len = len;
  178       }
  179   
  180       /**
  181        * Sets input data for compression. This should be called whenever
  182        * needsInput() returns true indicating that more input data is required.
  183        * @param b the input data bytes
  184        * @see Deflater#needsInput
  185        */
  186       public void setInput(byte[] b) {
  187           setInput(b, 0, b.length);
  188       }
  189   
  190       /**
  191        * Sets preset dictionary for compression. A preset dictionary is used
  192        * when the history buffer can be predetermined. When the data is later
  193        * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
  194        * in order to get the Adler-32 value of the dictionary required for
  195        * decompression.
  196        * @param b the dictionary data bytes
  197        * @param off the start offset of the data
  198        * @param len the length of the data
  199        * @see Inflater#inflate
  200        * @see Inflater#getAdler
  201        */
  202       public synchronized void setDictionary(byte[] b, int off, int len) {
  203           if (strm == 0 || b == null) {
  204               throw new NullPointerException();
  205           }
  206           if (off < 0 || len < 0 || off > b.length - len) {
  207               throw new ArrayIndexOutOfBoundsException();
  208           }
  209           setDictionary(strm, b, off, len);
  210       }
  211   
  212       /**
  213        * Sets preset dictionary for compression. A preset dictionary is used
  214        * when the history buffer can be predetermined. When the data is later
  215        * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
  216        * in order to get the Adler-32 value of the dictionary required for
  217        * decompression.
  218        * @param b the dictionary data bytes
  219        * @see Inflater#inflate
  220        * @see Inflater#getAdler
  221        */
  222       public void setDictionary(byte[] b) {
  223           setDictionary(b, 0, b.length);
  224       }
  225   
  226       /**
  227        * Sets the compression strategy to the specified value.
  228        * @param strategy the new compression strategy
  229        * @exception IllegalArgumentException if the compression strategy is
  230        *                                     invalid
  231        */
  232       public synchronized void setStrategy(int strategy) {
  233           switch (strategy) {
  234             case DEFAULT_STRATEGY:
  235             case FILTERED:
  236             case HUFFMAN_ONLY:
  237               break;
  238             default:
  239               throw new IllegalArgumentException();
  240           }
  241           if (this.strategy != strategy) {
  242               this.strategy = strategy;
  243               setParams = true;
  244           }
  245       }
  246   
  247       /**
  248        * Sets the current compression level to the specified value.
  249        * @param level the new compression level (0-9)
  250        * @exception IllegalArgumentException if the compression level is invalid
  251        */
  252       public synchronized void setLevel(int level) {
  253           if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) {
  254               throw new IllegalArgumentException("invalid compression level");
  255           }
  256           if (this.level != level) {
  257               this.level = level;
  258               setParams = true;
  259           }
  260       }
  261   
  262       /**
  263        * Returns true if the input data buffer is empty and setInput()
  264        * should be called in order to provide more input.
  265        * @return true if the input data buffer is empty and setInput()
  266        * should be called in order to provide more input
  267        */
  268       public boolean needsInput() {
  269           return len <= 0;
  270       }
  271   
  272       /**
  273        * When called, indicates that compression should end with the current
  274        * contents of the input buffer.
  275        */
  276       public synchronized void finish() {
  277           finish = true;
  278       }
  279   
  280       /**
  281        * Returns true if the end of the compressed data output stream has
  282        * been reached.
  283        * @return true if the end of the compressed data output stream has
  284        * been reached
  285        */
  286       public synchronized boolean finished() {
  287           return finished;
  288       }
  289   
  290       /**
  291        * Fills specified buffer with compressed data. Returns actual number
  292        * of bytes of compressed data. A return value of 0 indicates that
  293        * needsInput() should be called in order to determine if more input
  294        * data is required.
  295        * @param b the buffer for the compressed data
  296        * @param off the start offset of the data
  297        * @param len the maximum number of bytes of compressed data
  298        * @return the actual number of bytes of compressed data
  299        */
  300       public synchronized int deflate(byte[] b, int off, int len) {
  301           if (b == null) {
  302               throw new NullPointerException();
  303           }
  304           if (off < 0 || len < 0 || off > b.length - len) {
  305               throw new ArrayIndexOutOfBoundsException();
  306           }
  307           return deflateBytes(b, off, len);
  308       }
  309   
  310       /**
  311        * Fills specified buffer with compressed data. Returns actual number
  312        * of bytes of compressed data. A return value of 0 indicates that
  313        * needsInput() should be called in order to determine if more input
  314        * data is required.
  315        * @param b the buffer for the compressed data
  316        * @return the actual number of bytes of compressed data
  317        */
  318       public int deflate(byte[] b) {
  319           return deflate(b, 0, b.length);
  320       }
  321   
  322       /**
  323        * Returns the ADLER-32 value of the uncompressed data.
  324        * @return the ADLER-32 value of the uncompressed data
  325        */
  326       public synchronized int getAdler() {
  327           ensureOpen();
  328           return getAdler(strm);
  329       }
  330   
  331       /**
  332        * Returns the total number of uncompressed bytes input so far.
  333        *
  334        * <p>Since the number of bytes may be greater than
  335        * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now
  336        * the preferred means of obtaining this information.</p>
  337        *
  338        * @return the total number of uncompressed bytes input so far
  339        */
  340       public int getTotalIn() {
  341           return (int) getBytesRead();
  342       }
  343   
  344       /**
  345        * Returns the total number of uncompressed bytes input so far.</p>
  346        *
  347        * @return the total (non-negative) number of uncompressed bytes input so far
  348        * @since 1.5
  349        */
  350       public synchronized long getBytesRead() {
  351           ensureOpen();
  352           return getBytesRead(strm);
  353       }
  354   
  355       /**
  356        * Returns the total number of compressed bytes output so far.
  357        *
  358        * <p>Since the number of bytes may be greater than
  359        * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now
  360        * the preferred means of obtaining this information.</p>
  361        *
  362        * @return the total number of compressed bytes output so far
  363        */
  364       public int getTotalOut() {
  365           return (int) getBytesWritten();
  366       }
  367   
  368       /**
  369        * Returns the total number of compressed bytes output so far.</p>
  370        *
  371        * @return the total (non-negative) number of compressed bytes output so far
  372        * @since 1.5
  373        */
  374       public synchronized long getBytesWritten() {
  375           ensureOpen();
  376           return getBytesWritten(strm);
  377       }
  378   
  379       /**
  380        * Resets deflater so that a new set of input data can be processed.
  381        * Keeps current compression level and strategy settings.
  382        */
  383       public synchronized void reset() {
  384           ensureOpen();
  385           reset(strm);
  386           finish = false;
  387           finished = false;
  388           off = len = 0;
  389       }
  390   
  391       /**
  392        * Closes the compressor and discards any unprocessed input.
  393        * This method should be called when the compressor is no longer
  394        * being used, but will also be called automatically by the
  395        * finalize() method. Once this method is called, the behavior
  396        * of the Deflater object is undefined.
  397        */
  398       public synchronized void end() {
  399           if (strm != 0) {
  400               end(strm);
  401               strm = 0;
  402               buf = null;
  403           }
  404       }
  405   
  406       /**
  407        * Closes the compressor when garbage is collected.
  408        */
  409       protected void finalize() {
  410           end();
  411       }
  412   
  413       private void ensureOpen() {
  414           if (strm == 0)
  415               throw new NullPointerException();
  416       }
  417   
  418       private static native void initIDs();
  419       private native static long init(int level, int strategy, boolean nowrap);
  420       private native static void setDictionary(long strm, byte[] b, int off,
  421                                                int len);
  422       private native int deflateBytes(byte[] b, int off, int len);
  423       private native static int getAdler(long strm);
  424       private native static long getBytesRead(long strm);
  425       private native static long getBytesWritten(long strm);
  426       private native static void reset(long strm);
  427       private native static void end(long strm);
  428   }

Save This Page
Home » openjdk-7 » java » util » zip » [javadoc | source]