package com.netthreads.network.osc.decoder; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.socket.DatagramPacket; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.MessageToMessageDecoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.netthreads.osc.common.domain.OSCBundle; import com.netthreads.osc.common.domain.OSCMessage; /** * Decode OSC Message. * */ public class OSCBundleDecoder extends MessageToMessageDecoder<DatagramPacket, OSCBundle> { private static final Logger logger = LoggerFactory.getLogger(OSCBundleDecoder.class); private static final int MAX_BUFFER = 0xFFFF; private DelimiterBasedFrameDecoder delimiterBasedFrameDecoder; private LengthFieldBasedFrameDecoder lengthFieldBasedFrameDecoder; private OSCMessageDecoder oscMessageDecoder; /** * Construct decoder. * */ public OSCBundleDecoder() { delimiterBasedFrameDecoder = new DelimiterBasedFrameDecoder(8192, true, Delimiters.nulDelimiter()); lengthFieldBasedFrameDecoder = new LengthFieldBasedFrameDecoder(MAX_BUFFER, 0, 4, 0, 4); oscMessageDecoder = new OSCMessageDecoder(); } /** * Decode message and populate OSCBundle from pool. * */ @Override public OSCBundle decode(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { OSCBundle oscBundle = null; ByteBuf byteBuf = msg.data(); // Read past "bundle message" ByteBuf data = (ByteBuf) delimiterBasedFrameDecoder.decode(ctx, byteBuf); if (data != null) { // Time-stamp (2208988800000) long timeStamp = byteBuf.readLong(); while (data != null) { // Message length data = (ByteBuf) lengthFieldBasedFrameDecoder.decode(ctx, byteBuf); if (data != null) { // Message OSCMessage oscMessage = oscMessageDecoder.decode(ctx, data); if (oscMessage != null) { if (oscBundle == null) { oscBundle = OSCBundle.$(); oscBundle.setTimeTag(timeStamp); } oscBundle.addMessage(oscMessage); } } } } logger.debug(oscBundle.toString()); return oscBundle; } }