ReplayDecoder and LITTLE_ENDIANness
UweH
uwe.hehn.external at eads.com
Mon Apr 19 11:05:22 EDT 2010
I have found a way to make it work. What I have is a PipelineFactory like
this:
public class TracingPipelineFactory implements ChannelPipelineFactory {
...
@Override
public ChannelPipeline getPipeline() throws Exception {
final ChannelPipeline pipeline = pipeline();
pipeline.addLast("byteorder_decoder", new ByteOrderDecoder());
pipeline.addLast("tracing_decoder", new TracingDecoder());
// pipeline.addLast("frame_decoder", new TracingFrameDecoder());
pipeline.addLast("handler", new TracingHandler());
return pipeline;
}
}
The ByteOrderDecoder decodes only the first byte (which is
endianess-independent), and switches the BufferFactory to the correct
endianess, so that the next decoder (TracingDecoder) gets the buffer set to
proper endianess already:
public class ByteOrderDecoder extends FrameDecoder {
@Override
protected Object decode(final ChannelHandlerContext ctx, final Channel
channel, final ChannelBuffer buffer)
throws Exception {
if (buffer.readableBytes() < 1) {
return null;
}
final short order = buffer.getUnsignedByte(buffer.readerIndex());
if (order != 1 && order != 2) {
buffer.resetReaderIndex();
throw new CorruptedFrameException("Invalid byte order: " + order);
}
final ByteOrder byteOrder = getByteOrder(order);
// switch byte order of buffer factory, so that next decoders get proper
buffers
if (channel.getConfig().getBufferFactory().getDefaultOrder() != byteOrder)
{
channel.getConfig().setBufferFactory(new
HeapChannelBufferFactory(byteOrder));
}
ctx.getPipeline().remove(this); // dont check byte order again, since it
wont change
// hand off remaining data to signal decoder
return buffer.readBytes(buffer.readableBytes());
}
Next in line is the TracingDecoder, which does the actual decoding, creates
a list of business objects and hands them to the TracingHandler.
public class TracingDecoder extends ReplayingDecoder<DecoderState> {
private final List<TracingSignal> tracingSignals = new
LinkedList<TracingSignal>();
public TracingDecoder(final TracingManager manager) {
super(DecoderState.READ_BYTEORDER, true); // initial state
this.manager = manager;
}
@Override
protected Object decode(final ChannelHandlerContext ctx, final Channel
channel, final ChannelBuffer buffer,
final DecoderState state) throws Exception {
System.out.println("converted buffer class: " + buffer.getClass());
System.out.println("converted buffer byte order: " + buffer.order());
switch (state) {
case READ_BYTEORDER:
tracingSignals.clear();
buffer.readUnsignedByte(); // read byte order
......
return Collections.unmodifiableList(tracingSignals);
default:
throw new ServiceException("Error decoding trace!");
}
}
While this setup works, strange enough, if I replace the TracingDecoder with
TracingFrameDecoder (which is derived from FrameDecoder), it stops working.
The FrameDecoder-version doesnt get a proper-endianess buffer, but a
standard BIG_ENDIAN one.
Any idea why this is?
--
View this message in context: http://n2.nabble.com/ReplayDecoder-and-LITTLE-ENDIANness-tp4906895p4925755.html
Sent from the Netty User Group mailing list archive at Nabble.com.
More information about the netty-users
mailing list