Пример #1
0
  /**
   * Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally the entire
   * buffer must be read, it may be more efficient to read the packed-stream to a file and pass the
   * File object, in the alternate method described below.
   *
   * <p>Closes its input but not its output. (The output can accumulate more elements.)
   *
   * @param in an InputStream.
   * @param out a JarOutputStream.
   * @exception IOException if an error is encountered.
   */
  public void unpack(InputStream in0, JarOutputStream out) throws IOException {
    assert (Utils.currentInstance.get() == null);
    TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : TimeZone.getDefault();

    try {
      Utils.currentInstance.set(this);
      if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
      final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
      BufferedInputStream in = new BufferedInputStream(in0);
      if (Utils.isJarMagic(Utils.readMagic(in))) {
        if (verbose > 0) Utils.log.info("Copying unpacked JAR file...");
        Utils.copyJarFile(new JarInputStream(in), out);
      } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
        (new DoUnpack()).run(in, out);
        in.close();
        Utils.markJarFile(out);
      } else {
        (new NativeUnpack(this)).run(in, out);
        in.close();
        Utils.markJarFile(out);
      }
    } finally {
      _nunp = null;
      Utils.currentInstance.set(null);
      if (tz != null) TimeZone.setDefault(tz);
    }
  }
Пример #2
0
  void run(InputStream inRaw, JarOutputStream jstream, ByteBuffer presetInput) throws IOException {
    BufferedInputStream in0 = new BufferedInputStream(inRaw);
    this.in = in0; // for readInputFn to see
    _verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
    // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000
    // TODO eliminate and fix in unpack.cpp

    final int modtime =
        Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0"))
            ? Constants.NO_MODTIME
            : _props.getTime(Utils.UNPACK_MODIFICATION_TIME);

    copyInOption(Utils.DEBUG_VERBOSE);
    copyInOption(Pack200.Unpacker.DEFLATE_HINT);
    if (modtime == Constants.NO_MODTIME) // Dont pass KEEP && NOW
    copyInOption(Utils.UNPACK_MODIFICATION_TIME);
    updateProgress(); // reset progress bar
    for (; ; ) {
      // Read the packed bits.
      long counts = start(presetInput, 0);
      _byteCount = _estByteLimit = 0; // reset partial scan counts
      ++_segCount; // just finished scanning a whole segment...
      int nextSeg = (int) (counts >>> 32);
      int nextFile = (int) (counts >>> 0);

      // Estimate eventual total number of segments and files.
      _estSegLimit = _segCount + nextSeg;
      double filesAfterThisSeg = _fileCount + nextFile;
      _estFileLimit = (int) ((filesAfterThisSeg * _estSegLimit) / _segCount);

      // Write the files.
      int[] intParts = {0, 0, 0, 0};
      //    intParts = {size.hi/lo, mod, defl}
      Object[] parts = {intParts, null, null, null};
      //       parts = { {intParts}, name, data0/1 }
      while (getNextFile(parts)) {
        // BandStructure.printArrayTo(System.out, intParts, 0, parts.length);
        String name = (String) parts[1];
        long size = ((long) intParts[0] << 32) + (((long) intParts[1] << 32) >>> 32);

        long mtime = (modtime != Constants.NO_MODTIME) ? modtime : intParts[2];
        boolean deflateHint = (intParts[3] != 0);
        ByteBuffer data0 = (ByteBuffer) parts[2];
        ByteBuffer data1 = (ByteBuffer) parts[3];
        writeEntry(jstream, name, mtime, size, deflateHint, data0, data1);
        ++_fileCount;
        updateProgress();
      }
      presetInput = getUnusedInput();
      long consumed = finish();
      if (_verbose > 0) Utils.log.info("bytes consumed = " + consumed);
      if (presetInput == null && !Utils.isPackMagic(Utils.readMagic(in0))) {
        break;
      }
      if (_verbose > 0) {
        if (presetInput != null) Utils.log.info("unused input = " + presetInput);
      }
    }
  }