/** * 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); } }
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); } } }