Allow a user to define his/her own length field decoder

- Fixes #1960
This commit is contained in:
Trustin Lee 2013-11-02 21:58:08 +09:00
parent 9d611a182f
commit f767abe5b0

View File

@ -320,14 +320,6 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
initialBytesToStrip); 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) { if (lengthFieldOffset > maxFrameLength - lengthFieldLength) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"maxFrameLength (" + maxFrameLength + ") " + "maxFrameLength (" + maxFrameLength + ") " +
@ -378,7 +370,7 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
} }
int actualLengthFieldOffset = in.readerIndex() + lengthFieldOffset; int actualLengthFieldOffset = in.readerIndex() + lengthFieldOffset;
long frameLength = getFrameLength(in, actualLengthFieldOffset); long frameLength = getUnadjustedFrameLength(in, actualLengthFieldOffset, lengthFieldLength);
if (frameLength < 0) { if (frameLength < 0) {
in.skipBytes(lengthFieldEndOffset); in.skipBytes(lengthFieldEndOffset);
@ -434,27 +426,36 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
return frame; 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) {
buf = buf.order(byteOrder);
long frameLength; long frameLength;
switch (lengthFieldLength) { switch (length) {
case 1: case 1:
frameLength = in.getUnsignedByte(actualLengthFieldOffset); frameLength = buf.getUnsignedByte(offset);
break; break;
case 2: case 2:
frameLength = in.getUnsignedShort(actualLengthFieldOffset); frameLength = buf.getUnsignedShort(offset);
break; break;
case 3: case 3:
frameLength = in.getUnsignedMedium(actualLengthFieldOffset); frameLength = buf.getUnsignedMedium(offset);
break; break;
case 4: case 4:
frameLength = in.getUnsignedInt(actualLengthFieldOffset); frameLength = buf.getUnsignedInt(offset);
break; break;
case 8: case 8:
frameLength = in.getLong(actualLengthFieldOffset); frameLength = buf.getLong(offset);
break; break;
default: default:
throw new Error("should not reach here"); throw new DecoderException(
"unsupported lengthFieldLength: " + lengthFieldLength + " (expected: 1, 2, 3, 4, or 8)");
} }
return frameLength; return frameLength;
} }