package org.codesharp.traffic.netty; import java.util.List; import org.codesharp.traffic.Asserter; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; public class MessageDecoder extends ByteToMessageDecoder { enum State { LEN, PAYLOAD } private MessageHandleImpl handle; private int len; private State state = State.LEN; private ByteBuf buf; public MessageDecoder(MessageHandleImpl handle) { this.handle = handle; } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { switch (this.state) { case LEN: if (!in.isReadable(MessageHandleImpl.LEN + 4)) return; this.len = this.handle.getLen(in); this.buf = ctx.alloc().buffer(MessageHandleImpl.LEN + 4 + this.len); this.read(in, this.buf, MessageHandleImpl.LEN + 4); this.state = State.PAYLOAD; break; case PAYLOAD: if (in.readableBytes() < this.len) return; this.read(in, this.buf, this.len); this.state = State.LEN; out.add(this.buf); break; default: Asserter.throwUnsupported(null); break; } } private ByteBuf read(ByteBuf src, ByteBuf dst, int length) { boolean release = true; try { src.readBytes(dst, length); release = false; return dst; } finally { if (release) { dst.release(); } } } }