Fixed issue: NETTY-165 FrameDecoder and ReplayingDecoder must call decodeLast even if there's no data in the buffer.

* Made sure decodeLast() is called even if the cumulative buffer is empty so that a decoder implementation always get notified when the connection is closed
* Updated Javadoc to explain that the buffer can be empty
This commit is contained in:
Trustin Lee 2009-06-04 06:00:26 +00:00
parent 553c4d2df8
commit c4bfb45183
2 changed files with 32 additions and 18 deletions

View File

@ -211,7 +211,10 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler {
*
* @param ctx the context of this handler
* @param channel the current channel
* @param buffer the cumulative buffer of received packets so far
* @param buffer the cumulative buffer of received packets so far.
* Note that the buffer might be empty, which means you
* should not make an assumption that the buffer contains
* at least one byte in your decoder implementation.
*
* @return the decoded frame if a full frame was received and decoded.
* {@code null} if there's not enough data in the buffer to decode a frame.
@ -225,7 +228,10 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler {
*
* @param ctx the context of this handler
* @param channel the current channel
* @param buffer the cumulative buffer of received packets so far
* @param buffer the cumulative buffer of received packets so far.
* Note that the buffer might be empty, which means you
* should not make an assumption that the buffer contains
* at least one byte in your decoder implementation.
*
* @return the decoded frame if a full frame was received and decoded.
* {@code null} if there's not enough data in the buffer to decode a frame.
@ -292,13 +298,14 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler {
if (cumulation.readable()) {
// Make sure all frames are read before notifying a closed channel.
callDecode(ctx, ctx.getChannel(), cumulation, null);
if (cumulation.readable()) {
// and send the remainders too if necessary.
Object partialFrame = decodeLast(ctx, ctx.getChannel(), cumulation);
if (partialFrame != null) {
fireMessageReceived(ctx, null, partialFrame);
}
}
}
// Call decodeLast() finally. Please note that decodeLast() is
// called even if there's nothing more to read from the buffer to
// notify a user that the connection was closed explicitly.
Object partialFrame = decodeLast(ctx, ctx.getChannel(), cumulation);
if (partialFrame != null) {
fireMessageReceived(ctx, null, partialFrame);
}
} finally {
ctx.sendUpstream(e);

View File

@ -326,7 +326,10 @@ public abstract class ReplayingDecoder<T extends Enum<T>>
*
* @param ctx the context of this handler
* @param channel the current channel
* @param buffer the cumulative buffer of received packets so far\
* @param buffer the cumulative buffer of received packets so far.
* Note that the buffer might be empty, which means you
* should not make an assumption that the buffer contains
* at least one byte in your decoder implementation.
* @param state the current decoder state ({@code null} if unused)
*
* @return the decoded frame
@ -340,7 +343,10 @@ public abstract class ReplayingDecoder<T extends Enum<T>>
*
* @param ctx the context of this handler
* @param channel the current channel
* @param buffer the cumulative buffer of received packets so far
* @param buffer the cumulative buffer of received packets so far.
* Note that the buffer might be empty, which means you
* should not make an assumption that the buffer contains
* at least one byte in your decoder implementation.
* @param state the current decoder state ({@code null} if unused)
*
* @return the decoded frame
@ -460,13 +466,14 @@ public abstract class ReplayingDecoder<T extends Enum<T>>
if (cumulation.readable()) {
// Make sure all data was read before notifying a closed channel.
callDecode(ctx, e.getChannel(), cumulation, null);
if (cumulation.readable()) {
// and send the remainders too if necessary.
Object partiallyDecoded = decodeLast(ctx, e.getChannel(), replayable, state);
if (partiallyDecoded != null) {
unfoldAndfireMessageReceived(ctx, partiallyDecoded, null);
}
}
}
// Call decodeLast() finally. Please note that decodeLast() is
// called even if there's nothing more to read from the buffer to
// notify a user that the connection was closed explicitly.
Object partiallyDecoded = decodeLast(ctx, e.getChannel(), replayable, state);
if (partiallyDecoded != null) {
unfoldAndfireMessageReceived(ctx, partiallyDecoded, null);
}
} catch (ReplayError replay) {
// Ignore