private void setSizesAndOffsetFromZip64Extra( final ZipEntry ze, final OffsetEntry offset, final int diskStart) throws IOException { final Zip64ExtendedInformationExtraField z64 = (Zip64ExtendedInformationExtraField) ze.getExtraField(Zip64ExtendedInformationExtraField.HEADER_ID); if (z64 != null) { final boolean hasUncompressedSize = ze.getSize() == 4294967295L; final boolean hasCompressedSize = ze.getCompressedSize() == 4294967295L; final boolean hasRelativeHeaderOffset = offset.headerOffset == 4294967295L; z64.reparseCentralDirectoryData( hasUncompressedSize, hasCompressedSize, hasRelativeHeaderOffset, diskStart == 65535); if (hasUncompressedSize) { ze.setSize(z64.getSize().getLongValue()); } else if (hasCompressedSize) { z64.setSize(new ZipEightByteInteger(ze.getSize())); } if (hasCompressedSize) { ze.setCompressedSize(z64.getCompressedSize().getLongValue()); } else if (hasUncompressedSize) { z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize())); } if (hasRelativeHeaderOffset) { offset.headerOffset = z64.getRelativeHeaderOffset().getLongValue(); } } }
/** Creates a new JAR file. */ void create(OutputStream out, Manifest manifest) throws IOException { ZipOutputStream zos = new JarOutputStream(out); if (flag0) { zos.setMethod(ZipOutputStream.STORED); } if (manifest != null) { if (vflag) { output(getMsg("out.added.manifest")); } ZipEntry e = new ZipEntry(MANIFEST_DIR); e.setTime(System.currentTimeMillis()); e.setSize(0); e.setCrc(0); zos.putNextEntry(e); e = new ZipEntry(MANIFEST_NAME); e.setTime(System.currentTimeMillis()); if (flag0) { crc32Manifest(e, manifest); } zos.putNextEntry(e); manifest.write(zos); zos.closeEntry(); } for (File file : entries) { addFile(zos, file); } zos.close(); }
public void installFramework(File frameFile, String tag) throws AndrolibException { InputStream in = null; ZipOutputStream out = null; try { ZipFile zip = new ZipFile(frameFile); ZipEntry entry = zip.getEntry("resources.arsc"); if (entry == null) { throw new AndrolibException("Can't find resources.arsc file"); } in = zip.getInputStream(entry); byte[] data = IOUtils.toByteArray(in); ARSCData arsc = ARSCDecoder.decode(new ByteArrayInputStream(data), true, true); publicizeResources(data, arsc.getFlagsOffsets()); File outFile = new File( getFrameworkDir(), String.valueOf(arsc.getOnePackage().getId()) + (tag == null ? "" : '-' + tag) + ".apk"); out = new ZipOutputStream(new FileOutputStream(outFile)); out.setMethod(ZipOutputStream.STORED); CRC32 crc = new CRC32(); crc.update(data); entry = new ZipEntry("resources.arsc"); entry.setSize(data.length); entry.setCrc(crc.getValue()); out.putNextEntry(entry); out.write(data); LOGGER.info("Framework installed to: " + outFile); } catch (ZipException ex) { throw new AndrolibException(ex); } catch (IOException ex) { throw new AndrolibException(ex); } finally { if (in != null) { try { in.close(); } catch (IOException ex) { } } if (out != null) { try { out.close(); } catch (IOException ex) { } } } }
/** Adds a new file entry to the ZIP output stream. */ void addFile(ZipOutputStream zos, File file) throws IOException { String name = file.getPath(); boolean isDir = file.isDirectory(); if (isDir) { name = name.endsWith(File.separator) ? name : (name + File.separator); } name = entryName(name); if (name.equals("") || name.equals(".") || name.equals(zname)) { return; } else if ((name.equals(MANIFEST_DIR) || name.equals(MANIFEST_NAME)) && !Mflag) { if (vflag) { output(formatMsg("out.ignore.entry", name)); } return; } long size = isDir ? 0 : file.length(); if (vflag) { out.print(formatMsg("out.adding", name)); } ZipEntry e = new ZipEntry(name); e.setTime(file.lastModified()); if (size == 0) { e.setMethod(ZipEntry.STORED); e.setSize(0); e.setCrc(0); } else if (flag0) { crc32File(e, file); } zos.putNextEntry(e); if (!isDir) { copy(file, zos); } zos.closeEntry(); /* report how much compression occurred. */ if (vflag) { size = e.getSize(); long csize = e.getCompressedSize(); out.print(formatMsg2("out.size", String.valueOf(size), String.valueOf(csize))); if (e.getMethod() == ZipEntry.DEFLATED) { long ratio = 0; if (size != 0) { ratio = ((size - csize) * 100) / size; } output(formatMsg("out.deflated", String.valueOf(ratio))); } else { output(getMsg("out.stored")); } } }
/** * Zips byte array. * * @param input Input bytes. * @param initBufSize Initial buffer size. * @return Zipped byte array. * @throws IOException If failed. */ public static byte[] zipBytes(byte[] input, int initBufSize) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(initBufSize); try (ZipOutputStream zos = new ZipOutputStream(bos)) { ZipEntry entry = new ZipEntry(""); try { entry.setSize(input.length); zos.putNextEntry(entry); zos.write(input); } finally { zos.closeEntry(); } } return bos.toByteArray(); }
/** Updates an existing jar file. */ boolean update(InputStream in, OutputStream out, InputStream newManifest, JarIndex jarIndex) throws IOException { ZipInputStream zis = new ZipInputStream(in); ZipOutputStream zos = new JarOutputStream(out); ZipEntry e = null; boolean foundManifest = false; boolean updateOk = true; if (jarIndex != null) { addIndex(jarIndex, zos); } // put the old entries first, replace if necessary while ((e = zis.getNextEntry()) != null) { String name = e.getName(); boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME); if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME)) || (Mflag && isManifestEntry)) { continue; } else if (isManifestEntry && ((newManifest != null) || (ename != null) || (pname != null))) { foundManifest = true; if (newManifest != null) { // Don't read from the newManifest InputStream, as we // might need it below, and we can't re-read the same data // twice. FileInputStream fis = new FileInputStream(mname); boolean ambiguous = isAmbiguousMainClass(new Manifest(fis)); fis.close(); if (ambiguous) { return false; } } // Update the manifest. Manifest old = new Manifest(zis); if (newManifest != null) { old.read(newManifest); } if (!updateManifest(old, zos)) { return false; } } else { if (!entryMap.containsKey(name)) { // copy the old stuff // do our own compression ZipEntry e2 = new ZipEntry(name); e2.setMethod(e.getMethod()); e2.setTime(e.getTime()); e2.setComment(e.getComment()); e2.setExtra(e.getExtra()); if (e.getMethod() == ZipEntry.STORED) { e2.setSize(e.getSize()); e2.setCrc(e.getCrc()); } zos.putNextEntry(e2); copy(zis, zos); } else { // replace with the new files File f = entryMap.get(name); addFile(zos, f); entryMap.remove(name); entries.remove(f); } } } // add the remaining new files for (File f : entries) { addFile(zos, f); } if (!foundManifest) { if (newManifest != null) { Manifest m = new Manifest(newManifest); updateOk = !isAmbiguousMainClass(m); if (updateOk) { if (!updateManifest(m, zos)) { updateOk = false; } } } else if (ename != null || pname != null) { if (!updateManifest(new Manifest(), zos)) { updateOk = false; } } } zis.close(); zos.close(); return updateOk; }
/** Updates a ZipEntry which describes the data read by this output stream, in STORED mode. */ public void updateEntry(ZipEntry e) { e.setMethod(ZipEntry.STORED); e.setSize(n); e.setCrc(crc.getValue()); }