[#980] Automatically trigger a read operation if isAutoRead() == false but we only had a partial decode
This commit is contained in:
parent
3843cfd702
commit
291293a6dc
@ -16,6 +16,7 @@
|
||||
package io.netty.handler.codec;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelConfig;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelHandlerUtil;
|
||||
import io.netty.channel.ChannelInboundByteHandler;
|
||||
@ -42,6 +43,7 @@ public abstract class ByteToMessageDecoder
|
||||
extends ChannelInboundHandlerAdapter implements ChannelInboundByteHandler {
|
||||
|
||||
private volatile boolean singleDecode;
|
||||
private boolean decodeWasNull;
|
||||
|
||||
/**
|
||||
* If set then only one message is decoded on each {@link #inboundBufferUpdated(ChannelHandlerContext)} call.
|
||||
@ -62,7 +64,6 @@ public abstract class ByteToMessageDecoder
|
||||
public boolean isSingleDecode() {
|
||||
return singleDecode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||
return ctx.alloc().buffer();
|
||||
@ -78,6 +79,17 @@ public abstract class ByteToMessageDecoder
|
||||
callDecode(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelReadSuspended(ChannelHandlerContext ctx) throws Exception {
|
||||
if (decodeWasNull) {
|
||||
decodeWasNull = false;
|
||||
if (!ctx.channel().config().isAutoRead()) {
|
||||
ctx.read();
|
||||
}
|
||||
}
|
||||
super.channelReadSuspended(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
ByteBuf in = ctx.inboundByteBuffer();
|
||||
@ -101,6 +113,8 @@ public abstract class ByteToMessageDecoder
|
||||
}
|
||||
|
||||
protected void callDecode(ChannelHandlerContext ctx) {
|
||||
boolean wasNull = false;
|
||||
|
||||
ByteBuf in = ctx.inboundByteBuffer();
|
||||
|
||||
boolean decoded = false;
|
||||
@ -109,12 +123,14 @@ public abstract class ByteToMessageDecoder
|
||||
int oldInputLength = in.readableBytes();
|
||||
Object o = decode(ctx, in);
|
||||
if (o == null) {
|
||||
wasNull = true;
|
||||
if (oldInputLength == in.readableBytes()) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
wasNull = false;
|
||||
if (oldInputLength == in.readableBytes()) {
|
||||
throw new IllegalStateException(
|
||||
"decode() did not read anything but decoded a message.");
|
||||
@ -143,7 +159,12 @@ public abstract class ByteToMessageDecoder
|
||||
}
|
||||
|
||||
if (decoded) {
|
||||
decodeWasNull = false;
|
||||
ctx.fireInboundBufferUpdated();
|
||||
} else {
|
||||
if (wasNull) {
|
||||
decodeWasNull = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,6 +272,7 @@ public abstract class ReplayingDecoder<S> extends ByteToMessageDecoder {
|
||||
private ReplayingDecoderBuffer replayable;
|
||||
private S state;
|
||||
private int checkpoint = -1;
|
||||
private boolean decodeWasNull;
|
||||
|
||||
/**
|
||||
* Creates a new instance with no initial state (i.e: {@code null}).
|
||||
@ -385,6 +386,8 @@ public abstract class ReplayingDecoder<S> extends ByteToMessageDecoder {
|
||||
|
||||
@Override
|
||||
protected void callDecode(ChannelHandlerContext ctx) {
|
||||
boolean wasNull = false;
|
||||
|
||||
ByteBuf in = cumulation;
|
||||
boolean decoded = false;
|
||||
while (in.readable()) {
|
||||
@ -417,10 +420,13 @@ public abstract class ReplayingDecoder<S> extends ByteToMessageDecoder {
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
wasNull = true;
|
||||
|
||||
// Seems like more data is required.
|
||||
// Let us wait for the next notification.
|
||||
break;
|
||||
}
|
||||
wasNull = false;
|
||||
|
||||
if (oldReaderIndex == in.readerIndex() && oldState == state) {
|
||||
throw new IllegalStateException(
|
||||
@ -451,7 +457,25 @@ public abstract class ReplayingDecoder<S> extends ByteToMessageDecoder {
|
||||
}
|
||||
|
||||
if (decoded) {
|
||||
decodeWasNull = false;
|
||||
ctx.fireInboundBufferUpdated();
|
||||
} else {
|
||||
if (wasNull) {
|
||||
decodeWasNull = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelReadSuspended(ChannelHandlerContext ctx) throws Exception {
|
||||
if (decodeWasNull) {
|
||||
decodeWasNull = false;
|
||||
if (!ctx.channel().config().isAutoRead()) {
|
||||
ctx.read();
|
||||
}
|
||||
}
|
||||
|
||||
super.channelReadSuspended(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user