package com.joey.codec;

import com.joey.common.Protocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.apache.log4j.Logger;

import java.util.List;

/**
 * Created by joey on 14-7-4.
 */
public class MessageDecoder extends ByteToMessageDecoder {
    private final static Logger logger = Logger.getLogger(MessageDecoder.class);

    private Protocol proto_ = null;
    private int lenToRead_ = 0;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
    {
        if (proto_ == null) {
            if (in.readableBytes() < 4) {
                return;
            }

            proto_ = new Protocol();
            proto_.len = Integer.reverseBytes(in.readInt());
            if ((proto_.len < Protocol.PROTO_MIN_LEN) || (proto_.len > Protocol.PROTO_MAX_LEN)) {
                throw new InvalidProtoException("ProtoLen Must >= 18B && <= 1M: " + proto_.len);
            }
            lenToRead_ = proto_.len - 4;
        }

        if (in.readableBytes() >= lenToRead_) {
            proto_.seq = Integer.reverseBytes(in.readInt());
            proto_.hash = Integer.reverseBytes(in.readInt());
            proto_.cmd = (Integer.reverseBytes(in.readUnsignedShort()) >>> 16);
            proto_.ret = Short.reverseBytes(in.readShort());
            proto_.hlen = Short.reverseBytes(in.readShort());

            int bodyLen = proto_.len - Protocol.PROTO_MIN_LEN;
            if (bodyLen > 0) {
                proto_.data = new byte[bodyLen];
                in.readBytes(proto_.data);
            }
            out.add(proto_);

            proto_ = null;
            lenToRead_ = 0;
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
    {
        logger.error(cause.getMessage(), cause);

        proto_ = null;
        lenToRead_ = 0;
        ctx.close();
    }

    @SuppressWarnings("serial")
    private static class InvalidProtoException extends RuntimeException {
        public InvalidProtoException(String msg)
        {
            super(msg);
        }
    }

}

@@ -440,25 +440,27 @@
 otocol proto
-_
+col
  = null;%0A   
@@ -477,25 +477,24 @@
 nt lenToRead
-_
  = 0;%0A%0A    @
@@ -625,17 +625,19 @@
 f (proto
-_
+col
  == null
@@ -734,25 +734,27 @@
        proto
-_
+col
  = new Proto
@@ -773,25 +773,27 @@
        proto
-_
+col
 .len = Integ
@@ -841,25 +841,27 @@
   if ((proto
-_
+col
 .len %3C Proto
@@ -884,25 +884,27 @@
 N) %7C%7C (proto
-_
+col
 .len %3E Proto
@@ -1010,25 +1010,27 @@
 M: %22 + proto
-_
+col
 .len);%0A     
@@ -1063,17 +1063,16 @@
 Read
-_
  = proto
 _.le
@@ -1063,25 +1063,27 @@
 Read = proto
-_
+col
 .len - 4;%0A  
@@ -1134,17 +1134,16 @@
 enToRead
-_
 ) %7B%0A    
@@ -1155,17 +1155,19 @@
    proto
-_
+col
 .seq = I
@@ -1218,17 +1218,19 @@
    proto
-_
+col
 .hash = 
@@ -1282,17 +1282,19 @@
    proto
-_
+col
 .cmd = (
@@ -1364,17 +1364,19 @@
    proto
-_
+col
 .ret = S
@@ -1427,17 +1427,19 @@
    proto
-_
+col
 .hlen = 
@@ -1506,17 +1506,19 @@
  = proto
-_
+col
 .len - P
@@ -1588,25 +1588,27 @@
        proto
-_
+col
 .data = new 
@@ -1656,17 +1656,19 @@
 es(proto
-_
+col
 .data);%0A
@@ -1706,17 +1706,19 @@
 dd(proto
-_
+col
 );%0A%0A    
@@ -1722,33 +1722,35 @@
            proto
-_
+col
  = null;%0A       
@@ -1755,33 +1755,32 @@
        lenToRead
-_
  = 0;%0A        %7D%0A
@@ -1962,17 +1962,19 @@
    proto
-_
+col
  = null;
@@ -1991,17 +1991,16 @@
 enToRead
-_
  = 0;%0A  

rename class members