Skip to content

Java OTF User Guide

Martin Thompson edited this page Dec 27, 2013 · 22 revisions

Some applications, such as network sniffers, need to decode messages dynamically and thus have to use the Intermediate Representation to decode the messages on-the-fly (OTF).

The Java OTF decoder follows the design principles of the generated codecs and is thread safe to be reused concurrently across multiple threads for memory efficiency.

Note: Due to the dynamic nature of OTF decoding, the stubs generated by the SBE compiler will yield greater relative performance.

Getting Started

Before messages can be decoded it is necessary to retrieve the IR for the schema describing the messages and types. This can be down by reading the encoded IR into a ByteBuffer and then decoding it using the provided IrDecoder.

private static IntermediateRepresentation decodeIr(final ByteBuffer buffer)
    throws IOException
{
    final IrDecoder irDecoder = new IrDecoder(buffer);
    return irDecoder.decode();
}

Once the IR is decoded you can then create the OTF decoders for the message header, groups, variable data, and messages as follows:

// From the IR we can create OTF decoders for messages.
final OtfHeaderDecoder headerDecoder = new OtfHeaderDecoder(ir.headerStructure());
final OtfMessageDecoder messageDecoder 
    = new OtfMessageDecoder(new OtfGroupSizeDecoder(ir.getType(OtfGroupSizeDecoder.GROUP_SIZE_ENCODING_NAME)), 
                            new OtfVarDataDecoder(ir.getType(OtfVarDataDecoder.VAR_DATA_ENCODING_NAME)));

You are now ready to decode messages as they arrive. This can be done by first reading the message header then looking up the appropriate template.

// Now we have IR we can read the message header
int bufferOffset = 0;
final DirectBuffer buffer = new DirectBuffer(encodedMsgBuffer);

final int templateId = headerDecoder.getTemplateId(buffer, bufferOffset);
final int actingVersion = headerDecoder.getTemplateVersion(buffer, bufferOffset);
final int blockLength = headerDecoder.getBlockLength(buffer, bufferOffset);

bufferOffset += headerDecoder.size();

Note: Don't forget to increment the bufferOffset to account for the message header size!

Once you have decoded the header you can lookup the message template IR and begin decoding.

final List<Token> msgTokens = ir.getMessage(templateId);

bufferOffset = messageDecoder.decode(buffer,
                                     bufferOffset,
                                     actingVersion,
                                     blockLength,
                                     msgTokens,
                                     new ExampleTokenListener(new PrintWriter(System.out, true)));
Clone this wiki locally