From 4f5c52572b480b3d4c9fea904f3a83dbe163a3e5 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Sat, 2 Nov 2013 21:58:08 +0900 Subject: [PATCH] Allow a user to define his/her own length field decoder - Fixes #1960 --- .../codec/LengthFieldBasedFrameDecoder.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java index 714cb142be..2aa95cba71 100644 --- a/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java @@ -320,14 +320,6 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder { initialBytesToStrip); } - if (lengthFieldLength != 1 && lengthFieldLength != 2 && - lengthFieldLength != 3 && lengthFieldLength != 4 && - lengthFieldLength != 8) { - throw new IllegalArgumentException( - "lengthFieldLength must be either 1, 2, 3, 4, or 8: " + - lengthFieldLength); - } - if (lengthFieldOffset > maxFrameLength - lengthFieldLength) { throw new IllegalArgumentException( "maxFrameLength (" + maxFrameLength + ") " + @@ -378,7 +370,7 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder { } int actualLengthFieldOffset = in.readerIndex() + lengthFieldOffset; - long frameLength = getFrameLength(in, actualLengthFieldOffset); + long frameLength = getUnadjustedFrameLength(in, actualLengthFieldOffset, lengthFieldLength, byteOrder); if (frameLength < 0) { in.skipBytes(lengthFieldEndOffset); @@ -434,27 +426,36 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder { return frame; } - private long getFrameLength(ByteBuf in, int actualLengthFieldOffset) { - in = in.order(byteOrder); + /** + * Decodes the specified region of the buffer into an unadjusted frame length. The default implementation is + * capable of decoding the specified region into an unsigned 8/16/24/32/64 bit integer. Override this method to + * decode the length field encoded differently. Note that this method must not modify the state of the specified + * buffer (e.g. {@code readerIndex}, {@code writerIndex}, and the content of the buffer.) + * + * @throws DecoderException if failed to decode the specified region + */ + protected long getUnadjustedFrameLength(ByteBuf buf, int offset, int length, ByteOrder order) { + buf = buf.order(order); long frameLength; - switch (lengthFieldLength) { + switch (length) { case 1: - frameLength = in.getUnsignedByte(actualLengthFieldOffset); + frameLength = buf.getUnsignedByte(offset); break; case 2: - frameLength = in.getUnsignedShort(actualLengthFieldOffset); + frameLength = buf.getUnsignedShort(offset); break; case 3: - frameLength = in.getUnsignedMedium(actualLengthFieldOffset); + frameLength = buf.getUnsignedMedium(offset); break; case 4: - frameLength = in.getUnsignedInt(actualLengthFieldOffset); + frameLength = buf.getUnsignedInt(offset); break; case 8: - frameLength = in.getLong(actualLengthFieldOffset); + frameLength = buf.getLong(offset); break; default: - throw new Error("should not reach here"); + throw new DecoderException( + "unsupported lengthFieldLength: " + lengthFieldLength + " (expected: 1, 2, 3, 4, or 8)"); } return frameLength; }