diff --git a/buffer/src/main/java/io/netty/buffer/AbstractDerivedByteBuf.java b/buffer/src/main/java/io/netty/buffer/AbstractDerivedByteBuf.java index 6a1de6b835..58f1d907a1 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractDerivedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractDerivedByteBuf.java @@ -91,7 +91,7 @@ public abstract class AbstractDerivedByteBuf extends AbstractByteBuf { @Override public final boolean release(int decrement) { - return unwrap().release(decrement); + return release0(decrement); } boolean release0(int decrement) { diff --git a/buffer/src/main/java/io/netty/buffer/AbstractPooledDerivedByteBuf.java b/buffer/src/main/java/io/netty/buffer/AbstractPooledDerivedByteBuf.java index b5958b1f6d..0dfe5e3cf2 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractPooledDerivedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractPooledDerivedByteBuf.java @@ -269,15 +269,13 @@ abstract class AbstractPooledDerivedByteBuf extends AbstractReferenceCountedByte @Override public ByteBuf duplicate() { - // Capacity is not allowed to change for a sliced ByteBuf, so length == capacity() - final ByteBuf duplicate = slice(0, capacity()); - duplicate.setIndex(readerIndex(), writerIndex()); - return duplicate; + return new PooledNonRetainedDuplicateByteBuf(referenceCountDelegate, unwrap()) + .setIndex(idx(readerIndex()), idx(writerIndex())); } @Override public ByteBuf retainedDuplicate() { - return PooledDuplicatedByteBuf.newInstance(unwrap(), this, readerIndex(), writerIndex()); + return PooledDuplicatedByteBuf.newInstance(unwrap(), this, idx(readerIndex()), idx(writerIndex())); } @Override diff --git a/buffer/src/main/java/io/netty/buffer/AbstractUnpooledSlicedByteBuf.java b/buffer/src/main/java/io/netty/buffer/AbstractUnpooledSlicedByteBuf.java index 080da3f1dd..1ac0992e41 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractUnpooledSlicedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractUnpooledSlicedByteBuf.java @@ -216,9 +216,7 @@ abstract class AbstractUnpooledSlicedByteBuf extends AbstractDerivedByteBuf { @Override public ByteBuf duplicate() { - final ByteBuf duplicate = unwrap().slice(adjustment, length()); - duplicate.setIndex(readerIndex(), writerIndex()); - return duplicate; + return unwrap().duplicate().setIndex(idx(readerIndex()), idx(writerIndex())); } @Override diff --git a/buffer/src/main/java/io/netty/buffer/ByteBuf.java b/buffer/src/main/java/io/netty/buffer/ByteBuf.java index f51caabd62..607a4b13ac 100644 --- a/buffer/src/main/java/io/netty/buffer/ByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/ByteBuf.java @@ -2135,12 +2135,14 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable { * Returns a buffer which shares the whole region of this buffer. * Modifying the content of the returned buffer or this buffer affects * each other's content while they maintain separate indexes and marks. - * This method is identical to {@code buf.slice(0, buf.capacity())}. * This method does not modify {@code readerIndex} or {@code writerIndex} of * this buffer. *

* The reader and writer marks will not be duplicated. Also be aware that this method will * NOT call {@link #retain()} and so the reference count will NOT be increased. + * @return A buffer whose readable content is equivalent to the buffer returned by {@link #slice()}. + * However this buffer will share the capacity of the underlying buffer, and therefore allows access to all of the + * underlying content if necessary. */ public abstract ByteBuf duplicate(); diff --git a/buffer/src/main/java/io/netty/buffer/PooledDuplicatedByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledDuplicatedByteBuf.java index e3d6e92d52..1260f4e31f 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledDuplicatedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledDuplicatedByteBuf.java @@ -94,9 +94,7 @@ final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf { @Override public ByteBuf duplicate() { - ByteBuf duplicate = duplicate0(); - duplicate.setIndex(readerIndex(), writerIndex()); - return duplicate; + return duplicate0().setIndex(readerIndex(), writerIndex()); } @Override diff --git a/buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java index 09468eb132..44051881ab 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java @@ -113,15 +113,12 @@ final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf { @Override public ByteBuf duplicate() { - ByteBuf duplicate = duplicate0(); - duplicate.setIndex(idx(readerIndex()), adjustment + capacity()); - return duplicate; + return duplicate0().setIndex(idx(readerIndex()), idx(writerIndex())); } @Override public ByteBuf retainedDuplicate() { - // Capacity is not allowed to change for a sliced ByteBuf, so length == capacity() - return PooledDuplicatedByteBuf.newInstance(unwrap(), this, idx(readerIndex()), adjustment + capacity()); + return PooledDuplicatedByteBuf.newInstance(unwrap(), this, idx(readerIndex()), idx(writerIndex())); } @Override diff --git a/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java b/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java index 670cf138d2..3474422127 100644 --- a/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java +++ b/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java @@ -52,7 +52,6 @@ import static io.netty.buffer.Unpooled.buffer; import static io.netty.buffer.Unpooled.copiedBuffer; import static io.netty.buffer.Unpooled.directBuffer; import static io.netty.buffer.Unpooled.wrappedBuffer; -import static io.netty.util.ReferenceCountUtil.releaseLater; import static io.netty.util.internal.EmptyArrays.EMPTY_BYTES; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertArrayEquals; @@ -1729,19 +1728,15 @@ public abstract class AbstractByteBufTest { // Make sure all properties are copied. ByteBuf duplicate = buffer.duplicate(); - assertEquals(buffer.readerIndex(), duplicate.readerIndex()); - assertEquals(buffer.writerIndex(), duplicate.writerIndex()); - assertEquals(buffer.capacity(), duplicate.capacity()); assertSame(buffer.order(), duplicate.order()); - for (int i = 0; i < duplicate.capacity(); i ++) { - assertEquals(buffer.getByte(i), duplicate.getByte(i)); - } + assertEquals(buffer.readableBytes(), duplicate.readableBytes()); + assertEquals(0, buffer.compareTo(duplicate)); // Make sure the buffer content is shared. buffer.setByte(readerIndex, (byte) (buffer.getByte(readerIndex) + 1)); - assertEquals(buffer.getByte(readerIndex), duplicate.getByte(readerIndex)); - duplicate.setByte(1, (byte) (duplicate.getByte(1) + 1)); - assertEquals(buffer.getByte(1), duplicate.getByte(1)); + assertEquals(buffer.getByte(readerIndex), duplicate.getByte(duplicate.readerIndex())); + duplicate.setByte(duplicate.readerIndex(), (byte) (duplicate.getByte(duplicate.readerIndex()) + 1)); + assertEquals(buffer.getByte(readerIndex), duplicate.getByte(duplicate.readerIndex())); } @Test @@ -3411,6 +3406,15 @@ public abstract class AbstractByteBufTest { ByteBuf slice2 = slice1.retainedSlice(slice1.readerIndex() + 1, 4); assertEquals(0, slice2.compareTo(expected2)); + assertEquals(0, slice2.compareTo(slice2.duplicate())); + assertEquals(0, slice2.compareTo(slice2.slice())); + + ByteBuf tmpBuf = slice2.retainedDuplicate(); + assertEquals(0, slice2.compareTo(tmpBuf)); + tmpBuf.release(); + tmpBuf = slice2.retainedSlice(); + assertEquals(0, slice2.compareTo(tmpBuf)); + tmpBuf.release(); ByteBuf slice3 = doSlice1 ? slice2.slice(slice2.readerIndex() + 1, 2) : slice2.duplicate(); if (doSlice1) { @@ -3540,6 +3544,15 @@ public abstract class AbstractByteBufTest { ByteBuf dup2 = retainedDuplicate2 ? dup1.retainedDuplicate() : dup1.duplicate().retain(); assertEquals(0, dup2.compareTo(expected)); + assertEquals(0, dup2.compareTo(dup2.duplicate())); + assertEquals(0, dup2.compareTo(dup2.slice())); + + ByteBuf tmpBuf = dup2.retainedDuplicate(); + assertEquals(0, dup2.compareTo(tmpBuf)); + tmpBuf.release(); + tmpBuf = dup2.retainedSlice(); + assertEquals(0, dup2.compareTo(tmpBuf)); + tmpBuf.release(); // The handler created a slice of the slice and is now done with it. dup2.release(); @@ -3574,7 +3587,7 @@ public abstract class AbstractByteBufTest { ByteBuf b = dup.retainedDuplicate(); assertEquals(0, dup.compareTo(b)); b.release(); - assertEquals(0, dup.compareTo(dup.slice(0, dup.capacity()))); + assertEquals(0, dup.compareTo(dup.slice(dup.readerIndex(), dup.readableBytes()))); } finally { if (retainedDuplicate) { dup.release(); diff --git a/buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java b/buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java index 4b45d98764..9fd3796d43 100644 --- a/buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java +++ b/buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java @@ -27,10 +27,23 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; -import static io.netty.buffer.Unpooled.*; -import static io.netty.util.internal.EmptyArrays.*; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; +import static io.netty.buffer.Unpooled.EMPTY_BUFFER; +import static io.netty.buffer.Unpooled.buffer; +import static io.netty.buffer.Unpooled.compositeBuffer; +import static io.netty.buffer.Unpooled.directBuffer; +import static io.netty.buffer.Unpooled.wrappedBuffer; +import static io.netty.util.internal.EmptyArrays.EMPTY_BYTES; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * An abstract test class for composite channel buffers @@ -567,13 +580,15 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest { buf.release(); } + @SuppressWarnings("deprecation") @Test - public void testComponentMustBeSlice() { + public void testComponentMustBeDuplicate() { CompositeByteBuf buf = compositeBuffer(); - buf.addComponent(buffer(4).setIndex(1, 3)); - assertThat(buf.component(0), is(instanceOf(AbstractUnpooledSlicedByteBuf.class))); - assertThat(buf.component(0).capacity(), is(2)); - assertThat(buf.component(0).maxCapacity(), is(2)); + buf.addComponent(buffer(4, 6).setIndex(1, 3)); + assertThat(buf.component(0), is(instanceOf(AbstractDerivedByteBuf.class))); + assertThat(buf.component(0).capacity(), is(4)); + assertThat(buf.component(0).maxCapacity(), is(6)); + assertThat(buf.component(0).readableBytes(), is(2)); buf.release(); } diff --git a/buffer/src/test/java/io/netty/buffer/SlicedByteBufTest.java b/buffer/src/test/java/io/netty/buffer/SlicedByteBufTest.java index bc96e6c81e..7941b7d500 100644 --- a/buffer/src/test/java/io/netty/buffer/SlicedByteBufTest.java +++ b/buffer/src/test/java/io/netty/buffer/SlicedByteBufTest.java @@ -16,6 +16,7 @@ package io.netty.buffer; import io.netty.util.internal.ThreadLocalRandom; +import org.junit.Ignore; import org.junit.Test; import java.io.IOException; @@ -138,16 +139,14 @@ public class SlicedByteBufTest extends AbstractByteBufTest { // Ignore for SlicedByteBuf } - @Test(expected = UnsupportedOperationException.class) + @Ignore("Sliced ByteBuf objects don't allow the capacity to change. So this test would fail and shouldn't be run") @Override public void testDuplicateCapacityChange() { - super.testDuplicateCapacityChange(); } - @Test(expected = UnsupportedOperationException.class) + @Ignore("Sliced ByteBuf objects don't allow the capacity to change. So this test would fail and shouldn't be run") @Override public void testRetainedDuplicateCapacityChange() { - super.testRetainedDuplicateCapacityChange(); } @Test