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);
}
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);
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) {
buf = buf.order(byteOrder);
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;
}