Author: proyal Date: Fri Apr 28 11:00:56 2006 New Revision: 397971 URL: http://svn.apache.org/viewcvs?rev=397971&view=rev Log: When changing ByteBufferAllocators, dispose of the old allocator. Modified: directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBuffer.java directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferAllocator.java directory/trunks/mina/core/src/main/java/org/apache/mina/common/SimpleByteBufferAllocator.java Modified: directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBuffer.java URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBuffer.java?rev=397971&r1=397970&r2=397971&view=diff ============================================================================== --- directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBuffer.java (original) +++ directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBuffer.java Fri Apr 28 11:00:56 2006 @@ -18,6 +18,9 @@ */ package org.apache.mina.common; +import org.apache.mina.common.support.ByteBufferHexDumper; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; @@ -38,9 +41,6 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; -import org.apache.mina.common.support.ByteBufferHexDumper; -import org.apache.mina.filter.codec.ProtocolEncoderOutput; - /** * A byte buffer used by MINA applications. *
@@ -58,7 +58,7 @@ * capacity * *
- * + * ** You can get a heap buffer from buffer pool: @@ -74,7 +74,7 @@ * ByteBuffer buf = ByteBuffer.allocate(1024); * *
- * + * ** Please note that you never need to release the allocated buffer @@ -94,7 +94,7 @@ *
* This class provides a few wrap(...) methods that wraps @@ -123,17 +123,17 @@ * increase by two times, and its limit will increase to the last position * the string is written. *
- * + * *+ *
* Derived buffers are the buffers which were created by * {@link #duplicate()}, {@link #slice()}, or {@link #asReadOnlyBuffer()}. - * They are useful especially when you broadcast the same messages to + * They are useful especially when you broadcast the same messages to * multiple {@link IoSession}s. Please note that the derived buffers are * neither pooled nor auto-expandable. Trying to expand a derived buffer will * raise {@link IllegalStateException}. *
- * + * ** MINA provides a {@link ByteBufferAllocator} interface to let you override @@ -145,16 +145,16 @@ * * You can change the allocator by calling {@link #setAllocator(ByteBufferAllocator)}. *
- * + * * @author The Apache Directory Project (mina-dev@directory.apache.org) * @version $Rev$, $Date$ - * + * * @see ByteBufferAllocator */ public abstract class ByteBuffer implements Comparable { private static ByteBufferAllocator allocator = new PooledByteBufferAllocator(); - + /** * Returns the current allocator which manages the allocated buffers. */ @@ -173,15 +173,22 @@ { throw new NullPointerException( "allocator" ); } + + ByteBufferAllocator oldAllocator = allocator; + allocator = newAllocator; + + if( null != oldAllocator ) { + oldAllocator.dispose(); + } } - + /** * Returns the direct or heap buffer which is capable of the specified * size. This method tries to allocate direct buffer first, and then * tries heap buffer if direct buffer memory is exhausted. Please use * {@link #allocate(int, boolean)} to allocate buffers of specific type. - * + * * @param capacity the capacity of the buffer */ public static ByteBuffer allocate( int capacity ) @@ -197,10 +204,10 @@ return allocate( capacity, false ); } } - + /** * Returns the buffer which is capable of the specified size. - * + * * @param capacity the capacity of the buffer * @param direct true to get a direct buffer, * false to get a heap buffer. @@ -217,7 +224,7 @@ { return allocator.wrap( nioBuffer ); } - + /** * Wraps the specified byte array into MINA heap buffer. */ @@ -225,7 +232,7 @@ { return wrap( java.nio.ByteBuffer.wrap( byteArray ) ); } - + /** * Wraps the specified byte array into MINA heap buffer. * Please note that MINA buffers are going to be pooled, and @@ -236,7 +243,7 @@ { return wrap( java.nio.ByteBuffer.wrap( byteArray, offset, length ) ); } - + protected ByteBuffer() { } @@ -245,7 +252,7 @@ * Increases the internal reference count of this buffer to defer * automatic release. You have to invoke {@link #release()} as many * as you invoked this method to release this buffer. - * + * * @throws IllegalStateException if you attempt to acquire already * released buffer. */ @@ -253,7 +260,7 @@ /** * Releases the specified buffer to buffer pool. - * + * * @throws IllegalStateException if you attempt to release already * released buffer. */ @@ -263,21 +270,21 @@ * Returns the underlying NIO buffer instance. */ public abstract java.nio.ByteBuffer buf(); - + public abstract boolean isDirect(); - + public abstract int capacity(); - + /** * Returns true if and only if autoExpand is turned on. */ public abstract boolean isAutoExpand(); - + /** * Turns on or off autoExpand. */ public abstract ByteBuffer setAutoExpand( boolean autoExpand ); - + /** * Changes the capacity and limit of this buffer so this buffer get * the specified expectedRemaining room from the current position. @@ -285,7 +292,7 @@ * true. */ public abstract ByteBuffer expand( int expectedRemaining ); - + /** * Changes the capacity and limit of this buffer so this buffer get * the specified expectedRemaining room from the specified @@ -294,7 +301,7 @@ * true. */ public abstract ByteBuffer expand( int pos, int expectedRemaining ); - + /** * Returns true if and only if this buffer is returned back * to the buffer pool when released. @@ -315,7 +322,7 @@ * and {@link #wrap(java.nio.ByteBuffer)}) */ public abstract void setPooled( boolean pooled ); - + /** * @see java.nio.Buffer#position() */ @@ -350,7 +357,7 @@ * @see java.nio.Buffer#clear() */ public abstract ByteBuffer clear(); - + /** * Clears this buffer and fills its content with NUL. * The position is set to zero, the limit is set to the capacity, @@ -361,7 +368,7 @@ clear(); return fillAndReset( remaining() ); } - + /** * Clears this buffer and fills its content with value. * The position is set to zero, the limit is set to the capacity, @@ -395,7 +402,7 @@ { return remaining() > 0; } - + /** * @see java.nio.ByteBuffer#duplicate() */ @@ -405,7 +412,7 @@ * @see java.nio.ByteBuffer#slice() */ public abstract ByteBuffer slice(); - + /** * @see java.nio.ByteBuffer#asReadOnlyBuffer() */ @@ -531,13 +538,13 @@ { return false; } - + ByteBuffer that = ( ByteBuffer ) o; if( this.remaining() != that.remaining() ) { return false; } - + int p = this.position(); for( int i = this.limit() - 1, j = that.limit() - 1; i >= p; i --, j --) { @@ -567,7 +574,7 @@ { return -1; } - + return +1; } return this.remaining() - that.remaining(); @@ -764,7 +771,7 @@ * @see java.nio.ByteBuffer#asDoubleBuffer() */ public abstract DoubleBuffer asDoubleBuffer(); - + /** * Returns an {@link InputStream} that reads the data from this buffer. * {@link InputStream#read()} returns -1 if the buffer position @@ -774,7 +781,7 @@ { return new InputStream() { - public int available() throws IOException + public int available() { return ByteBuffer.this.remaining(); } @@ -789,7 +796,7 @@ return true; } - public int read() throws IOException + public int read() { if( ByteBuffer.this.hasRemaining() ) { @@ -801,7 +808,7 @@ } } - public int read( byte[] b, int off, int len ) throws IOException + public int read( byte[] b, int off, int len ) { int remaining = ByteBuffer.this.remaining(); if( remaining > 0 ) @@ -816,12 +823,12 @@ } } - public synchronized void reset() throws IOException + public synchronized void reset() { ByteBuffer.this.reset(); } - public long skip( long n ) throws IOException + public long skip( long n ) { int bytes; if( n > Integer.MAX_VALUE ) @@ -837,7 +844,7 @@ } }; } - + /** * Returns an {@link OutputStream} that appends the data into this buffer. * Please note that the {@link OutputStream#write(int)} will throw a @@ -850,12 +857,12 @@ { return new OutputStream() { - public void write( byte[] b, int off, int len ) throws IOException + public void write( byte[] b, int off, int len ) { ByteBuffer.this.put( b, off, len ); } - public void write( int b ) throws IOException + public void write( int b ) { ByteBuffer.this.put( ( byte ) b ); } @@ -955,12 +962,12 @@ { cr = decoder.flush( out ); } - + if ( cr.isUnderflow() ) { break; } - + if ( cr.isOverflow() ) { CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength ); @@ -972,7 +979,7 @@ cr.throwException(); } - + limit( oldLimit ); position( end ); return out.flip().toString(); @@ -981,7 +988,7 @@ /** * Reads aNUL-terminated string from this buffer using the
* specified decoder and returns it.
- *
+ *
* @param fieldSize the maximum number of bytes to read
*/
public String getString( int fieldSize, CharsetDecoder decoder ) throws CharacterCodingException
@@ -1005,7 +1012,6 @@
throw new IllegalArgumentException( "fieldSize is not even." );
}
- int i;
int oldPos = position();
int oldLimit = limit();
int end = position() + fieldSize;
@@ -1015,6 +1021,8 @@
throw new BufferUnderflowException();
}
+ int i;
+
if( !utf16 )
{
for( i = 0; i < fieldSize; i ++ )
@@ -1076,12 +1084,12 @@
{
cr = decoder.flush( out );
}
-
+
if ( cr.isUnderflow() )
{
break;
}
-
+
if ( cr.isOverflow() )
{
CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength );
@@ -1093,17 +1101,17 @@
cr.throwException();
}
-
+
limit( oldLimit );
position( end );
return out.flip().toString();
}
-
+
/**
* Writes the content of in into this buffer using the
* specified encoder. This method doesn't terminate
* string with NUL. You have to do it by yourself.
- *
+ *
* @throws BufferOverflowException if the specified string doesn't fit
*/
public ByteBuffer putString(
@@ -1113,12 +1121,12 @@
{
return this;
}
-
- CharBuffer in = CharBuffer.wrap( val );
+
+ CharBuffer in = CharBuffer.wrap( val );
encoder.reset();
-
+
int expandedState = 0;
-
+
for (;;) {
CoderResult cr;
if( in.hasRemaining() )
@@ -1129,7 +1137,7 @@
{
cr = encoder.flush( buf() );
}
-
+
if( cr.isUnderflow() )
{
break;
@@ -1166,7 +1174,7 @@
}
/**
- * Writes the content of in into this buffer as a
+ * Writes the content of in into this buffer as a
* NUL-terminated string using the specified
* encoder.
* @@ -1176,7 +1184,7 @@ *
* Please note that this method doesn't terminate with NUL
* if the input string is longer than fieldSize.
- *
+ *
* @param fieldSize the maximum number of bytes to write
*/
public ByteBuffer putString(
@@ -1186,9 +1194,9 @@
if( fieldSize == 0 )
return this;
-
+
autoExpand( fieldSize );
-
+
boolean utf16 = encoder.charset().name().startsWith( "UTF-16" );
if( utf16 && ( ( fieldSize & 1 ) != 0 ) )
@@ -1218,8 +1226,8 @@
position( end );
return this;
}
-
- CharBuffer in = CharBuffer.wrap( val );
+
+ CharBuffer in = CharBuffer.wrap( val );
limit( end );
encoder.reset();
@@ -1233,7 +1241,7 @@
{
cr = encoder.flush( buf() );
}
-
+
if( cr.isUnderflow() || cr.isOverflow() )
{
break;
@@ -1269,11 +1277,11 @@
{
return getPrefixedString( 2, decoder );
}
-
+
/**
* Reads a string which has a length field before the actual
* encoded string, using the specified decoder and returns it.
- *
+ *
* @param prefixLength the length of the length field (1, 2, or 4)
*/
public String getPrefixedString( int prefixLength, CharsetDecoder decoder ) throws CharacterCodingException
@@ -1284,7 +1292,7 @@
}
int fieldSize = 0;
-
+
switch( prefixLength )
{
case 1:
@@ -1297,7 +1305,7 @@
fieldSize = getInt();
break;
}
-
+
if( fieldSize == 0 )
{
return "";
@@ -1334,12 +1342,12 @@
{
cr = decoder.flush( out );
}
-
+
if ( cr.isUnderflow() )
{
break;
}
-
+
if ( cr.isOverflow() )
{
CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength );
@@ -1351,65 +1359,65 @@
cr.throwException();
}
-
+
limit( oldLimit );
position( end );
return out.flip().toString();
}
/**
- * Writes the content of in into this buffer as a
+ * Writes the content of in into this buffer as a
* string which has a 16-bit length field before the actual
* encoded string, using the specified encoder.
* This method is a shortcut for putPrefixedString(in, 2, 0, encoder).
- *
+ *
* @throws BufferOverflowException if the specified string doesn't fit
*/
public ByteBuffer putPrefixedString( CharSequence in, CharsetEncoder encoder ) throws CharacterCodingException
{
return putPrefixedString( in, 2, 0, encoder );
}
-
+
/**
- * Writes the content of in into this buffer as a
+ * Writes the content of in into this buffer as a
* string which has a 16-bit length field before the actual
* encoded string, using the specified encoder.
* This method is a shortcut for putPrefixedString(in, prefixLength, 0, encoder).
- *
+ *
* @param prefixLength the length of the length field (1, 2, or 4)
- *
+ *
* @throws BufferOverflowException if the specified string doesn't fit
*/
public ByteBuffer putPrefixedString( CharSequence in, int prefixLength, CharsetEncoder encoder ) throws CharacterCodingException
{
return putPrefixedString( in, prefixLength, 0, encoder );
}
-
+
/**
- * Writes the content of in into this buffer as a
+ * Writes the content of in into this buffer as a
* string which has a 16-bit length field before the actual
* encoded string, using the specified encoder.
* This method is a shortcut for putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder).
- *
+ *
* @param prefixLength the length of the length field (1, 2, or 4)
* @param padding the number of padded NULs (1 (or 0), 2, or 4)
- *
+ *
* @throws BufferOverflowException if the specified string doesn't fit
*/
public ByteBuffer putPrefixedString( CharSequence in, int prefixLength, int padding, CharsetEncoder encoder ) throws CharacterCodingException
{
return putPrefixedString( in, prefixLength, padding, ( byte ) 0, encoder );
}
-
+
/**
- * Writes the content of in into this buffer as a
+ * Writes the content of in into this buffer as a
* string which has a 16-bit length field before the actual
* encoded string, using the specified encoder.
- *
+ *
* @param prefixLength the length of the length field (1, 2, or 4)
* @param padding the number of padded bytes (1 (or 0), 2, or 4)
* @param padValue the value of padded bytes
- *
+ *
* @throws BufferOverflowException if the specified string doesn't fit
*/
public ByteBuffer putPrefixedString( CharSequence val, int prefixLength, int padding, byte padValue, CharsetEncoder encoder ) throws CharacterCodingException
@@ -1429,7 +1437,7 @@
default:
throw new IllegalArgumentException( "prefixLength: " + prefixLength );
}
-
+
if( val.length() > maxLength )
{
throw new IllegalArgumentException( "The specified string is too long." );
@@ -1450,7 +1458,7 @@
}
return this;
}
-
+
int padMask;
switch( padding )
{
@@ -1468,7 +1476,7 @@
throw new IllegalArgumentException( "padding: " + padding );
}
- CharBuffer in = CharBuffer.wrap( val );
+ CharBuffer in = CharBuffer.wrap( val );
int expectedLength = (int) (in.remaining() * encoder.averageBytesPerChar()) + 1;
skip( prefixLength ); // make a room for the length field
@@ -1485,12 +1493,12 @@
{
cr = encoder.flush( buf() );
}
-
+
if( position() - oldPos > maxLength )
{
throw new IllegalArgumentException( "The specified string is too long." );
}
-
+
if( cr.isUnderflow() )
{
break;
@@ -1502,7 +1510,7 @@
}
cr.throwException();
}
-
+
// Write the length field
fill( padValue, padding - ( ( position() - oldPos ) & padMask ) );
int length = position() - oldPos;
@@ -1520,7 +1528,7 @@
}
return this;
}
-
+
/**
* Reads a Java object from the buffer using the context {@link ClassLoader}
* of the current thread.
@@ -1529,7 +1537,7 @@
{
return getObject( Thread.currentThread().getContextClassLoader() );
}
-
+
/**
* Reads a Java object from the buffer using the specified classLoader.
*/
@@ -1556,8 +1564,7 @@
{
String className = readUTF();
Class clazz = Class.forName( className, true, classLoader );
- ObjectStreamClass descriptor = ObjectStreamClass.lookup(clazz);
- return descriptor;
+ return ObjectStreamClass.lookup(clazz);
}
};
return in.readObject();
@@ -1571,7 +1578,7 @@
limit( oldLimit );
}
}
-
+
/**
* Writes the specified Java object to the buffer.
*/
@@ -1595,7 +1602,7 @@
{
throw new BufferDataException( e );
}
-
+
// Fill the length field
int newPos = position();
position( oldPos );
@@ -1603,7 +1610,7 @@
position( newPos );
return this;
}
-
+
/**
* Returns true if this buffer contains a data which has a data
* length as a prefix and the buffer has remaining data as enough as
@@ -1612,10 +1619,10 @@
* Please not that using this method can allow DoS (Denial of Service)
* attack in case the remote peer sends too big data length value.
* It is recommended to use {@link #prefixedDataAvailable(int, int)}
- * instead.
- *
+ * instead.
+ *
* @param prefixLength the length of the prefix field (1, 2, or 4)
- *
+ *
* @throws IllegalArgumentException if prefixLength is wrong
* @throws BufferDataException if data length is negative
*/
@@ -1623,15 +1630,15 @@
{
return prefixedDataAvailable( prefixLength, Integer.MAX_VALUE );
}
-
+
/**
* Returns true if this buffer contains a data which has a data
* length as a prefix and the buffer has remaining data as enough as
* specified in the data length field.
- *
+ *
* @param prefixLength the length of the prefix field (1, 2, or 4)
* @param maxDataLength the allowed maximum of the read data length
- *
+ *
* @throws IllegalArgumentException if prefixLength is wrong
* @throws BufferDataException if data length is negative or greater then maxDataLength
*/
@@ -1657,12 +1664,12 @@
default:
throw new IllegalArgumentException( "prefixLength: " + prefixLength );
}
-
+
if( dataLength < 0 || dataLength > maxDataLength )
{
throw new BufferDataException( "dataLength: " + dataLength );
}
-
+
return remaining() - prefixLength >= dataLength;
}
@@ -1821,7 +1828,7 @@
}
return this;
}
-
+
/**
* This method forwards the call to {@link #expand(int)} only when
* autoExpand property is true.
@@ -1834,7 +1841,7 @@
}
return this;
}
-
+
private static void checkFieldSize( int fieldSize )
{
if( fieldSize < 0 )
Modified: directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferAllocator.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferAllocator.java?rev=397971&r1=397970&r2=397971&view=diff
==============================================================================
--- directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferAllocator.java (original)
+++ directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferAllocator.java Fri Apr 28 11:00:56 2006
@@ -34,10 +34,15 @@
* @param direct true to get a direct buffer,
* false to get a heap buffer.
*/
- public ByteBuffer allocate( int capacity, boolean direct );
+ ByteBuffer allocate( int capacity, boolean direct );
/**
* Wraps the specified NIO {@link java.nio.ByteBuffer} into MINA buffer.
*/
- public ByteBuffer wrap( java.nio.ByteBuffer nioBuffer );
+ ByteBuffer wrap( java.nio.ByteBuffer nioBuffer );
+
+ /**
+ * Dispose of this allocator.
+ */
+ void dispose();
}
Modified: directory/trunks/mina/core/src/main/java/org/apache/mina/common/SimpleByteBufferAllocator.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/main/java/org/apache/mina/common/SimpleByteBufferAllocator.java?rev=397971&r1=397970&r2=397971&view=diff
==============================================================================
--- directory/trunks/mina/core/src/main/java/org/apache/mina/common/SimpleByteBufferAllocator.java (original)
+++ directory/trunks/mina/core/src/main/java/org/apache/mina/common/SimpleByteBufferAllocator.java Fri Apr 28 11:00:56 2006
@@ -60,6 +60,10 @@
return new SimpleByteBuffer( nioBuffer );
}
+ public void dispose()
+ {
+ }
+
private static class SimpleByteBuffer extends ByteBuffer
{
private java.nio.ByteBuffer buf;