/[Apache-SVN]/tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java
ViewVC logotype

Diff of /tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java	2005/10/31 16:38:34	329852
+++ tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java	2005/10/31 16:39:42	329853
@@ -18,6 +18,10 @@ package org.apache.tomcat.util.buf;
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+import sun.security.krb5.internal.crypto.b;
+import sun.security.krb5.internal.crypto.t;
 
 /*
  * In a server it is very important to be able to operate on
@@ -33,9 +37,6 @@ import java.io.Serializable;
  * to be able to parse the request without converting to string.
  */
 
-// TODO: This class could either extend ByteBuffer, or better a ByteBuffer inside
-// this way it could provide the search/etc on ByteBuffer, as a helper.
-
 /**
  * This class is used to represent a chunk of bytes, and
  * utilities to manipulate byte[].
@@ -65,6 +66,8 @@ public final class ByteChunk implements
     /** Input interface, used when the buffer is emptiy
      *
      * Same as java.nio.channel.ReadableByteChannel
+     * It is used in InputBuffer class in connector.
+     * @deprecated Use RedableByteChannel
      */
     public static interface ByteInputChannel {
         /** 
@@ -77,6 +80,8 @@ public final class ByteChunk implements
     }
 
     /** Same as java.nio.channel.WrittableByteChannel.
+     * 
+     * @deprecated use WrittableByteChannel
      */
     public static interface ByteOutputChannel {
         /** 
@@ -95,16 +100,19 @@ public final class ByteChunk implements
     */
     public static final String DEFAULT_CHARACTER_ENCODING="ISO-8859-1";
         
-    // byte[]
-    private byte[] buff;
+    private ByteBuffer bb;
+    
+    // old style - while I'm updating
+    //private byte[] buff;
 
-    private int start=0;
-    private int end;
+    //private int start=0; // bb.getPosition() 
+    //private int end; // bb.getLimit()
 
     private String enc;
 
-    private boolean isSet=false; // XXX
-
+    // true if null. Is this used ??
+    private boolean isSet=false; 
+    
     // How much can it grow, when data is added
     private int limit=-1;
 
@@ -125,6 +133,15 @@ public final class ByteChunk implements
     }
 
     //--------------------
+    
+    public void setByteBuffer(ByteBuffer buf) {
+        bb=buf;
+    }
+    
+    public ByteBuffer getByteBuffer() {
+        return bb;
+    }
+    
     public ByteChunk getClone() {
 	try {
 	    return (ByteChunk)this.clone();
@@ -133,6 +150,9 @@ public final class ByteChunk implements
 	}
     }
 
+    /** @deprecated The buffer shouldn't be null - track this on the 
+     * MessageBytes.
+     */ 
     public boolean isNull() {
 	return ! isSet; // buff==null;
     }
@@ -143,25 +163,32 @@ public final class ByteChunk implements
     public void recycle() {
 	//	buff = null;
 	enc=null;
-	start=0;
-	end=0;
+	//start=0;
+	//end=0;
 	isSet=false;
+        if( bb!=null ) bb.clear();
     }
 
     public void reset() {
-	buff=null;
+//	buff=null;
+        bb=null;
     }
 
     // -------------------- Setup --------------------
 
     public void allocate( int initial, int limit  ) {
 	isOutput=true;
-	if( buff==null || buff.length < initial ) {
-	    buff=new byte[initial];
-	}    
+        if( bb==null || bb.capacity() < initial ) {
+            bb=ByteBuffer.allocate( initial );
+        }
+        
+//	if( buff==null || buff.length < initial ) {
+//	    buff=new byte[initial];
+//	}    
+        
 	this.limit=limit;
-	start=0;
-	end=0;
+	//start=0;
+	//end=0;
 	isSet=true;
     }
 
@@ -171,12 +198,15 @@ public final class ByteChunk implements
      * @param b the ascii bytes
      * @param off the start offset of the bytes
      * @param len the length of the bytes
+     * @deprecated use getByteBuffer().wrap( b, off, len )
      */
     public void setBytes(byte[] b, int off, int len) {
-        buff = b;
-        start = off;
-        end = start+ len;
+//        buff = b;
+        //start = off;
+        //end = start+ len;
         isSet=true;
+        
+        bb=ByteBuffer.wrap(b, off, len);
     }
 
     public void setOptimizedWrite(boolean optimizedWrite) {
@@ -186,6 +216,7 @@ public final class ByteChunk implements
     public void setEncoding( String enc ) {
 	this.enc=enc;
     }
+
     public String getEncoding() {
         if (enc == null)
             enc=DEFAULT_CHARACTER_ENCODING;
@@ -194,6 +225,7 @@ public final class ByteChunk implements
 
     /**
      * Returns the message bytes.
+     * @deprecated use getBuffer() ( or better - don't use it, ByteBuffer )
      */
     public byte[] getBytes() {
 	return getBuffer();
@@ -201,9 +233,10 @@ public final class ByteChunk implements
 
     /**
      * Returns the message bytes.
+     * @deprecated Should be avoided, it's optional on direct buffers 
      */
     public byte[] getBuffer() {
-	return buff;
+	return bb.array(); //buff;
     }
 
     /**
@@ -211,16 +244,21 @@ public final class ByteChunk implements
      * For output this is the end of the buffer.
      */
     public int getStart() {
-	return start;
+	return bb.position();// start;
     }
 
     public int getOffset() {
-	return start;
+	return bb.position();//start;
     }
 
     public void setOffset(int off) {
-        if (end < off ) end=off;
-	start=off;
+        //if (end < off ) end=off;
+        if( bb.limit() < off ) {
+            bb.limit(off);
+        }
+        
+	//start=off;
+        bb.position( off );
     }
 
     /**
@@ -228,7 +266,7 @@ public final class ByteChunk implements
      * XXX need to clean this up
      */
     public int getLength() {
-	return end-start;
+	return bb.remaining(); // end-start;
     }
 
     /** Maximum amount of data in this buffer.
@@ -263,11 +301,11 @@ public final class ByteChunk implements
     }
 
     public int getEnd() {
-	return end;
+	return bb.limit(); // end;
     }
 
     public void setEnd( int i ) {
-	end=i;
+	bb.limit(i); // end=i;
     }
 
     // -------------------- Adding data to the buffer --------------------
@@ -288,10 +326,10 @@ public final class ByteChunk implements
 	makeSpace( 1 );
 
 	// couldn't make space
-	if( limit >0 && end >= limit ) {
+	if( limit >0 && bb.limit() >= limit ) {
 	    flushBuffer();
 	}
-	buff[end++]=b;
+	bb.put( b ); //buff[end++]=b;
     }
 
     public void append( ByteChunk src )
@@ -300,6 +338,15 @@ public final class ByteChunk implements
 	append( src.getBytes(), src.getStart(), src.getLength());
     }
 
+    /** 
+     * Copy all data from another bytebuffer.
+     * 
+     * @param bb
+     */
+    public void append( ByteBuffer src ) {
+        bb.put( src );
+    }
+    
     /** Add data to the buffer
      */
     public void append( byte src[], int off, int len )
@@ -311,8 +358,9 @@ public final class ByteChunk implements
 	// if we don't have limit: makeSpace can grow as it wants
 	if( limit < 0 ) {
 	    // assert: makeSpace made enough space
-	    System.arraycopy( src, off, buff, end, len );
-	    end+=len;
+	    //System.arraycopy( src, off, buff, end, len );
+            bb.put(src, off, len);
+	    //end+=len;
 	    return;
 	}
 
@@ -320,16 +368,17 @@ public final class ByteChunk implements
         // If the buffer is empty and the source is going to fill up all the
         // space in buffer, may as well write it directly to the output,
         // and avoid an extra copy
-        if ( optimizedWrite && len == limit && end == start) {
+        if ( optimizedWrite && len == limit && bb.limit() == bb.position()) {
             out.realWriteBytes( src, off, len );
             return;
         }
 	// if we have limit and we're below
-	if( len <= limit - end ) {
+	if( len <= limit - bb.limit() ) {
 	    // makeSpace will grow the buffer to the limit,
 	    // so we have space
-	    System.arraycopy( src, off, buff, end, len );
-	    end+=len;
+	    //System.arraycopy( src, off, buff, end, len );
+            bb.put( src, off, len );
+	    //end+=len;
 	    return;
 	}
 
@@ -341,21 +390,23 @@ public final class ByteChunk implements
         // We chunk the data into slices fitting in the buffer limit, although
         // if the data is written directly if it doesn't fit
 
-        int avail=limit-end;
-        System.arraycopy(src, off, buff, end, avail);
-        end += avail;
+        int avail=limit-bb.limit(); // end;
+        //System.arraycopy(src, off, buff, end, avail);
+        bb.put( src, off, avail );
+        //end += avail;
 
         flushBuffer();
 
         int remain = len - avail;
 
-        while (remain > (limit - end)) {
-            out.realWriteBytes( src, (off + len) - remain, limit - end );
-            remain = remain - (limit - end);
+        while (remain > (limit - bb.limit())) {
+            out.realWriteBytes( src, (off + len) - remain, limit - bb.limit() );
+            remain = remain - (limit - bb.limit());
         }
 
-        System.arraycopy(src, (off + len) - remain, buff, end, remain);
-        end += remain;
+        //System.arraycopy(src, (off + len) - remain, buff, end, remain);
+        bb.put( src, (off+len ) - remain, remain);
+        //end += remain;
 
     }
 
@@ -365,43 +416,46 @@ public final class ByteChunk implements
     public int substract()
         throws IOException {
 
-        if ((end - start) == 0) {
+        if ((bb.limit() - bb.position()) == 0) {
             if (in == null)
                 return -1;
-            int n = in.realReadBytes( buff, 0, buff.length );
+            // TODO: if( in != null ) ... 
+            int n = in.realReadBytes( bb.array(), 0, bb.capacity() );
             if (n < 0)
                 return -1;
         }
 
-        return (buff[start++] & 0xFF);
+        return (bb.get() & 0xFF);
 
     }
 
     public int substract(ByteChunk src)
         throws IOException {
 
-        if ((end - start) == 0) {
+        if ((bb.limit() - bb.position()) == 0) {
             if (in == null)
                 return -1;
-            int n = in.realReadBytes( buff, 0, buff.length );
+            int n = in.realReadBytes( bb.array(), 0, bb.capacity());
             if (n < 0)
                 return -1;
         }
 
         int len = getLength();
-        src.append(buff, start, len);
-        start = end;
+        
+        src.getByteBuffer().put( bb );
+        //src.append(buff, start, len);
+        //start = end;
+        
         return len;
-
     }
 
     public int substract( byte src[], int off, int len )
         throws IOException {
 
-        if ((end - start) == 0) {
+        if ((bb.limit() - bb.position()) == 0) {
             if (in == null)
                 return -1;
-            int n = in.realReadBytes( buff, 0, buff.length );
+            int n = in.realReadBytes( bb.array(), 0, bb.capacity() );
             if (n < 0)
                 return -1;
         }
@@ -410,8 +464,10 @@ public final class ByteChunk implements
         if (len > getLength()) {
             n = getLength();
         }
-        System.arraycopy(buff, start, src, off, n);
-        start += n;
+        
+        bb.get( src, off, n);
+        //System.arraycopy(buff, start, src, off, n);
+        //start += n;
         return n;
 
     }
@@ -428,10 +484,11 @@ public final class ByteChunk implements
 	//assert out!=null
 	if( out==null ) {
 	    throw new IOException( "Buffer overflow, no sink " + limit + " " +
-				   buff.length  );
+				   bb.capacity()  );
 	}
-	out.realWriteBytes( buff, start, end-start );
-	end=start;
+	out.realWriteBytes( bb.array(), bb.position(), bb.limit()-bb.position());
+	bb.position(bb.limit());
+        //end=start;
     }
 
     /** Make space for len chars. If len is small, allocate
@@ -439,10 +496,10 @@ public final class ByteChunk implements
      */
     private void makeSpace(int count)
     {
-	byte[] tmp = null;
+	ByteBuffer tmp = null;
 
 	int newSize;
-	int desiredSize=end + count;
+	int desiredSize=bb.limit() + count;
 
 	// Can't grow above the limit
 	if( limit > 0 &&
@@ -450,42 +507,45 @@ public final class ByteChunk implements
 	    desiredSize=limit;
 	}
 
-	if( buff==null ) {
+	if( bb==null ) {
 	    if( desiredSize < 256 ) desiredSize=256; // take a minimum
-	    buff=new byte[desiredSize];
+	    //buff=new byte[desiredSize];
+            bb=ByteBuffer.allocate(desiredSize);
 	}
 	
 	// limit < buf.length ( the buffer is already big )
 	// or we already have space XXX
-	if( desiredSize <= buff.length ) {
+	if( desiredSize <= bb.capacity() ) {
 	    return;
 	}
 	// grow in larger chunks
-	if( desiredSize < 2 * buff.length ) {
-	    newSize= buff.length * 2;
+	if( desiredSize < 2 * bb.capacity() ) {
+	    newSize= bb.capacity() * 2;
 	    if( limit >0 &&
 		newSize > limit ) newSize=limit;
-	    tmp=new byte[newSize];
+	    tmp=ByteBuffer.allocate(newSize);
 	} else {
-	    newSize= buff.length * 2 + count ;
+	    newSize= bb.capacity() * 2 + count ;
 	    if( limit > 0 &&
 		newSize > limit ) newSize=limit;
-	    tmp=new byte[newSize];
+	    tmp=ByteBuffer.allocate(newSize);
 	}
 	
-	System.arraycopy(buff, start, tmp, 0, end-start);
-	buff = tmp;
+	//System.arraycopy(buff, start, tmp, 0, end-start);
+        tmp.put(bb);
+	bb = tmp;
 	tmp = null;
-	end=end-start;
-	start=0;
+	//end=end-start;
+	bb.position(0);
+        //start=0;
     }
     
     // -------------------- Conversion and getters --------------------
 
     public String toString() {
-        if (null == buff) {
+        if (null == bb) {
             return null;
-        } else if (end-start == 0) {
+        } else if (bb.remaining() == 0) {
             return "";
         }
         return StringCache.toString(this);
@@ -495,7 +555,7 @@ public final class ByteChunk implements
         String strValue=null;
         try {
             if( enc==null ) enc=DEFAULT_CHARACTER_ENCODING;
-            strValue = new String( buff, start, end-start, enc );
+            strValue = new String( bb.array(), bb.position(), bb.remaining(), enc );
             /*
              Does not improve the speed too much on most systems,
              it's safer to use the "clasical" new String().
@@ -511,18 +571,18 @@ public final class ByteChunk implements
         } catch (java.io.UnsupportedEncodingException e) {
             // Use the platform encoding in that case; the usage of a bad
             // encoding will have been logged elsewhere already
-            strValue = new String(buff, start, end-start);
+            strValue = new String(bb.array(), bb.position(), bb.remaining());
         }
         return strValue;
     }
 
     public int getInt()
     {
-	return Ascii.parseInt(buff, start,end-start);
+	return Ascii.parseInt(bb.array(), bb.position(),bb.remaining());
     }
 
     public long getLong() {
-        return Ascii.parseLong(buff, start,end-start);
+        return Ascii.parseLong(bb.array(), bb.position(),bb.remaining());
     }
 
 
@@ -537,12 +597,12 @@ public final class ByteChunk implements
 	// XXX ENCODING - this only works if encoding is UTF8-compat
 	// ( ok for tomcat, where we compare ascii - header names, etc )!!!
 	
-	byte[] b = buff;
-	int blen = end-start;
+	byte[] b = bb.array();
+	int blen = bb.remaining();
 	if (b == null || blen != s.length()) {
 	    return false;
 	}
-	int boff = start;
+	int boff = bb.position();
 	for (int i = 0; i < blen; i++) {
 	    if (b[boff++] != s.charAt(i)) {
 		return false;
@@ -557,12 +617,12 @@ public final class ByteChunk implements
      * @return true if the comparison succeeded, false otherwise
      */
     public boolean equalsIgnoreCase(String s) {
-	byte[] b = buff;
-	int blen = end-start;
+	byte[] b = bb.array();
+	int blen = bb.remaining();
 	if (b == null || blen != s.length()) {
 	    return false;
 	}
-	int boff = start;
+	int boff = bb.position();
 	for (int i = 0; i < blen; i++) {
 	    if (Ascii.toLower(b[boff++]) != Ascii.toLower(s.charAt(i))) {
 		return false;
@@ -576,14 +636,14 @@ public final class ByteChunk implements
     }
     
     public boolean equals( byte b2[], int off2, int len2) {
-	byte b1[]=buff;
+	byte b1[]=bb.array();
 	if( b1==null && b2==null ) return true;
 
-	int len=end-start;
+	int len=bb.remaining();
 	if ( len2 != len || b1==null || b2==null ) 
 	    return false;
 		
-	int off1 = start;
+	int off1 = bb.position();
 
 	while ( len-- > 0) {
 	    if (b1[off1++] != b2[off2++]) {
@@ -599,14 +659,14 @@ public final class ByteChunk implements
     
     public boolean equals( char c2[], int off2, int len2) {
 	// XXX works only for enc compatible with ASCII/UTF !!!
-	byte b1[]=buff;
+	byte b1[]=bb.array();
 	if( c2==null && b1==null ) return true;
 	
-	if (b1== null || c2==null || end-start != len2 ) {
+	if (b1== null || c2==null || bb.remaining() != len2 ) {
 	    return false;
 	}
-	int off1 = start;
-	int len=end-start;
+	int off1 = bb.position();
+	int len=bb.remaining();
 	
 	while ( len-- > 0) {
 	    if ( (char)b1[off1++] != c2[off2++]) {
@@ -622,12 +682,12 @@ public final class ByteChunk implements
      */
     public boolean startsWith(String s) {
 	// Works only if enc==UTF
-	byte[] b = buff;
+	byte[] b = bb.array();
 	int blen = s.length();
-	if (b == null || blen > end-start) {
+	if (b == null || blen > bb.remaining()) {
 	    return false;
 	}
-	int boff = start;
+	int boff = bb.position();
 	for (int i = 0; i < blen; i++) {
 	    if (b[boff++] != s.charAt(i)) {
 		return false;
@@ -638,16 +698,16 @@ public final class ByteChunk implements
 
     /* Returns true if the message bytes start with the specified byte array */
     public boolean startsWith(byte[] b2) {
-        byte[] b1 = buff;
+        byte[] b1 = bb.array();
         if (b1 == null && b2 == null) {
             return true;
         }
 
-        int len = end - start;
+        int len = bb.remaining();
         if (b1 == null || b2 == null || b2.length > len) {
             return false;
         }
-        for (int i = start, j = 0; i < end && j < b2.length; ) {
+        for (int i = bb.position(), j = 0; i < bb.limit() && j < b2.length; ) {
             if (b1[i++] != b2[j++]) 
                 return false;
         }
@@ -660,12 +720,12 @@ public final class ByteChunk implements
      * @param pos The position
      */
     public boolean startsWithIgnoreCase(String s, int pos) {
-	byte[] b = buff;
+	byte[] b = bb.array();
 	int len = s.length();
-	if (b == null || len+pos > end-start) {
+	if (b == null || len+pos > bb.remaining()) {
 	    return false;
 	}
-	int off = start+pos;
+	int off = bb.position()+pos;
 	for (int i = 0; i < len; i++) {
 	    if (Ascii.toLower( b[off++] ) != Ascii.toLower( s.charAt(i))) {
 		return false;
@@ -680,14 +740,14 @@ public final class ByteChunk implements
 	// Look for first char 
 	int srcEnd = srcOff + srcLen;
         
-	for( int i=myOff+start; i <= (end - srcLen); i++ ) {
-	    if( buff[i] != first ) continue;
+	for( int i=myOff+bb.position(); i <= (bb.limit() - srcLen); i++ ) {
+	    if( bb.get(i) != first ) continue;
 	    // found first char, now look for a match
             int myPos=i+1;
 	    for( int srcPos=srcOff + 1; srcPos< srcEnd; ) {
-                if( buff[myPos++] != src.charAt( srcPos++ ))
+                if( bb.get(myPos++) != src.charAt( srcPos++ ))
 		    break;
-                if( srcPos==srcEnd ) return i-start; // found it
+                if( srcPos==srcEnd ) return i-bb.position(); // found it
 	    }
 	}
 	return -1;
@@ -697,12 +757,12 @@ public final class ByteChunk implements
 
     // normal hash. 
     public int hash() {
-	return hashBytes( buff, start, end-start);
+	return hashBytes( bb.array(), bb.position(), bb.remaining());
     }
 
     // hash ignoring case
     public int hashIgnoreCase() {
-	return hashBytesIC( buff, start, end-start );
+	return hashBytesIC( bb.array(), bb.position(), bb.remaining() );
     }
 
     private static int hashBytes( byte buff[], int start, int bytesLen ) {
@@ -733,8 +793,8 @@ public final class ByteChunk implements
      * @param starting The start position
      */
     public int indexOf(char c, int starting) {
-	int ret = indexOf( buff, start+starting, end, c);
-	return (ret >= start) ? ret - start : -1;
+	int ret = indexOf( bb.array(), bb.position()+starting, bb.limit(), c);
+	return (ret >= bb.position()) ? ret - bb.position() : -1;
     }
 
     public static int  indexOf( byte bytes[], int off, int end, char qq )

 

infrastructure at apache.org
ViewVC Help
Powered by ViewVC 1.1.26