/**
   * Flushes this output stream, forcing any pending buffered output bytes to be written.
   *
   * @throws IOException if an I/O error occurs or this stream is already closed
   */
  public void flush() throws IOException {
    ensureOpen();

    // Finish decompressing and writing pending output data
    if (!inf.finished()) {
      try {
        while (!inf.finished() && !inf.needsInput()) {
          int n;

          // Decompress pending output data
          n = inf.inflate(buf, 0, buf.length);
          if (n < 1) {
            break;
          }

          // Write the uncompressed output data block
          out.write(buf, 0, n);
        }
        super.flush();
      } catch (DataFormatException ex) {
        // Improperly formatted compressed (ZIP) data
        String msg = ex.getMessage();
        if (msg == null) {
          msg = "Invalid ZLIB data format";
        }
        throw new ZipException(msg);
      }
    }
  }
Beispiel #2
0
  /**
   * @param compressed_size or use null if not known
   * @param uncompressed_size or use null if not known
   * @return uncompressed ByteArrayOutputStream
   * @throws IOException
   * @throws DataFormatException
   */
  private ByteArrayOutputStream unCompress(Integer compressed_size, Integer uncompressed_size)
      throws IOException, DataFormatException {
    byte[] uncompressed_data = null;
    byte[] input_data = null;
    ByteArrayOutputStream ret = new ByteArrayOutputStream();
    Inflater decompresser = new Inflater(false);
    long first_seek = fileChannel.position();
    Boolean uncompressing = true;
    while (uncompressing) {
      if (decompresser.needsInput()) {
        input_data = new byte[(compressed_size != null) ? compressed_size.intValue() : 1024];
        fileChannel.read(ByteBuffer.wrap(input_data));
        decompresser.setInput(input_data, 0, input_data.length);
      }
      uncompressed_data =
          new byte
              [(uncompressed_size != null)
                  ? uncompressed_size.intValue()
                  : (input_data.length * 4)];
      decompresser.inflate(uncompressed_data);
      int op = (int) (decompresser.getBytesWritten() - (long) ret.size());
      if (op > 0) ret.write(uncompressed_data, 0, op);

      if (decompresser.finished()) uncompressing = false;
    }
    fileChannel.position(
        (first_seek + decompresser.getBytesRead())); // move file pointer to start of next stream
    decompresser.end();
    return ret;
  }
 /**
  * Reads uncompressed data into an array of bytes. If <code>len</code> is not zero, the method
  * will block until some input can be decompressed; otherwise, no bytes are read and <code>0
  * </code> is returned.
  *
  * @param b the buffer into which the data is read
  * @param off the start offset in the destination array <code>b</code>
  * @param len the maximum number of bytes read
  * @return the actual number of bytes read, or -1 if the end of the compressed input is reached or
  *     a preset dictionary is needed
  * @exception NullPointerException If <code>b</code> is <code>null</code>.
  * @exception IndexOutOfBoundsException If <code>off</code> is negative, <code>len</code> is
  *     negative, or <code>len</code> is greater than <code>b.length - off</code>
  * @exception ZipException if a ZIP format error has occurred
  * @exception IOException if an I/O error has occurred
  */
 public int read(byte[] b, int off, int len) throws IOException {
   ensureOpen();
   if (b == null) {
     throw new NullPointerException();
   } else if (off < 0 || len < 0 || len > b.length - off) {
     throw new IndexOutOfBoundsException();
   } else if (len == 0) {
     return 0;
   }
   try {
     int n;
     while ((n = inf.inflate(b, off, len)) == 0) {
       if (inf.finished() || inf.needsDictionary()) {
         reachEOF = true;
         return -1;
       }
       if (inf.needsInput()) {
         fill();
       }
     }
     return n;
   } catch (DataFormatException e) {
     String s = e.getMessage();
     throw new ZipException(s != null ? s : "Invalid ZLIB data format");
   }
 }
  @Override
  public void decompress() {
    if (compressed) {
      Inflater decompressor = new Inflater();
      decompressor.setInput(data);

      ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);

      byte[] buf = new byte[1024];
      while (!decompressor.finished()) {
        try {
          int count = decompressor.inflate(buf);
          bos.write(buf, 0, count);
        } catch (DataFormatException e) {

        }
      }
      try {
        bos.close();
      } catch (IOException e) {

      }

      data = bos.toByteArray();
    }
  }
  private final byte[] uncompress(final byte[] input) throws IOException {

    Inflater decompressor = new Inflater();
    decompressor.setInput(input);

    // Create an expandable byte array to hold the decompressed data
    ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length);

    // Decompress the data
    byte[] buf = new byte[1024];
    while (!decompressor.finished()) {
      try {
        int count = decompressor.inflate(buf);
        bos.write(buf, 0, count);
      } catch (DataFormatException e) {
        // this will happen if the field is not compressed
        IOException newException =
            new IOException("field data are in wrong format: " + e.toString());
        newException.initCause(e);
        throw newException;
      }
    }

    decompressor.end();

    // Get the decompressed data
    return bos.toByteArray();
  }
 /**
  * inflater 解壓縮
  *
  * @param value
  * @return
  */
 public static byte[] inflater(byte[] value) {
   byte[] result = new byte[0];
   Inflater inflater = null;
   ByteArrayOutputStream out = null;
   try {
     inflater = new Inflater();
     inflater.setInput(value);
     //
     out = new ByteArrayOutputStream();
     byte[] buffer = new byte[1024];
     while (!inflater.finished()) {
       int count = inflater.inflate(buffer);
       out.write(buffer, 0, count);
     }
     //
     result = out.toByteArray();
   } catch (Exception ex) {
     ex.printStackTrace();
   } finally {
     if (inflater != null) {
       inflater.end(); // 不end也不會有oom,不過還是關了吧
     }
     IoHelper.close(out);
   }
   return result;
 }
  public static byte[] decompress(byte[] data) throws IOException, DataFormatException {

    Inflater inflater = new Inflater();

    inflater.setInput(data);

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);

    byte[] buffer = new byte[1024];

    while (!inflater.finished()) {

      int count = inflater.inflate(buffer);

      outputStream.write(buffer, 0, count);
    }
    outputStream.close();
    byte[] output = outputStream.toByteArray();

    System.out.println("Original: " + data.length);

    System.out.println("Compressed: " + output.length);

    return output;
  }
  private boolean handleCompressedFrame(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
      throws Exception {
    if (!in.isReadable(FRAME_COMPRESS_HEADER_LENGTH)) {
      return false;
    }

    int compressedPayloadLength = in.readInt();
    if (!in.isReadable(compressedPayloadLength)) {
      return false;
    }

    // decompress payload
    Inflater inflater = new Inflater();
    if (in.hasArray()) {
      inflater.setInput(in.array(), in.arrayOffset() + in.readerIndex(), compressedPayloadLength);
      in.skipBytes(compressedPayloadLength);
    } else {
      byte[] array = new byte[compressedPayloadLength];
      in.readBytes(array);
      inflater.setInput(array);
    }

    while (!inflater.finished()) {
      ByteBuf decompressed = ctx.alloc().heapBuffer(1024, 1024);
      byte[] outArray = decompressed.array();
      int count =
          inflater.inflate(outArray, decompressed.arrayOffset(), decompressed.writableBytes());
      decompressed.writerIndex(count);
      // put data in the pipeline
      out.add(decompressed);
    }

    return true;
  }
Beispiel #9
0
  public static byte[] inflateObject(byte[] compressedData) throws Exception {
    // Create the decompressor and give it the data to compress
    Inflater decompressor = new Inflater();
    decompressor.setInput(compressedData);

    // Create an expandable byte array to hold the decompressed data
    ByteArrayOutputStream bos = new ByteArrayOutputStream(compressedData.length);

    // Decompress the data
    byte[] buf = new byte[1024];
    while (!decompressor.finished()) {
      try {
        int count = decompressor.inflate(buf);
        bos.write(buf, 0, count);
      } catch (DataFormatException e) {
        throw e;
      } finally {
        try {
          bos.close();
        } catch (IOException ioe) {
        }
      }
    }

    // Get the decompressed data
    return bos.toByteArray();
  }
  /**
   * Writes an array of bytes to the uncompressed output stream.
   *
   * @param b buffer containing compressed data to decompress and write to the output stream
   * @param off starting offset of the compressed data within {@code b}
   * @param len number of bytes to decompress from {@code b}
   * @throws IndexOutOfBoundsException if {@code off < 0}, or if {@code len < 0}, or if {@code len >
   *     b.length - off}
   * @throws IOException if an I/O error occurs or this stream is already closed
   * @throws NullPointerException if {@code b} is null
   * @throws ZipException if a compression (ZIP) format error occurs
   */
  public void write(byte[] b, int off, int len) throws IOException {
    // Sanity checks
    ensureOpen();
    if (b == null) {
      throw new NullPointerException("Null buffer for read");
    } else if (off < 0 || len < 0 || len > b.length - off) {
      throw new IndexOutOfBoundsException();
    } else if (len == 0) {
      return;
    }

    // Write uncompressed data to the output stream
    try {
      for (; ; ) {
        int n;

        // Fill the decompressor buffer with output data
        if (inf.needsInput()) {
          int part;

          if (len < 1) {
            break;
          }

          part = (len < 512 ? len : 512);
          inf.setInput(b, off, part);
          off += part;
          len -= part;
        }

        // Decompress and write blocks of output data
        do {
          n = inf.inflate(buf, 0, buf.length);
          if (n > 0) {
            out.write(buf, 0, n);
          }
        } while (n > 0);

        // Check the decompressor
        if (inf.finished()) {
          break;
        }
        if (inf.needsDictionary()) {
          throw new ZipException("ZLIB dictionary missing");
        }
      }
    } catch (DataFormatException ex) {
      // Improperly formatted compressed (ZIP) data
      String msg = ex.getMessage();
      if (msg == null) {
        msg = "Invalid ZLIB data format";
      }
      throw new ZipException(msg);
    }
  }
Beispiel #11
0
 /** TIFF Adobe ZIP support contributed by Jason Newton. */
 public byte[] zipUncompress(byte[] input) {
   ByteArrayOutputStream imageBuffer = new ByteArrayOutputStream();
   byte[] buffer = new byte[1024];
   Inflater decompressor = new Inflater();
   decompressor.setInput(input);
   try {
     while (!decompressor.finished()) {
       int rlen = decompressor.inflate(buffer);
       imageBuffer.write(buffer, 0, rlen);
     }
   } catch (DataFormatException e) {
     IJ.log(e.toString());
   }
   decompressor.end();
   return imageBuffer.toByteArray();
 }
 public static byte[] decompress(byte[] compressedData) throws IOException {
   Inflater inflater = new Inflater();
   inflater.setInput(compressedData);
   ByteArrayOutputStream bos = new ByteArrayOutputStream(compressedData.length);
   byte[] buf = new byte[1024];
   while (!inflater.finished()) {
     try {
       int count = inflater.inflate(buf);
       bos.write(buf, 0, count);
     } catch (DataFormatException e) {
     }
   }
   bos.close();
   inflater.end();
   return bos.toByteArray();
 }
Beispiel #13
0
  /**
   * Reads from the compressed stream and stores the resulting uncompressed data into the byte
   * array.
   *
   * @return number of bytes read, or -1 upon EOF
   */
  public int read(byte[] b, int off, int len) throws IOException {
    if (len <= 0 || off < 0 || off + len > b.length) return 0;

    if (_eof) return -1;

    // Read from uncompressed stream
    if (!_isGzip) return _in.read(b, off, len);

    try {
      int sublen;
      int length = 0;
      while (length < len) {
        if (_inflater.needsInput()) {
          _readBufferSize = _in.read(_readBuffer, 0, _readBuffer.length);
          if (_readBufferSize < 0) break;

          _inflater.setInput(_readBuffer, 0, _readBufferSize);
        }

        sublen = _inflater.inflate(b, off + length, len - length);

        _crc.update(b, off + length, sublen);
        _inputSize += sublen;
        _totalInputSize += sublen;

        length += sublen;

        // Unread gzip trailer and possibly beginning of appended gzip data.
        if (_inflater.finished()) {
          int remaining = _inflater.getRemaining();
          _in.unread(_readBuffer, _readBufferSize - remaining, remaining);

          readTrailer();

          int secondPart = read(b, off + length, len - length);

          return secondPart > 0 ? length + secondPart : length;
        }
      }

      return length;
    } catch (DataFormatException e) {
      throw new IOException(e.getMessage());
    }
  }
Beispiel #14
0
  private static byte[] inflate(byte[] input) throws IOException {

    ByteArrayOutputStream bos;
    Inflater decompressor = new Inflater();

    decompressor.setInput(input, 0, input.length);
    bos = new ByteArrayOutputStream(input.length);

    byte[] buf = new byte[CHUNKSIZE];

    try {
      while (!decompressor.finished()) {
        int count = decompressor.inflate(buf);
        bos.write(buf, 0, count);
      }
      return bos.toByteArray();
    } catch (DataFormatException e) {
      throw new IOException("failed to inflate data", e);
    }
  }
Beispiel #15
0
 /**
  * decompress 0..len in data
  *
  * @param data
  * @param len length of data for decompress in data[]
  * @return
  * @throws java.util.zip.DataFormatException
  */
 public static byte[] defalteDecompress(byte[] data) throws DataFormatException {
   ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
   Inflater decompresser = new Inflater();
   try {
     decompresser.reset();
     decompresser.setInput(data, 0, data.length);
     byte[] buf = new byte[1024];
     while (!decompresser.finished()) {
       int i = decompresser.inflate(buf);
       o.write(buf, 0, i);
     }
     return o.toByteArray();
   } finally {
     decompresser.end();
     try {
       o.close();
     } catch (IOException e) {
     }
   }
 }
Beispiel #16
0
 /** Decompress the data bytes in the given message (in place). */
 private void _decompressMessageData(Message msg) {
   if ((msg.flags & Message.FLAGS_COMPRESSED) == 0) {
     throw new IllegalArgumentException("message data is not compressed");
   }
   Inflater decompresser = new Inflater();
   decompresser.setInput(msg.data);
   ByteArrayOutputStream bos = new ByteArrayOutputStream(msg.data.length);
   byte[] buffer = new byte[8192];
   try {
     while (!decompresser.finished()) {
       int size = decompresser.inflate(buffer);
       bos.write(buffer, 0, size);
     }
     msg.data = bos.toByteArray();
     msg.flags &= ~Message.FLAGS_COMPRESSED;
     decompresser.end();
   } catch (DataFormatException e) {
     throw new PyroException("invalid compressed data: ", e);
   }
 }
 /**
  * Descomprime un certificado contenido en la tarjeta CERES.
  *
  * @param compressedCertificate Certificado comprimido en ZIP a partir del 9 octeto.
  * @return Certificado codificado.
  * @throws IOException Cuando se produce un error en la descompresi&oacute;n del certificado.
  */
 private static byte[] deflate(final byte[] compressedCertificate) throws IOException {
   final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
   final Inflater decompressor = new Inflater();
   decompressor.setInput(compressedCertificate, 8, compressedCertificate.length - 8);
   final byte[] buf = new byte[1024];
   try {
     // Descomprimimos los datos
     while (!decompressor.finished()) {
       final int count = decompressor.inflate(buf);
       if (count == 0) {
         throw new DataFormatException();
       }
       buffer.write(buf, 0, count);
     }
     // Obtenemos los datos descomprimidos
     return buffer.toByteArray();
   } catch (final DataFormatException ex) {
     throw new IOException("Error al descomprimir el certificado: " + ex, ex); // $NON-NLS-1$
   }
 }
Beispiel #18
0
  /*
   * feed inflater more bytes in order to get some
   * decompressed output.
   * returns number of bytes actually got
   */
  private int doRead(byte[] buf, int offset, int len) throws DataFormatException, IOException {
    int read = 0;
    int n = 0;
    byte[] inputBuffer = new byte[len];

    while (len > 0) {
      n = inflater.inflate(buf, offset, len);
      if (n == 0) {
        if (inflater.finished()) {
          break;
        } else if (inflater.needsInput()) {
          // feeding
          int m = input.read(inputBuffer);

          if (m == -1) {
            // it shouldn't be here, throw exception
            throw new DataFormatException("Input is over while inflater still expecting data");
          } else {
            // feed the data in
            inflater.setInput(inputBuffer, 0, m);
            n = inflater.inflate(buf, offset, len);
            if (n > 0) {
              read += n;
              offset += n;
              len -= n;
            }
          }
        } else {
          // it shouldn't be here, throw
          throw new DataFormatException("Inflater is neither finished nor needing input.");
        }
      } else {
        read += n;
        offset += n;
        len -= n;
      }
    }
    return read;
  }
Beispiel #19
0
  public static byte[] decompress(byte[] data) throws Exception {
    if (data.length == 0) return null;

    Inflater inf = new Inflater();
    inf.setInput(data);

    ByteArrayOutputStream baos = new ByteArrayOutputStream(data.length);

    byte[] buf = new byte[1024];

    while (!inf.finished()) {

      int decompressed = inf.inflate(buf);

      baos.write(buf, 0, decompressed);
    }

    inf.end();
    baos.close();

    return baos.toByteArray();
  }
  /**
   * Decompresses a compressed byte array.
   *
   * @param input The byte array to be decompressed.
   * @return The byte array in its decompressed, readable form.
   */
  public static byte[] decompress(byte[] input) {
    try {
      final Inflater inflater = new Inflater();
      final ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(input.length);
      final byte[] buffer = new byte[1024];
      inflater.setInput(input);

      while (!inflater.finished()) {
        final int count = inflater.inflate(buffer);
        byteOutput.write(buffer, 0, count);
      }

      byteOutput.close();
      return byteOutput.toByteArray();
    } catch (final DataFormatException e) {
      RadixCore.getInstance().quitWithException("Error decompressing byte array.", e);
      return null;
    } catch (final IOException e) {
      RadixCore.getInstance().quitWithException("Error decompressing byte array.", e);
      return null;
    }
  }
 /** Parse out and decompress the data part of a fileblock helper function. */
 FileBlock parseData(byte buf[]) throws InvalidProtocolBufferException {
   FileBlock out = FileBlock.newInstance(type, indexdata);
   Fileformat.Blob blob = Fileformat.Blob.parseFrom(buf);
   if (blob.hasRaw()) {
     out.data = blob.getRaw();
   } else if (blob.hasZlibData()) {
     byte buf2[] = new byte[blob.getRawSize()];
     Inflater decompresser = new Inflater();
     decompresser.setInput(blob.getZlibData().toByteArray());
     // decompresser.getRemaining();
     try {
       decompresser.inflate(buf2);
     } catch (DataFormatException e) {
       e.printStackTrace();
       throw new Error(e);
     }
     assert (decompresser.finished());
     decompresser.end();
     out.data = ByteString.copyFrom(buf2);
   }
   return out;
 }
  @Override
  public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
    try {
      ByteBufferList transformed = new ByteBufferList();
      ByteBuffer output = ByteBuffer.allocate(bb.remaining() * 2);
      int totalInflated = 0;
      int totalRead = 0;
      while (bb.size() > 0) {
        ByteBuffer b = bb.remove();
        if (b.hasRemaining()) {
          totalRead = +b.remaining();
          mInflater.setInput(b.array(), b.arrayOffset() + b.position(), b.remaining());
          do {
            int inflated =
                mInflater.inflate(
                    output.array(), output.arrayOffset() + output.position(), output.remaining());
            totalInflated += inflated;
            output.position(output.position() + inflated);
            if (!output.hasRemaining()) {
              output.limit(output.position());
              output.position(0);
              transformed.add(output);
              Assert.assertNotSame(totalRead, 0);
              int newSize = output.capacity() * 2;
              output = ByteBuffer.allocate(newSize);
            }
          } while (!mInflater.needsInput() && !mInflater.finished());
        }
      }
      output.limit(output.position());
      output.position(0);
      transformed.add(output);

      Util.emitAllData(this, transformed);
    } catch (Exception ex) {
      report(ex);
    }
  }
  /**
   * Returns the non-null InputStream that should be returned to by all requests to {@link
   * #getContent()}.
   *
   * @return a non-null InputStream
   * @throws IOException if there was a problem
   */
  @Override
  InputStream decorate(final InputStream wrapped) throws IOException {
    /*
     * A zlib stream will have a header.
     *
     * CMF | FLG [| DICTID ] | ...compressed data | ADLER32 |
     *
     * * CMF is one byte.
     *
     * * FLG is one byte.
     *
     * * DICTID is four bytes, and only present if FLG.FDICT is set.
     *
     * Sniff the content. Does it look like a zlib stream, with a CMF, etc? c.f. RFC1950,
     * section 2.2. http://tools.ietf.org/html/rfc1950#page-4
     *
     * We need to see if it looks like a proper zlib stream, or whether it is just a deflate
     * stream. RFC2616 calls zlib streams deflate. Confusing, isn't it? That's why some servers
     * implement deflate Content-Encoding using deflate streams, rather than zlib streams.
     *
     * We could start looking at the bytes, but to be honest, someone else has already read
     * the RFCs and implemented that for us. So we'll just use the JDK libraries and exception
     * handling to do this. If that proves slow, then we could potentially change this to check
     * the first byte - does it look like a CMF? What about the second byte - does it look like
     * a FLG, etc.
     */

    /* We read a small buffer to sniff the content. */
    final byte[] peeked = new byte[6];

    final PushbackInputStream pushback = new PushbackInputStream(wrapped, peeked.length);

    final int headerLength = pushback.read(peeked);

    if (headerLength == -1) {
      throw new IOException("Unable to read the response");
    }

    /* We try to read the first uncompressed byte. */
    final byte[] dummy = new byte[1];

    final Inflater inf = new Inflater();

    try {
      int n;
      while ((n = inf.inflate(dummy)) == 0) {
        if (inf.finished()) {

          /* Not expecting this, so fail loudly. */
          throw new IOException("Unable to read the response");
        }

        if (inf.needsDictionary()) {

          /* Need dictionary - then it must be zlib stream with DICTID part? */
          break;
        }

        if (inf.needsInput()) {
          inf.setInput(peeked);
        }
      }

      if (n == -1) {
        throw new IOException("Unable to read the response");
      }

      /*
       * We read something without a problem, so it's a valid zlib stream. Just need to reset
       * and return an unused InputStream now.
       */
      pushback.unread(peeked, 0, headerLength);
      return new DeflateStream(pushback, new Inflater());
    } catch (final DataFormatException e) {

      /* Presume that it's an RFC1951 deflate stream rather than RFC1950 zlib stream and try
       * again. */
      pushback.unread(peeked, 0, headerLength);
      return new DeflateStream(pushback, new Inflater(true));
    } finally {
      inf.end();
    }
  }
  /**
   * Look up the byte code definition of the named class.
   *
   * <p>Created: Mar 30, 2004
   *
   * @param className
   * @return - byte code for the class definition.
   */
  private byte[] lookupClassData(String className) {

    if (isJar(moduleParentLocator)) {
      String fileName;
      if (LECCMachineConfiguration.generateBytecode()) {
        fileName = className.replace('.', '/') + COMPRESSED_CLASS_FILE_EXTENSION;
      } else {
        fileName = className.replace('.', '/') + CLASS_FILE_EXTENSION;
      }
      return loadJarData((ProgramResourceLocator.File) moduleParentLocator, fileName);

    } else {

      ProgramResourceLocator.File fileLocator;
      if (LECCMachineConfiguration.generateBytecode()) {
        String extension =
            className.substring(className.lastIndexOf('.') + 1)
                + CALClassLoader.COMPRESSED_CLASS_FILE_EXTENSION;
        fileLocator = ((ProgramResourceLocator.Folder) moduleParentLocator).extendFile(extension);
      } else {
        String extension =
            className.substring(className.lastIndexOf('.') + 1)
                + CALClassLoader.CLASS_FILE_EXTENSION;
        fileLocator = ((ProgramResourceLocator.Folder) moduleParentLocator).extendFile(extension);
      }

      byte[] fileData = loadFileData(fileLocator);
      if (LECCMachineConfiguration.generateBytecode()) {
        if (fileData == null) {
          return null;
        }

        // uncompress the data..
        inflater.reset();
        inflater.setInput(fileData);

        // Reusing this baos should be ok, since its only other use is in loadFileData(), which
        // we've finished calling.
        ByteArrayOutputStream baos = threadLocalByteArrayOutputStream.get();
        baos.reset();

        try {
          // Reusing this bytearray should be ok, since its only other use is in loadFileData(),
          // which we've finished calling.
          byte[] buf = threadLocalByteArray.get();
          while (!inflater.finished()) {
            int len = inflater.inflate(buf);
            baos.write(buf, 0, len);
          }

        } catch (DataFormatException e) {
          // Can't read the compressed class..

          // return null;
          throw new IllegalStateException("Can't read compressed class: " + className);
        }

        return baos.toByteArray();

        // Not necessary to close the ByteArrayOutputStream.

      } else {
        // Source generator.
        return fileData;
      }
    }
  }
  /**
   * {@inheritDoc}
   *
   * <p>If the decoding did not produce any output, for example because it consumed gzip header or
   * trailer bytes, it returns a buffer with zero capacity.
   *
   * <p>This method never returns null.
   *
   * <p>The given {@code buffer}'s position will be modified to reflect the bytes consumed during
   * the decoding.
   *
   * <p>The decoding may be finished without consuming the buffer completely if the buffer contains
   * gzip bytes plus other bytes (either plain or gzipped).
   */
  @Override
  public ByteBuffer decode(ByteBuffer buffer) {
    try {
      while (buffer.hasRemaining()) {
        byte currByte = buffer.get();
        switch (state) {
          case INITIAL:
            {
              buffer.position(buffer.position() - 1);
              state = State.ID;
              break;
            }
          case ID:
            {
              value += (currByte & 0xFF) << 8 * size;
              ++size;
              if (size == 2) {
                if (value != 0x8B1F) throw new ZipException("Invalid gzip bytes");
                state = State.CM;
              }
              break;
            }
          case CM:
            {
              if ((currByte & 0xFF) != 0x08)
                throw new ZipException("Invalid gzip compression method");
              state = State.FLG;
              break;
            }
          case FLG:
            {
              flags = currByte;
              state = State.MTIME;
              size = 0;
              value = 0;
              break;
            }
          case MTIME:
            {
              // Skip the 4 MTIME bytes
              ++size;
              if (size == 4) state = State.XFL;
              break;
            }
          case XFL:
            {
              // Skip XFL
              state = State.OS;
              break;
            }
          case OS:
            {
              // Skip OS
              state = State.FLAGS;
              break;
            }
          case FLAGS:
            {
              buffer.position(buffer.position() - 1);
              if ((flags & 0x04) == 0x04) {
                state = State.EXTRA_LENGTH;
                size = 0;
                value = 0;
              } else if ((flags & 0x08) == 0x08) state = State.NAME;
              else if ((flags & 0x10) == 0x10) state = State.COMMENT;
              else if ((flags & 0x2) == 0x2) {
                state = State.HCRC;
                size = 0;
                value = 0;
              } else state = State.DATA;
              break;
            }
          case EXTRA_LENGTH:
            {
              value += (currByte & 0xFF) << 8 * size;
              ++size;
              if (size == 2) state = State.EXTRA;
              break;
            }
          case EXTRA:
            {
              // Skip EXTRA bytes
              --value;
              if (value == 0) {
                // Clear the EXTRA flag and loop on the flags
                flags &= ~0x04;
                state = State.FLAGS;
              }
              break;
            }
          case NAME:
            {
              // Skip NAME bytes
              if (currByte == 0) {
                // Clear the NAME flag and loop on the flags
                flags &= ~0x08;
                state = State.FLAGS;
              }
              break;
            }
          case COMMENT:
            {
              // Skip COMMENT bytes
              if (currByte == 0) {
                // Clear the COMMENT flag and loop on the flags
                flags &= ~0x10;
                state = State.FLAGS;
              }
              break;
            }
          case HCRC:
            {
              // Skip HCRC
              ++size;
              if (size == 2) {
                // Clear the HCRC flag and loop on the flags
                flags &= ~0x02;
                state = State.FLAGS;
              }
              break;
            }
          case DATA:
            {
              buffer.position(buffer.position() - 1);
              while (true) {
                int decoded = inflate(bytes);
                if (decoded == 0) {
                  if (inflater.needsInput()) {
                    if (buffer.hasRemaining()) {
                      byte[] input = new byte[buffer.remaining()];
                      buffer.get(input);
                      inflater.setInput(input);
                    } else {
                      if (output != null) {
                        ByteBuffer result = ByteBuffer.wrap(output);
                        output = null;
                        return result;
                      }
                      break;
                    }
                  } else if (inflater.finished()) {
                    int remaining = inflater.getRemaining();
                    buffer.position(buffer.limit() - remaining);
                    state = State.CRC;
                    size = 0;
                    value = 0;
                    break;
                  } else {
                    throw new ZipException("Invalid inflater state");
                  }
                } else {
                  if (output == null) {
                    // Save the inflated bytes and loop to see if we have finished
                    output = Arrays.copyOf(bytes, decoded);
                  } else {
                    // Accumulate inflated bytes and loop to see if we have finished
                    byte[] newOutput = Arrays.copyOf(output, output.length + decoded);
                    System.arraycopy(bytes, 0, newOutput, output.length, decoded);
                    output = newOutput;
                  }
                }
              }
              break;
            }
          case CRC:
            {
              value += (currByte & 0xFF) << 8 * size;
              ++size;
              if (size == 4) {
                // From RFC 1952, compliant decoders need not to verify the CRC
                state = State.ISIZE;
                size = 0;
                value = 0;
              }
              break;
            }
          case ISIZE:
            {
              value += (currByte & 0xFF) << 8 * size;
              ++size;
              if (size == 4) {
                if (value != inflater.getBytesWritten())
                  throw new ZipException("Invalid input size");

                ByteBuffer result =
                    output == null ? BufferUtil.EMPTY_BUFFER : ByteBuffer.wrap(output);
                reset();
                return result;
              }
              break;
            }
          default:
            throw new ZipException();
        }
      }
      return BufferUtil.EMPTY_BUFFER;
    } catch (ZipException x) {
      throw new RuntimeException(x);
    }
  }
Beispiel #26
0
 public boolean finished() {
   return inflater.finished();
 }