diff --git a/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java b/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java index 4c8cb0c..21dae15 100644 --- a/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java +++ b/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java @@ -18,6 +18,7 @@ package io.netty.buffer.api.adaptor; import io.netty.buffer.ByteBufConvertible; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.buffer.api.Buffer; import io.netty.buffer.api.BufferAllocator; @@ -464,7 +465,8 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { - if (index < 0 || capacity() < index + length) { + checkAccess(); + if (index < 0 || capacity() < index + length || dst.length < dstIndex + length) { throw new IndexOutOfBoundsException(); } for (int i = 0; i < length; i++) { @@ -475,6 +477,10 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public ByteBuf getBytes(int index, ByteBuffer dst) { + checkAccess(); + if (index < 0 || capacity() < index + dst.remaining()) { + throw new IndexOutOfBoundsException(); + } while (dst.hasRemaining()) { dst.put(getByte(index)); index++; @@ -492,6 +498,7 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + checkAccess(); ByteBuffer transfer = ByteBuffer.allocate(length); buffer.copyInto(index, transfer, 0, length); return out.write(transfer); @@ -499,6 +506,7 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public int getBytes(int index, FileChannel out, long position, int length) throws IOException { + checkAccess(); ByteBuffer transfer = ByteBuffer.allocate(length); buffer.copyInto(index, transfer, 0, length); return out.write(transfer, position); @@ -940,8 +948,9 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public ByteBuf readBytes(int length) { + checkAccess(); Buffer copy = preferredBufferAllocator().allocate(length); - buffer.copyInto(0, copy, readerIndex(), length); + buffer.copyInto(readerIndex(), copy, 0, length); readerIndex(readerIndex() + length); return wrap(copy).writerIndex(length); } @@ -1015,6 +1024,7 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public int readBytes(GatheringByteChannel out, int length) throws IOException { + checkAccess(); ByteBuffer[] components = new ByteBuffer[buffer.countReadableComponents()]; buffer.forEachReadable(0, (i, component) -> { components[i] = component.readableBuffer(); @@ -1301,31 +1311,30 @@ public final class ByteBufAdaptor extends ByteBuf { if (!buffer.isAccessible()) { return -1; } - int inc, start, end; if (fromIndex <= toIndex) { - inc = 1; - start = fromIndex; - end = toIndex - 1; - if (start < 0) { - start = 0; // Required to pass regression tests. + if (fromIndex < 0) { + fromIndex = 0; // Required to pass regression tests. } - if (capacity() <= end) { + if (capacity() < toIndex) { throw new IndexOutOfBoundsException(); } + for (; fromIndex < toIndex; fromIndex++) { + if (getByte(fromIndex) == value) { + return fromIndex; + } + } } else { - inc = -1; - start = fromIndex - 1; - end = toIndex; - if (capacity() <= start) { - start = capacity() - 1; // Required to pass regression tests. + if (capacity() < fromIndex) { + fromIndex = capacity(); // Required to pass regression tests. } - if (end < 0) { + fromIndex--; + if (toIndex < 0) { throw new IndexOutOfBoundsException(); } - } - for (int i = start; i != end; i += inc) { - if (getByte(i) == value) { - return i; + for (; fromIndex > toIndex; fromIndex--) { + if (getByte(fromIndex) == value) { + return fromIndex; + } } } return -1; @@ -1376,7 +1385,7 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public int forEachByteDesc(int index, int length, ByteProcessor processor) { checkAccess(); - int bytes = buffer.openReverseCursor(index, length).process(processor); + int bytes = buffer.openReverseCursor(index + length - 1, length).process(processor); return bytes == -1 ? -1 : index - bytes; } @@ -1559,41 +1568,29 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public int hashCode() { - int hash = 4242; - int capacity = capacity(); - for (int i = 0; i < capacity; i++) { - hash = 31 * hash + getByte(i); - } - return hash; + return ByteBufUtil.hashCode(this); } @Override public boolean equals(Object obj) { if (obj instanceof ByteBufConvertible) { ByteBuf other = ((ByteBufConvertible) obj).asByteBuf(); - boolean equal = true; - int capacity = capacity(); - if (other.capacity() != capacity) { - return false; - } - for (int i = 0; i < capacity; i++) { - equal &= getByte(i) == other.getByte(i); - } - return equal; + return this == other || ByteBufUtil.equals(this, other); } return false; } @Override public int compareTo(ByteBuf buffer) { - var cap = Math.min(capacity(), buffer.capacity()); - for (int i = 0; i < cap; i++) { - int cmp = Byte.compare(getByte(i), buffer.getByte(i)); - if (cmp != 0) { - return cmp; - } + ByteOrder orderThis = order(); + ByteOrder orderThat = buffer.order(); + try { + // Little-ending implementation of the compare seems to be broken. + return ByteBufUtil.compare(order(ByteOrder.BIG_ENDIAN), buffer.order(ByteOrder.BIG_ENDIAN)); + } finally { + order(orderThis); + buffer.order(orderThat); } - return Integer.compare(capacity(), buffer.capacity()); } @Override diff --git a/src/test/java/io/netty/buffer/api/adaptor/ByteBufAdaptorTest.java b/src/test/java/io/netty/buffer/api/adaptor/ByteBufAdaptorTest.java index 48a753c..16d994e 100644 --- a/src/test/java/io/netty/buffer/api/adaptor/ByteBufAdaptorTest.java +++ b/src/test/java/io/netty/buffer/api/adaptor/ByteBufAdaptorTest.java @@ -39,33 +39,225 @@ public class ByteBufAdaptorTest extends AbstractByteBufTest { return alloc.buffer(capacity, capacity); } - @Ignore("new buffers not thread-safe like this") + @Ignore("New buffers not thread-safe like this.") @Override public void testSliceReadGatheringByteChannelMultipleThreads() throws Exception { } - @Ignore("new buffers not thread-safe like this") + @Ignore("New buffers not thread-safe like this.") @Override public void testDuplicateReadGatheringByteChannelMultipleThreads() throws Exception { } - @Ignore("new buffers not thread-safe like this") + @Ignore("New buffers not thread-safe like this.") @Override public void testSliceReadOutputStreamMultipleThreads() throws Exception { } - @Ignore("new buffers not thread-safe like this") + @Ignore("New buffers not thread-safe like this.") @Override public void testDuplicateReadOutputStreamMultipleThreads() throws Exception { } - @Ignore("new buffers not thread-safe like this") + @Ignore("New buffers not thread-safe like this.") @Override public void testSliceBytesInArrayMultipleThreads() throws Exception { } - @Ignore("new buffers not thread-safe like this") + @Ignore("New buffers not thread-safe like this.") @Override public void testDuplicateBytesInArrayMultipleThreads() throws Exception { } + + @Ignore("This test codifies that asking to reading 0 bytes from an empty but unclosed stream should return -1, " + + "which is just weird.") + @Override + public void testStreamTransfer1() throws Exception { + } + + @Ignore("Relies on capacity and max capacity being separate things.") + @Override + public void testCapacityIncrease() { + } + + @Ignore("Decreasing capacity not supported in new API.") + @Override + public void testCapacityDecrease() { + } + + @Ignore("Decreasing capacity not supported in new API.") + @Override + public void testCapacityNegative() { + throw new IllegalArgumentException(); // Can't ignore tests annotated with throws expectation? + } + + @Ignore("Decreasing capacity not supported in new API.") + @Override + public void testCapacityEnforceMaxCapacity() { + throw new IllegalArgumentException(); // Can't ignore tests annotated with throws expectation? + } + + @Ignore("Decreasing capacity not supported in new API.") + @Override + public void testMaxFastWritableBytes() { + } + + @Ignore("Impossible to expose entire memory as a ByteBuffer using new API.") + @Override + public void testNioBufferExposeOnlyRegion() { + } + + @Ignore("Impossible to expose entire memory as a ByteBuffer using new API.") + @Override + public void testToByteBuffer2() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedDuplicateUnreleasable3() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedDuplicateUnreleasable4() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedDuplicateAndRetainedSliceContentIsExpected() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testMultipleRetainedSliceReleaseOriginal2() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testMultipleRetainedSliceReleaseOriginal3() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testMultipleRetainedSliceReleaseOriginal4() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testReadRetainedSliceUnreleasable3() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testReadRetainedSliceUnreleasable4() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedSliceUnreleasable3() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedSliceUnreleasable4() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedSliceReleaseOriginal2() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedSliceReleaseOriginal3() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedSliceReleaseOriginal4() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testMultipleRetainedDuplicateReleaseOriginal2() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testMultipleRetainedDuplicateReleaseOriginal3() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testMultipleRetainedDuplicateReleaseOriginal4() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedDuplicateReleaseOriginal2() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedDuplicateReleaseOriginal3() { + } + + @Ignore("This assumes a single reference count for the memory, but all buffers (views of memory) have " + + "independent reference counts now. Also, this plays tricks with reference that we cannot support.") + @Override + public void testRetainedDuplicateReleaseOriginal4() { + } + + @Ignore("No longer allowed to allocate 0 sized buffers, except for composite buffers with no components.") + @Override + public void testLittleEndianWithExpand() { + } + + @Ignore("Test seems to inherently have double-free bug?") + @Override + public void testRetainedSliceAfterReleaseRetainedSliceDuplicate() { + } + + @Ignore("Test seems to inherently have double-free bug?") + @Override + public void testRetainedSliceAfterReleaseRetainedDuplicateSlice() { + } + + @Ignore("Test seems to inherently have double-free bug?") + @Override + public void testSliceAfterReleaseRetainedSliceDuplicate() { + } + + @Ignore("Test seems to inherently have double-free bug?") + @Override + public void testDuplicateAfterReleaseRetainedSliceDuplicate() { + } + + @Ignore("Test seems to inherently have double-free bug?") + @Override + public void testDuplicateAfterReleaseRetainedDuplicateSlice() { + } + + @Ignore("Test seems to inherently have double-free bug?") + @Override + public void testSliceAfterReleaseRetainedDuplicateSlice() { + } }