Skip to content

Commit b9fefb7

Browse files
committed
[Java]: Perform a dynamic decode of group and var data headers to allow different types by field specification as per issue aeron-io#60.
1 parent d9ae897 commit b9fefb7

File tree

4 files changed

+53
-331
lines changed

4 files changed

+53
-331
lines changed

examples/java/uk/co/real_logic/sbe/examples/OtfExample.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@
1919
import baseline.MessageHeader;
2020
import uk.co.real_logic.sbe.codec.java.DirectBuffer;
2121
import uk.co.real_logic.sbe.ir.*;
22-
import uk.co.real_logic.sbe.otf.OtfGroupSizeDecoder;
2322
import uk.co.real_logic.sbe.otf.OtfMessageDecoder;
2423
import uk.co.real_logic.sbe.otf.OtfHeaderDecoder;
25-
import uk.co.real_logic.sbe.otf.OtfVarDataDecoder;
2624
import uk.co.real_logic.sbe.xml.IrGenerator;
2725
import uk.co.real_logic.sbe.xml.MessageSchema;
2826
import uk.co.real_logic.sbe.xml.XmlSchemaParser;
@@ -55,11 +53,8 @@ public static void main(final String[] args) throws Exception
5553
encodedSchemaBuffer.flip();
5654
final IntermediateRepresentation ir = decodeIr(encodedSchemaBuffer);
5755

58-
// From the IR we can create OTF decoders for messages.
56+
// From the IR we can create OTF decoder for message headers.
5957
final OtfHeaderDecoder headerDecoder = new OtfHeaderDecoder(ir.headerStructure());
60-
final OtfMessageDecoder messageDecoder
61-
= new OtfMessageDecoder(new OtfGroupSizeDecoder(ir.getType(OtfGroupSizeDecoder.GROUP_SIZE_ENCODING_NAME)),
62-
new OtfVarDataDecoder(ir.getType(OtfVarDataDecoder.VAR_DATA_ENCODING_NAME)));
6358

6459
// Now we have IR we can read the message header
6560
int bufferOffset = 0;
@@ -76,12 +71,12 @@ public static void main(final String[] args) throws Exception
7671

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

79-
bufferOffset = messageDecoder.decode(buffer,
80-
bufferOffset,
81-
actingVersion,
82-
blockLength,
83-
msgTokens,
84-
new ExampleTokenListener(new PrintWriter(System.out, true)));
74+
bufferOffset = OtfMessageDecoder.decode(buffer,
75+
bufferOffset,
76+
actingVersion,
77+
blockLength,
78+
msgTokens,
79+
new ExampleTokenListener(new PrintWriter(System.out, true)));
8580

8681
if (bufferOffset != encodedMsgBuffer.position())
8782
{

main/java/uk/co/real_logic/sbe/otf/OtfGroupSizeDecoder.java

Lines changed: 0 additions & 135 deletions
This file was deleted.

main/java/uk/co/real_logic/sbe/otf/OtfMessageDecoder.java

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import uk.co.real_logic.sbe.codec.java.DirectBuffer;
1919
import uk.co.real_logic.sbe.ir.Signal;
2020
import uk.co.real_logic.sbe.ir.Token;
21-
import uk.co.real_logic.sbe.util.Verify;
2221

2322
import java.util.List;
2423

@@ -33,41 +32,26 @@
3332
*/
3433
public class OtfMessageDecoder
3534
{
36-
private final OtfGroupSizeDecoder groupSizeDecoder;
37-
private final OtfVarDataDecoder varDataDecoder;
38-
39-
/**
40-
* Construct a message decoder with provided decoders for the group and var data headers. The provided decoders are expected to be thread safe.
41-
*
42-
* @param groupSizeDecoder for decoding the repeating group header.
43-
* @param varDataDecoder for decoding the var data field header.
44-
*/
45-
public OtfMessageDecoder(final OtfGroupSizeDecoder groupSizeDecoder, final OtfVarDataDecoder varDataDecoder)
46-
{
47-
Verify.notNull(groupSizeDecoder, "groupSizeDecoder");
48-
Verify.notNull(varDataDecoder, "varDataDecoder");
49-
50-
this.groupSizeDecoder = groupSizeDecoder;
51-
this.varDataDecoder = varDataDecoder;
52-
}
35+
private static final int GROUP_DIM_TYPE_TOKENS = 5;
36+
private static final int VAR_DATA_TOKENS = 5;
5337

5438
/**
5539
* Decode a message from the provided buffer based on the message schema described with IR {@link uk.co.real_logic.sbe.ir.Token}s.
5640
*
57-
* @param buffer containing the encoded message.
58-
* @param bufferIndex at which the message encoding starts in the buffer.
41+
* @param buffer containing the encoded message.
42+
* @param bufferIndex at which the message encoding starts in the buffer.
5943
* @param actingVersion of the encoded message for dealing with extension fields.
60-
* @param blockLength of the root message fields.
61-
* @param msgTokens in IR format describing the message structure.
62-
* @param listener to callback for decoding the primitive values as discovered in the structure.
44+
* @param blockLength of the root message fields.
45+
* @param msgTokens in IR format describing the message structure.
46+
* @param listener to callback for decoding the primitive values as discovered in the structure.
6347
* @return the index in the underlying buffer after decoding.
6448
*/
65-
public int decode(final DirectBuffer buffer,
66-
int bufferIndex,
67-
final int actingVersion,
68-
final int blockLength,
69-
final List<Token> msgTokens,
70-
final TokenListener listener)
49+
public static int decode(final DirectBuffer buffer,
50+
int bufferIndex,
51+
final int actingVersion,
52+
final int blockLength,
53+
final List<Token> msgTokens,
54+
final TokenListener listener)
7155
{
7256
final int groupsBeginIndex = findNextOrLimit(msgTokens, 1, msgTokens.size(), Signal.BEGIN_GROUP);
7357
final int varDataSearchStart = groupsBeginIndex != msgTokens.size() ? groupsBeginIndex : 1;
@@ -104,30 +88,36 @@ private static void decodeFields(final DirectBuffer buffer,
10488
}
10589
}
10690

107-
private int decodeGroups(final DirectBuffer buffer,
108-
int bufferIndex,
109-
final int actingVersion,
110-
final List<Token> tokens,
111-
final int fromIndex,
112-
final int toIndex,
113-
final TokenListener listener)
91+
private static int decodeGroups(final DirectBuffer buffer,
92+
int bufferIndex,
93+
final int actingVersion,
94+
final List<Token> tokens,
95+
final int fromIndex,
96+
final int toIndex,
97+
final TokenListener listener)
11498
{
11599
for (int i = fromIndex; i < toIndex; i++)
116100
{
117101
final Token token = tokens.get(i);
118102

119103
if (Signal.BEGIN_GROUP == token.signal())
120104
{
121-
final int beginFieldsIndex = i + groupSizeDecoder.groupHeaderTokenCount() + 1;
105+
final Token blockLengthToken = tokens.get(i + 2);
106+
final int blockLength = Util.getInt(buffer, bufferIndex + blockLengthToken.offset(),
107+
blockLengthToken.encoding().primitiveType(), blockLengthToken.encoding().byteOrder());
108+
109+
final Token numInGroupToken = tokens.get(i + 3);
110+
final int numInGroup = Util.getInt(buffer, bufferIndex + numInGroupToken.offset(),
111+
numInGroupToken.encoding().primitiveType(), numInGroupToken.encoding().byteOrder());
112+
113+
final Token dimensionTypeComposite = tokens.get(i + 1);
114+
bufferIndex += dimensionTypeComposite.size();
115+
116+
final int beginFieldsIndex = i + GROUP_DIM_TYPE_TOKENS;
122117
final int endGroupIndex = findNextOrLimit(tokens, beginFieldsIndex, toIndex, Signal.END_GROUP);
123118
final int nextGroupIndex = findNextOrLimit(tokens, beginFieldsIndex, toIndex, Signal.BEGIN_GROUP);
124119
final int endOfFieldsIndex = Math.min(endGroupIndex, nextGroupIndex) - 1;
125120

126-
final int blockLength = groupSizeDecoder.getBlockLength(buffer, bufferIndex);
127-
final int numInGroup = groupSizeDecoder.getNumInGroup(buffer, bufferIndex);
128-
129-
bufferIndex += groupSizeDecoder.size();
130-
131121
for (int g = 0; g < numInGroup; g++)
132122
{
133123
listener.onBeginGroup(token, g, numInGroup);
@@ -150,27 +140,30 @@ private int decodeGroups(final DirectBuffer buffer,
150140
return bufferIndex;
151141
}
152142

153-
private int decodeVarData(final DirectBuffer buffer,
154-
int bufferIndex,
155-
final List<Token> tokens,
156-
final int fromIndex,
157-
final int toIndex,
158-
final TokenListener listener)
143+
private static int decodeVarData(final DirectBuffer buffer,
144+
int bufferIndex,
145+
final List<Token> tokens,
146+
final int fromIndex,
147+
final int toIndex,
148+
final TokenListener listener)
159149
{
160150
for (int i = fromIndex; i < toIndex; i++)
161151
{
162152
final Token token = tokens.get(i);
163153

164154
if (Signal.BEGIN_VAR_DATA == token.signal())
165155
{
166-
final int length = varDataDecoder.getLength(buffer, bufferIndex);
167-
final Token typeToken = tokens.get(i + 1 + varDataDecoder.varDataTokenOffset());
168-
bufferIndex += varDataDecoder.size();
156+
final Token lengthToken = tokens.get(i + 2);
157+
final int length = Util.getInt(buffer, bufferIndex + lengthToken.offset(),
158+
lengthToken.encoding().primitiveType(), lengthToken.encoding().byteOrder());
159+
160+
final Token varDataToken = tokens.get(i + 3);
161+
bufferIndex += varDataToken.offset();
169162

170-
listener.onVarData(token, buffer, bufferIndex, length, typeToken);
163+
listener.onVarData(token, buffer, bufferIndex, length, varDataToken);
171164

172165
bufferIndex += length;
173-
i += (varDataDecoder.tokenCount() + 1);
166+
i += VAR_DATA_TOKENS;
174167
}
175168
}
176169

0 commit comments

Comments
 (0)