|
What this is
Other links
The source code/* * Copyright 1999-2004 The Apache Software Foundation * * Licensed 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; hasDateValue=false; } /** * Sets the content to the specified subarray of bytes. * * @param b the ascii 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) { recycle(); // a new value is set, cached values must reset byteC.setBytes( b, off, len ); type=T_BYTES; } /** 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[] */ public void setChars( char[] c, int off, int len ) { recycle(); charC.setChars( c, off, len ); type=T_CHARS; } /** 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 ) { recycle(); if (s == null) return; strValue=s; hasStrValue=true; type=T_STR; } // -------------------- Conversion and getters -------------------- /** Compute the string value */ public String toString() { if( hasStrValue ) return strValue; hasStrValue=true; switch (type) { case T_CHARS: strValue=charC.toString(); return strValue; case T_BYTES: strValue=byteC.toString(); 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() { // XXX todo - not used yet } /** Convert to char[] and fill the CharChunk. * XXX Not optimized - it converts to String first. */ public void toChars() { if( ! charC.isNull() ) { return; } // inefficient toString(); char cc[]=strValue.toCharArray(); charC.setChars(cc, 0, cc.length); type=T_CHARS; } /** * 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 return true; } /** * Returns true if the message bytes starts with the specified string. * @param s the string */ public boolean startsWith(String s) { switch (type) { case T_STR: return strValue.startsWith( s ); case T_CHARS: return charC.startsWith( s ); case T_BYTES: return byteC.startsWith( s ); default: return false; } } /** * Returns true if the message bytes starts with the specified string. * @param s the string */ public boolean startsWithIgnoreCase(String s, int pos) { switch (type) { case T_STR: if( strValue==null ) return false; if( strValue.length() < pos + s.length() ) return false; for( int i=0; i |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.