Пример #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);
      }
    }
  }
Пример #3
0
 private void copyInOption(String opt) {
   String val = _props.getProperty(opt);
   if (_verbose > 0) Utils.log.info("set " + opt + "=" + val);
   if (val != null) {
     boolean set = setOption(opt, val);
     if (!set) Utils.log.warning("Invalid option " + opt + "=" + val);
   }
 }
Пример #4
0
 /**
  * Takes an input File containing the pack file, and generates a JarOutputStream.
  *
  * <p>Does not close its output. (The output can accumulate more elements.)
  *
  * @param in a File.
  * @param out a JarOutputStream.
  * @exception IOException if an error is encountered.
  */
 public void unpack(File in, JarOutputStream out) throws IOException {
   // Use the stream-based implementation.
   // %%% Reconsider if native unpacker learns to memory-map the file.
   FileInputStream instr = new FileInputStream(in);
   unpack(instr, out);
   if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
     in.delete();
   }
 }
Пример #5
0
 private void updateProgress() {
   // Progress is a combination of segment reading and file writing.
   final double READ_WT = 0.33;
   final double WRITE_WT = 0.67;
   double readProgress = _segCount;
   if (_estByteLimit > 0 && _byteCount > 0) readProgress += (double) _byteCount / _estByteLimit;
   double writeProgress = _fileCount;
   double scaledProgress =
       READ_WT * readProgress / Math.max(_estSegLimit, 1)
           + WRITE_WT * writeProgress / Math.max(_estFileLimit, 1);
   int percent = (int) Math.round(100 * scaledProgress);
   if (percent > 100) percent = 100;
   if (percent > _prevPercent) {
     _prevPercent = percent;
     _props.setInteger(Pack200.Unpacker.PROGRESS, percent);
     if (_verbose > 0) Utils.log.info("progress = " + percent);
   }
 }