/** * (C) 2007-2010 Taobao Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */ package com.taobao.tair.comm; import java.io.IOException; import java.net.InetSocketAddress; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.mina.common.ByteBuffer; import org.apache.mina.common.IoSession; import org.apache.mina.filter.codec.CumulativeProtocolDecoder; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import com.taobao.tair.etc.TairConstant; import com.taobao.tair.etc.TairUtil; import com.taobao.tair.packet.BasePacket; import com.taobao.tair.packet.PacketStreamer; public class TairProtocolDecoder extends CumulativeProtocolDecoder { private static final Log LOGGER = LogFactory.getLog(TairProtocolDecoder.class); private static final boolean isDebugEnabled=LOGGER.isDebugEnabled(); private static final int PROTOCOL_HEADER_LENGTH = 16; private PacketStreamer pstreamer; public TairProtocolDecoder(PacketStreamer pstreamer) { this.pstreamer = pstreamer; } @Override protected boolean doDecode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { final int origonPos = in.position(); final int packetLength = in.remaining(); if(packetLength<PROTOCOL_HEADER_LENGTH){ in.position(origonPos); return false; } int flag = in.getInt(); int chid = in.getInt(); int pcode = in.getInt(); int len = in.getInt(); if (flag != TairConstant.TAIR_PACKET_FLAG) throw new IOException("flag error, except: " + TairConstant.TAIR_PACKET_FLAG + ", but get " + flag); if (in.remaining() < len) { in.position(origonPos); return false; } if(isDebugEnabled){ final String remoteIP = ((InetSocketAddress) session.getRemoteAddress()).toString(); StringBuilder receiveTimeInfo = new StringBuilder(); receiveTimeInfo.append("receive response from [").append(remoteIP).append("],time is: "); receiveTimeInfo.append(System.currentTimeMillis()); receiveTimeInfo.append(", channel id: ").append(chid); LOGGER.debug(receiveTimeInfo.toString()); } byte[] data = new byte[len]; in.get(data); if (isDebugEnabled) LOGGER.debug(TairUtil.toHex(data)); BasePacket returnPacket = pstreamer.decodePacket(pcode, data); TairResponse response=new TairResponse(); response.setRequestId(chid); response.setResponse(returnPacket); out.write(response); return true; } }