Class CumulativeProtocolDecoder
java.lang.Object
org.apache.mina.filter.codec.ProtocolDecoderAdapter
org.apache.mina.filter.codec.CumulativeProtocolDecoder
- All Implemented Interfaces:
ProtocolDecoder
- Direct Known Subclasses:
DemuxingProtocolDecoder, ObjectSerializationDecoder, PrefixedStringDecoder
A
ProtocolDecoder that cumulates the content of received buffers to a
cumulative buffer to help users implement decoders.
If the received IoBuffer is only a part of a message. decoders should
cumulate received buffers to make a message complete or to postpone decoding
until more buffers arrive.
Here is an example decoder that decodes CRLF terminated lines into
Command objects:
public class CrLfTerminatedCommandLineDecoder extends CumulativeProtocolDecoder {
private Command parseCommand(IoBuffer in) {
// Convert the bytes in the specified buffer to a
// Command object.
...
}
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
// Remember the initial position.
int start = in.position();
// Now find the first CRLF in the buffer.
byte previous = 0;
while (in.hasRemaining()) {
byte current = in.get();
if (previous == '\r' && current == '\n') {
// Remember the current position and limit.
int position = in.position();
int limit = in.limit();
try {
in.position(start);
in.limit(position);
// The bytes between in.position() and in.limit()
// now contain a full CRLF terminated line.
out.write(parseCommand(in.slice()));
} finally {
// Set the position to point right after the
// detected line and set the limit to the old
// one.
in.position(position);
in.limit(limit);
}
// Decoded one line; CumulativeProtocolDecoder will
// call me again until I return false. So just
// return true until there are no more lines in the
// buffer.
return true;
}
previous = current;
}
// Could not find CRLF in the buffer. Reset the initial
// position to the one we recorded above.
in.position(start);
return false;
}
}
Please note that this decoder simply forward the call to
doDecode(IoSession, IoBuffer, ProtocolDecoderOutput) if the
underlying transport doesn't have a packet fragmentation. Whether the
transport has fragmentation or not is determined by querying
TransportMetadata.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final AttributeKeyThe buffer used to store the data in the sessionprivate booleanA flag set to true if we handle fragmentation accordingly to the TransportMetadata setting. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoiddecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) Cumulates content ofininto internal buffer and forwards decoding request to doDecode(IoSession, IoBuffer, ProtocolDecoderOutput).voidReleases the cumulative buffer used by the specifiedsession.protected abstract booleandoDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) Implement this method to consume the specified cumulative buffer and decode its content into message(s).private voidremoveSessionBuffer(IoSession session) voidsetTransportMetadataFragmentation(boolean transportMetadataFragmentation) Let the user change the way we handle fragmentation.private voidstoreRemainingInSession(IoBuffer buf, IoSession session) Methods inherited from class ProtocolDecoderAdapter
finishDecode
-
Field Details
-
BUFFER
The buffer used to store the data in the session -
transportMetadataFragmentation
private boolean transportMetadataFragmentationA flag set to true if we handle fragmentation accordingly to the TransportMetadata setting. It can be set to false if needed (UDP with fragments, for instance). the default value is 'true'
-
-
Constructor Details
-
CumulativeProtocolDecoder
protected CumulativeProtocolDecoder()Creates a new instance.
-
-
Method Details
-
decode
Cumulates content ofininto internal buffer and forwards decoding request to doDecode(IoSession, IoBuffer, ProtocolDecoderOutput).doDecode()is invoked repeatedly until it returnsfalseand the cumulative buffer is compacted after decoding ends.- Parameters:
session- The current Sessionin- the buffer to decodeout- TheProtocolDecoderOutputthat will receive the decoded message- Throws:
IllegalStateException- if yourdoDecode()returnedtruenot consuming the cumulative buffer.Exception- if the read data violated protocol specification
-
doDecode
protected abstract boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception Implement this method to consume the specified cumulative buffer and decode its content into message(s).- Parameters:
session- The current Sessionin- the cumulative bufferout- TheProtocolDecoderOutputthat will receive the decoded message- Returns:
trueif and only if there's more to decode in the buffer and you want to havedoDecodemethod invoked again. Returnfalseif remaining data is not enough to decode, then this method will be invoked again when more data is cumulated.- Throws:
Exception- if cannot decodein.
-
dispose
Releases the cumulative buffer used by the specifiedsession. Please don't forget to callsuper.dispose( session )when you override this method.- Specified by:
disposein interfaceProtocolDecoder- Overrides:
disposein classProtocolDecoderAdapter- Parameters:
session- The current Session- Throws:
Exception- if failed to dispose all resources
-
removeSessionBuffer
-
storeRemainingInSession
-
setTransportMetadataFragmentation
public void setTransportMetadataFragmentation(boolean transportMetadataFragmentation) Let the user change the way we handle fragmentation. If set tofalse, the decode() method will not check the TransportMetadata fragmentation capability- Parameters:
transportMetadataFragmentation- The flag to set.
-