/** * Decode a message from the provided buffer based on the message schema described with IR {@link Token}s. * * @param buffer containing the encoded message. * @param bufferIndex at which the message encoding starts in the buffer. * @param actingVersion of the encoded message for dealing with extension fields. * @param blockLength of the root message fields. * @param msgTokens in IR format describing the message structure. * @param listener to callback for decoding the primitive values as discovered in the structure. * @return the index in the underlying buffer after decoding. */ public static int decode( final DirectBuffer buffer, int bufferIndex, final int actingVersion, final int blockLength, final List<Token> msgTokens, final TokenListener listener) { final int groupsBeginIndex = findNextOrLimit(msgTokens, 1, msgTokens.size(), Signal.BEGIN_GROUP); final int varDataSearchStart = groupsBeginIndex != msgTokens.size() ? groupsBeginIndex : 1; final int varDataBeginIndex = findNextOrLimit(msgTokens, varDataSearchStart, msgTokens.size(), Signal.BEGIN_VAR_DATA); listener.onBeginMessage(msgTokens.get(0)); decodeFields(buffer, bufferIndex, actingVersion, msgTokens, 0, groupsBeginIndex, listener); bufferIndex += blockLength; bufferIndex = decodeGroups(buffer, bufferIndex, actingVersion, msgTokens, groupsBeginIndex, varDataBeginIndex, listener); bufferIndex = decodeVarData(buffer, bufferIndex, msgTokens, varDataBeginIndex, msgTokens.size(), listener); listener.onEndMessage(msgTokens.get(msgTokens.size() - 1)); return bufferIndex; }
private static int decodeField( final DirectBuffer buffer, final int bufferIndex, final List<Token> tokens, final int fromIndex, final int actingVersion, final TokenListener listener) { final int toIndex = findNextOrLimit(tokens, fromIndex + 1, tokens.size(), Signal.END_FIELD); final Token fieldToken = tokens.get(fromIndex); final Token typeToken = tokens.get(fromIndex + 1); final int offset = typeToken.offset(); switch (typeToken.signal()) { case BEGIN_COMPOSITE: decodeComposite( fieldToken, buffer, bufferIndex + offset, tokens, fromIndex + 1, toIndex - 1, actingVersion, listener); break; case BEGIN_ENUM: listener.onEnum(fieldToken, buffer, bufferIndex + offset, tokens, fromIndex + 1, toIndex - 1, actingVersion); break; case BEGIN_SET: listener.onBitSet(fieldToken, buffer, bufferIndex + offset, tokens, fromIndex + 1, toIndex - 1, actingVersion); break; case ENCODING: listener.onEncoding(fieldToken, buffer, bufferIndex + offset, typeToken, actingVersion); break; } return toIndex; }
final int endGroupIndex = findNextOrLimit(tokens, beginFieldsIndex, toIndex, Signal.END_GROUP); final int nextGroupIndex = findNextOrLimit(tokens, beginFieldsIndex, toIndex, Signal.BEGIN_GROUP); final int endOfFieldsIndex = Math.min(endGroupIndex, nextGroupIndex) - 1;