Skip to content

Commit

Permalink
[C++, C#] Avoid unnecessary validation code.
Browse files Browse the repository at this point in the history
Previously, regardless of whether the min and max values were the min
and max values for the host language representation of an SBE type, we
would generate a range check. Now, we do not generate the check unless
it is meaningful.

Also, adjust the property-based test dotnet version to bring inline with
other tests.
  • Loading branch information
ZachBray committed Jun 25, 2024
1 parent 801b5ba commit 334b463
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import uk.co.real_logic.sbe.PrimitiveType;
import uk.co.real_logic.sbe.generation.CodeGenerator;
import uk.co.real_logic.sbe.generation.Generators;
import uk.co.real_logic.sbe.ir.Encoding;
import uk.co.real_logic.sbe.ir.Ir;
import uk.co.real_logic.sbe.ir.Signal;
import uk.co.real_logic.sbe.ir.Token;
Expand Down Expand Up @@ -1489,7 +1490,8 @@ private void generateSingleValueProperty(
final Token typeToken,
final String indent)
{
final String elementTypeName = cppTypeName(typeToken.encoding().primitiveType());
final Encoding encoding = typeToken.encoding();
final String elementTypeName = cppTypeName(encoding.primitiveType());
final CharSequence typeName = typeWithFieldOptionality(
fieldToken,
elementTypeName
Expand Down Expand Up @@ -1518,6 +1520,31 @@ private void generateSingleValueProperty(
.append(indent).append(INDENT).append(fieldName).append(" = value;\n")
.append(indent).append("}\n");

generateSingleValuePropertyValidateMethod(
classBuilder,
codecClassName,
propertyName,
fieldToken,
indent,
validateMethod,
typeName,
formattedPropertyName,
elementTypeName,
encoding);
}

private static void generateSingleValuePropertyValidateMethod(
final ClassBuilder classBuilder,
final String codecClassName,
final String propertyName,
final Token fieldToken,
final String indent,
final String validateMethod,
final CharSequence typeName,
final String formattedPropertyName,
final String elementTypeName,
final Encoding encoding)
{
final StringBuilder validateBuilder = classBuilder.appendPrivate().append("\n")
.append(indent).append("static void ").append(validateMethod).append("(")
.append(typeName).append(" value)\n")
Expand Down Expand Up @@ -1554,21 +1581,41 @@ private void generateSingleValueProperty(
value = "actualValue";
}

validateBuilder.append(indent).append(INDENT)
.append("if (").append(value).append(" < ")
.append(codecClassName).append("::").append(formattedPropertyName).append("MinValue() || ")
.append(value).append(" > ")
.append(codecClassName).append("::").append(formattedPropertyName).append("MaxValue())\n")
.append(indent).append(INDENT)
.append("{\n")
.append(indent).append(INDENT).append(INDENT)
.append("throw std::invalid_argument(\"")
.append(propertyName)
.append(": value is out of allowed range: \" + std::to_string(")
.append(value).append("));\n")
.append(indent).append(INDENT)
.append("}\n")
.append(indent).append("}\n");
final boolean mustPreventLesser = !encoding.applicableMinValue().equals(encoding.primitiveType().minValue());
if (mustPreventLesser)
{
validateBuilder.append(indent).append(INDENT)
.append("if (").append(value).append(" < ")
.append(codecClassName).append("::").append(formattedPropertyName).append("MinValue())\n")
.append(indent).append(INDENT)
.append("{\n")
.append(indent).append(INDENT).append(INDENT)
.append("throw std::invalid_argument(\"")
.append(propertyName)
.append(": value is less than allowed minimum: \" + std::to_string(")
.append(value).append("));\n")
.append(indent).append(INDENT)
.append("}\n");
}

final boolean mustPreventGreater = !encoding.applicableMaxValue().equals(encoding.primitiveType().maxValue());
if (mustPreventGreater)
{
validateBuilder.append(indent).append(INDENT)
.append("if (").append(value).append(" > ")
.append(codecClassName).append("::").append(formattedPropertyName).append("MaxValue())\n")
.append(indent).append(INDENT)
.append("{\n")
.append(indent).append(INDENT).append(INDENT)
.append("throw std::invalid_argument(\"")
.append(propertyName)
.append(": value is greater than allowed maximum: \" + std::to_string(")
.append(value).append("));\n")
.append(indent).append(INDENT)
.append("}\n");
}

validateBuilder.append(indent).append("}\n");
}

private void generateConstPropertyMethods(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import uk.co.real_logic.sbe.PrimitiveType;
import uk.co.real_logic.sbe.generation.CodeGenerator;
import uk.co.real_logic.sbe.generation.Generators;
import uk.co.real_logic.sbe.ir.Encoding;
import uk.co.real_logic.sbe.ir.Ir;
import uk.co.real_logic.sbe.ir.Signal;
import uk.co.real_logic.sbe.ir.Token;
Expand Down Expand Up @@ -1194,7 +1195,8 @@ private void generateSingleValueProperty(
final String indent)
{
final String nullableSuffix = fieldToken.isOptionalEncoding() ? "?" : "";
final String typeName = cSharpTypeName(typeToken.encoding().primitiveType()) + nullableSuffix;
final Encoding encoding = typeToken.encoding();
final String typeName = cSharpTypeName(encoding.primitiveType()) + nullableSuffix;
final String formattedPropertyName = formatPropertyName(propertyName);
final String fieldName = "_" + toLowerFirstChar(propertyName);

Expand Down Expand Up @@ -1242,17 +1244,35 @@ private void generateSingleValueProperty(
.append("}\n");
}

final boolean mustPreventLesser = !encoding.applicableMinValue().equals(encoding.primitiveType().minValue());
if (mustPreventLesser)
{
sb.append(indent).append(INDENT)
.append("if (value < ")
.append(codecClassName).append(".").append(formattedPropertyName).append("MinValue)\n")
.append(indent).append(INDENT)
.append("{\n")
.append(indent).append(INDENT).append(INDENT)
.append("throw new ArgumentException(\"value is less than minimum allowed: \" + value);\n")
.append(indent).append(INDENT)
.append("}\n");
}

final boolean mustPreventGreater = !encoding.applicableMaxValue().equals(encoding.primitiveType().maxValue());
if (mustPreventGreater)
{
sb.append(indent).append(INDENT)
.append("if (value > ")
.append(codecClassName).append(".").append(formattedPropertyName).append("MaxValue)\n")
.append(indent).append(INDENT)
.append("{\n")
.append(indent).append(INDENT).append(INDENT)
.append("throw new ArgumentException(\"value is greater than maximum allowed: \" + value);\n")
.append(indent).append(INDENT)
.append("}\n");
}

sb.append(indent).append(INDENT)
.append("if (value < ")
.append(codecClassName).append(".").append(formattedPropertyName).append("MinValue || value > ")
.append(codecClassName).append(".").append(formattedPropertyName).append("MaxValue)\n")
.append(indent).append(INDENT)
.append("{\n")
.append(indent).append(INDENT).append(INDENT)
.append("throw new ArgumentException(\"value is out of allowed range: \" + value);\n")
.append(indent).append(INDENT)
.append("}\n")
.append(indent).append(INDENT)
.append("return value;\n")
.append(indent).append("}\n");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 334b463

Please sign in to comment.