Author: trustin
Date: Tue Apr 19 05:32:13 2005
New Revision: 161880
URL: http://svn.apache.org/viewcvs?view=rev&rev=161880
Log:
* Added ByteBuffer.autoExpand property
* Removed slice(), duplicate(), asReadOnlyBuffer(), isReadOnly()
Modified:
directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java
directory/network/trunk/src/java/org/apache/mina/common/ByteBufferProxy.java
directory/network/trunk/src/java/org/apache/mina/protocol/codec/CumulativeProtocolDecoder.java
directory/network/trunk/src/test/org/apache/mina/common/ByteBufferTest.java
directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java
Modified:
directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java
URL:
http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java?view=diff&r1=161879&r2=161880
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java
(original)
+++ directory/network/trunk/src/java/org/apache/mina/common/ByteBuffer.java Tue
Apr 19 05:32:13 2005
@@ -137,7 +137,7 @@
}
buf.clear();
- buf.resetRefCount();
+ buf.init();
return buf;
}
@@ -197,10 +197,12 @@
public abstract boolean isDirect();
- public abstract boolean isReadOnly();
-
public abstract int capacity();
+ public abstract boolean isAutoExpand();
+
+ public abstract ByteBuffer setAutoExpand( boolean autoExpand );
+
public abstract int position();
public abstract ByteBuffer position( int newPosition );
@@ -223,12 +225,6 @@
public abstract boolean hasRemaining();
- public abstract ByteBuffer slice();
-
- public abstract ByteBuffer duplicate();
-
- public abstract ByteBuffer asReadOnlyBuffer();
-
public abstract byte get();
public abstract short getUnsigned();
@@ -419,25 +415,13 @@
*/
public abstract ByteBuffer fillAndReset( int size );
- /**
- * Allocates and returns a new [EMAIL PROTECTED] ByteBuffer} whose
content, position,
- * limit, and capacity is identical.
- */
- public abstract ByteBuffer fork();
-
- /**
- * Allocates and returns a new [EMAIL PROTECTED] ByteBuffer} whose
content, position,
- * and limit except capacity is identical. New capacity can be both
greater
- * and less than original capacity. If limit or position is less than
- * new capacity, they will become same with new capacity.
- */
- public abstract ByteBuffer fork( int newCapacity );
-
- private static abstract class BaseByteBuffer extends ByteBuffer
+ private static class DefaultByteBuffer extends ByteBuffer
{
- private final java.nio.ByteBuffer buf;
+ private java.nio.ByteBuffer buf;
+ private int refCount = 1;
+ private boolean autoExpand;
- protected BaseByteBuffer( java.nio.ByteBuffer buf )
+ protected DefaultByteBuffer( java.nio.ByteBuffer buf )
{
if( buf == null )
{
@@ -446,6 +430,52 @@
this.buf = buf;
}
+ protected DefaultByteBuffer( int capacity, boolean direct )
+ {
+ this( direct? java.nio.ByteBuffer.allocateDirect( capacity ) :
+ java.nio.ByteBuffer.allocate( capacity ) );
+ }
+
+ private synchronized void init()
+ {
+ autoExpand = false;
+ refCount = 1;
+ }
+
+ public synchronized void acquire()
+ {
+ if( refCount <= 0 )
+ {
+ throw new IllegalStateException( "Already released buffer." );
+ }
+
+ refCount ++;
+ }
+
+ public synchronized void release()
+ {
+ if( refCount <= 0 )
+ {
+ refCount = 0;
+ throw new IllegalStateException(
+ "Already released buffer. You released the buffer too
many times." );
+ }
+
+ refCount --;
+ if( refCount > 0)
+ {
+ return;
+ }
+
+ Stack[] bufferStacks = isDirect()? directBufferStacks :
heapBufferStacks;
+ Stack stack = bufferStacks[ getBufferStackIndex( bufferStacks,
capacity() ) ];
+ synchronized( stack )
+ {
+ // push back
+ stack.push( this );
+ }
+ }
+
public java.nio.ByteBuffer buf()
{
return buf;
@@ -460,6 +490,17 @@
{
return buf.isReadOnly();
}
+
+ public boolean isAutoExpand()
+ {
+ return autoExpand;
+ }
+
+ public ByteBuffer setAutoExpand( boolean autoExpand )
+ {
+ this.autoExpand = autoExpand;
+ return this;
+ }
public int capacity()
{
@@ -473,6 +514,7 @@
public ByteBuffer position( int newPosition )
{
+ autoExpand( newPosition, 0 );
buf.position( newPosition );
return this;
}
@@ -484,6 +526,7 @@
public ByteBuffer limit( int newLimit )
{
+ autoExpand( newLimit, 0 );
buf.limit( newLimit );
return this;
}
@@ -528,21 +571,6 @@
return buf.hasRemaining();
}
- public ByteBuffer slice()
- {
- return new DuplicateByteBuffer( this, buf.slice());
- }
-
- public ByteBuffer duplicate()
- {
- return new DuplicateByteBuffer( this, buf.duplicate() );
- }
-
- public ByteBuffer asReadOnlyBuffer()
- {
- return new DuplicateByteBuffer( this, buf.asReadOnlyBuffer() );
- }
-
public byte get()
{
return buf.get();
@@ -555,6 +583,7 @@
public ByteBuffer put( byte b )
{
+ autoExpand( 1 );
buf.put( b );
return this;
}
@@ -571,6 +600,7 @@
public ByteBuffer put( int index, byte b )
{
+ autoExpand( index, 1 );
buf.put( index, b );
return this;
}
@@ -589,24 +619,28 @@
public ByteBuffer put( java.nio.ByteBuffer src )
{
+ autoExpand( src.remaining() );
buf.put( src );
return this;
}
public ByteBuffer put( ByteBuffer src )
{
+ autoExpand( src.remaining() );
buf.put( src.buf() );
return this;
}
public ByteBuffer put( byte[] src, int offset, int length )
{
+ autoExpand( length );
buf.put( src, offset, length );
return this;
}
public ByteBuffer put( byte[] src )
{
+ autoExpand( src.length );
buf.put( src );
return this;
}
@@ -659,6 +693,7 @@
public ByteBuffer putChar( char value )
{
+ autoExpand( 2 );
buf.putChar( value );
return this;
}
@@ -670,6 +705,7 @@
public ByteBuffer putChar( int index, char value )
{
+ autoExpand( index, 2 );
buf.putChar( index, value );
return this;
}
@@ -691,6 +727,7 @@
public ByteBuffer putShort( short value )
{
+ autoExpand( 2 );
buf.putShort( value );
return this;
}
@@ -707,6 +744,7 @@
public ByteBuffer putShort( int index, short value )
{
+ autoExpand( index, 2 );
buf.putShort( index, value );
return this;
}
@@ -728,6 +766,7 @@
public ByteBuffer putInt( int value )
{
+ autoExpand( 4 );
buf.putInt( value );
return this;
}
@@ -744,6 +783,7 @@
public ByteBuffer putInt( int index, int value )
{
+ autoExpand( index, 4 );
buf.putInt( index, value );
return this;
}
@@ -760,6 +800,7 @@
public ByteBuffer putLong( long value )
{
+ autoExpand( 8 );
buf.putLong( value );
return this;
}
@@ -771,6 +812,7 @@
public ByteBuffer putLong( int index, long value )
{
+ autoExpand( index, 8 );
buf.putLong( index, value );
return this;
}
@@ -787,6 +829,7 @@
public ByteBuffer putFloat( float value )
{
+ autoExpand( 4 );
buf.putFloat( value );
return this;
}
@@ -798,6 +841,7 @@
public ByteBuffer putFloat( int index, float value )
{
+ autoExpand( index, 4 );
buf.putFloat( index, value );
return this;
}
@@ -814,6 +858,7 @@
public ByteBuffer putDouble( double value )
{
+ autoExpand( 8 );
buf.putDouble( value );
return this;
}
@@ -825,6 +870,7 @@
public ByteBuffer putDouble( int index, double value )
{
+ autoExpand( index, 8 );
buf.putDouble( index, value );
return this;
}
@@ -1043,8 +1089,10 @@
if( fieldSize == 0 )
return this;
+ autoExpand( fieldSize );
+
CharBuffer in = CharBuffer.wrap( val );
-
+ int expectedLength = (int) (in.remaining() *
encoder.averageBytesPerChar());
boolean utf16 = encoder.charset().name().startsWith( "UTF-16" );
if( utf16 && ( ( fieldSize & 1 ) != 0 ) )
@@ -1104,7 +1152,7 @@
CharSequence val, CharsetEncoder encoder ) throws
CharacterCodingException
{
CharBuffer in = CharBuffer.wrap( val );
-
+ int expectedLength = (int) (in.remaining() *
encoder.averageBytesPerChar());
boolean utf16 = encoder.charset().name().startsWith( "UTF-16" );
encoder.reset();
@@ -1124,6 +1172,11 @@
{
break;
}
+ if( cr.isOverflow() && autoExpand )
+ {
+ autoExpand( expectedLength );
+ continue;
+ }
cr.throwException();
}
return this;
@@ -1131,11 +1184,13 @@
public ByteBuffer skip( int size )
{
+ autoExpand( size );
return position( position() + size );
}
public ByteBuffer fill( byte value, int size )
{
+ autoExpand( size );
int q = size >>> 3;
int r = size & 7;
@@ -1182,6 +1237,7 @@
public ByteBuffer fillAndReset( byte value, int size )
{
+ autoExpand( size );
int pos = buf.position();
try
{
@@ -1196,6 +1252,7 @@
public ByteBuffer fill( int size )
{
+ autoExpand( size );
int q = size >>> 3;
int r = size & 7;
@@ -1230,6 +1287,7 @@
public ByteBuffer fillAndReset( int size )
{
+ autoExpand( size );
int pos = buf.position();
try
{
@@ -1242,110 +1300,70 @@
return this;
}
-
- public ByteBuffer fork()
- {
- return fork( this.capacity() );
- }
-
- public ByteBuffer fork( int newCapacity )
- {
- ByteBuffer buf = allocate( newCapacity, isDirect() );
- int pos = this.position();
- int limit = this.limit();
- this.position( 0 );
- this.limit( newCapacity < this.capacity()? newCapacity :
this.capacity() );
- buf.put( this );
- buf.position( pos < newCapacity? pos : newCapacity );
- buf.limit( limit < newCapacity? limit : newCapacity );
- this.limit( this.capacity() );
- this.position( pos );
- this.limit( limit );
-
- return buf;
- }
- private static void checkFieldSize( int fieldSize )
+ private void autoExpand( int delta )
{
- if( fieldSize < 0 )
+ if( autoExpand )
{
- throw new IllegalArgumentException(
- "fieldSize cannot be negative: " + fieldSize );
+ int pos = buf.position();
+ int limit = buf.limit();
+ int end = pos + delta;
+ if( end > limit ) {
+ ensureCapacity( end );
+ buf.limit( end );
+ }
}
}
- }
-
- private static class DefaultByteBuffer extends BaseByteBuffer
- {
- private int refCount = 1;
-
- protected DefaultByteBuffer( java.nio.ByteBuffer buf )
- {
- super( buf );
- }
-
- protected DefaultByteBuffer( int capacity, boolean direct )
- {
- super( direct? java.nio.ByteBuffer.allocateDirect( capacity ) :
- java.nio.ByteBuffer.allocate( capacity ) );
- }
- private synchronized void resetRefCount()
+ private void autoExpand( int pos, int delta )
{
- refCount = 1;
- }
-
- public synchronized void acquire()
- {
- if( refCount <= 0 )
+ if( autoExpand )
{
- throw new IllegalStateException( "Already released buffer." );
+ int limit = buf.limit();
+ int end = pos + delta;
+ if( end > limit ) {
+ ensureCapacity( end ); // expand by 50%
+ buf.limit( end );
+ }
}
-
- refCount ++;
}
-
- public synchronized void release()
+
+ private void ensureCapacity( int requestedCapacity )
{
- if( refCount <= 0 )
- {
- refCount = 0;
- throw new IllegalStateException(
- "Already released buffer. You released the buffer too
many times." );
- }
-
- refCount --;
- if( refCount > 0)
+ if( requestedCapacity <= buf.capacity() )
{
return;
}
-
- Stack[] bufferStacks = isDirect()? directBufferStacks :
heapBufferStacks;
- Stack stack = bufferStacks[ getBufferStackIndex( bufferStacks,
capacity() ) ];
- synchronized( stack )
+
+ int newCapacity = MINIMUM_CAPACITY;
+ while( newCapacity < requestedCapacity )
{
- // push back
- stack.push( this );
+ newCapacity <<= 1;
}
+
+ java.nio.ByteBuffer oldBuf = this.buf;
+ java.nio.ByteBuffer newBuf = isDirect() ?
java.nio.ByteBuffer.allocateDirect( newCapacity ) :
+
java.nio.ByteBuffer.allocate( newCapacity );
+
+ int pos = oldBuf.position();
+ int limit = oldBuf.limit();
+ oldBuf.clear();
+ newBuf.put( oldBuf );
+ newBuf.position( 0 );
+ newBuf.limit( limit );
+ newBuf.position( pos );
+ this.buf = newBuf;
+ new DefaultByteBuffer( oldBuf ).release();
}
- }
-
- private static class DuplicateByteBuffer extends BaseByteBuffer
- {
- private ByteBuffer buf;
-
- private DuplicateByteBuffer( ByteBuffer buf, java.nio.ByteBuffer
duplicateBuf )
+
+ private static void checkFieldSize( int fieldSize )
{
- super( duplicateBuf );
- this.buf = buf;
- }
-
- public void acquire() {
- buf.acquire();
- }
-
- public void release() {
- buf.release();
+ if( fieldSize < 0 )
+ {
+ throw new IllegalArgumentException(
+ "fieldSize cannot be negative: " + fieldSize );
+ }
}
+
}
}
Modified:
directory/network/trunk/src/java/org/apache/mina/common/ByteBufferProxy.java
URL:
http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/common/ByteBufferProxy.java?view=diff&r1=161879&r2=161880
==============================================================================
---
directory/network/trunk/src/java/org/apache/mina/common/ByteBufferProxy.java
(original)
+++
directory/network/trunk/src/java/org/apache/mina/common/ByteBufferProxy.java
Tue Apr 19 05:32:13 2005
@@ -35,17 +35,11 @@
* You can think this class like a [EMAIL PROTECTED] FilterOutputStream}. All
operations
* are proxied by default so that you can extend this class and override
existing
* operations selectively. You can introduce new operations, too.
- * <p>
- * Please note that you have to implement [EMAIL PROTECTED]
ByteBuffer#duplicate()},
- * [EMAIL PROTECTED] ByteBuffer#slice()}, [EMAIL PROTECTED]
ByteBuffer#asReadOnlyBuffer()},
- * [EMAIL PROTECTED] ByteBuffer#fork()}, and [EMAIL PROTECTED]
ByteBuffer#fork(int)}.
- * It is because <tt>ByteBufferProxy</tt> itself cannot instantiate
- * the class you extended.
*
* @author Trustin Lee ([EMAIL PROTECTED])
* @version $Rev$, $Date$
*/
-public abstract class ByteBufferProxy extends ByteBuffer {
+public class ByteBufferProxy extends ByteBuffer {
/**
* The buffer proxied by this proxy.
@@ -78,11 +72,6 @@
return buf.isDirect();
}
- public boolean isReadOnly()
- {
- return buf.isReadOnly();
- }
-
public java.nio.ByteBuffer buf() {
return buf.buf();
}
@@ -424,6 +413,15 @@
public ByteBuffer fillAndReset(int size) {
buf.fillAndReset( size );
+ return this;
+ }
+
+ public boolean isAutoExpand() {
+ return buf.isAutoExpand();
+ }
+
+ public ByteBuffer setAutoExpand(boolean autoExpand) {
+ buf.setAutoExpand( autoExpand );
return this;
}
}
Modified:
directory/network/trunk/src/java/org/apache/mina/protocol/codec/CumulativeProtocolDecoder.java
URL:
http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/protocol/codec/CumulativeProtocolDecoder.java?view=diff&r1=161879&r2=161880
==============================================================================
---
directory/network/trunk/src/java/org/apache/mina/protocol/codec/CumulativeProtocolDecoder.java
(original)
+++
directory/network/trunk/src/java/org/apache/mina/protocol/codec/CumulativeProtocolDecoder.java
Tue Apr 19 05:32:13 2005
@@ -71,6 +71,7 @@
protected CumulativeProtocolDecoder( int defaultCapacity )
{
buf = ByteBuffer.allocate( defaultCapacity );
+ buf.setAutoExpand( true );
}
/**
@@ -91,9 +92,8 @@
"This decoder doesn't work for stateless transport types."
);
}
- put( in );
-
ByteBuffer buf = this.buf;
+ buf.put( in );
buf.flip();
try
@@ -132,24 +132,4 @@
*/
protected abstract boolean doDecode( ProtocolSession session, ByteBuffer
in,
ProtocolDecoderOutput out ) throws
ProtocolViolationException;
-
-
- private void put( ByteBuffer in )
- {
- ByteBuffer buf = this.buf;
-
- // Check capacity
- if( in.remaining() > buf.remaining() ) {
- int newCapacity = buf.position() + in.remaining();
- ByteBuffer newBuf = ByteBuffer.allocate( newCapacity );
- buf.flip();
- newBuf.put( buf );
- buf.release(); // Release old buffer
- buf = newBuf;
- }
-
- // Copy to cumulative buffer
- buf.put( in.buf() );
- this.buf = buf;
- }
}
Modified:
directory/network/trunk/src/test/org/apache/mina/common/ByteBufferTest.java
URL:
http://svn.apache.org/viewcvs/directory/network/trunk/src/test/org/apache/mina/common/ByteBufferTest.java?view=diff&r1=161879&r2=161880
==============================================================================
--- directory/network/trunk/src/test/org/apache/mina/common/ByteBufferTest.java
(original)
+++ directory/network/trunk/src/test/org/apache/mina/common/ByteBufferTest.java
Tue Apr 19 05:32:13 2005
@@ -18,6 +18,8 @@
*/
package org.apache.mina.common;
+import java.nio.BufferOverflowException;
+
import junit.framework.Assert;
import junit.framework.TestCase;
@@ -103,98 +105,42 @@
}
}
- public void testFork() throws Exception
+ public void testAutoExpand() throws Exception
{
- ByteBuffer buf = ByteBuffer.allocate( 16 );
- ByteBuffer newBuf;
+ ByteBuffer buf = ByteBuffer.allocate( 1 );
- // initialize buf
- for( int i = 0; i < 16; i ++ )
+ buf.put( (byte) 0 );
+ try
{
- buf.put( i, (byte) i );
+ buf.put( (byte) 0 );
+ Assert.fail();
}
-
- // without capacity
- buf.position( 4 );
- buf.limit( 8 );
- newBuf = buf.fork();
- Assert.assertEquals( 4, buf.position() );
- Assert.assertEquals( 8, buf.limit() );
- Assert.assertEquals( buf.position(), newBuf.position() );
- Assert.assertEquals( buf.limit(), newBuf.limit() );
- buf.limit( buf.capacity() );
- newBuf.limit( newBuf.capacity() );
-
- // with larger capacity
- buf.position( 4 );
- buf.limit( 8 );
- newBuf = buf.fork( 18 );
- Assert.assertEquals( 4, buf.position() );
- Assert.assertEquals( 8, buf.limit() );
- Assert.assertEquals( buf.position(), newBuf.position() );
- Assert.assertEquals( buf.limit(), newBuf.limit() );
- buf.limit( buf.capacity() );
- newBuf.limit( newBuf.capacity() );
- for( int i = 0; i < 16; i ++ )
+ catch( BufferOverflowException e )
{
- Assert.assertEquals( buf.get( i ), newBuf.get( i ) );
+ // ignore
}
- // with smaller capacity
- buf.position( 4 );
- buf.limit( 8 );
- newBuf = buf.fork( 12 );
- Assert.assertEquals( 4, buf.position() );
- Assert.assertEquals( 8, buf.limit() );
- Assert.assertEquals( buf.position(), newBuf.position() );
- Assert.assertEquals( buf.limit(), newBuf.limit() );
- buf.limit( buf.capacity() );
- newBuf.limit( newBuf.capacity() );
- for( int i = 0; i < 12; i ++ )
- {
- Assert.assertEquals( buf.get( i ), newBuf.get( i ) );
- }
+ buf.setAutoExpand( true );
+ buf.put( (byte) 0 );
+ Assert.assertEquals( 2, buf.position() );
+ Assert.assertEquals( 2, buf.limit() );
+ Assert.assertEquals( 2, buf.capacity() );
- // with more smaller capacity
- buf.position( 4 );
- buf.limit( 8 );
- newBuf = buf.fork( 6 );
- Assert.assertEquals( 4, buf.position() );
- Assert.assertEquals( 8, buf.limit() );
- Assert.assertEquals( buf.position(), newBuf.position() );
- Assert.assertEquals( 6, newBuf.limit() );
- buf.limit( buf.capacity() );
- newBuf.limit( newBuf.capacity() );
- for( int i = 0; i < 6; i ++ )
+ buf.setAutoExpand( false );
+ try
{
- Assert.assertEquals( buf.get( i ), newBuf.get( i ) );
+ buf.put( 3, (byte) 0 );
+ Assert.fail();
}
-
- // with smallest capacity
- buf.position( 4 );
- buf.limit( 8 );
- newBuf = buf.fork( 2 );
- Assert.assertEquals( 4, buf.position() );
- Assert.assertEquals( 8, buf.limit() );
- Assert.assertEquals( 2, newBuf.position() );
- Assert.assertEquals( 2, newBuf.limit() );
- buf.limit( buf.capacity() );
- newBuf.limit( newBuf.capacity() );
- for( int i = 0; i < 2; i ++ )
+ catch( IndexOutOfBoundsException e )
{
- Assert.assertEquals( buf.get( i ), newBuf.get( i ) );
+ // ignore
}
- }
-
- public void testDuplication()
- {
- ByteBuffer buf = ByteBuffer.allocate( 16 );
- buf.fillAndReset( buf.remaining() );
-
- ByteBuffer buf2 = buf.duplicate();
- buf.putInt( 1234 );
- Assert.assertEquals( 4, buf.position() );
- Assert.assertEquals( 0, buf2.position() );
- Assert.assertEquals( 1234, buf2.getInt() );
+
+ buf.setAutoExpand( true );
+ buf.put( 3, (byte) 0 );
+ Assert.assertEquals( 2, buf.position() );
+ Assert.assertEquals( 4, buf.limit() );
+ Assert.assertEquals( 4, buf.capacity() );
}
}
Modified:
directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java
URL:
http://svn.apache.org/viewcvs/directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java?view=diff&r1=161879&r2=161880
==============================================================================
---
directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java
(original)
+++
directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java
Tue Apr 19 05:32:13 2005
@@ -59,6 +59,7 @@
public void testTCPWithLocalAddress() throws Exception
{
+ System.out.println( "Using client port " + clientPort + " for
testing." );
IoConnector connector = new SocketConnector();
connector.getFilterChain().addFirst( "threadPool",
super.threadPoolFilter );
testTCP0( connector, new InetSocketAddress( clientPort ) );
@@ -148,6 +149,7 @@
public void testUDPWithLocalAddress() throws Exception
{
+ System.out.println( "Using client port " + clientPort + " for
testing." );
IoConnector connector = new DatagramConnector();
connector.getFilterChain().addFirst( "threadPool",
super.threadPoolFilter );
testTCP0( connector, new InetSocketAddress( clientPort ) );