Skip to content

Commit a2a067f

Browse files
authored
Implementation of sbeSkip and sbeDecodedLength for the Java Generator. (#865)
* [Java] Partial implementation of sbeSkip. * [Java] Complete implementation of sbeSkip and sbeDecodedLength. Pull out common test utility methods. * [Java] Regenerate IR codecs.
1 parent 5e0d462 commit a2a067f

File tree

6 files changed

+313
-106
lines changed

6 files changed

+313
-106
lines changed

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import java.util.function.Function;
3232

3333
import static uk.co.real_logic.sbe.SbeTool.JAVA_INTERFACE_PACKAGE;
34+
import static uk.co.real_logic.sbe.generation.cpp.CppUtil.formatClassName;
35+
import static uk.co.real_logic.sbe.generation.cpp.CppUtil.formatPropertyName;
3436
import static uk.co.real_logic.sbe.generation.java.JavaGenerator.CodecType.DECODER;
3537
import static uk.co.real_logic.sbe.generation.java.JavaGenerator.CodecType.ENCODER;
3638
import static uk.co.real_logic.sbe.generation.java.JavaUtil.*;
@@ -233,6 +235,7 @@ private void generateDecoder(
233235
generateDecoderVarData(sb, varData, BASE_INDENT);
234236

235237
generateDecoderDisplay(sb, msgToken.name(), fields, groups, varData);
238+
generateMessageLength(sb, className, true, groups, varData, BASE_INDENT);
236239

237240
out.append(sb);
238241
out.append("}\n");
@@ -284,6 +287,7 @@ private void generateDecoderGroups(
284287
generateDecoderVarData(sb, varData, indent + INDENT);
285288

286289
appendGroupInstanceDecoderDisplay(sb, fields, groups, varData, indent + INDENT);
290+
generateMessageLength(sb, groupName, false, groups, varData, indent + INDENT);
287291

288292
sb.append(indent).append(" }\n");
289293
}
@@ -2574,6 +2578,15 @@ private CharSequence generateDecoderFlyweightCode(final String className, final
25742578
" public " + className + " sbeRewind()\n" +
25752579
" {\n" +
25762580
" return wrap(buffer, initialOffset, actingBlockLength, actingVersion);\n" +
2581+
" }\n\n" +
2582+
2583+
" public int sbeDecodedLength()\n" +
2584+
" {\n" +
2585+
" final int currentLimit = limit();\n" +
2586+
" sbeSkip();\n" +
2587+
" final int decodedLength = encodedLength();\n" +
2588+
" limit(currentLimit);\n" +
2589+
" return decodedLength;\n" +
25772590
" }\n\n";
25782591

25792592
return generateFlyweightCode(DECODER, className, token, methods, readOnlyBuffer);
@@ -3650,6 +3663,64 @@ private void appendMessageToString(final StringBuilder sb, final String decoderN
36503663
append(sb, INDENT, "}");
36513664
}
36523665

3666+
private void generateMessageLength(
3667+
final StringBuilder sb,
3668+
final String className,
3669+
final boolean isParent,
3670+
final List<Token> groups,
3671+
final List<Token> varData,
3672+
final String baseIndent)
3673+
{
3674+
final String methodIndent = baseIndent + INDENT;
3675+
final String bodyIndent = methodIndent + INDENT;
3676+
append(sb, methodIndent, "");
3677+
append(sb, methodIndent, "public " + className + " sbeSkip()");
3678+
append(sb, methodIndent, "{");
3679+
if (isParent)
3680+
{
3681+
append(sb, bodyIndent, "sbeRewind();");
3682+
}
3683+
for (int i = 0, size = groups.size(); i < size; i++)
3684+
{
3685+
final Token groupToken = groups.get(i);
3686+
if (groupToken.signal() != Signal.BEGIN_GROUP)
3687+
{
3688+
throw new IllegalStateException("tokens must begin with BEGIN_GROUP: token=" + groupToken);
3689+
}
3690+
3691+
final String groupName = formatPropertyName(groupToken.name());
3692+
final String groupDecoderName = decoderName(groupToken.name());
3693+
3694+
append(sb, bodyIndent, groupDecoderName + " " + groupName + " = " + groupName + "();");
3695+
append(sb, bodyIndent, "if (" + groupName + ".count() > 0)");
3696+
append(sb, bodyIndent, "{");
3697+
append(sb, bodyIndent, " while (" + groupName + ".hasNext())");
3698+
append(sb, bodyIndent, " {");
3699+
append(sb, bodyIndent, " " + groupName + ".next();");
3700+
append(sb, bodyIndent, " " + groupName + ".sbeSkip();");
3701+
append(sb, bodyIndent, " }");
3702+
append(sb, bodyIndent, "}");
3703+
i = findEndSignal(groups, i, Signal.END_GROUP, groupToken.name());
3704+
}
3705+
3706+
for (int i = 0, size = varData.size(); i < size;)
3707+
{
3708+
final Token varDataToken = varData.get(i);
3709+
if (varDataToken.signal() != Signal.BEGIN_VAR_DATA)
3710+
{
3711+
throw new IllegalStateException("tokens must begin with BEGIN_VAR_DATA: token=" + varDataToken);
3712+
}
3713+
3714+
final String varDataName = formatPropertyName(varDataToken.name());
3715+
append(sb, bodyIndent, "skip" + Generators.toUpperFirstChar(varDataName) + "();");
3716+
3717+
i += varDataToken.componentTokenCount();
3718+
}
3719+
3720+
append(sb, bodyIndent, "return this;");
3721+
append(sb, methodIndent, "}");
3722+
}
3723+
36533724
private static String validateBufferImplementation(
36543725
final String fullyQualifiedBufferImplementation, final Class<?> bufferClass)
36553726
{

sbe-tool/src/main/java/uk/co/real_logic/sbe/ir/generated/FrameCodecDecoder.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ public FrameCodecDecoder sbeRewind()
109109
return wrap(buffer, initialOffset, actingBlockLength, actingVersion);
110110
}
111111

112+
public int sbeDecodedLength()
113+
{
114+
final int currentLimit = limit();
115+
sbeSkip();
116+
final int decodedLength = encodedLength();
117+
limit(currentLimit);
118+
return decodedLength;
119+
}
120+
112121
public int encodedLength()
113122
{
114123
return limit - offset;
@@ -664,4 +673,13 @@ public StringBuilder appendTo(final StringBuilder builder)
664673

665674
return builder;
666675
}
676+
677+
public FrameCodecDecoder sbeSkip()
678+
{
679+
sbeRewind();
680+
skipPackageName();
681+
skipNamespaceName();
682+
skipSemanticVersion();
683+
return this;
684+
}
667685
}

sbe-tool/src/main/java/uk/co/real_logic/sbe/ir/generated/TokenCodecDecoder.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ public TokenCodecDecoder sbeRewind()
109109
return wrap(buffer, initialOffset, actingBlockLength, actingVersion);
110110
}
111111

112+
public int sbeDecodedLength()
113+
{
114+
final int currentLimit = limit();
115+
sbeSkip();
116+
final int decodedLength = encodedLength();
117+
limit(currentLimit);
118+
return decodedLength;
119+
}
120+
112121
public int encodedLength()
113122
{
114123
return limit - offset;
@@ -1890,4 +1899,21 @@ public StringBuilder appendTo(final StringBuilder builder)
18901899

18911900
return builder;
18921901
}
1902+
1903+
public TokenCodecDecoder sbeSkip()
1904+
{
1905+
sbeRewind();
1906+
skipName();
1907+
skipConstValue();
1908+
skipMinValue();
1909+
skipMaxValue();
1910+
skipNullValue();
1911+
skipCharacterEncoding();
1912+
skipEpoch();
1913+
skipTimeUnit();
1914+
skipSemanticType();
1915+
skipDescription();
1916+
skipReferencedName();
1917+
return this;
1918+
}
18931919
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright 2013-2021 Real Logic Limited.
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+
* https://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.generation.java;
17+
18+
import baseline.CarDecoder;
19+
import baseline.EngineDecoder;
20+
import baseline.OptionalExtrasDecoder;
21+
22+
import java.util.ArrayList;
23+
24+
public class CarDecodeTestUtil
25+
{
26+
static ArrayList<Object> getValues(final CarDecoder carDecoder)
27+
{
28+
final ArrayList<Object> values = new ArrayList<>();
29+
30+
values.add(carDecoder.serialNumber());
31+
values.add(carDecoder.modelYear());
32+
values.add(carDecoder.available());
33+
values.add(carDecoder.code());
34+
values.add(CarDecoder.someNumbersLength());
35+
for (int i = 0, n = CarDecoder.someNumbersLength(); i < n; i++)
36+
{
37+
values.add(carDecoder.someNumbers(i));
38+
}
39+
values.add(carDecoder.vehicleCode());
40+
final OptionalExtrasDecoder extras = carDecoder.extras();
41+
values.add(extras.sunRoof());
42+
values.add(extras.sportsPack());
43+
values.add(extras.cruiseControl());
44+
final EngineDecoder engine = carDecoder.engine();
45+
values.add(engine.capacity());
46+
values.add(engine.numCylinders());
47+
values.add(engine.maxRpm());
48+
values.add(engine.manufacturerCode());
49+
values.add(engine.fuel());
50+
final CarDecoder.FuelFiguresDecoder fuelFigures = carDecoder.fuelFigures();
51+
while (fuelFigures.hasNext())
52+
{
53+
fuelFigures.next();
54+
values.add(fuelFigures.speed());
55+
values.add(fuelFigures.mpg());
56+
}
57+
final CarDecoder.PerformanceFiguresDecoder performanceFigures = carDecoder.performanceFigures();
58+
while (performanceFigures.hasNext())
59+
{
60+
performanceFigures.next();
61+
values.add(performanceFigures.octaneRating());
62+
final CarDecoder.PerformanceFiguresDecoder.AccelerationDecoder acceleration =
63+
performanceFigures.acceleration();
64+
while (acceleration.hasNext())
65+
{
66+
acceleration.next();
67+
values.add(acceleration.mph());
68+
values.add(acceleration.seconds());
69+
}
70+
}
71+
values.add(carDecoder.manufacturer());
72+
values.add(carDecoder.model());
73+
values.add(carDecoder.activationCode());
74+
return values;
75+
}
76+
77+
static ArrayList<Object> getPartialValues(final CarDecoder carDecoder)
78+
{
79+
final ArrayList<Object> values = new ArrayList<>();
80+
81+
values.add(carDecoder.serialNumber());
82+
values.add(carDecoder.modelYear());
83+
values.add(carDecoder.available());
84+
values.add(carDecoder.code());
85+
values.add(CarDecoder.someNumbersLength());
86+
for (int i = 0, n = CarDecoder.someNumbersLength(); i < n; i++)
87+
{
88+
values.add(carDecoder.someNumbers(i));
89+
}
90+
values.add(carDecoder.vehicleCode());
91+
final OptionalExtrasDecoder extras = carDecoder.extras();
92+
values.add(extras.sunRoof());
93+
values.add(extras.sportsPack());
94+
values.add(extras.cruiseControl());
95+
final EngineDecoder engine = carDecoder.engine();
96+
values.add(engine.capacity());
97+
values.add(engine.numCylinders());
98+
values.add(engine.maxRpm());
99+
values.add(engine.manufacturerCode());
100+
values.add(engine.fuel());
101+
final CarDecoder.FuelFiguresDecoder fuelFigures = carDecoder.fuelFigures();
102+
while (fuelFigures.hasNext())
103+
{
104+
fuelFigures.next();
105+
values.add(fuelFigures.speed());
106+
values.add(fuelFigures.mpg());
107+
}
108+
final CarDecoder.PerformanceFiguresDecoder performanceFigures = carDecoder.performanceFigures();
109+
110+
// Stop decoding part way through the message.
111+
if (performanceFigures.hasNext())
112+
{
113+
performanceFigures.next();
114+
values.add(performanceFigures.octaneRating());
115+
final CarDecoder.PerformanceFiguresDecoder.AccelerationDecoder acceleration =
116+
performanceFigures.acceleration();
117+
if (acceleration.hasNext())
118+
{
119+
acceleration.next();
120+
values.add(acceleration.mph());
121+
}
122+
}
123+
124+
return values;
125+
}
126+
}

0 commit comments

Comments
 (0)