⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manifest.java

📁 JAVA基本类源代码,大家可以学习学习!
💻 JAVA
字号:
/* * @(#)Manifest.java	1.41 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.util.jar;import java.io.FilterInputStream;import java.io.DataOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.io.IOException;import java.util.Map;import java.util.HashMap;import java.util.Iterator;/** * The Manifest class is used to maintain Manifest entry names and their * associated Attributes. There are main Manifest Attributes as well as * per-entry Attributes. For information on the Manifest format, please * see the  * <a href="../../../../guide/jar/jar.html"> * Manifest format specification</a>. * * @author  David Connelly * @version 1.41, 01/23/03 * @see	    Attributes * @since   1.2 */public class Manifest implements Cloneable {    // manifest main attributes    private Attributes attr = new Attributes();    // manifest entries    private Map entries = new HashMap();    /**     * Constructs a new, empty Manifest.     */    public Manifest() {    }    /**     * Constructs a new Manifest from the specified input stream.     *     * @param is the input stream containing manifest data     * @throws IOException if an I/O error has occured     */    public Manifest(InputStream is) throws IOException {	read(is);    }    /**     * Constructs a new Manifest that is a copy of the specified Manifest.     *     * @param man the Manifest to copy     */    public Manifest(Manifest man) {	attr.putAll(man.getMainAttributes());	entries.putAll(man.getEntries());    }    /**     * Returns the main Attributes for the Manifest.     * @return the main Attributes for the Manifest     */    public Attributes getMainAttributes() {	return attr;    }    /**     * Returns a Map of the entries contained in this Manifest. Each entry     * is represented by a String name (key) and associated Attributes (value).     *     * @return a Map of the entries contained in this Manifest     */    public Map getEntries() {	return entries;    }    /**     * Returns the Attributes for the specified entry name.     * This method is defined as:     * <pre>     *	    return (Attributes)getEntries().get(name)     * </pre>     *     * @param name entry name     * @return the Attributes for the specified entry name     */    public Attributes getAttributes(String name) {	return (Attributes)getEntries().get(name);    }    /**     * Clears the main Attributes as well as the entries in this Manifest.     */    public void clear() {	attr.clear();	entries.clear();    }    /**     * Writes the Manifest to the specified OutputStream.      * Attributes.Name.MANIFEST_VERSION must be set in      * MainAttributes prior to invoking this method.     *     * @param out the output stream     * @exception IOException if an I/O error has occurred     * @see #getMainAttributes     */    public void write(OutputStream out) throws IOException {	DataOutputStream dos = new DataOutputStream(out);	// Write out the main attributes for the manifest	attr.writeMain(dos);	// Now write out the pre-entry attributes	Iterator it = entries.entrySet().iterator();	while (it.hasNext()) {	    Map.Entry e = (Map.Entry)it.next();            StringBuffer buffer = new StringBuffer("Name: ");            String value = (String)e.getKey();            if (value != null) {                byte[] vb = value.getBytes("UTF8");                value = new String(vb, 0, 0, vb.length);            }	    buffer.append(value);	    buffer.append("\r\n");            make72Safe(buffer);            dos.writeBytes(buffer.toString());	    ((Attributes)e.getValue()).write(dos);	}	dos.flush();    }    /**     * Adds line breaks to enforce a maximum 72 bytes per line.     */    static void make72Safe(StringBuffer line) {        int length = line.length();        if (length > 72) {            int index = 70;            while (index < length - 2) {                line.insert(index, "\r\n ");                index += 72;                length += 3;            }        }        return;    }    /**     * Reads the Manifest from the specified InputStream. The entry     * names and attributes read will be merged in with the current     * manifest entries.     *     * @param is the input stream     * @exception IOException if an I/O error has occurred     */    public void read(InputStream is) throws IOException {	// Buffered input stream for reading manifest data	FastInputStream fis = new FastInputStream(is);	// Line buffer	byte[] lbuf = new byte[512];	// Read the main attributes for the manifest	attr.read(fis, lbuf);	// Total number of entries, attributes read	int ecount = 0, acount = 0;	// Average size of entry attributes	int asize = 2;	// Now parse the manifest entries	int len;	String name = null;        boolean skipEmptyLines = true;        byte[] lastline = null;	while ((len = fis.readLine(lbuf)) != -1) {	    if (lbuf[--len] != '\n') {		throw new IOException("manifest line too long");	    }	    if (len > 0 && lbuf[len-1] == '\r') {		--len;	    }            if (len == 0 && skipEmptyLines) {                continue;            }            skipEmptyLines = false;	    if (name == null) {		name = parseName(lbuf, len);		if (name == null) {		    throw new IOException("invalid manifest format");                		}                if (fis.peek() == ' ') {		    // name is wrapped                    lastline = new byte[len - 6];                    System.arraycopy(lbuf, 6, lastline, 0, len - 6);                    continue;                }	    } else {		// continuation line                byte[] buf = new byte[lastline.length + len - 1];                System.arraycopy(lastline, 0, buf, 0, lastline.length);                System.arraycopy(lbuf, 1, buf, lastline.length, len - 1);                if (fis.peek() == ' ') {		    // name is wrapped                    lastline = buf;		    continue;	        }		name = new String(buf, 0, buf.length, "UTF8");                lastline = null;	    }	    Attributes attr = getAttributes(name);	    if (attr == null) {		attr = new Attributes(asize);		entries.put(name, attr);	    }	    attr.read(fis, lbuf);	    ecount++;	    acount += attr.size();	    //XXX: Fix for when the average is 0. When it is 0, 	    // you get an Attributes object with an initial	    // capacity of 0, which tickles a bug in HashMap.	    asize = Math.max(2, acount / ecount);	    name = null;            skipEmptyLines = true;	}    }    private String parseName(byte[] lbuf, int len) {	if (toLower(lbuf[0]) == 'n' && toLower(lbuf[1]) == 'a' &&	    toLower(lbuf[2]) == 'm' && toLower(lbuf[3]) == 'e' &&	    lbuf[4] == ':' && lbuf[5] == ' ') {            try {	        return new String(lbuf, 6, len - 6, "UTF8");            }            catch (Exception e) {            }	}	return null;    }    private int toLower(int c) {	return (c >= 'A' && c <= 'Z') ? 'a' + (c - 'A') : c;    }    /**     * Returns true if the specified Object is also a Manifest and has     * the same main Attributes and entries.     *     * @param o the object to be compared     * @return true if the specified Object is also a Manifest and has     * the same main Attributes and entries     */    public boolean equals(Object o) {	if (o instanceof Manifest) {	    Manifest m = (Manifest)o;	    return attr.equals(m.getMainAttributes()) &&		   entries.equals(m.getEntries());	} else {	    return false;	}    }    /**     * Returns the hash code for this Manifest.     */    public int hashCode() {	return attr.hashCode() + entries.hashCode();    }    /**     * Returns a shallow copy of this Manifest.  The shallow copy is     * implemented as follows:     * <pre>     *     public Object clone() { return new Manifest(this); }     * </pre>     * @return a shallow copy of this Manifest     */    public Object clone() {	return new Manifest(this);    }    /*     * A fast buffered input stream for parsing manifest files.     */    static class FastInputStream extends FilterInputStream {	private byte buf[];	private int count = 0;	private int pos = 0;	FastInputStream(InputStream in) {	    this(in, 8192);	}	FastInputStream(InputStream in, int size) {	    super(in);	    buf = new byte[size];	}	public int read() throws IOException {	    if (pos >= count) {		fill();		if (pos >= count) {		    return -1;		}	    }	    return buf[pos++] & 0xff;	}	public int read(byte[] b, int off, int len) throws IOException {	    int avail = count - pos;	    if (avail <= 0) {		if (len >= buf.length) {		    return in.read(b, off, len);		}		fill();		avail = count - pos;		if (avail <= 0) {		    return -1;		}	    }	    if (len > avail) {		len = avail;	    }	    System.arraycopy(buf, pos, b, off, len);	    pos += len;	    return len;	}	/*	 * Reads 'len' bytes from the input stream, or until an end-of-line	 * is reached. Returns the number of bytes read.	 */	public int readLine(byte[] b, int off, int len) throws IOException {	    byte[] tbuf = this.buf;	    int total = 0;	    while (total < len) {		int avail = count - pos;		if (avail <= 0) {		    fill();		    avail = count - pos;		    if (avail <= 0) {			return -1;		    }		}		int n = len - total;		if (n > avail) {		    n = avail;		}		int tpos = pos;		int maxpos = tpos + n;		while (tpos < maxpos && tbuf[tpos++] != '\n') ;		n = tpos - pos;		System.arraycopy(tbuf, pos, b, off, n);		off += n;		total += n;		pos = tpos;		if (tbuf[tpos-1] == '\n') {		    break;		}	    }	    return total;	}	public byte peek() throws IOException {	    if (pos == count)		fill();	    return buf[pos];	}	public int readLine(byte[] b) throws IOException {	    return readLine(b, 0, b.length);	}	public long skip(long n) throws IOException {	    if (n <= 0) {		return 0;	    }	    long avail = count - pos;	    if (avail <= 0) {		return in.skip(n);	    }	    if (n > avail) {		n = avail;	    }	    pos += n;	    return n;	}	public int available() throws IOException {	    return (count - pos) + in.available();	}	public void close() throws IOException {	    if (in != null) {		in.close();		in = null;		buf = null;	    }	}	private void fill() throws IOException {	    count = pos = 0;	    int n = in.read(buf, 0, buf.length);	    if (n > 0) {		count = n;	    }	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -