package com.lefu.remote.netty; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.lefu.remote.netty.enums.RequestHeadLenType; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; /** * 针对基础报文格式的解析类 * * <pre> * 2/4 byte(len) + len bytes * </pre> * * @author jiang.li * */ public class DefaultIByteArrayDecoderHandler extends ByteToMessageDecoder { public static final int DEFAULT_DATA_MAX_LENGTH = 2048; private final Logger log = LoggerFactory.getLogger(getClass()); private int maxLength = DEFAULT_DATA_MAX_LENGTH; private RequestHeadLenType headLenType = RequestHeadLenType.ShortLen; public DefaultIByteArrayDecoderHandler() { } public DefaultIByteArrayDecoderHandler(int maxLength, RequestHeadLenType headLenType) { this.maxLength = maxLength; this.headLenType = headLenType; } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { // Will called when connection closed and byte will be zero. if (in.readableBytes() < headLenType.getLen()) { return; } in.markReaderIndex(); int len = 0; switch (headLenType) { case ByteLen: len = in.readByte(); break; case ShortLen: len = in.readShort(); break; case IntLen: len = in.readInt(); break; default: throw new RuntimeException("Unkown RequestHeadLenType " + headLenType.toString()); } if (len > maxLength) { in.clear(); throw new RuntimeException("Data too large " + len); } if (in.readableBytes() < len) { in.resetReaderIndex(); return; } in.resetReaderIndex(); byte[] content = new byte[len + headLenType.getLen()]; in.readBytes(content); out.add(content); if (log.isDebugEnabled()) { log.debug("Decode data with size {}", len); } } /** * 设置最大的报文长度 * * @param maxLength */ public void setMaxLength(int maxLength) { this.maxLength = maxLength; } public void setHeadLenType(RequestHeadLenType headLenType) { this.headLenType = headLenType; } }