/* * Helper to read the entire contents of the manifest from the * given input stream. Usually we can do this in a single read * but we need to account for 'infinite' streams, by ensuring we * have a line feed within a reasonable number of characters. */ private byte[] readFully(InputStream is) throws IOException { // Initial read byte[] buffer = new byte[4096]; int count = is.read(buffer); int nextByte = is.read(); // Did we get it all in one read? if (nextByte == -1) { byte[] dest = new byte[count]; System.arraycopy(buffer, 0, dest, 0, count); return dest; } // Does it look like a manifest? if (!containsLine(buffer, count)) { // archive.2E=Manifest is too long throw new IOException(Messages.getString("archive.2E")); // $NON-NLS-1$ } // Requires additional reads ByteArrayOutputStream baos = new ByteArrayOutputStream(count * 2); baos.write(buffer, 0, count); baos.write(nextByte); while (true) { count = is.read(buffer); if (count == -1) { return baos.toByteArray(); } baos.write(buffer, 0, count); } }
private static void writeEntry( OutputStream os, Attributes.Name name, String value, CharsetEncoder encoder, ByteBuffer bBuf) throws IOException { byte[] out = name.getBytes(); if (out.length > LINE_LENGTH_LIMIT) { throw new IOException( Messages.getString( "archive.33", name, Integer.valueOf(LINE_LENGTH_LIMIT))); // $NON-NLS-1$ } os.write(out); os.write(VALUE_SEPARATOR); encoder.reset(); bBuf.clear().limit(LINE_LENGTH_LIMIT - out.length - 2); CharBuffer cBuf = CharBuffer.wrap(value); CoderResult r; while (true) { r = encoder.encode(cBuf, bBuf, true); if (CoderResult.UNDERFLOW == r) { r = encoder.flush(bBuf); } os.write(bBuf.array(), bBuf.arrayOffset(), bBuf.position()); os.write(LINE_SEPARATOR); if (CoderResult.UNDERFLOW == r) { break; } os.write(' '); bBuf.clear().limit(LINE_LENGTH_LIMIT - 1); } }
/** * Returns the {@code Manifest} object associated with this {@code JarFile} or {@code null} if no * MANIFEST entry exists. * * @return the MANIFEST. * @throws IOException if an error occurs reading the MANIFEST file. * @throws IllegalStateException if the jar file is closed. * @see Manifest */ public Manifest getManifest() throws IOException { if (closed) { // archive.35=JarFile has been closed throw new IllegalStateException(Messages.getString("archive.35")); // $NON-NLS-1$ } if (manifest != null) { return manifest; } try { InputStream is = super.getInputStream(manifestEntry); if (verifier != null) { verifier.addMetaEntry(manifestEntry.getName(), getAllBytesFromStreamAndClose(is)); is = super.getInputStream(manifestEntry); } try { manifest = new Manifest(is, verifier != null); } finally { is.close(); } manifestEntry = null; // Can discard the entry now. } catch (NullPointerException e) { manifestEntry = null; } return manifest; }