diff --git a/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java b/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java index 254d40480a..daa65431f4 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractByteBuf.java @@ -1263,7 +1263,44 @@ public abstract class AbstractByteBuf extends ByteBuf { @Override public int indexOf(int fromIndex, int toIndex, byte value) { - return ByteBufUtil.indexOf(this, fromIndex, toIndex, value); + if (fromIndex <= toIndex) { + return firstIndexOf(fromIndex, toIndex, value); + } else { + return lastIndexOf(fromIndex, toIndex, value); + } + } + + private int firstIndexOf(int fromIndex, int toIndex, byte value) { + fromIndex = Math.max(fromIndex, 0); + if (fromIndex >= toIndex || capacity() == 0) { + return -1; + } + checkIndex(fromIndex, toIndex - fromIndex); + + for (int i = fromIndex; i < toIndex; i ++) { + if (_getByte(i) == value) { + return i; + } + } + + return -1; + } + + private int lastIndexOf(int fromIndex, int toIndex, byte value) { + fromIndex = Math.min(fromIndex, capacity()); + if (fromIndex < 0 || capacity() == 0) { + return -1; + } + + checkIndex(toIndex, fromIndex - toIndex); + + for (int i = fromIndex - 1; i >= toIndex; i --) { + if (_getByte(i) == value) { + return i; + } + } + + return -1; } @Override diff --git a/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java b/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java index 1642f9dc20..a3a1347f08 100644 --- a/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java +++ b/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java @@ -2125,6 +2125,9 @@ public abstract class AbstractByteBufTest { @Test public void testIndexOf() { buffer.clear(); + // Ensure the buffer is completely zero'ed. + buffer.setZero(0, buffer.capacity()); + buffer.writeByte((byte) 1); buffer.writeByte((byte) 2); buffer.writeByte((byte) 3); @@ -2135,6 +2138,38 @@ public abstract class AbstractByteBufTest { assertEquals(-1, buffer.indexOf(4, 1, (byte) 1)); assertEquals(1, buffer.indexOf(1, 4, (byte) 2)); assertEquals(3, buffer.indexOf(4, 1, (byte) 2)); + + try { + buffer.indexOf(0, buffer.capacity() + 1, (byte) 0); + fail(); + } catch (IndexOutOfBoundsException expected) { + // expected + } + + try { + buffer.indexOf(buffer.capacity(), -1, (byte) 0); + fail(); + } catch (IndexOutOfBoundsException expected) { + // expected + } + + assertEquals(4, buffer.indexOf(buffer.capacity() + 1, 0, (byte) 1)); + assertEquals(0, buffer.indexOf(-1, buffer.capacity(), (byte) 1)); + } + + @Test + public void testIndexOfReleaseBuffer() { + ByteBuf buffer = releasedBuffer(); + if (buffer.capacity() != 0) { + try { + buffer.indexOf(0, 1, (byte) 1); + fail(); + } catch (IllegalReferenceCountException expected) { + // expected + } + } else { + assertEquals(-1, buffer.indexOf(0, 1, (byte) 1)); + } } @Test @@ -2570,7 +2605,6 @@ public abstract class AbstractByteBufTest { private ByteBuf releasedBuffer() { ByteBuf buffer = newBuffer(8); - // Clear the buffer so we are sure the reader and writer indices are 0. // This is important as we may return a slice from newBuffer(...). buffer.clear();