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 decompression 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         Deflater
   70    * @author      David Connelly
   71    *
   72    */
   73   public
   74   class Inflater {
   75       private long strm;
   76       private byte[] buf = new byte[0];
   77       private int off, len;
   78       private boolean finished;
   79       private boolean needDict;
   80   
   81       static {
   82           /* Zip library is loaded from System.initializeSystemClass */
   83           initIDs();
   84       }
   85   
   86       /**
   87        * Creates a new decompressor. If the parameter 'nowrap' is true then
   88        * the ZLIB header and checksum fields will not be used. This provides
   89        * compatibility with the compression format used by both GZIP and PKZIP.
   90        * <p>
   91        * Note: When using the 'nowrap' option it is also necessary to provide
   92        * an extra "dummy" byte as input. This is required by the ZLIB native
   93        * library in order to support certain optimizations.
   94        *
   95        * @param nowrap if true then support GZIP compatible compression
   96        */
   97       public Inflater(boolean nowrap) {
   98           strm = init(nowrap);
   99       }
  100   
  101       /**
  102        * Creates a new decompressor.
  103        */
  104       public Inflater() {
  105           this(false);
  106       }
  107   
  108       /**
  109        * Sets input data for decompression. Should be called whenever
  110        * needsInput() returns true indicating that more input data is
  111        * required.
  112        * @param b the input data bytes
  113        * @param off the start offset of the input data
  114        * @param len the length of the input data
  115        * @see Inflater#needsInput
  116        */
  117       public synchronized void setInput(byte[] b, int off, int len) {
  118           if (b == null) {
  119               throw new NullPointerException();
  120           }
  121           if (off < 0 || len < 0 || off > b.length - len) {
  122               throw new ArrayIndexOutOfBoundsException();
  123           }
  124           this.buf = b;
  125           this.off = off;
  126           this.len = len;
  127       }
  128   
  129       /**
  130        * Sets input data for decompression. Should be called whenever
  131        * needsInput() returns true indicating that more input data is
  132        * required.
  133        * @param b the input data bytes
  134        * @see Inflater#needsInput
  135        */
  136       public void setInput(byte[] b) {
  137           setInput(b, 0, b.length);
  138       }
  139   
  140       /**
  141        * Sets the preset dictionary to the given array of bytes. Should be
  142        * called when inflate() returns 0 and needsDictionary() returns true
  143        * indicating that a preset dictionary is required. The method getAdler()
  144        * can be used to get the Adler-32 value of the dictionary needed.
  145        * @param b the dictionary data bytes
  146        * @param off the start offset of the data
  147        * @param len the length of the data
  148        * @see Inflater#needsDictionary
  149        * @see Inflater#getAdler
  150        */
  151       public synchronized void setDictionary(byte[] b, int off, int len) {
  152           if (strm == 0 || b == null) {
  153               throw new NullPointerException();
  154           }
  155           if (off < 0 || len < 0 || off > b.length - len) {
  156               throw new ArrayIndexOutOfBoundsException();
  157           }
  158           setDictionary(strm, b, off, len);
  159           needDict = false;
  160       }
  161   
  162       /**
  163        * Sets the preset dictionary to the given array of bytes. Should be
  164        * called when inflate() returns 0 and needsDictionary() returns true
  165        * indicating that a preset dictionary is required. The method getAdler()
  166        * can be used to get the Adler-32 value of the dictionary needed.
  167        * @param b the dictionary data bytes
  168        * @see Inflater#needsDictionary
  169        * @see Inflater#getAdler
  170        */
  171       public void setDictionary(byte[] b) {
  172           setDictionary(b, 0, b.length);
  173       }
  174   
  175       /**
  176        * Returns the total number of bytes remaining in the input buffer.
  177        * This can be used to find out what bytes still remain in the input
  178        * buffer after decompression has finished.
  179        * @return the total number of bytes remaining in the input buffer
  180        */
  181       public synchronized int getRemaining() {
  182           return len;
  183       }
  184   
  185       /**
  186        * Returns true if no data remains in the input buffer. This can
  187        * be used to determine if #setInput should be called in order
  188        * to provide more input.
  189        * @return true if no data remains in the input buffer
  190        */
  191       public synchronized boolean needsInput() {
  192           return len <= 0;
  193       }
  194   
  195       /**
  196        * Returns true if a preset dictionary is needed for decompression.
  197        * @return true if a preset dictionary is needed for decompression
  198        * @see Inflater#setDictionary
  199        */
  200       public synchronized boolean needsDictionary() {
  201           return needDict;
  202       }
  203   
  204       /**
  205        * Returns true if the end of the compressed data stream has been
  206        * reached.
  207        * @return true if the end of the compressed data stream has been
  208        * reached
  209        */
  210       public synchronized boolean finished() {
  211           return finished;
  212       }
  213   
  214       /**
  215        * Uncompresses bytes into specified buffer. Returns actual number
  216        * of bytes uncompressed. A return value of 0 indicates that
  217        * needsInput() or needsDictionary() should be called in order to
  218        * determine if more input data or a preset dictionary is required.
  219        * In the latter case, getAdler() can be used to get the Adler-32
  220        * value of the dictionary required.
  221        * @param b the buffer for the uncompressed data
  222        * @param off the start offset of the data
  223        * @param len the maximum number of uncompressed bytes
  224        * @return the actual number of uncompressed bytes
  225        * @exception DataFormatException if the compressed data format is invalid
  226        * @see Inflater#needsInput
  227        * @see Inflater#needsDictionary
  228        */
  229       public synchronized int inflate(byte[] b, int off, int len)
  230           throws DataFormatException
  231       {
  232           if (b == null) {
  233               throw new NullPointerException();
  234           }
  235           if (off < 0 || len < 0 || off > b.length - len) {
  236               throw new ArrayIndexOutOfBoundsException();
  237           }
  238           return inflateBytes(b, off, len);
  239       }
  240   
  241       /**
  242        * Uncompresses bytes into specified buffer. Returns actual number
  243        * of bytes uncompressed. A return value of 0 indicates that
  244        * needsInput() or needsDictionary() should be called in order to
  245        * determine if more input data or a preset dictionary is required.
  246        * In the latter case, getAdler() can be used to get the Adler-32
  247        * value of the dictionary required.
  248        * @param b the buffer for the uncompressed data
  249        * @return the actual number of uncompressed bytes
  250        * @exception DataFormatException if the compressed data format is invalid
  251        * @see Inflater#needsInput
  252        * @see Inflater#needsDictionary
  253        */
  254       public int inflate(byte[] b) throws DataFormatException {
  255           return inflate(b, 0, b.length);
  256       }
  257   
  258       /**
  259        * Returns the ADLER-32 value of the uncompressed data.
  260        * @return the ADLER-32 value of the uncompressed data
  261        */
  262       public synchronized int getAdler() {
  263           ensureOpen();
  264           return getAdler(strm);
  265       }
  266   
  267       /**
  268        * Returns the total number of compressed bytes input so far.
  269        *
  270        * <p>Since the number of bytes may be greater than
  271        * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now
  272        * the preferred means of obtaining this information.</p>
  273        *
  274        * @return the total number of compressed bytes input so far
  275        */
  276       public int getTotalIn() {
  277           return (int) getBytesRead();
  278       }
  279   
  280       /**
  281        * Returns the total number of compressed bytes input so far.</p>
  282        *
  283        * @return the total (non-negative) number of compressed bytes input so far
  284        * @since 1.5
  285        */
  286       public synchronized long getBytesRead() {
  287           ensureOpen();
  288           return getBytesRead(strm);
  289       }
  290   
  291       /**
  292        * Returns the total number of uncompressed bytes output so far.
  293        *
  294        * <p>Since the number of bytes may be greater than
  295        * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now
  296        * the preferred means of obtaining this information.</p>
  297        *
  298        * @return the total number of uncompressed bytes output so far
  299        */
  300       public int getTotalOut() {
  301           return (int) getBytesWritten();
  302       }
  303   
  304       /**
  305        * Returns the total number of uncompressed bytes output so far.</p>
  306        *
  307        * @return the total (non-negative) number of uncompressed bytes output so far
  308        * @since 1.5
  309        */
  310       public synchronized long getBytesWritten() {
  311           ensureOpen();
  312           return getBytesWritten(strm);
  313       }
  314   
  315       /**
  316        * Resets inflater so that a new set of input data can be processed.
  317        */
  318       public synchronized void reset() {
  319           ensureOpen();
  320           reset(strm);
  321           finished = false;
  322           needDict = false;
  323           off = len = 0;
  324       }
  325   
  326       /**
  327        * Closes the decompressor and discards any unprocessed input.
  328        * This method should be called when the decompressor is no longer
  329        * being used, but will also be called automatically by the finalize()
  330        * method. Once this method is called, the behavior of the Inflater
  331        * object is undefined.
  332        */
  333       public synchronized void end() {
  334           if (strm != 0) {
  335               end(strm);
  336               strm = 0;
  337               buf = null;
  338           }
  339       }
  340   
  341       /**
  342        * Closes the decompressor when garbage is collected.
  343        */
  344       protected void finalize() {
  345           end();
  346       }
  347   
  348       private void ensureOpen () {
  349           if (strm == 0)
  350               throw new NullPointerException();
  351       }
  352   
  353       private native static void initIDs();
  354       private native static long init(boolean nowrap);
  355       private native static void setDictionary(long strm, byte[] b, int off,
  356                                                int len);
  357       private native int inflateBytes(byte[] b, int off, int len)
  358               throws DataFormatException;
  359       private native static int getAdler(long strm);
  360       private native static long getBytesRead(long strm);
  361       private native static long getBytesWritten(long strm);
  362       private native static void reset(long strm);
  363       private native static void end(long strm);
  364   }

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