Fix FixedCompositeByteBuf handling when copying to direct buffers and streams

Motivation:

FixedCompositeByteBuf does not properly implement a number of methods for
copying its content to direct buffers and output streams

Modifications:

Replace improper use of capacity() with readableBytes() when computing offesets during writes

Result:

Copying works correctly
This commit is contained in:
Louis Ryan 2015-06-26 14:43:16 -07:00 committed by Norman Maurer
parent b39223e295
commit ba6319eb6c
2 changed files with 66 additions and 4 deletions

View File

@ -343,7 +343,7 @@ final class FixedCompositeByteBuf extends AbstractReferenceCountedByteBuf {
int adjustment = c.offset; int adjustment = c.offset;
ByteBuf s = c.buf; ByteBuf s = c.buf;
for (;;) { for (;;) {
int localLength = Math.min(length, s.capacity() - (index - adjustment)); int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
dst.limit(dst.position() + localLength); dst.limit(dst.position() + localLength);
s.getBytes(index - adjustment, dst); s.getBytes(index - adjustment, dst);
index += localLength; index += localLength;
@ -372,7 +372,7 @@ final class FixedCompositeByteBuf extends AbstractReferenceCountedByteBuf {
int adjustment = c.offset; int adjustment = c.offset;
ByteBuf s = c.buf; ByteBuf s = c.buf;
for (;;) { for (;;) {
int localLength = Math.min(length, s.capacity() - (index - adjustment)); int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
s.getBytes(index - adjustment, dst, dstIndex, localLength); s.getBytes(index - adjustment, dst, dstIndex, localLength);
index += localLength; index += localLength;
dstIndex += localLength; dstIndex += localLength;
@ -414,7 +414,7 @@ final class FixedCompositeByteBuf extends AbstractReferenceCountedByteBuf {
int adjustment = c.offset; int adjustment = c.offset;
ByteBuf s = c.buf; ByteBuf s = c.buf;
for (;;) { for (;;) {
int localLength = Math.min(length, s.capacity() - (index - adjustment)); int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
s.getBytes(index - adjustment, out, localLength); s.getBytes(index - adjustment, out, localLength);
index += localLength; index += localLength;
length -= localLength; length -= localLength;
@ -491,7 +491,7 @@ final class FixedCompositeByteBuf extends AbstractReferenceCountedByteBuf {
int adjustment = c.offset; int adjustment = c.offset;
ByteBuf s = c.buf; ByteBuf s = c.buf;
for (;;) { for (;;) {
int localLength = Math.min(length, s.capacity() - (index - adjustment)); int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
switch (s.nioBufferCount()) { switch (s.nioBufferCount()) {
case 0: case 0:
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException; import java.nio.ReadOnlyBufferException;
import java.nio.channels.ScatteringByteChannel; import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import static io.netty.buffer.Unpooled.*; import static io.netty.buffer.Unpooled.*;
import static io.netty.util.ReferenceCountUtil.*; import static io.netty.util.ReferenceCountUtil.*;
@ -252,4 +253,65 @@ public class FixedCompositeByteBufTest {
buf.release(); buf.release();
} }
@Test
public void testCopyingToOtherBuffer() {
ByteBuf buf1 = directBuffer(10);
ByteBuf buf2 = buffer(10);
ByteBuf buf3 = directBuffer(10);
buf1.writeBytes("a".getBytes(Charset.defaultCharset()));
buf2.writeBytes("b".getBytes(Charset.defaultCharset()));
buf3.writeBytes("c".getBytes(Charset.defaultCharset()));
ByteBuf composite = unmodifiableBuffer(buf1, buf2, buf3);
ByteBuf copy = directBuffer(3);
ByteBuf copy2 = buffer(3);
copy.setBytes(0, composite, 0, 3);
copy2.setBytes(0, composite, 0, 3);
copy.writerIndex(3);
copy2.writerIndex(3);
assertEquals(0, ByteBufUtil.compare(copy, composite));
assertEquals(0, ByteBufUtil.compare(copy2, composite));
assertEquals(0, ByteBufUtil.compare(copy, copy2));
copy.release();
copy2.release();
composite.release();
}
@Test
public void testCopyingToOutputStream() throws IOException {
ByteBuf buf1 = directBuffer(10);
ByteBuf buf2 = buffer(10);
ByteBuf buf3 = directBuffer(10);
buf1.writeBytes("a".getBytes(Charset.defaultCharset()));
buf2.writeBytes("b".getBytes(Charset.defaultCharset()));
buf3.writeBytes("c".getBytes(Charset.defaultCharset()));
ByteBuf composite = unmodifiableBuffer(buf1, buf2, buf3);
ByteBuf copy = directBuffer(3);
ByteBuf copy2 = buffer(3);
composite.getBytes(0, new ByteBufOutputStream(copy), 3);
composite.getBytes(0, new ByteBufOutputStream(copy2), 3);
assertEquals(0, ByteBufUtil.compare(copy, composite));
assertEquals(0, ByteBufUtil.compare(copy2, composite));
assertEquals(0, ByteBufUtil.compare(copy, copy2));
copy.release();
copy2.release();
composite.release();
}
@Test
public void testExtractNioBuffers() {
ByteBuf buf1 = directBuffer(10);
ByteBuf buf2 = buffer(10);
ByteBuf buf3 = directBuffer(10);
buf1.writeBytes("a".getBytes(Charset.defaultCharset()));
buf2.writeBytes("b".getBytes(Charset.defaultCharset()));
buf3.writeBytes("c".getBytes(Charset.defaultCharset()));
ByteBuf composite = unmodifiableBuffer(buf1, buf2, buf3);
ByteBuffer[] byteBuffers = composite.nioBuffers(0, 3);
assertEquals(3, byteBuffers.length);
assertEquals(1, byteBuffers[0].limit());
assertEquals(1, byteBuffers[1].limit());
assertEquals(1, byteBuffers[2].limit());
composite.release();
}
} }