You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2006/03/22 09:28:56 UTC
svn commit: r387793 - in /directory/trunks/mina/core/src:
main/java/org/apache/mina/common/ test/java/org/apache/mina/common/
Author: trustin
Date: Wed Mar 22 00:28:53 2006
New Revision: 387793
URL: http://svn.apache.org/viewcvs?rev=387793&view=rev
Log:
Resolved issue: DIRMINA-165 (Easy and performant copy of the ByteBuffer)
* Added duplicate(), slice(), and asReadOnlyBuffer() to Bytebuffer
* Implemented these three methods for all allocator implementations
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/ByteBufferProxy.java
directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java
directory/trunks/mina/core/src/main/java/org/apache/mina/common/SimpleByteBufferAllocator.java
directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.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=387793&r1=387792&r2=387793&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 Wed Mar 22 00:28:53 2006
@@ -381,6 +381,21 @@
{
return remaining() > 0;
}
+
+ /**
+ * @see java.nio.ByteBuffer#duplicate()
+ */
+ public abstract ByteBuffer duplicate();
+
+ /**
+ * @see java.nio.ByteBuffer#slice()
+ */
+ public abstract ByteBuffer slice();
+
+ /**
+ * @see java.nio.ByteBuffer#asReadOnlyBuffer()
+ */
+ public abstract ByteBuffer asReadOnlyBuffer();
/**
* @see java.nio.ByteBuffer#get()
Modified: directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferProxy.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferProxy.java?rev=387793&r1=387792&r2=387793&view=diff
==============================================================================
--- directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferProxy.java (original)
+++ directory/trunks/mina/core/src/main/java/org/apache/mina/common/ByteBufferProxy.java Wed Mar 22 00:28:53 2006
@@ -607,4 +607,19 @@
{
return buf.asOutputStream();
}
+
+ public ByteBuffer duplicate()
+ {
+ return buf.duplicate();
+ }
+
+ public ByteBuffer slice()
+ {
+ return buf.slice();
+ }
+
+ public ByteBuffer asReadOnlyBuffer()
+ {
+ return buf.asReadOnlyBuffer();
+ }
}
Modified: directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java?rev=387793&r1=387792&r2=387793&view=diff
==============================================================================
--- directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java (original)
+++ directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java Wed Mar 22 00:28:53 2006
@@ -173,9 +173,9 @@
public ByteBuffer allocate( int capacity, boolean direct )
{
ensureNotDisposed();
- java.nio.ByteBuffer nioBuffer = allocate0( capacity, direct );
+ UnexpandableByteBuffer ubb = allocate0( capacity, direct );
PooledByteBuffer buf = allocateContainer();
- buf.init( nioBuffer, true );
+ buf.init( ubb, true );
return buf;
}
@@ -194,31 +194,36 @@
return buf;
}
- private java.nio.ByteBuffer allocate0( int capacity, boolean direct )
+ private UnexpandableByteBuffer allocate0( int capacity, boolean direct )
{
ExpiringStack[] bufferStacks = direct? directBufferStacks : heapBufferStacks;
int idx = getBufferStackIndex( bufferStacks, capacity );
ExpiringStack stack = bufferStacks[ idx ];
- java.nio.ByteBuffer buf;
+ UnexpandableByteBuffer buf;
synchronized( stack )
{
- buf = ( java.nio.ByteBuffer ) stack.pop();
+ buf = ( UnexpandableByteBuffer ) stack.pop();
}
if( buf == null )
{
- buf = direct ? java.nio.ByteBuffer.allocateDirect( MINIMUM_CAPACITY << idx ) :
- java.nio.ByteBuffer.allocate( MINIMUM_CAPACITY << idx );
+ java.nio.ByteBuffer nioBuf =
+ direct ? java.nio.ByteBuffer.allocateDirect( MINIMUM_CAPACITY << idx ) :
+ java.nio.ByteBuffer.allocate( MINIMUM_CAPACITY << idx );
+ buf = new UnexpandableByteBuffer( nioBuf );
}
+
+ buf.init();
return buf;
}
- private void release0( java.nio.ByteBuffer buf )
+ private void release0( UnexpandableByteBuffer buf )
{
- ExpiringStack[] bufferStacks = buf.isDirect()? directBufferStacks : heapBufferStacks;
- ExpiringStack stack = bufferStacks[ getBufferStackIndex( bufferStacks, buf.capacity() ) ];
+ ExpiringStack[] bufferStacks = buf.buf().isDirect()? directBufferStacks : heapBufferStacks;
+ ExpiringStack stack = bufferStacks[ getBufferStackIndex( bufferStacks, buf.buf().capacity() ) ];
+
synchronized( stack )
{
// push back
@@ -230,7 +235,7 @@
{
ensureNotDisposed();
PooledByteBuffer buf = allocateContainer();
- buf.init( nioBuffer, false );
+ buf.init( new UnexpandableByteBuffer( nioBuffer ), false );
buf.setPooled( false );
return buf;
}
@@ -337,26 +342,23 @@
private class PooledByteBuffer extends ByteBuffer
{
- private java.nio.ByteBuffer buf;
+ private UnexpandableByteBuffer buf;
private int refCount = 1;
private boolean autoExpand;
- private boolean pooled;
- private long timestamp;
protected PooledByteBuffer()
{
}
- private synchronized void init( java.nio.ByteBuffer buf, boolean clear )
+ public synchronized void init( UnexpandableByteBuffer buf, boolean clear )
{
this.buf = buf;
if( clear )
{
- buf.clear();
+ buf.buf().clear();
}
- buf.order( ByteOrder.BIG_ENDIAN );
+ buf.buf().order( ByteOrder.BIG_ENDIAN );
autoExpand = false;
- pooled = true;
refCount = 1;
}
@@ -394,13 +396,7 @@
return;
}
- if( pooled )
- {
- release0( buf );
- }
-
- // Update timestamp.
- timestamp = System.currentTimeMillis();
+ buf.release();
synchronized( containerStack )
{
@@ -410,17 +406,17 @@
public java.nio.ByteBuffer buf()
{
- return buf;
+ return buf.buf();
}
public boolean isDirect()
{
- return buf.isDirect();
+ return buf.buf().isDirect();
}
public boolean isReadOnly()
{
- return buf.isReadOnly();
+ return buf.buf().isReadOnly();
}
public boolean isAutoExpand()
@@ -436,333 +432,352 @@
public boolean isPooled()
{
- return pooled;
+ return buf.isPooled();
}
public void setPooled( boolean pooled )
{
- this.pooled = pooled;
- }
-
- public long getTimestamp()
- {
- return timestamp;
+ buf.setPooled(pooled);
}
public int capacity()
{
- return buf.capacity();
+ return buf.buf().capacity();
}
public int position()
{
- return buf.position();
+ return buf.buf().position();
}
public ByteBuffer position( int newPosition )
{
autoExpand( newPosition, 0 );
- buf.position( newPosition );
+ buf.buf().position( newPosition );
return this;
}
public int limit()
{
- return buf.limit();
+ return buf.buf().limit();
}
public ByteBuffer limit( int newLimit )
{
autoExpand( newLimit, 0 );
- buf.limit( newLimit );
+ buf.buf().limit( newLimit );
return this;
}
public ByteBuffer mark()
{
- buf.mark();
+ buf.buf().mark();
return this;
}
public ByteBuffer reset()
{
- buf.reset();
+ buf.buf().reset();
return this;
}
public ByteBuffer clear()
{
- buf.clear();
+ buf.buf().clear();
return this;
}
public ByteBuffer flip()
{
- buf.flip();
+ buf.buf().flip();
return this;
}
public ByteBuffer rewind()
{
- buf.rewind();
+ buf.buf().rewind();
return this;
}
public int remaining()
{
- return buf.remaining();
+ return buf.buf().remaining();
+ }
+
+ public ByteBuffer duplicate()
+ {
+ PooledByteBuffer newBuf = allocateContainer();
+ newBuf.init(
+ new UnexpandableByteBuffer( buf.buf().duplicate(), buf ), false );
+ return newBuf;
+ }
+
+ public ByteBuffer slice()
+ {
+ PooledByteBuffer newBuf = allocateContainer();
+ newBuf.init(
+ new UnexpandableByteBuffer( buf.buf().slice(), buf ), false );
+ return newBuf;
+ }
+
+ public ByteBuffer asReadOnlyBuffer()
+ {
+ PooledByteBuffer newBuf = allocateContainer();
+ newBuf.init(
+ new UnexpandableByteBuffer( buf.buf().asReadOnlyBuffer(), buf ), false );
+ return newBuf;
}
public byte get()
{
- return buf.get();
+ return buf.buf().get();
}
public ByteBuffer put( byte b )
{
autoExpand( 1 );
- buf.put( b );
+ buf.buf().put( b );
return this;
}
public byte get( int index )
{
- return buf.get( index );
+ return buf.buf().get( index );
}
public ByteBuffer put( int index, byte b )
{
autoExpand( index, 1 );
- buf.put( index, b );
+ buf.buf().put( index, b );
return this;
}
public ByteBuffer get( byte[] dst, int offset, int length )
{
- buf.get( dst, offset, length );
+ buf.buf().get( dst, offset, length );
return this;
}
public ByteBuffer put( java.nio.ByteBuffer src )
{
autoExpand( src.remaining() );
- buf.put( src );
+ buf.buf().put( src );
return this;
}
public ByteBuffer put( byte[] src, int offset, int length )
{
autoExpand( length );
- buf.put( src, offset, length );
+ buf.buf().put( src, offset, length );
return this;
}
public ByteBuffer compact()
{
- buf.compact();
+ buf.buf().compact();
return this;
}
public int compareTo( ByteBuffer that )
{
- return this.buf.compareTo( that.buf() );
+ return this.buf.buf().compareTo( that.buf() );
}
public ByteOrder order()
{
- return buf.order();
+ return buf.buf().order();
}
public ByteBuffer order( ByteOrder bo )
{
- buf.order( bo );
+ buf.buf().order( bo );
return this;
}
public char getChar()
{
- return buf.getChar();
+ return buf.buf().getChar();
}
public ByteBuffer putChar( char value )
{
autoExpand( 2 );
- buf.putChar( value );
+ buf.buf().putChar( value );
return this;
}
public char getChar( int index )
{
- return buf.getChar( index );
+ return buf.buf().getChar( index );
}
public ByteBuffer putChar( int index, char value )
{
autoExpand( index, 2 );
- buf.putChar( index, value );
+ buf.buf().putChar( index, value );
return this;
}
public CharBuffer asCharBuffer()
{
- return buf.asCharBuffer();
+ return buf.buf().asCharBuffer();
}
public short getShort()
{
- return buf.getShort();
+ return buf.buf().getShort();
}
public ByteBuffer putShort( short value )
{
autoExpand( 2 );
- buf.putShort( value );
+ buf.buf().putShort( value );
return this;
}
public short getShort( int index )
{
- return buf.getShort( index );
+ return buf.buf().getShort( index );
}
public ByteBuffer putShort( int index, short value )
{
autoExpand( index, 2 );
- buf.putShort( index, value );
+ buf.buf().putShort( index, value );
return this;
}
public ShortBuffer asShortBuffer()
{
- return buf.asShortBuffer();
+ return buf.buf().asShortBuffer();
}
public int getInt()
{
- return buf.getInt();
+ return buf.buf().getInt();
}
public ByteBuffer putInt( int value )
{
autoExpand( 4 );
- buf.putInt( value );
+ buf.buf().putInt( value );
return this;
}
public int getInt( int index )
{
- return buf.getInt( index );
+ return buf.buf().getInt( index );
}
public ByteBuffer putInt( int index, int value )
{
autoExpand( index, 4 );
- buf.putInt( index, value );
+ buf.buf().putInt( index, value );
return this;
}
public IntBuffer asIntBuffer()
{
- return buf.asIntBuffer();
+ return buf.buf().asIntBuffer();
}
public long getLong()
{
- return buf.getLong();
+ return buf.buf().getLong();
}
public ByteBuffer putLong( long value )
{
autoExpand( 8 );
- buf.putLong( value );
+ buf.buf().putLong( value );
return this;
}
public long getLong( int index )
{
- return buf.getLong( index );
+ return buf.buf().getLong( index );
}
public ByteBuffer putLong( int index, long value )
{
autoExpand( index, 8 );
- buf.putLong( index, value );
+ buf.buf().putLong( index, value );
return this;
}
public LongBuffer asLongBuffer()
{
- return buf.asLongBuffer();
+ return buf.buf().asLongBuffer();
}
public float getFloat()
{
- return buf.getFloat();
+ return buf.buf().getFloat();
}
public ByteBuffer putFloat( float value )
{
autoExpand( 4 );
- buf.putFloat( value );
+ buf.buf().putFloat( value );
return this;
}
public float getFloat( int index )
{
- return buf.getFloat( index );
+ return buf.buf().getFloat( index );
}
public ByteBuffer putFloat( int index, float value )
{
autoExpand( index, 4 );
- buf.putFloat( index, value );
+ buf.buf().putFloat( index, value );
return this;
}
public FloatBuffer asFloatBuffer()
{
- return buf.asFloatBuffer();
+ return buf.buf().asFloatBuffer();
}
public double getDouble()
{
- return buf.getDouble();
+ return buf.buf().getDouble();
}
public ByteBuffer putDouble( double value )
{
autoExpand( 8 );
- buf.putDouble( value );
+ buf.buf().putDouble( value );
return this;
}
public double getDouble( int index )
{
- return buf.getDouble( index );
+ return buf.buf().getDouble( index );
}
public ByteBuffer putDouble( int index, double value )
{
autoExpand( index, 8 );
- buf.putDouble( index, value );
+ buf.buf().putDouble( index, value );
return this;
}
public DoubleBuffer asDoubleBuffer()
{
- return buf.asDoubleBuffer();
+ return buf.buf().asDoubleBuffer();
}
public ByteBuffer expand( int expectedRemaining )
{
if( autoExpand )
{
- int pos = buf.position();
- int limit = buf.limit();
+ int pos = buf.buf().position();
+ int limit = buf.buf().limit();
int end = pos + expectedRemaining;
if( end > limit ) {
ensureCapacity( end );
- buf.limit( end );
+ buf.buf().limit( end );
}
}
return this;
@@ -772,11 +787,11 @@
{
if( autoExpand )
{
- int limit = buf.limit();
+ int limit = buf.buf().limit();
int end = pos + expectedRemaining;
if( end > limit ) {
ensureCapacity( end );
- buf.limit( end );
+ buf.buf().limit( end );
}
}
return this;
@@ -784,31 +799,142 @@
private void ensureCapacity( int requestedCapacity )
{
- if( requestedCapacity <= buf.capacity() )
+ if( requestedCapacity <= buf.buf().capacity() )
{
return;
}
+ if( buf.isDerived() )
+ {
+ throw new IllegalStateException( "Derived buffers cannot be expanded." );
+ }
+
int newCapacity = MINIMUM_CAPACITY;
while( newCapacity < requestedCapacity )
{
newCapacity <<= 1;
}
- java.nio.ByteBuffer oldBuf = this.buf;
- java.nio.ByteBuffer newBuf = allocate0( newCapacity, isDirect() );
- newBuf.clear();
- newBuf.order( oldBuf.order() );
-
- int pos = oldBuf.position();
- int limit = oldBuf.limit();
- oldBuf.clear();
- newBuf.put( oldBuf );
- newBuf.position( 0 );
- newBuf.limit( limit );
- newBuf.position( pos );
+ UnexpandableByteBuffer oldBuf = this.buf;
+ UnexpandableByteBuffer newBuf = allocate0( newCapacity, isDirect() );
+ newBuf.buf().clear();
+ newBuf.buf().order( oldBuf.buf().order() );
+
+ int pos = oldBuf.buf().position();
+ int limit = oldBuf.buf().limit();
+ oldBuf.buf().clear();
+ newBuf.buf().put( oldBuf.buf() );
+ newBuf.buf().position( 0 );
+ newBuf.buf().limit( limit );
+ newBuf.buf().position( pos );
this.buf = newBuf;
- release0( oldBuf );
+ oldBuf.release();
+ }
+ }
+
+ private class UnexpandableByteBuffer
+ {
+ private final java.nio.ByteBuffer buf;
+ private final UnexpandableByteBuffer parentBuf;
+ private int refCount;
+ private boolean pooled;
+
+ protected UnexpandableByteBuffer( java.nio.ByteBuffer buf )
+ {
+ this.buf = buf;
+ this.parentBuf = null;
+ }
+
+ protected UnexpandableByteBuffer(
+ java.nio.ByteBuffer buf,
+ UnexpandableByteBuffer parentBuf )
+ {
+ parentBuf.acquire();
+ this.buf = buf;
+ this.parentBuf = parentBuf;
+ }
+
+ public void init()
+ {
+ refCount = 1;
+ pooled = true;
+ }
+
+ public synchronized void acquire()
+ {
+ if( isDerived() ) {
+ parentBuf.acquire();
+ return;
+ }
+
+ if( refCount <= 0 )
+ {
+ throw new IllegalStateException( "Already released buffer." );
+ }
+
+ refCount ++;
+ }
+
+ public void release()
+ {
+ if( isDerived() ) {
+ parentBuf.release();
+ return;
+ }
+
+ synchronized( this )
+ {
+ if( refCount <= 0 )
+ {
+ refCount = 0;
+ throw new IllegalStateException(
+ "Already released buffer. You released the buffer too many times." );
+ }
+
+ refCount --;
+ if( refCount > 0)
+ {
+ return;
+ }
+ }
+
+ // No need to return buffers to the pool if it is disposed already.
+ if( disposed )
+ {
+ return;
+ }
+
+ if( pooled )
+ {
+ if( parentBuf != null )
+ {
+ release0( parentBuf );
+ }
+ else
+ {
+ release0( this );
+ }
+ }
+ }
+
+ public java.nio.ByteBuffer buf()
+ {
+ return buf;
+ }
+
+ public boolean isPooled()
+ {
+ return pooled;
+ }
+
+ public void setPooled( boolean pooled )
+ {
+ this.pooled = pooled;
+ }
+
+ public boolean isDerived()
+ {
+ return parentBuf != null;
}
}
}
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=387793&r1=387792&r2=387793&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 Wed Mar 22 00:28:53 2006
@@ -52,12 +52,12 @@
{
nioBuffer = java.nio.ByteBuffer.allocate( capacity );
}
- return new SimpleByteBuffer( nioBuffer, true );
+ return new SimpleByteBuffer( nioBuffer );
}
public ByteBuffer wrap( java.nio.ByteBuffer nioBuffer )
{
- return new SimpleByteBuffer( nioBuffer, false );
+ return new SimpleByteBuffer( nioBuffer );
}
private static class SimpleByteBuffer extends ByteBuffer
@@ -66,13 +66,9 @@
private int refCount = 1;
private boolean autoExpand;
- protected SimpleByteBuffer( java.nio.ByteBuffer buf, boolean clear )
+ protected SimpleByteBuffer( java.nio.ByteBuffer buf )
{
this.buf = buf;
- if( clear )
- {
- buf.clear();
- }
buf.order( ByteOrder.BIG_ENDIAN );
autoExpand = false;
refCount = 1;
@@ -510,6 +506,18 @@
newBuf.limit( limit );
newBuf.position( pos );
this.buf = newBuf;
+ }
+
+ public ByteBuffer duplicate() {
+ return new SimpleByteBuffer( this.buf.duplicate() );
+ }
+
+ public ByteBuffer slice() {
+ return new SimpleByteBuffer( this.buf.slice() );
+ }
+
+ public ByteBuffer asReadOnlyBuffer() {
+ return new SimpleByteBuffer( this.buf.asReadOnlyBuffer() );
}
}
}
Modified: directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java?rev=387793&r1=387792&r2=387793&view=diff
==============================================================================
--- directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java (original)
+++ directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java Wed Mar 22 00:28:53 2006
@@ -19,6 +19,7 @@
package org.apache.mina.common;
import java.nio.BufferOverflowException;
+import java.nio.ReadOnlyBufferException;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
@@ -630,6 +631,148 @@
Assert.fail();
}
catch( IllegalStateException e )
+ {
+ // OK
+ }
+ }
+
+ public void testDuplicate() throws Exception
+ {
+ java.nio.ByteBuffer nioBuf;
+ ByteBuffer original;
+ ByteBuffer duplicate;
+
+ // Test if the buffer is duplicated correctly.
+ original = ByteBuffer.allocate( 16 ).sweep();
+ nioBuf = original.buf();
+ original.position( 4 );
+ original.limit( 10 );
+ duplicate = original.duplicate();
+ original.put( 4, ( byte ) 127 );
+ Assert.assertEquals( 4, duplicate.position() );
+ Assert.assertEquals( 10, duplicate.limit() );
+ Assert.assertEquals( 16, duplicate.capacity() );
+ Assert.assertNotSame( original.buf(), duplicate.buf() );
+ Assert.assertEquals( 127, duplicate.get( 4 ) );
+ original.release();
+ duplicate.release();
+
+ //// Check if pooled correctly.
+ original = ByteBuffer.allocate( 16 );
+ Assert.assertSame( nioBuf, original.buf() );
+ original.release();
+
+ // Try to release duplicate first.
+ original = ByteBuffer.allocate( 16 );
+ duplicate = original.duplicate();
+ duplicate.release();
+ original.release();
+
+ //// Check if pooled correctly.
+ original = ByteBuffer.allocate( 16 );
+ Assert.assertSame( nioBuf, original.buf() );
+ original.release();
+
+ // Test a duplicate of a duplicate.
+ original = ByteBuffer.allocate( 16 );
+ duplicate = original.duplicate();
+ ByteBuffer anotherDuplicate = duplicate.duplicate();
+ anotherDuplicate.release();
+ original.release();
+ duplicate.release();
+ try
+ {
+ duplicate.release();
+ Assert.fail();
+ }
+ catch( IllegalStateException e )
+ {
+ // OK
+ }
+ try
+ {
+ anotherDuplicate.release();
+ Assert.fail();
+ }
+ catch( IllegalStateException e )
+ {
+ // OK
+ }
+
+ //// Check if pooled correctly.
+ original = ByteBuffer.allocate( 16 );
+ Assert.assertSame( nioBuf, original.buf() );
+ original.release();
+
+
+
+ // Try to expand.
+ try
+ {
+ original = ByteBuffer.allocate( 16 );
+ duplicate = original.duplicate();
+ duplicate.setAutoExpand( true );
+ duplicate.putString(
+ "A very very very very looooooong string",
+ Charset.forName( "ISO-8859-1" ).newEncoder() );
+ Assert.fail();
+ }
+ catch( IllegalStateException e )
+ {
+ // OK
+ }
+ }
+
+ public void testSlice() throws Exception
+ {
+ ByteBuffer original;
+ ByteBuffer slice;
+
+ // Test if the buffer is sliced correctly.
+ original = ByteBuffer.allocate( 16 ).sweep();
+ original.position( 4 );
+ original.limit( 10 );
+ slice = original.slice();
+ original.put( 4, ( byte ) 127 );
+ Assert.assertEquals( 0, slice.position() );
+ Assert.assertEquals( 6, slice.limit() );
+ Assert.assertEquals( 6, slice.capacity() );
+ Assert.assertNotSame( original.buf(), slice.buf() );
+ Assert.assertEquals( 127, slice.get( 0 ) );
+ original.release();
+ slice.release();
+ }
+
+ public void testReadOnlyBuffer() throws Exception
+ {
+ ByteBuffer original;
+ ByteBuffer duplicate;
+
+ // Test if the buffer is duplicated correctly.
+ original = ByteBuffer.allocate( 16 ).sweep();
+ original.position( 4 );
+ original.limit( 10 );
+ duplicate = original.asReadOnlyBuffer();
+ original.put( 4, ( byte ) 127 );
+ Assert.assertEquals( 4, duplicate.position() );
+ Assert.assertEquals( 10, duplicate.limit() );
+ Assert.assertEquals( 16, duplicate.capacity() );
+ Assert.assertNotSame( original.buf(), duplicate.buf() );
+ Assert.assertEquals( 127, duplicate.get( 4 ) );
+ original.release();
+ duplicate.release();
+
+ // Try to expand.
+ try
+ {
+ original = ByteBuffer.allocate( 16 );
+ duplicate = original.asReadOnlyBuffer();
+ duplicate.putString(
+ "A very very very very looooooong string",
+ Charset.forName( "ISO-8859-1" ).newEncoder() );
+ Assert.fail();
+ }
+ catch( ReadOnlyBufferException e )
{
// OK
}