FileDocCategorySizeDatePackage
MimeHeaders.javaAPI DocGlassfish v2 API15129Tue Jun 05 14:49:26 BST 2007org.apache.tomcat.util.http

MimeHeaders

public class MimeHeaders extends Object
Memory-efficient repository for Mime Headers. When the object is recycled, it will keep the allocated headers[] and all the MimeHeaderField - no GC is generated. For input headers it is possible to use the MessageByte for Fileds - so no GC will be generated. The only garbage is generated when using the String for header names/values - this can't be avoided when the servlet calls header methods, but is easy to avoid inside tomcat. The goal is to use _only_ MessageByte-based Fields, and reduce to 0 the memory overhead of tomcat. TODO: XXX one-buffer parsing - for http ( other protocols don't need that ) XXX remove unused methods XXX External enumerations, with 0 GC. XXX use HeaderName ID
author
dac@eng.sun.com
author
James Todd [gonzo@eng.sun.com]
author
Costin Manolache
author
kevin seguin

Fields Summary
public static final int
DEFAULT_HEADER_SIZE
Initial size - should be == average number of headers per request XXX make it configurable ( fine-tuning of web-apps )
private MimeHeaderField[]
headers
The header fields.
private int
count
The current number of header fields.
Constructors Summary
public MimeHeaders()
Creates a new MimeHeaders object using a default buffer size.


                   
      
    
Methods Summary
public org.apache.tomcat.util.buf.MessageBytesaddValue(java.lang.String name)
Create a new named header , return the MessageBytes container for the new value

 	MimeHeaderField mh = createHeader();
	mh.getName().setString(name);
	return mh.getValue();
    
public org.apache.tomcat.util.buf.MessageBytesaddValue(byte[] b, int startN, int len)
Create a new named header using un-translated byte[]. The conversion to chars can be delayed until encoding is known.

	MimeHeaderField mhf=createHeader();
	mhf.getName().setBytes(b, startN, len);
	return mhf.getValue();
    
public org.apache.tomcat.util.buf.MessageBytesaddValue(char[] c, int startN, int len)
Create a new named header using translated char[].

	MimeHeaderField mhf=createHeader();
	mhf.getName().setChars(c, startN, len);
	return mhf.getValue();
    
public voidclear()
Clears all header fields.

	for (int i = 0; i < count; i++) {
	    headers[i].recycle();
	}
	count = 0;
    
private org.apache.tomcat.util.http.MimeHeaderFieldcreateHeader()
Adds a partially constructed field to the header. This field has not had its name or value initialized.

	MimeHeaderField mh;
	int len = headers.length;
	if (count >= len) {
	    // expand header list array
	    MimeHeaderField tmp[] = new MimeHeaderField[count * 2];
	    System.arraycopy(headers, 0, tmp, 0, len);
	    headers = tmp;
	}
	if ((mh = headers[count]) == null) {
	    headers[count] = mh = new MimeHeaderField();
	}
	count++;
	return mh;
    
public intfindHeader(java.lang.String name, int starting)
Find the index of a header with the given name.

	// We can use a hash - but it's not clear how much
	// benefit you can get - there is an  overhead 
	// and the number of headers is small (4-5 ?)
	// Another problem is that we'll pay the overhead
	// of constructing the hashtable

	// A custom search tree may be better
        for (int i = starting; i < count; i++) {
	    if (headers[i].getName().equalsIgnoreCase(name)) {
                return i;
            }
        }
        return -1;
    
public java.lang.StringgetHeader(java.lang.String name)

	MessageBytes mh = getValue(name);
	return mh != null ? mh.toString() : null;
    
public org.apache.tomcat.util.buf.MessageBytesgetName(int n)
Returns the Nth header name, or null if there is no such header. This may be used to iterate through all header fields.

	return n >= 0 && n < count ? headers[n].getName() : null;
    
public org.apache.tomcat.util.buf.MessageBytesgetUniqueValue(java.lang.String name)
Finds and returns a unique header field with the given name. If no such field exists, null is returned. If the specified header field is not unique then an {@link IllegalArgumentException} is thrown.

        MessageBytes result = null;
        for (int i = 0; i < count; i++) {
            if (headers[i].getName().equalsIgnoreCase(name)) {
                if (result == null) {
                    result = headers[i].getValue();
                } else {
                    throw new IllegalArgumentException();
                }
            }
        }
        return result;
    
public org.apache.tomcat.util.buf.MessageBytesgetValue(java.lang.String name)
Finds and returns a header field with the given name. If no such field exists, null is returned. If more than one such field is in the header, an arbitrary one is returned.

        for (int i = 0; i < count; i++) {
	    if (headers[i].getName().equalsIgnoreCase(name)) {
                return headers[i].getValue();
            }
        }
        return null;
    
public org.apache.tomcat.util.buf.MessageBytesgetValue(int n)
Returns the Nth header value, or null if there is no such header. This may be used to iterate through all header fields.

	return n >= 0 && n < count ? headers[n].getValue() : null;
    
public java.util.Enumerationnames()
Returns an enumeration of strings representing the header field names. Field names may appear multiple times in this enumeration, indicating that multiple fields with that name exist in this header.

	return new NamesEnumerator(this);
    
public voidrecycle()
Clears all header fields.

        clear();
    
public voidremoveHeader(java.lang.String name)
Removes a header field with the specified name. Does nothing if such a field could not be found.

param
name the name of the header field to be removed

        // XXX
        // warning: rather sticky code; heavily tuned

        for (int i = 0; i < count; i++) {
            if (headers[i].getName().equalsIgnoreCase(name)) {
                removeHeader(i--);
            }
        }
    
public voidremoveHeader(java.lang.String name, java.lang.String str)
Removes the headers with the given name whose values contain the given string.

param
name The name of the headers to be removed
param
str The string to check the header values against

        for (int i = 0; i < count; i++) {
            if (headers[i].getName().equalsIgnoreCase(name)
                    && getValue(i) != null
                    && getValue(i).toString() != null
                    && getValue(i).toString().indexOf(str) != -1) {
                removeHeader(i--);
            }
        }
    
private voidremoveHeader(int idx)
reset and swap with last header

param
idx the index of the header to remove.

        MimeHeaderField mh = headers[idx];
        
        mh.recycle();
        headers[idx] = headers[count - 1];
        headers[count - 1] = mh;
        count--;
    
public org.apache.tomcat.util.buf.MessageBytessetValue(java.lang.String name)
Allow "set" operations - return a MessageBytes container for the header value ( existing header or new if this .

        for ( int i = 0; i < count; i++ ) {
            if(headers[i].getName().equalsIgnoreCase(name)) {
                for ( int j=i+1; j < count; j++ ) {
                    if(headers[j].getName().equalsIgnoreCase(name)) {
                        removeHeader(j--);
                    }
                }
                return headers[i].getValue();
            }
        }
        MimeHeaderField mh = createHeader();
        mh.getName().setString(name);
        return mh.getValue();
    
public intsize()
Returns the current number of header fields.

	return count;
    
public java.lang.StringtoString()
EXPENSIVE!!! only for debugging.

        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        pw.println("=== MimeHeaders ===");
        Enumeration e = names();
        while (e.hasMoreElements()) {
            String n = (String)e.nextElement();
            pw.println(n + " = " + getHeader(n));
        }
        return sw.toString();
    
public java.util.Enumerationvalues(java.lang.String name)

	return new ValuesEnumerator(this, name);