Skip to content

Commit 7e4946f

Browse files
committed
[Java]: Added support for groups to Java OTF decoder.
1 parent 533b50e commit 7e4946f

File tree

9 files changed

+427
-201
lines changed

9 files changed

+427
-201
lines changed

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ public void onEndComposite(final Token fieldToken, final List<Token> tokens, fin
124124
namedScope.pop();
125125
}
126126

127+
public void onBeginGroup(final Token token, final int groupIndex, final int numInGroup)
128+
{
129+
namedScope.push(token.name() + ".");
130+
}
131+
132+
public void onEndGroup(final Token token, final int groupIndex, final int numInGroup)
133+
{
134+
namedScope.pop();
135+
}
136+
127137
private static CharSequence readEncodingAsString(final DirectBuffer buffer,
128138
final int index,
129139
final Token typeToken,
@@ -158,7 +168,7 @@ private long readEncodingAsLong(final DirectBuffer buffer, final int bufferIndex
158168
return constOrNotPresentValue.longValue();
159169
}
160170

161-
return readAsLong(buffer, bufferIndex, typeToken.encoding());
171+
return getLong(buffer, bufferIndex, typeToken.encoding());
162172
}
163173

164174
private static PrimitiveValue constOrNotPresentValue(final Token token, final int actingVersion)
@@ -229,7 +239,7 @@ private static void mapEncodingToString(final StringBuilder sb, final DirectBuff
229239
}
230240
}
231241

232-
private static long readAsLong(final DirectBuffer buffer, final int index, final Encoding encoding)
242+
private static long getLong(final DirectBuffer buffer, final int index, final Encoding encoding)
233243
{
234244
switch (encoding.primitiveType())
235245
{

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

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import baseline.MessageHeader;
55
import uk.co.real_logic.sbe.codec.java.DirectBuffer;
66
import uk.co.real_logic.sbe.ir.*;
7-
import uk.co.real_logic.sbe.otf.OtfDecoder;
7+
import uk.co.real_logic.sbe.otf.OtfGroupSizeDecoder;
8+
import uk.co.real_logic.sbe.otf.OtfMessageDecoder;
89
import uk.co.real_logic.sbe.otf.OtfHeaderDecoder;
910
import uk.co.real_logic.sbe.xml.IrGenerator;
1011
import uk.co.real_logic.sbe.xml.MessageSchema;
@@ -39,23 +40,25 @@ public static void main(final String[] args) throws Exception
3940
// Now we have IR we can read the message header
4041
int bufferOffset = 0;
4142
final DirectBuffer buffer = new DirectBuffer(encodedMsgBuffer);
42-
final OtfHeaderDecoder otfHeaderDecoder = new OtfHeaderDecoder(ir.headerStructure());
43+
final OtfHeaderDecoder headerDecoder = new OtfHeaderDecoder(ir.headerStructure());
4344

44-
final int templateId = otfHeaderDecoder.getTemplateId(buffer, bufferOffset);
45-
final int actingVersion = otfHeaderDecoder.getTemplateVersion(buffer, bufferOffset);
46-
final int blockLength = otfHeaderDecoder.getBlockLength(buffer, bufferOffset);
45+
final int templateId = headerDecoder.getTemplateId(buffer, bufferOffset);
46+
final int actingVersion = headerDecoder.getTemplateVersion(buffer, bufferOffset);
47+
final int blockLength = headerDecoder.getBlockLength(buffer, bufferOffset);
4748

48-
bufferOffset += otfHeaderDecoder.size();
49+
bufferOffset += headerDecoder.size();
4950

5051
// Given the header information we can select the appropriate message template to do the decode.
52+
final OtfGroupSizeDecoder groupSizeDecoder = new OtfGroupSizeDecoder(ir.getType(OtfGroupSizeDecoder.GROUP_SIZE_ENCODING_NAME));
5153
final List<Token> msgTokens = ir.getMessage(templateId);
52-
final OtfDecoder oftDecoder = new OtfDecoder();
53-
bufferOffset = oftDecoder.decode(buffer,
54-
bufferOffset,
55-
actingVersion,
56-
blockLength,
57-
msgTokens,
58-
new ExampleTokenListener(new PrintWriter(System.out, true)));
54+
55+
final OtfMessageDecoder messageDecoder = new OtfMessageDecoder(groupSizeDecoder);
56+
bufferOffset = messageDecoder.decode(buffer,
57+
bufferOffset,
58+
actingVersion,
59+
blockLength,
60+
msgTokens,
61+
new ExampleTokenListener(new PrintWriter(System.out, true)));
5962

6063
if (bufferOffset != encodedMsgBuffer.position())
6164
{

examples/resources/TestSchema.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<type name="version" primitiveType="uint8"/>
1212
<type name="reserved" primitiveType="uint8"/>
1313
</composite>
14-
<composite name="groupSizeEncoding" description="Repeating group dimensions" >
14+
<composite name="groupSizeEncoding" description="Repeating group dimensions">
1515
<type name="blockLength" primitiveType="uint16"/>
1616
<type name="numInGroup" primitiveType="uint8"/>
1717
</composite>

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

Lines changed: 0 additions & 153 deletions
This file was deleted.
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Copyright 2012 Real Logic Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package uk.co.real_logic.sbe.otf;
17+
18+
import uk.co.real_logic.sbe.PrimitiveType;
19+
import uk.co.real_logic.sbe.codec.java.DirectBuffer;
20+
import uk.co.real_logic.sbe.ir.Signal;
21+
import uk.co.real_logic.sbe.ir.Token;
22+
23+
import java.nio.ByteOrder;
24+
import java.util.List;
25+
26+
/**
27+
* Used to decode the group size header.
28+
*/
29+
public class OtfGroupSizeDecoder
30+
{
31+
public static final String GROUP_SIZE_ENCODING_NAME = "groupSizeEncoding";
32+
public static final String BLOCK_LENGTH_NAME = "blockLength";
33+
public static final String NUM_IN_GROUP_NAME = "numInGroup";
34+
35+
private final int size;
36+
private final int groupHeaderTokenCount;
37+
private int blockLengthOffset = -1;
38+
private int numInGroupOffset = -1;
39+
private PrimitiveType blockLengthType;
40+
private PrimitiveType numInGroupType;
41+
private ByteOrder blockLengthByteOrder;
42+
private ByteOrder numInGroupByteOrder;
43+
44+
/**
45+
* Scan the tokens and cache meta data to make decoding more efficient.
46+
*
47+
* @param tokens describing the group header.
48+
*/
49+
public OtfGroupSizeDecoder(final List<Token> tokens)
50+
{
51+
final Token compositeToken = tokens.get(0);
52+
if (!GROUP_SIZE_ENCODING_NAME.equals(compositeToken.name()) ||
53+
Signal.BEGIN_COMPOSITE != compositeToken.signal())
54+
{
55+
throw new IllegalArgumentException("Invalid Group: " + compositeToken);
56+
}
57+
58+
size = compositeToken.size();
59+
groupHeaderTokenCount = tokens.size();
60+
61+
for (final Token token : tokens)
62+
{
63+
switch (token.name())
64+
{
65+
case BLOCK_LENGTH_NAME:
66+
blockLengthOffset = token.offset();
67+
blockLengthType = token.encoding().primitiveType();
68+
blockLengthByteOrder = token.encoding().byteOrder();
69+
break;
70+
71+
case NUM_IN_GROUP_NAME:
72+
numInGroupOffset = token.offset();
73+
numInGroupType = token.encoding().primitiveType();
74+
numInGroupByteOrder = token.encoding().byteOrder();
75+
break;
76+
}
77+
}
78+
79+
if (-1 == blockLengthOffset)
80+
{
81+
throw new IllegalStateException(BLOCK_LENGTH_NAME + " is missing");
82+
}
83+
84+
if (-1 == numInGroupOffset)
85+
{
86+
throw new IllegalStateException(NUM_IN_GROUP_NAME + " is missing");
87+
}
88+
}
89+
90+
/**
91+
* Get the block length that is used for each iteration of the group fields.
92+
*
93+
* @param buffer to be read.
94+
* @param bufferIndex at which he group header begins.
95+
* @return the blockLength for an iteration of the group fields.
96+
*/
97+
public int getBlockLength(final DirectBuffer buffer, final int bufferIndex)
98+
{
99+
return Util.getInt(buffer, bufferIndex + blockLengthOffset, blockLengthType, blockLengthByteOrder);
100+
}
101+
102+
/**
103+
* Get the number of times the group fields will be repeated.
104+
*
105+
* @param buffer to be read.
106+
* @param bufferIndex at which he group header begins.
107+
* @return the number of times the group fields will be repeated.
108+
*/
109+
public int getNumInGroup(final DirectBuffer buffer, final int bufferIndex)
110+
{
111+
return Util.getInt(buffer, bufferIndex + numInGroupOffset, numInGroupType, numInGroupByteOrder);
112+
}
113+
114+
/**
115+
* Get the size of the group header in bytes.
116+
*
117+
* @return the size of the group header in bytes.
118+
*/
119+
public int size()
120+
{
121+
return size;
122+
}
123+
124+
/**
125+
* The number of tokens in the group header.
126+
*
127+
* @return the number of tokens in the group header.
128+
*/
129+
public int groupHeaderTokenCount()
130+
{
131+
return groupHeaderTokenCount;
132+
}
133+
}

0 commit comments

Comments
 (0)