1 /* 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.java.util.jar.pack; 27 28 import java.io.BufferedInputStream; 29 import java.io.ByteArrayOutputStream; 30 import java.io.File; 31 import java.io.FileInputStream; 32 import java.io.IOException; 33 import java.io.InputStream; 34 import java.io.OutputStream; 35 import java.util.HashSet; 36 import java.util.Set; 37 import java.util.SortedMap; 38 import java.util.TimeZone; 39 import java.util.jar.JarEntry; 40 import java.util.jar.JarInputStream; 41 import java.util.jar.JarOutputStream; 42 import java.util.jar.Pack200; 43 import java.util.zip.CRC32; 44 import java.util.zip.CheckedOutputStream; 45 import java.util.zip.ZipEntry; 46 47 /* 48 * Implementation of the Pack provider. 49 * </pre></blockquote> 50 * @author John Rose 51 * @author Kumar Srinivasan 52 */ 53 54 55 public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker { 56 57 public UnpackerImpl() {} 58 78 79 // The unpack worker... 80 /** 81 * Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally 82 * the entire buffer must be read, it may be more efficient to read the packed-stream 83 * to a file and pass the File object, in the alternate method described below. 84 * <p> 85 * Closes its input but not its output. (The output can accumulate more elements.) 86 * @param in an InputStream. 87 * @param out a JarOutputStream. 88 * @exception IOException if an error is encountered. 89 */ 90 public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException { 91 if (in == null) { 92 throw new NullPointerException("null input"); 93 } 94 if (out == null) { 95 throw new NullPointerException("null output"); 96 } 97 assert(Utils.currentInstance.get() == null); 98 TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) 99 ? null 100 : TimeZone.getDefault(); 101 102 try { 103 Utils.currentInstance.set(this); 104 if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); 105 final int verbose = props.getInteger(Utils.DEBUG_VERBOSE); 106 BufferedInputStream in0 = new BufferedInputStream(in); 107 if (Utils.isJarMagic(Utils.readMagic(in0))) { 108 if (verbose > 0) 109 Utils.log.info("Copying unpacked JAR file..."); 110 Utils.copyJarFile(new JarInputStream(in0), out); 111 } else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { 112 (new DoUnpack()).run(in0, out); 113 in0.close(); 114 Utils.markJarFile(out); 115 } else { 116 try { 117 (new NativeUnpack(this)).run(in0, out); 118 } catch (UnsatisfiedLinkError | NoClassDefFoundError ex) { 119 // failover to java implementation 120 (new DoUnpack()).run(in0, out); 121 } 122 in0.close(); 123 Utils.markJarFile(out); 124 } 125 } finally { 126 _nunp = null; 127 Utils.currentInstance.set(null); 128 if (tz != null) TimeZone.setDefault(tz); 129 } 130 } 131 132 /** 133 * Takes an input File containing the pack file, and generates a JarOutputStream. 134 * <p> 135 * Does not close its output. (The output can accumulate more elements.) 136 * @param in a File. 137 * @param out a JarOutputStream. 138 * @exception IOException if an error is encountered. 139 */ 140 public synchronized void unpack(File in, JarOutputStream out) throws IOException { 141 if (in == null) { 142 throw new NullPointerException("null input"); 143 } 144 if (out == null) { 145 throw new NullPointerException("null output"); 146 } 147 // Use the stream-based implementation. 148 // %%% Reconsider if native unpacker learns to memory-map the file. 229 bufOut.reset(); 230 if (file.isClassStub()) { 231 Package.Class cls = file.getStubClass(); 232 assert(cls != null); 233 new ClassWriter(cls, needCRC ? crcOut : bufOut).write(); 234 classesToWrite.remove(cls); // for an error check 235 } else { 236 // collect data & maybe CRC 237 file.writeTo(needCRC ? crcOut : bufOut); 238 } 239 je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED); 240 if (needCRC) { 241 if (verbose > 0) 242 Utils.log.info("stored size="+bufOut.size()+" and crc="+crc.getValue()); 243 244 je.setMethod(JarEntry.STORED); 245 je.setSize(bufOut.size()); 246 je.setCrc(crc.getValue()); 247 } 248 if (keepModtime) { 249 je.setTime(file.modtime); 250 // Convert back to milliseconds 251 je.setTime((long)file.modtime * 1000); 252 } else { 253 je.setTime((long)modtime * 1000); 254 } 255 out.putNextEntry(je); 256 bufOut.writeTo(out); 257 out.closeEntry(); 258 if (verbose > 0) 259 Utils.log.info("Writing "+Utils.zeString((ZipEntry)je)); 260 } 261 assert(classesToWrite.isEmpty()); 262 props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100"); 263 pkg.reset(); // reset for the next segment, if any 264 } 265 } 266 } | 1 /* 2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.java.util.jar.pack; 27 28 import java.io.BufferedInputStream; 29 import java.io.ByteArrayOutputStream; 30 import java.io.File; 31 import java.io.FileInputStream; 32 import java.io.IOException; 33 import java.io.InputStream; 34 import java.io.OutputStream; 35 import java.time.LocalDateTime; 36 import java.time.ZoneOffset; 37 import java.util.HashSet; 38 import java.util.Set; 39 import java.util.SortedMap; 40 import java.util.jar.JarEntry; 41 import java.util.jar.JarInputStream; 42 import java.util.jar.JarOutputStream; 43 import java.util.jar.Pack200; 44 import java.util.zip.CRC32; 45 import java.util.zip.CheckedOutputStream; 46 import java.util.zip.ZipEntry; 47 48 /* 49 * Implementation of the Pack provider. 50 * </pre></blockquote> 51 * @author John Rose 52 * @author Kumar Srinivasan 53 */ 54 55 56 public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker { 57 58 public UnpackerImpl() {} 59 79 80 // The unpack worker... 81 /** 82 * Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally 83 * the entire buffer must be read, it may be more efficient to read the packed-stream 84 * to a file and pass the File object, in the alternate method described below. 85 * <p> 86 * Closes its input but not its output. (The output can accumulate more elements.) 87 * @param in an InputStream. 88 * @param out a JarOutputStream. 89 * @exception IOException if an error is encountered. 90 */ 91 public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException { 92 if (in == null) { 93 throw new NullPointerException("null input"); 94 } 95 if (out == null) { 96 throw new NullPointerException("null output"); 97 } 98 assert(Utils.currentInstance.get() == null); 99 100 try { 101 Utils.currentInstance.set(this); 102 final int verbose = props.getInteger(Utils.DEBUG_VERBOSE); 103 BufferedInputStream in0 = new BufferedInputStream(in); 104 if (Utils.isJarMagic(Utils.readMagic(in0))) { 105 if (verbose > 0) 106 Utils.log.info("Copying unpacked JAR file..."); 107 Utils.copyJarFile(new JarInputStream(in0), out); 108 } else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { 109 (new DoUnpack()).run(in0, out); 110 in0.close(); 111 Utils.markJarFile(out); 112 } else { 113 try { 114 (new NativeUnpack(this)).run(in0, out); 115 } catch (UnsatisfiedLinkError | NoClassDefFoundError ex) { 116 // failover to java implementation 117 (new DoUnpack()).run(in0, out); 118 } 119 in0.close(); 120 Utils.markJarFile(out); 121 } 122 } finally { 123 _nunp = null; 124 Utils.currentInstance.set(null); 125 } 126 } 127 128 /** 129 * Takes an input File containing the pack file, and generates a JarOutputStream. 130 * <p> 131 * Does not close its output. (The output can accumulate more elements.) 132 * @param in a File. 133 * @param out a JarOutputStream. 134 * @exception IOException if an error is encountered. 135 */ 136 public synchronized void unpack(File in, JarOutputStream out) throws IOException { 137 if (in == null) { 138 throw new NullPointerException("null input"); 139 } 140 if (out == null) { 141 throw new NullPointerException("null output"); 142 } 143 // Use the stream-based implementation. 144 // %%% Reconsider if native unpacker learns to memory-map the file. 225 bufOut.reset(); 226 if (file.isClassStub()) { 227 Package.Class cls = file.getStubClass(); 228 assert(cls != null); 229 new ClassWriter(cls, needCRC ? crcOut : bufOut).write(); 230 classesToWrite.remove(cls); // for an error check 231 } else { 232 // collect data & maybe CRC 233 file.writeTo(needCRC ? crcOut : bufOut); 234 } 235 je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED); 236 if (needCRC) { 237 if (verbose > 0) 238 Utils.log.info("stored size="+bufOut.size()+" and crc="+crc.getValue()); 239 240 je.setMethod(JarEntry.STORED); 241 je.setSize(bufOut.size()); 242 je.setCrc(crc.getValue()); 243 } 244 if (keepModtime) { 245 LocalDateTime ldt = LocalDateTime 246 .ofEpochSecond(file.modtime, 0, ZoneOffset.UTC); 247 je.setTimeLocal(ldt); 248 } else { 249 je.setTime((long)modtime * 1000); 250 } 251 out.putNextEntry(je); 252 bufOut.writeTo(out); 253 out.closeEntry(); 254 if (verbose > 0) 255 Utils.log.info("Writing "+Utils.zeString((ZipEntry)je)); 256 } 257 assert(classesToWrite.isEmpty()); 258 props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100"); 259 pkg.reset(); // reset for the next segment, if any 260 } 261 } 262 } |