// Copyright (C) 2015 anduo
// All rights reserved
package com.anduo.filesync.codec;
import com.anduo.filesync.msg.FileMsg;
import com.anduo.filesync.msg.MsgType;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* ━━━━━━神兽出没━━━━━━
* ┏┓ ┏┓
* ┏┛┻━━━┛┻┓
* ┃ ┃
* ┃ ━ ┃
* ┃ ┳┛ ┗┳ ┃
* ┃ ┃
* ┃ ┻ ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃神兽保佑, 永无BUG!
* ┃ ┃Code is far away from bug with the animal protecting
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
* ━━━━━━感觉萌萌哒━━━━━━
* Summary: 解码器
* Author : anduo@qq.com
* Version: 1.0
* Date : 15/7/5
* time : 18:05
*/
public class FileMsgDecoder extends ByteToMessageDecoder {
/**
* 日志组件.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(FileMsgDecoder.class);
public FileMsgDecoder() {
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
throws Exception {
// 防止不发报文就关闭连接出现的错误
if (!in.isReadable()) {
return;
}
LOGGER.info(String.format("[%s]收到的的报文:[%s]", ctx.channel().remoteAddress(), ByteBufUtil.hexDump(in)));
in.markReaderIndex();//标记初始位置
if (in.readableBytes() < 3) {
return;
}
byte msgType = in.readByte();
short dataLength = in.readShort();
if (in.readableBytes() < dataLength) {
in.resetReaderIndex();//恢复到标记位
return;
}
if (MsgType.HEADER == msgType) {
//文件头
// 1、文件名
FileMsg msg = getMsgHeader(in);
out.add(msg);
} else if (MsgType.BODY == msgType) {
//数据段
} else if (MsgType.TAILER == msgType) {
//数据尾端
} else if (MsgType.COMMAND == msgType) {
// 命令工具
}
}
private FileMsg getMsgHeader(ByteBuf in) {
long sumCountPackage = in.readLong();
short fileNameLength = in.readShort();
byte[] fileNameData = new byte[fileNameLength];
in.readBytes(fileNameData);
String filename = new String(fileNameData, CharsetUtil.UTF_8);
// 2、数据源node节点名称
short srcNodeLength = in.readShort();
byte[] srcNodeData = new byte[srcNodeLength];
in.readBytes(srcNodeData);
String srcNode = new String(srcNodeData, CharsetUtil.UTF_8);
//3、数据文件md5值
short fileMd5Length = in.readShort();
byte[] fileMd5Data = new byte[fileMd5Length];
in.readBytes(fileMd5Data);
String fileMd5 = new String(fileMd5Data, CharsetUtil.UTF_8);
FileMsg msg = new FileMsg();
msg.setSumCountPackage(sumCountPackage);
msg.setFileName(filename);
msg.setSrcNode(srcNode);
msg.setFileMd5(fileMd5);
return msg;
}
}