FixedCompositeByteBuf should allow to access memoryAddress / array when wrap a single buffer.

Motivation:

We should allow to access the memoryAddress / array of the FixedCompositeByteBuf when it only wraps a single ByteBuf. We do the same for CompositeByteBuf.

Modifications:

- Check how many buffers FixedCompositeByteBuf wraps and depending on it delegate the access to the memoryAddress / array
- Add unit tests.

Result:

Fixes [#7752].
This commit is contained in:
Norman Maurer 2018-03-10 00:46:45 -08:00 committed by Norman Maurer
parent 6eb9674bf5
commit bd772d127e
2 changed files with 113 additions and 5 deletions

View File

@ -612,27 +612,62 @@ final class FixedCompositeByteBuf extends AbstractReferenceCountedByteBuf {
@Override
public boolean hasArray() {
return false;
switch (buffers.length) {
case 0:
return true;
case 1:
return buffer(0).hasArray();
default:
return false;
}
}
@Override
public byte[] array() {
throw new UnsupportedOperationException();
switch (buffers.length) {
case 0:
return EmptyArrays.EMPTY_BYTES;
case 1:
return buffer(0).array();
default:
throw new UnsupportedOperationException();
}
}
@Override
public int arrayOffset() {
throw new UnsupportedOperationException();
switch (buffers.length) {
case 0:
return 0;
case 1:
return buffer(0).arrayOffset();
default:
throw new UnsupportedOperationException();
}
}
@Override
public boolean hasMemoryAddress() {
return false;
switch (buffers.length) {
case 0:
return Unpooled.EMPTY_BUFFER.hasMemoryAddress();
case 1:
return buffer(0).hasMemoryAddress();
default:
return false;
}
}
@Override
public long memoryAddress() {
throw new UnsupportedOperationException();
switch (buffers.length) {
case 0:
return Unpooled.EMPTY_BUFFER.memoryAddress();
case 1:
return buffer(0).memoryAddress();
default:
throw new UnsupportedOperationException();
}
}
@Override

View File

@ -16,6 +16,7 @@
package io.netty.buffer;
import org.junit.Assume;
import org.junit.Test;
import java.io.ByteArrayInputStream;
@ -377,4 +378,76 @@ public class FixedCompositeByteBufTest {
ByteBuf buf = newBuffer(new ByteBuf[0]);
buf.release();
}
@Test
public void testHasMemoryAddressWithSingleBuffer() {
ByteBuf buf1 = directBuffer(10);
if (!buf1.hasMemoryAddress()) {
buf1.release();
return;
}
ByteBuf buf = newBuffer(buf1);
assertTrue(buf.hasMemoryAddress());
assertEquals(buf1.memoryAddress(), buf.memoryAddress());
buf.release();
}
@Test
public void testHasMemoryAddressWhenEmpty() {
Assume.assumeTrue(EMPTY_BUFFER.hasMemoryAddress());
ByteBuf buf = newBuffer(new ByteBuf[0]);
assertTrue(buf.hasMemoryAddress());
assertEquals(EMPTY_BUFFER.memoryAddress(), buf.memoryAddress());
buf.release();
}
@Test(expected = UnsupportedOperationException.class)
public void testHasNoMemoryAddressWhenMultipleBuffers() {
ByteBuf buf1 = directBuffer(10);
if (!buf1.hasMemoryAddress()) {
buf1.release();
return;
}
ByteBuf buf2 = directBuffer(10);
ByteBuf buf = newBuffer(buf1, buf2);
assertFalse(buf.hasMemoryAddress());
try {
buf.memoryAddress();
fail();
} finally {
buf.release();
}
}
@Test
public void testHasArrayWithSingleBuffer() {
ByteBuf buf1 = buffer(10);
ByteBuf buf = newBuffer(buf1);
assertTrue(buf.hasArray());
assertArrayEquals(buf1.array(), buf.array());
buf.release();
}
@Test
public void testHasArrayWhenEmpty() {
ByteBuf buf = newBuffer(new ByteBuf[0]);
assertTrue(buf.hasArray());
assertArrayEquals(EMPTY_BUFFER.array(), buf.array());
buf.release();
}
@Test(expected = UnsupportedOperationException.class)
public void testHasNoArrayWhenMultipleBuffers() {
ByteBuf buf1 = buffer(10);
ByteBuf buf2 = buffer(10);
ByteBuf buf = newBuffer(buf1, buf2);
assertFalse(buf.hasArray());
try {
buf.array();
fail();
} finally {
buf.release();
}
}
}