79 80 /** 81 * Get the set of options for the pack and unpack engines. 82 * @return A sorted association of option key strings to option values. 83 */ 84 public SortedMap<String, String> properties() { 85 return props; 86 } 87 88 // Back-pointer to NativeUnpacker, when active. 89 Object _nunp; 90 91 92 public String toString() { 93 return Utils.getVersionString(); 94 } 95 96 //Driver routines 97 98 // The unpack worker... 99 /** 100 * Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally 101 * the entire buffer must be read, it may be more efficient to read the packed-stream 102 * to a file and pass the File object, in the alternate method described below. 103 * <p> 104 * Closes its input but not its output. (The output can accumulate more elements.) 105 * @param in an InputStream. 106 * @param out a JarOutputStream. 107 * @exception IOException if an error is encountered. 108 */ 109 public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException { 110 if (in == null) { 111 throw new NullPointerException("null input"); 112 } 113 if (out == null) { 114 throw new NullPointerException("null output"); 115 } 116 assert(Utils.currentInstance.get() == null); 117 TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) 118 ? null 119 : TimeZone.getDefault(); 120 121 try { 122 Utils.currentInstance.set(this); 123 if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); 124 final int verbose = props.getInteger(Utils.DEBUG_VERBOSE); 125 BufferedInputStream in0 = new BufferedInputStream(in); 126 if (Utils.isJarMagic(Utils.readMagic(in0))) { 127 if (verbose > 0) 128 Utils.log.info("Copying unpacked JAR file..."); 129 Utils.copyJarFile(new JarInputStream(in0), out); 130 } else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { 131 (new DoUnpack()).run(in0, out); 132 in0.close(); 133 Utils.markJarFile(out); 134 } else { 135 try { 136 (new NativeUnpack(this)).run(in0, out); 137 } catch (UnsatisfiedLinkError | NoClassDefFoundError ex) { 138 // failover to java implementation 139 (new DoUnpack()).run(in0, out); 140 } 141 in0.close(); 142 Utils.markJarFile(out); 143 } 144 } finally { 145 _nunp = null; 146 Utils.currentInstance.set(null); 147 if (tz != null) TimeZone.setDefault(tz); 148 } 149 } 150 151 /** 152 * Takes an input File containing the pack file, and generates a JarOutputStream. 153 * <p> 154 * Does not close its output. (The output can accumulate more elements.) 155 * @param in a File. 156 * @param out a JarOutputStream. 157 * @exception IOException if an error is encountered. 158 */ 159 public synchronized void unpack(File in, JarOutputStream out) throws IOException { 160 if (in == null) { 161 throw new NullPointerException("null input"); 162 } 163 if (out == null) { 164 throw new NullPointerException("null output"); 165 } 166 // Use the stream-based implementation. 167 // %%% Reconsider if native unpacker learns to memory-map the file. 168 try (FileInputStream instr = new FileInputStream(in)) { 169 unpack(instr, out); 170 } 171 if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { 172 in.delete(); 173 } 174 } | 79 80 /** 81 * Get the set of options for the pack and unpack engines. 82 * @return A sorted association of option key strings to option values. 83 */ 84 public SortedMap<String, String> properties() { 85 return props; 86 } 87 88 // Back-pointer to NativeUnpacker, when active. 89 Object _nunp; 90 91 92 public String toString() { 93 return Utils.getVersionString(); 94 } 95 96 //Driver routines 97 98 // The unpack worker... 99 100 /** 101 * Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally 102 * the entire buffer must be read, it may be more efficient to read the packed-stream 103 * to a file and pass the File object, in the alternate method described below. 104 * <p> 105 * Closes its input but not its output. (The output can accumulate more elements.) 106 * 107 * @param in an InputStream. 108 * @param out a JarOutputStream. 109 * @exception IOException if an error is encountered. 110 */ 111 public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException { 112 if (in == null) { 113 throw new NullPointerException("null input"); 114 } 115 if (out == null) { 116 throw new NullPointerException("null output"); 117 } 118 assert (Utils.currentInstance.get() == null); 119 boolean needUTC = !props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE); 120 try { 121 Utils.currentInstance.set(this); 122 if (needUTC) { 123 Utils.changeDefaultTimeZoneToUtc(); 124 } 125 final int verbose = props.getInteger(Utils.DEBUG_VERBOSE); 126 BufferedInputStream in0 = new BufferedInputStream(in); 127 if (Utils.isJarMagic(Utils.readMagic(in0))) { 128 if (verbose > 0) { 129 Utils.log.info("Copying unpacked JAR file..."); 130 } 131 Utils.copyJarFile(new JarInputStream(in0), out); 132 } else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { 133 (new DoUnpack()).run(in0, out); 134 in0.close(); 135 Utils.markJarFile(out); 136 } else { 137 try { 138 (new NativeUnpack(this)).run(in0, out); 139 } catch (UnsatisfiedLinkError | NoClassDefFoundError ex) { 140 // failover to java implementation 141 (new DoUnpack()).run(in0, out); 142 } 143 in0.close(); 144 Utils.markJarFile(out); 145 } 146 } finally { 147 _nunp = null; 148 Utils.currentInstance.set(null); 149 if (needUTC) { 150 Utils.restoreDefaultTimeZone(); 151 } 152 } 153 } 154 155 /** 156 * Takes an input File containing the pack file, and generates a JarOutputStream. 157 * <p> 158 * Does not close its output. (The output can accumulate more elements.) 159 * 160 * @param in a File. 161 * @param out a JarOutputStream. 162 * @exception IOException if an error is encountered. 163 */ 164 public synchronized void unpack(File in, JarOutputStream out) throws IOException { 165 if (in == null) { 166 throw new NullPointerException("null input"); 167 } 168 if (out == null) { 169 throw new NullPointerException("null output"); 170 } 171 // Use the stream-based implementation. 172 // %%% Reconsider if native unpacker learns to memory-map the file. 173 try (FileInputStream instr = new FileInputStream(in)) { 174 unpack(instr, out); 175 } 176 if (props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { 177 in.delete(); 178 } 179 } |