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

📄 messagebytes.java

📁 业界著名的tomcat服务器的最新6.0的源代码。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.tomcat.util.buf;

import java.text.*;
import java.util.*;
import java.io.Serializable;
import java.io.IOException;

/**
 * This class is used to represent a subarray of bytes in an HTTP message.
 * It represents all request/response elements. The byte/char conversions are
 * delayed and cached. Everything is recyclable.
 *
 * The object can represent a byte[], a char[], or a (sub) String. All
 * operations can be made in case sensitive mode or not.
 *
 * @author dac@eng.sun.com
 * @author James Todd [gonzo@eng.sun.com]
 * @author Costin Manolache
 */
public final class MessageBytes implements Cloneable, Serializable {
    // primary type ( whatever is set as original value )
    private int type = T_NULL;

    public static final int T_NULL = 0;
    /** getType() is T_STR if the the object used to create the MessageBytes
        was a String */
    public static final int T_STR  = 1;
    /** getType() is T_STR if the the object used to create the MessageBytes
        was a byte[] */ 
    public static final int T_BYTES = 2;
    /** getType() is T_STR if the the object used to create the MessageBytes
        was a char[] */ 
    public static final int T_CHARS = 3;

    private int hashCode=0;
    // did we computed the hashcode ? 
    private boolean hasHashCode=false;

    // Is the represented object case sensitive ?
    private boolean caseSensitive=true;

    // Internal objects to represent array + offset, and specific methods
    private ByteChunk byteC=new ByteChunk();
    private CharChunk charC=new CharChunk();
    
    // String
    private String strValue;
    // true if a String value was computed. Probably not needed,
    // strValue!=null is the same
    private boolean hasStrValue=false;

    /**
     * Creates a new, uninitialized MessageBytes object.
     * @deprecated Use static newInstance() in order to allow
     *   future hooks.
     */
    public MessageBytes() {
    }

    /** Construct a new MessageBytes instance
     */
    public static MessageBytes newInstance() {
	return factory.newInstance();
    }

    /** Configure the case sensitivity
     */
    public void setCaseSenitive( boolean b ) {
	caseSensitive=b;
    }

    public MessageBytes getClone() {
	try {
	    return (MessageBytes)this.clone();
	} catch( Exception ex) {
	    return null;
	}
    }

    public boolean isNull() {
//		should we check also hasStrValue ???
		return byteC.isNull() && charC.isNull() && ! hasStrValue;
	// bytes==null && strValue==null;
    }
    
    /**
     * Resets the message bytes to an uninitialized (NULL) state.
     */
    public void recycle() {
	type=T_NULL;
	byteC.recycle();
	charC.recycle();

	strValue=null;
	caseSensitive=true;

	hasStrValue=false;
	hasHashCode=false;
	hasIntValue=false;
    hasLongValue=false;
	hasDateValue=false;	
    }


    /**
     * Sets the content to the specified subarray of bytes.
     *
     * @param b the bytes
     * @param off the start offset of the bytes
     * @param len the length of the bytes
     */
    public void setBytes(byte[] b, int off, int len) {
        byteC.setBytes( b, off, len );
        type=T_BYTES;
        hasStrValue=false;
        hasHashCode=false;
        hasIntValue=false;
        hasLongValue=false;
        hasDateValue=false; 
    }

    /** Set the encoding. If the object was constructed from bytes[]. any
     *  previous conversion is reset.
     *  If no encoding is set, we'll use 8859-1.
     */
    public void setEncoding( String enc ) {
	if( !byteC.isNull() ) {
	    // if the encoding changes we need to reset the converion results
	    charC.recycle();
	    hasStrValue=false;
	}
	byteC.setEncoding(enc);
    }

    /** 
     * Sets the content to be a char[]
     *
     * @param c the bytes
     * @param off the start offset of the bytes
     * @param len the length of the bytes
     */
    public void setChars( char[] c, int off, int len ) {
        charC.setChars( c, off, len );
        type=T_CHARS;
        hasStrValue=false;
        hasHashCode=false;
        hasIntValue=false;
        hasLongValue=false;
        hasDateValue=false; 
    }

    /** Remove the cached string value. Use it after a conversion on the
     *	byte[] or after the encoding is changed
     *  XXX Is this needed ?
     */
    public void resetStringValue() {
	if( type != T_STR ) {
	    // If this was cread as a byte[] or char[], we remove
	    // the old string value
	    hasStrValue=false;
	    strValue=null;
	}
    }

    /** 
     * Set the content to be a string
     */
    public void setString( String s ) {
        strValue=s;
        hasHashCode=false;
        hasIntValue=false;
        hasLongValue=false;
        hasDateValue=false; 
        if (s == null) {
            hasStrValue=false;
            type=T_NULL;
        } else {
            hasStrValue=true;
            type=T_STR;
        }
    }

    // -------------------- Conversion and getters --------------------

    /** Compute the string value
     */
    public String toString() {
        if( hasStrValue ) return strValue;
        
        switch (type) {
        case T_CHARS:
            strValue=charC.toString();
            hasStrValue=true;
            return strValue;
        case T_BYTES:
            strValue=byteC.toString();
            hasStrValue=true;
            return strValue;
        }
        return null;
    }

    //----------------------------------------
    /** Return the type of the original content. Can be
     *  T_STR, T_BYTES, T_CHARS or T_NULL
     */
    public int getType() {
	return type;
    }
    
    /**
     * Returns the byte chunk, representing the byte[] and offset/length.
     * Valid only if T_BYTES or after a conversion was made.
     */
    public ByteChunk getByteChunk() {
	return byteC;
    }

    /**
     * Returns the char chunk, representing the char[] and offset/length.
     * Valid only if T_CHARS or after a conversion was made.
     */
    public CharChunk getCharChunk() {
	return charC;
    }

    /**
     * Returns the string value.
     * Valid only if T_STR or after a conversion was made.
     */
    public String getString() {
	return strValue;
    }

    /** Unimplemented yet. Do a char->byte conversion.
     */
    public void toBytes() {
        if( ! byteC.isNull() ) {
            type=T_BYTES;
            return;
        }
        toString();
        type=T_BYTES;
        byte bb[] = strValue.getBytes();
        byteC.setBytes(bb, 0, bb.length);
    }

    /** Convert to char[] and fill the CharChunk.
     *  XXX Not optimized - it converts to String first.
     */
    public void toChars() {
	if( ! charC.isNull() ) {
            type=T_CHARS;
	    return;
	}
	// inefficient
	toString();
        type=T_CHARS;
	char cc[]=strValue.toCharArray();
	charC.setChars(cc, 0, cc.length);
    }
    

    /**
     * Returns the length of the original buffer.
     * Note that the length in bytes may be different from the length
     * in chars.
     */
    public int getLength() {
	if(type==T_BYTES)
	    return byteC.getLength();
	if(type==T_CHARS) {
	    return charC.getLength();
	}
	if(type==T_STR)
	    return strValue.length();
	toString();
	if( strValue==null ) return 0;
	return strValue.length();
    }

    // -------------------- equals --------------------

    /**
     * Compares the message bytes to the specified String object.
     * @param s the String to compare
     * @return true if the comparison succeeded, false otherwise
     */
    public boolean equals(String s) {
	if( ! caseSensitive )
	    return equalsIgnoreCase( s );
	switch (type) {
	case T_STR:
	    if( strValue==null && s!=null) return false;
	    return strValue.equals( s );
	case T_CHARS:
	    return charC.equals( s );
	case T_BYTES:
	    return byteC.equals( s );
	default:
	    return false;
	}
    }

    /**
     * Compares the message bytes to the specified String object.
     * @param s the String to compare
     * @return true if the comparison succeeded, false otherwise
     */
    public boolean equalsIgnoreCase(String s) {
	switch (type) {
	case T_STR:
	    if( strValue==null && s!=null) return false;
	    return strValue.equalsIgnoreCase( s );
	case T_CHARS:
	    return charC.equalsIgnoreCase( s );
	case T_BYTES:
	    return byteC.equalsIgnoreCase( s );
	default:
	    return false;
	}
    }

    public boolean equals(MessageBytes mb) {
	switch (type) {
	case T_STR:
	    return mb.equals( strValue );
	}

	if( mb.type != T_CHARS &&
	    mb.type!= T_BYTES ) {
	    // it's a string or int/date string value
	    return equals( mb.toString() );
	}

	// mb is either CHARS or BYTES.
	// this is either CHARS or BYTES
	// Deal with the 4 cases ( in fact 3, one is simetric)
	
	if( mb.type == T_CHARS && type==T_CHARS ) {
	    return charC.equals( mb.charC );
	} 
	if( mb.type==T_BYTES && type== T_BYTES ) {
	    return byteC.equals( mb.byteC );
	}
	if( mb.type== T_CHARS && type== T_BYTES ) {
	    return byteC.equals( mb.charC );
	}
	if( mb.type== T_BYTES && type== T_CHARS ) {
	    return mb.byteC.equals( charC );
	}
	// can't happen

⌨️ 快捷键说明

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