Skip to content

Commit 599a692

Browse files
committed
[CSharp] Generate (more) presence checks in accessors.
Previously, some accessors did not check that the acting version (being decoded) had the field/group/varData being accessed. Therefore, it might return garbage. But other accessors did check. In this commit, I've attempted to make more of the accessors (hopefully all) check the acting version before attempting to read data from the underlying buffer. This change should make the C# codecs closer to the Java decoders.
1 parent 50198c9 commit 599a692

File tree

1 file changed

+49
-8
lines changed

1 file changed

+49
-8
lines changed

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

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,15 @@ private void generateGroupClassHeader(
255255
groupName));
256256
}
257257

258+
sb.append("\n")
259+
.append(indent).append(INDENT).append("public void NotPresent()\n")
260+
.append(indent).append(INDENT).append("{\n")
261+
.append(indent).append(TWO_INDENT).append("_count = 0;\n")
262+
.append(indent).append(TWO_INDENT).append("_index = 0;\n")
263+
.append(indent).append(TWO_INDENT).append("_buffer = null;\n")
264+
.append(indent).append(TWO_INDENT).append("_offset = 0;\n")
265+
.append(indent).append(INDENT).append("}\n");
266+
258267
sb.append(String.format("\n" +
259268
indent + INDENT + "public void WrapForDecode(%s parentMessage, DirectBuffer buffer, int actingVersion)\n" +
260269
indent + INDENT + "{\n" +
@@ -407,15 +416,18 @@ private CharSequence generateGroupProperty(
407416

408417
generateSinceActingDeprecated(sb, indent, toUpperFirstChar(groupName), token);
409418

419+
final String groupField = "_" + toLowerFirstChar(groupName);
420+
410421
sb.append(String.format("\n" +
411422
"%1$s" +
412423
indent + "public %2$sGroup %3$s\n" +
413424
indent + "{\n" +
414425
indent + INDENT + "get\n" +
415426
indent + INDENT + "{\n" +
427+
generateGroupNotPresentCondition(token.version(), indent + INDENT + INDENT, groupField) +
416428
indent + INDENT + INDENT + "_%4$s.WrapForDecode(_parentMessage, _buffer, _actingVersion);\n" +
417429
generateAccessOrderListenerCall(accessOrderModel, indent + TWO_INDENT, token,
418-
"_" + groupName + ".Count", "\"decode\"") +
430+
groupField + ".Count", "\"decode\"") +
419431
indent + INDENT + INDENT + "return _%4$s;\n" +
420432
indent + INDENT + "}\n" +
421433
indent + "}\n",
@@ -480,6 +492,7 @@ private CharSequence generateVarData(
480492
sb.append(String.format(indent + "\n" +
481493
indent + "public int %1$sLength()\n" +
482494
indent + "{\n" +
495+
generateArrayFieldNotPresentCondition(token.version(), indent, "0") +
483496
accessOrderListenerCall +
484497
indent + INDENT + "_buffer.CheckLimit(_parentMessage.Limit + %2$d);\n" +
485498
indent + INDENT + "return (int)_buffer.%3$sGet%4$s(_parentMessage.Limit);\n" +
@@ -509,7 +522,7 @@ private CharSequence generateVarData(
509522
indent + INDENT + "return bytesCopied;\n" +
510523
indent + "}\n",
511524
propertyName,
512-
generateArrayFieldNotPresentCondition(token.version(), indent),
525+
generateArrayFieldNotPresentCondition(token.version(), indent, "0"),
513526
sizeOfLengthField,
514527
lengthTypePrefix,
515528
byteOrderStr));
@@ -518,6 +531,7 @@ private CharSequence generateVarData(
518531
indent + "// Allocates and returns a new byte array\n" +
519532
indent + "public byte[] Get%1$sBytes()\n" +
520533
indent + "{\n" +
534+
generateArrayFieldNotPresentCondition(token.version(), indent, "new byte[0]") +
521535
accessOrderListenerCall +
522536
indent + INDENT + "const int sizeOfLengthField = %2$d;\n" +
523537
indent + INDENT + "int limit = _parentMessage.Limit;\n" +
@@ -561,6 +575,7 @@ private CharSequence generateVarData(
561575
.append(String.format(
562576
indent + "public string Get%1$s()\n" +
563577
indent + "{\n" +
578+
generateArrayFieldNotPresentCondition(token.version(), indent, "\"\"") +
564579
accessOrderListenerCall +
565580
indent + INDENT + "const int sizeOfLengthField = %2$d;\n" +
566581
indent + INDENT + "int limit = _parentMessage.Limit;\n" +
@@ -948,16 +963,34 @@ private CharSequence generateFieldNotPresentCondition(
948963
literal);
949964
}
950965

951-
private CharSequence generateArrayFieldNotPresentCondition(final int sinceVersion, final String indent)
966+
private CharSequence generateGroupNotPresentCondition(
967+
final int sinceVersion,
968+
final String indent,
969+
final String groupInstanceField)
952970
{
953971
if (0 == sinceVersion)
954972
{
955973
return "";
956974
}
957975

958-
return String.format(
959-
indent + INDENT + INDENT + "if (_actingVersion < %d) return 0;\n\n",
960-
sinceVersion);
976+
return indent + "if (_actingVersion < " + sinceVersion + ")" +
977+
indent + "{\n" +
978+
indent + INDENT + groupInstanceField + ".NotPresent();\n" +
979+
indent + INDENT + "return " + groupInstanceField + ";\n" +
980+
indent + "}\n\n";
981+
}
982+
983+
private CharSequence generateArrayFieldNotPresentCondition(
984+
final int sinceVersion,
985+
final String indent,
986+
final String defaultValue)
987+
{
988+
if (0 == sinceVersion)
989+
{
990+
return "";
991+
}
992+
993+
return indent + INDENT + "if (_actingVersion < " + sinceVersion + ") return " + defaultValue + ";\n\n";
961994
}
962995

963996
private CharSequence generateBitSetNotPresentCondition(
@@ -1053,6 +1086,7 @@ private CharSequence generateArrayProperty(
10531086
indent + "{\n" +
10541087
indent + INDENT + "get\n" +
10551088
indent + INDENT + "{\n" +
1089+
generateArrayFieldNotPresentCondition(fieldToken.version(), indent + INDENT + INDENT, "new %2$s[0]") +
10561090
accessOrderListenerCallDoubleIndent +
10571091
indent + INDENT + INDENT + "return _buffer.AsReadOnlySpan<%2$s>(_offset + %4$s, %3$sLength);\n" +
10581092
indent + INDENT + "}\n" +
@@ -1069,6 +1103,7 @@ private CharSequence generateArrayProperty(
10691103
"%1$s" +
10701104
indent + "public Span<%2$s> %3$sAsSpan()\n" +
10711105
indent + "{\n" +
1106+
generateArrayFieldNotPresentCondition(fieldToken.version(), indent + INDENT + INDENT, "new %2$s[0]") +
10721107
accessOrderListenerCall +
10731108
indent + INDENT + "return _buffer.AsSpan<%2$s>(_offset + %4$s, %3$sLength);\n" +
10741109
indent + "}\n",
@@ -1087,7 +1122,10 @@ private CharSequence generateArrayProperty(
10871122
accessOrderListenerCall +
10881123
indent + INDENT + "return Get%1$s(new Span<byte>(dst, dstOffset, length));\n" +
10891124
indent + "}\n",
1090-
propName, fieldLength, generateArrayFieldNotPresentCondition(fieldToken.version(), indent), offset));
1125+
propName,
1126+
fieldLength,
1127+
generateArrayFieldNotPresentCondition(fieldToken.version(), indent, "0"),
1128+
offset));
10911129

10921130
sb.append(String.format("\n" +
10931131
indent + "public int Get%1$s(Span<byte> dst)\n" +
@@ -1102,7 +1140,10 @@ private CharSequence generateArrayProperty(
11021140
indent + INDENT + "_buffer.GetBytes(_offset + %4$d, dst);\n" +
11031141
indent + INDENT + "return length;\n" +
11041142
indent + "}\n",
1105-
propName, fieldLength, generateArrayFieldNotPresentCondition(fieldToken.version(), indent), offset));
1143+
propName,
1144+
fieldLength,
1145+
generateArrayFieldNotPresentCondition(fieldToken.version(), indent, "0"),
1146+
offset));
11061147

11071148
sb.append(String.format("\n" +
11081149
indent + "public void Set%1$s(byte[] src, int srcOffset)\n" +

0 commit comments

Comments
 (0)