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