package cc.blynk.server.core.protocol.handlers.decoders;
import cc.blynk.server.core.protocol.enums.Command;
import cc.blynk.server.core.protocol.model.messages.MessageBase;
import cc.blynk.server.core.protocol.model.messages.ResponseMessage;
import cc.blynk.server.core.stats.GlobalStats;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
import static cc.blynk.server.core.protocol.model.messages.MessageFactory.*;
/**
* Decodes input byte array into java message.
*
* The Blynk Project.
* Created by Dmitriy Dumanskiy.
* Created on 2/1/2015.
*/
public class MessageDecoder extends ByteToMessageDecoder {
protected static final Logger log = LogManager.getLogger(MessageDecoder.class);
private final GlobalStats stats;
public MessageDecoder(GlobalStats stats) {
this.stats = stats;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (in.readableBytes() < 5) {
return;
}
in.markReaderIndex();
final short command = in.readUnsignedByte();
final int messageId = in.readUnsignedShort();
final int codeOrLength = in.readUnsignedShort();
MessageBase message;
if (command == Command.RESPONSE) {
message = new ResponseMessage(messageId, codeOrLength);
} else {
if (in.readableBytes() < codeOrLength) {
in.resetReaderIndex();
return;
}
message = produce(messageId, command, in.readSlice(codeOrLength).toString(CharsetUtil.UTF_8));
}
log.trace("Incoming {}", message);
stats.mark(command);
out.add(message);
}
}