Save This Page
Home » openjdk-7 » java » util » zip » [javadoc | source]
    1   /*
    2    * Copyright 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   import java.io.FilterInputStream;
   29   import java.io.InputStream;
   30   import java.io.IOException;
   31   
   32   /**
   33    * Implements an input stream filter for compressing data in the "deflate"
   34    * compression format.
   35    *
   36    * @since       1.6
   37    * @author      David R Tribble (david@tribble.com)
   38    *
   39    * @see DeflaterOutputStream
   40    * @see InflaterOutputStream
   41    * @see InflaterInputStream
   42    */
   43   
   44   public class DeflaterInputStream extends FilterInputStream {
   45       /** Compressor for this stream. */
   46       protected final Deflater def;
   47   
   48       /** Input buffer for reading compressed data. */
   49       protected final byte[] buf;
   50   
   51       /** Temporary read buffer. */
   52       private byte[] rbuf = new byte[1];
   53   
   54       /** Default compressor is used. */
   55       private boolean usesDefaultDeflater = false;
   56   
   57       /** End of the underlying input stream has been reached. */
   58       private boolean reachEOF = false;
   59   
   60       /**
   61        * Check to make sure that this stream has not been closed.
   62        */
   63       private void ensureOpen() throws IOException {
   64           if (in == null) {
   65               throw new IOException("Stream closed");
   66           }
   67       }
   68   
   69       /**
   70        * Creates a new input stream with a default compressor and buffer
   71        * size.
   72        *
   73        * @param in input stream to read the uncompressed data to
   74        * @throws NullPointerException if {@code in} is null
   75        */
   76       public DeflaterInputStream(InputStream in) {
   77           this(in, new Deflater());
   78           usesDefaultDeflater = true;
   79       }
   80   
   81       /**
   82        * Creates a new input stream with the specified compressor and a
   83        * default buffer size.
   84        *
   85        * @param in input stream to read the uncompressed data to
   86        * @param defl compressor ("deflater") for this stream
   87        * @throws NullPointerException if {@code in} or {@code defl} is null
   88        */
   89       public DeflaterInputStream(InputStream in, Deflater defl) {
   90           this(in, defl, 512);
   91       }
   92   
   93       /**
   94        * Creates a new input stream with the specified compressor and buffer
   95        * size.
   96        *
   97        * @param in input stream to read the uncompressed data to
   98        * @param defl compressor ("deflater") for this stream
   99        * @param bufLen compression buffer size
  100        * @throws IllegalArgumentException if {@code bufLen} is <= 0
  101        * @throws NullPointerException if {@code in} or {@code defl} is null
  102        */
  103       public DeflaterInputStream(InputStream in, Deflater defl, int bufLen) {
  104           super(in);
  105   
  106           // Sanity checks
  107           if (in == null)
  108               throw new NullPointerException("Null input");
  109           if (defl == null)
  110               throw new NullPointerException("Null deflater");
  111           if (bufLen < 1)
  112               throw new IllegalArgumentException("Buffer size < 1");
  113   
  114           // Initialize
  115           def = defl;
  116           buf = new byte[bufLen];
  117       }
  118   
  119       /**
  120        * Closes this input stream and its underlying input stream, discarding
  121        * any pending uncompressed data.
  122        *
  123        * @throws IOException if an I/O error occurs
  124        */
  125       public void close() throws IOException {
  126           if (in != null) {
  127               try {
  128                   // Clean up
  129                   if (usesDefaultDeflater) {
  130                       def.end();
  131                   }
  132   
  133                   in.close();
  134               } finally {
  135                   in = null;
  136               }
  137           }
  138       }
  139   
  140       /**
  141        * Reads a single byte of compressed data from the input stream.
  142        * This method will block until some input can be read and compressed.
  143        *
  144        * @return a single byte of compressed data, or -1 if the end of the
  145        * uncompressed input stream is reached
  146        * @throws IOException if an I/O error occurs or if this stream is
  147        * already closed
  148        */
  149       public int read() throws IOException {
  150           // Read a single byte of compressed data
  151           int len = read(rbuf, 0, 1);
  152           if (len <= 0)
  153               return -1;
  154           return (rbuf[0] & 0xFF);
  155       }
  156   
  157       /**
  158        * Reads compressed data into a byte array.
  159        * This method will block until some input can be read and compressed.
  160        *
  161        * @param b buffer into which the data is read
  162        * @param off starting offset of the data within {@code b}
  163        * @param len maximum number of compressed bytes to read into {@code b}
  164        * @return the actual number of bytes read, or -1 if the end of the
  165        * uncompressed input stream is reached
  166        * @throws IndexOutOfBoundsException  if {@code len} > {@code b.length -
  167        * off}
  168        * @throws IOException if an I/O error occurs or if this input stream is
  169        * already closed
  170        */
  171       public int read(byte[] b, int off, int len) throws IOException {
  172           // Sanity checks
  173           ensureOpen();
  174           if (b == null) {
  175               throw new NullPointerException("Null buffer for read");
  176           } else if (off < 0 || len < 0 || len > b.length - off) {
  177               throw new IndexOutOfBoundsException();
  178           } else if (len == 0) {
  179               return 0;
  180           }
  181   
  182           // Read and compress (deflate) input data bytes
  183           int cnt = 0;
  184           while (len > 0 && !def.finished()) {
  185               int n;
  186   
  187               // Read data from the input stream
  188               if (def.needsInput()) {
  189                   n = in.read(buf, 0, buf.length);
  190                   if (n < 0) {
  191                       // End of the input stream reached
  192                       def.finish();
  193                   } else if (n > 0) {
  194                       def.setInput(buf, 0, n);
  195                   }
  196               }
  197   
  198               // Compress the input data, filling the read buffer
  199               n = def.deflate(b, off, len);
  200               cnt += n;
  201               off += n;
  202               len -= n;
  203           }
  204           if (cnt == 0 && def.finished()) {
  205               reachEOF = true;
  206               cnt = -1;
  207           }
  208   
  209           return cnt;
  210       }
  211   
  212       /**
  213        * Skips over and discards data from the input stream.
  214        * This method may block until the specified number of bytes are read and
  215        * skipped. <em>Note:</em> While {@code n} is given as a {@code long},
  216        * the maximum number of bytes which can be skipped is
  217        * {@code Integer.MAX_VALUE}.
  218        *
  219        * @param n number of bytes to be skipped
  220        * @return the actual number of bytes skipped
  221        * @throws IOException if an I/O error occurs or if this stream is
  222        * already closed
  223        */
  224       public long skip(long n) throws IOException {
  225           if (n < 0) {
  226               throw new IllegalArgumentException("negative skip length");
  227           }
  228           ensureOpen();
  229   
  230           // Skip bytes by repeatedly decompressing small blocks
  231           if (rbuf.length < 512)
  232               rbuf = new byte[512];
  233   
  234           int total = (int)Math.min(n, Integer.MAX_VALUE);
  235           long cnt = 0;
  236           while (total > 0) {
  237               // Read a small block of uncompressed bytes
  238               int len = read(rbuf, 0, (total <= rbuf.length ? total : rbuf.length));
  239   
  240               if (len < 0) {
  241                   break;
  242               }
  243               cnt += len;
  244               total -= len;
  245           }
  246           return cnt;
  247       }
  248   
  249       /**
  250        * Returns 0 after EOF has been reached, otherwise always return 1.
  251        * <p>
  252        * Programs should not count on this method to return the actual number
  253        * of bytes that could be read without blocking
  254        * @return zero after the end of the underlying input stream has been
  255        * reached, otherwise always returns 1
  256        * @throws IOException if an I/O error occurs or if this stream is
  257        * already closed
  258        */
  259       public int available() throws IOException {
  260           ensureOpen();
  261           if (reachEOF) {
  262               return 0;
  263           }
  264           return 1;
  265       }
  266   
  267       /**
  268        * Always returns {@code false} because this input stream does not support
  269        * the {@link #mark mark()} and {@link #reset reset()} methods.
  270        *
  271        * @return false, always
  272        */
  273       public boolean markSupported() {
  274           return false;
  275       }
  276   
  277       /**
  278        * <i>This operation is not supported</i>.
  279        *
  280        * @param limit maximum bytes that can be read before invalidating the position marker
  281        */
  282       public void mark(int limit) {
  283           // Operation not supported
  284       }
  285   
  286       /**
  287        * <i>This operation is not supported</i>.
  288        *
  289        * @throws IOException always thrown
  290        */
  291       public void reset() throws IOException {
  292           throw new IOException("mark/reset not supported");
  293       }
  294   }

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