diff --git a/codec/src/main/java/io/netty/handler/codec/LengthFieldPrepender.java b/codec/src/main/java/io/netty/handler/codec/LengthFieldPrepender.java index dd8e0e834c..0bfd23759f 100644 --- a/codec/src/main/java/io/netty/handler/codec/LengthFieldPrepender.java +++ b/codec/src/main/java/io/netty/handler/codec/LengthFieldPrepender.java @@ -19,6 +19,8 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; +import java.util.List; + /** * An encoder that prepends the length of the message. The length value is @@ -47,7 +49,7 @@ import io.netty.channel.ChannelHandlerContext; * */ @Sharable -public class LengthFieldPrepender extends MessageToByteEncoder { +public class LengthFieldPrepender extends MessageToMessageEncoder { private final int lengthFieldLength; private final boolean lengthIncludesLengthFieldLength; @@ -128,7 +130,7 @@ public class LengthFieldPrepender extends MessageToByteEncoder { } @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception { + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { int length = msg.readableBytes() + lengthAdjustment; if (lengthIncludesLengthFieldLength) { length += lengthFieldLength; @@ -145,32 +147,31 @@ public class LengthFieldPrepender extends MessageToByteEncoder { throw new IllegalArgumentException( "length does not fit into a byte: " + length); } - out.writeByte((byte) length); + out.add(ctx.alloc().buffer(1).writeByte((byte) length)); break; case 2: if (length >= 65536) { throw new IllegalArgumentException( "length does not fit into a short integer: " + length); } - out.writeShort((short) length); + out.add(ctx.alloc().buffer(2).writeShort((short) length)); break; case 3: if (length >= 16777216) { throw new IllegalArgumentException( "length does not fit into a medium integer: " + length); } - out.writeMedium(length); + out.add(ctx.alloc().buffer(3).writeMedium(length)); break; case 4: - out.writeInt(length); + out.add(ctx.alloc().buffer(4).writeInt(length)); break; case 8: - out.writeLong(length); + out.add(ctx.alloc().buffer(8).writeLong(length)); break; default: throw new Error("should not reach here"); } - - out.writeBytes(msg, msg.readerIndex(), msg.readableBytes()); + out.add(msg.retain()); } } diff --git a/codec/src/test/java/io/netty/handler/codec/frame/LengthFieldPrependerTest.java b/codec/src/test/java/io/netty/handler/codec/frame/LengthFieldPrependerTest.java index c02affe905..92984cf917 100644 --- a/codec/src/test/java/io/netty/handler/codec/frame/LengthFieldPrependerTest.java +++ b/codec/src/test/java/io/netty/handler/codec/frame/LengthFieldPrependerTest.java @@ -24,7 +24,6 @@ import org.junit.Before; import org.junit.Test; import static io.netty.buffer.Unpooled.*; -import static org.hamcrest.core.Is.*; import static org.junit.Assert.*; public class LengthFieldPrependerTest { @@ -40,8 +39,13 @@ public class LengthFieldPrependerTest { public void testPrependLength() throws Exception { final EmbeddedChannel ch = new EmbeddedChannel(new LengthFieldPrepender(4)); ch.writeOutbound(msg); - final ByteBuf buf = (ByteBuf) ch.readOutbound(); - assertThat(buf, is(wrappedBuffer(new byte[]{0, 0, 0, 1, 'A'}))); + ByteBuf buf = (ByteBuf) ch.readOutbound(); + assertEquals(4, buf.readableBytes()); + assertEquals(msg.readableBytes(), buf.readInt()); + buf.release(); + + buf = (ByteBuf) ch.readOutbound(); + assertSame(buf, msg); buf.release(); } @@ -49,8 +53,13 @@ public class LengthFieldPrependerTest { public void testPrependLengthIncludesLengthFieldLength() throws Exception { final EmbeddedChannel ch = new EmbeddedChannel(new LengthFieldPrepender(4, true)); ch.writeOutbound(msg); - final ByteBuf buf = (ByteBuf) ch.readOutbound(); - assertThat(buf, is(wrappedBuffer(new byte[]{0, 0, 0, 5, 'A'}))); + ByteBuf buf = (ByteBuf) ch.readOutbound(); + assertEquals(4, buf.readableBytes()); + assertEquals(5, buf.readInt()); + buf.release(); + + buf = (ByteBuf) ch.readOutbound(); + assertSame(buf, msg); buf.release(); } @@ -58,8 +67,13 @@ public class LengthFieldPrependerTest { public void testPrependAdjustedLength() throws Exception { final EmbeddedChannel ch = new EmbeddedChannel(new LengthFieldPrepender(4, -1)); ch.writeOutbound(msg); - final ByteBuf buf = (ByteBuf) ch.readOutbound(); - assertThat(buf, is(wrappedBuffer(new byte[]{0, 0, 0, 0, 'A'}))); + ByteBuf buf = (ByteBuf) ch.readOutbound(); + assertEquals(4, buf.readableBytes()); + assertEquals(msg.readableBytes() - 1, buf.readInt()); + buf.release(); + + buf = (ByteBuf) ch.readOutbound(); + assertSame(buf, msg); buf.release(); }