1420c9859SShuo Chenpackage muduo.rpc;
2420c9859SShuo Chen
3420c9859SShuo Chenimport java.nio.charset.Charset;
4420c9859SShuo Chenimport java.util.zip.Adler32;
5420c9859SShuo Chen
6420c9859SShuo Chenimport muduo.rpc.proto.RpcProto.RpcMessage;
7420c9859SShuo Chen
8420c9859SShuo Chenimport org.jboss.netty.buffer.ChannelBuffer;
9420c9859SShuo Chenimport org.jboss.netty.channel.Channel;
10420c9859SShuo Chenimport org.jboss.netty.channel.ChannelHandlerContext;
11420c9859SShuo Chenimport org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
12420c9859SShuo Chenimport org.jboss.netty.channel.ChannelHandler.Sharable;
13420c9859SShuo Chen
14420c9859SShuo Chen@Sharable
15420c9859SShuo Chenpublic class RpcDecoder extends OneToOneDecoder {
16420c9859SShuo Chen
17420c9859SShuo Chen    @Override
18420c9859SShuo Chen    public Object decode(ChannelHandlerContext ctx, Channel channel, Object obj)
19420c9859SShuo Chen            throws Exception {
20420c9859SShuo Chen        if (obj instanceof ChannelBuffer) {
21420c9859SShuo Chen            ChannelBuffer buffer = (ChannelBuffer) obj;
22420c9859SShuo Chen            if (buffer.readableBytes() > 8) {
23420c9859SShuo Chen                String version = buffer.toString(buffer.readerIndex(), 4, Charset.defaultCharset());
24420c9859SShuo Chen                if (version.equals("RPC0")) {
25420c9859SShuo Chen                    Adler32 adler32 = new Adler32();
26420c9859SShuo Chen                    adler32.update(buffer.array(),
27420c9859SShuo Chen                            buffer.arrayOffset() + buffer.readerIndex(),
28420c9859SShuo Chen                            buffer.readableBytes() - 4);
29420c9859SShuo Chen                    buffer.markReaderIndex();
30420c9859SShuo Chen                    buffer.readerIndex(buffer.writerIndex() - 4);
31420c9859SShuo Chen                    int checksum = buffer.readInt();
32420c9859SShuo Chen                    if (checksum == (int)adler32.getValue()) {
33420c9859SShuo Chen                        buffer.resetReaderIndex();
34420c9859SShuo Chen                        RpcMessage message = RpcMessage.newBuilder().mergeFrom(
35420c9859SShuo Chen                                buffer.array(),
36420c9859SShuo Chen                                buffer.arrayOffset() + buffer.readerIndex() + 4,
37420c9859SShuo Chen                                buffer.readableBytes() - 8).build();
38420c9859SShuo Chen                        return message;
39420c9859SShuo Chen                    }
40420c9859SShuo Chen                }
41420c9859SShuo Chen            }
42420c9859SShuo Chen        }
43420c9859SShuo Chen        return obj;
44420c9859SShuo Chen    }
45420c9859SShuo Chen}
46