Skip to content

Implementation of sbeSkip and sbeDecodedLength for the Java Generator. #865

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 3 commits into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import java.util.function.Function;

import static uk.co.real_logic.sbe.SbeTool.JAVA_INTERFACE_PACKAGE;
import static uk.co.real_logic.sbe.generation.cpp.CppUtil.formatClassName;
import static uk.co.real_logic.sbe.generation.cpp.CppUtil.formatPropertyName;
import static uk.co.real_logic.sbe.generation.java.JavaGenerator.CodecType.DECODER;
import static uk.co.real_logic.sbe.generation.java.JavaGenerator.CodecType.ENCODER;
import static uk.co.real_logic.sbe.generation.java.JavaUtil.*;
Expand Down Expand Up @@ -233,6 +235,7 @@ private void generateDecoder(
generateDecoderVarData(sb, varData, BASE_INDENT);

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

out.append(sb);
out.append("}\n");
Expand Down Expand Up @@ -284,6 +287,7 @@ private void generateDecoderGroups(
generateDecoderVarData(sb, varData, indent + INDENT);

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

sb.append(indent).append(" }\n");
}
Expand Down Expand Up @@ -2579,6 +2583,15 @@ private CharSequence generateDecoderFlyweightCode(final String className, final
" public " + className + " sbeRewind()\n" +
" {\n" +
" return wrap(buffer, initialOffset, actingBlockLength, actingVersion);\n" +
" }\n\n" +

" public int sbeDecodedLength()\n" +
" {\n" +
" final int currentLimit = limit();\n" +
" sbeSkip();\n" +
" final int decodedLength = encodedLength();\n" +
" limit(currentLimit);\n" +
" return decodedLength;\n" +
" }\n\n";

return generateFlyweightCode(DECODER, className, token, methods, readOnlyBuffer);
Expand Down Expand Up @@ -3655,6 +3668,64 @@ private void appendMessageToString(final StringBuilder sb, final String decoderN
append(sb, INDENT, "}");
}

private void generateMessageLength(
final StringBuilder sb,
final String className,
final boolean isParent,
final List<Token> groups,
final List<Token> varData,
final String baseIndent)
{
final String methodIndent = baseIndent + INDENT;
final String bodyIndent = methodIndent + INDENT;
append(sb, methodIndent, "");
append(sb, methodIndent, "public " + className + " sbeSkip()");
append(sb, methodIndent, "{");
if (isParent)
{
append(sb, bodyIndent, "sbeRewind();");
}
for (int i = 0, size = groups.size(); i < size; i++)
{
final Token groupToken = groups.get(i);
if (groupToken.signal() != Signal.BEGIN_GROUP)
{
throw new IllegalStateException("tokens must begin with BEGIN_GROUP: token=" + groupToken);
}

final String groupName = formatPropertyName(groupToken.name());
final String groupDecoderName = decoderName(groupToken.name());

append(sb, bodyIndent, groupDecoderName + " " + groupName + " = " + groupName + "();");
append(sb, bodyIndent, "if (" + groupName + ".count() > 0)");
append(sb, bodyIndent, "{");
append(sb, bodyIndent, " while (" + groupName + ".hasNext())");
append(sb, bodyIndent, " {");
append(sb, bodyIndent, " " + groupName + ".next();");
append(sb, bodyIndent, " " + groupName + ".sbeSkip();");
append(sb, bodyIndent, " }");
append(sb, bodyIndent, "}");
i = findEndSignal(groups, i, Signal.END_GROUP, groupToken.name());
}

for (int i = 0, size = varData.size(); i < size;)
{
final Token varDataToken = varData.get(i);
if (varDataToken.signal() != Signal.BEGIN_VAR_DATA)
{
throw new IllegalStateException("tokens must begin with BEGIN_VAR_DATA: token=" + varDataToken);
}

final String varDataName = formatPropertyName(varDataToken.name());
append(sb, bodyIndent, "skip" + Generators.toUpperFirstChar(varDataName) + "();");

i += varDataToken.componentTokenCount();
}

append(sb, bodyIndent, "return this;");
append(sb, methodIndent, "}");
}

private static String validateBufferImplementation(
final String fullyQualifiedBufferImplementation, final Class<?> bufferClass)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ public FrameCodecDecoder sbeRewind()
return wrap(buffer, initialOffset, actingBlockLength, actingVersion);
}

public int sbeDecodedLength()
{
final int currentLimit = limit();
sbeSkip();
final int decodedLength = encodedLength();
limit(currentLimit);
return decodedLength;
}

public int encodedLength()
{
return limit - offset;
Expand Down Expand Up @@ -664,4 +673,13 @@ public StringBuilder appendTo(final StringBuilder builder)

return builder;
}

public FrameCodecDecoder sbeSkip()
{
sbeRewind();
skipPackageName();
skipNamespaceName();
skipSemanticVersion();
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ public TokenCodecDecoder sbeRewind()
return wrap(buffer, initialOffset, actingBlockLength, actingVersion);
}

public int sbeDecodedLength()
{
final int currentLimit = limit();
sbeSkip();
final int decodedLength = encodedLength();
limit(currentLimit);
return decodedLength;
}

public int encodedLength()
{
return limit - offset;
Expand Down Expand Up @@ -1890,4 +1899,21 @@ public StringBuilder appendTo(final StringBuilder builder)

return builder;
}

public TokenCodecDecoder sbeSkip()
{
sbeRewind();
skipName();
skipConstValue();
skipMinValue();
skipMaxValue();
skipNullValue();
skipCharacterEncoding();
skipEpoch();
skipTimeUnit();
skipSemanticType();
skipDescription();
skipReferencedName();
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright 2013-2021 Real Logic Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package uk.co.real_logic.sbe.generation.java;

import baseline.CarDecoder;
import baseline.EngineDecoder;
import baseline.OptionalExtrasDecoder;

import java.util.ArrayList;

public class CarDecodeTestUtil
{
static ArrayList<Object> getValues(final CarDecoder carDecoder)
{
final ArrayList<Object> values = new ArrayList<>();

values.add(carDecoder.serialNumber());
values.add(carDecoder.modelYear());
values.add(carDecoder.available());
values.add(carDecoder.code());
values.add(CarDecoder.someNumbersLength());
for (int i = 0, n = CarDecoder.someNumbersLength(); i < n; i++)
{
values.add(carDecoder.someNumbers(i));
}
values.add(carDecoder.vehicleCode());
final OptionalExtrasDecoder extras = carDecoder.extras();
values.add(extras.sunRoof());
values.add(extras.sportsPack());
values.add(extras.cruiseControl());
final EngineDecoder engine = carDecoder.engine();
values.add(engine.capacity());
values.add(engine.numCylinders());
values.add(engine.maxRpm());
values.add(engine.manufacturerCode());
values.add(engine.fuel());
final CarDecoder.FuelFiguresDecoder fuelFigures = carDecoder.fuelFigures();
while (fuelFigures.hasNext())
{
fuelFigures.next();
values.add(fuelFigures.speed());
values.add(fuelFigures.mpg());
}
final CarDecoder.PerformanceFiguresDecoder performanceFigures = carDecoder.performanceFigures();
while (performanceFigures.hasNext())
{
performanceFigures.next();
values.add(performanceFigures.octaneRating());
final CarDecoder.PerformanceFiguresDecoder.AccelerationDecoder acceleration =
performanceFigures.acceleration();
while (acceleration.hasNext())
{
acceleration.next();
values.add(acceleration.mph());
values.add(acceleration.seconds());
}
}
values.add(carDecoder.manufacturer());
values.add(carDecoder.model());
values.add(carDecoder.activationCode());
return values;
}

static ArrayList<Object> getPartialValues(final CarDecoder carDecoder)
{
final ArrayList<Object> values = new ArrayList<>();

values.add(carDecoder.serialNumber());
values.add(carDecoder.modelYear());
values.add(carDecoder.available());
values.add(carDecoder.code());
values.add(CarDecoder.someNumbersLength());
for (int i = 0, n = CarDecoder.someNumbersLength(); i < n; i++)
{
values.add(carDecoder.someNumbers(i));
}
values.add(carDecoder.vehicleCode());
final OptionalExtrasDecoder extras = carDecoder.extras();
values.add(extras.sunRoof());
values.add(extras.sportsPack());
values.add(extras.cruiseControl());
final EngineDecoder engine = carDecoder.engine();
values.add(engine.capacity());
values.add(engine.numCylinders());
values.add(engine.maxRpm());
values.add(engine.manufacturerCode());
values.add(engine.fuel());
final CarDecoder.FuelFiguresDecoder fuelFigures = carDecoder.fuelFigures();
while (fuelFigures.hasNext())
{
fuelFigures.next();
values.add(fuelFigures.speed());
values.add(fuelFigures.mpg());
}
final CarDecoder.PerformanceFiguresDecoder performanceFigures = carDecoder.performanceFigures();

// Stop decoding part way through the message.
if (performanceFigures.hasNext())
{
performanceFigures.next();
values.add(performanceFigures.octaneRating());
final CarDecoder.PerformanceFiguresDecoder.AccelerationDecoder acceleration =
performanceFigures.acceleration();
if (acceleration.hasNext())
{
acceleration.next();
values.add(acceleration.mph());
}
}

return values;
}
}
Loading