package com.manning.nettyinaction.chapter14;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.util.CharsetUtil;
@ChannelHandler.Sharable
public class MemcachedRequestEncoder extends
MessageToByteEncoder<MemcachedRequest> {
@Override
protected void encode(ChannelHandlerContext ctx, MemcachedRequest msg,
ByteBuf out) throws Exception {
byte[] key = msg.key().getBytes(CharsetUtil.UTF_8);
byte[] body = msg.body().getBytes(CharsetUtil.UTF_8);
//total size of the body = key size + content size + extras size
int bodySize = key.length + body.length + (msg.hasExtras() ? 8 : 0);
//write magic byte
out.writeByte(msg.magic());
//write opcode byte
out.writeByte(msg.opCode());
//write key length (2 byte)
out.writeShort(key.length); //key length is max 2 bytes i.e. a Java short
//write extras length (1 byte)
int extraSize = msg.hasExtras() ? 0x08 : 0x0;
out.writeByte(extraSize);
//byte is the data type, not currently implemented in Memcached but required
out.writeByte(0);
//next two bytes are reserved, not currently implemented but are required
out.writeShort(0);
//write total body length ( 4 bytes - 32 bit int)
out.writeInt(bodySize);
//write opaque ( 4 bytes) - a 32 bit int that is returned in the response
out.writeInt(msg.id());
//write CAS ( 8 bytes)
out.writeLong(msg.cas()); //24 byte header finishes with the CAS
if (msg.hasExtras()) {
//write extras (flags and expiry, 4 bytes each) - 8 bytes total
out.writeInt(msg.flags());
out.writeInt(msg.expires());
}
//write key
out.writeBytes(key);
//write value
out.writeBytes(body);
}
}