From 0b20b265fd91aae3a9255d3119b2ed2cc7e350d4 Mon Sep 17 00:00:00 2001 From: Ami Bar Date: Wed, 24 Apr 2024 10:59:48 +0300 Subject: [PATCH] [C#] Avoid ToString() affect the message internal state --- csharp/sbe-tests/Issue992Tests.cs | 65 +++++++++++++++++++ .../generation/csharp/CSharpGenerator.java | 20 ++++-- 2 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 csharp/sbe-tests/Issue992Tests.cs diff --git a/csharp/sbe-tests/Issue992Tests.cs b/csharp/sbe-tests/Issue992Tests.cs new file mode 100644 index 0000000000..8a5e47ca3a --- /dev/null +++ b/csharp/sbe-tests/Issue992Tests.cs @@ -0,0 +1,65 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Org.SbeTool.Sbe.Dll; +using Mktdata; + +namespace Org.SbeTool.Sbe.Tests +{ + [TestClass] + public class Issue992Tests + { + private const int Offset = 0; + private DirectBuffer _buffer; + private MessageHeader _messageHeader; + + [TestInitialize] + public void SetUp() + { + var byteArray = new byte[4096]; + _buffer = new DirectBuffer(byteArray); + + _messageHeader = new MessageHeader(); + + _messageHeader.Wrap(_buffer, 0, MessageHeader.SbeSchemaVersion); + _messageHeader.BlockLength = MDIncrementalRefreshBook46.BlockLength; + _messageHeader.SchemaId = MDIncrementalRefreshBook46.SchemaId; + _messageHeader.TemplateId = MDIncrementalRefreshBook46.TemplateId; + _messageHeader.Version = MDIncrementalRefreshBook46.SchemaVersion; + } + + [TestMethod] + public void CheckToStringDontMessWithGroupIteration() + { + var encoder = new MDIncrementalRefreshBook46() + .WrapForEncodeAndApplyHeader(_buffer, Offset, _messageHeader); + encoder.TransactTime = (ulong)new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks; + var noMDEntries = encoder.NoMDEntriesCount(2); + noMDEntries.Next(); + noMDEntries.MDEntryPx.Mantissa = 12; + noMDEntries.MDEntrySize = 3; + noMDEntries.Next(); + noMDEntries.MDEntryPx.Mantissa = 15; + noMDEntries.MDEntrySize = 7; + encoder.NoOrderIDEntriesCount(0); + encoder.CheckEncodingIsComplete(); + + var expectedString = "[MDIncrementalRefreshBook46](sbeTemplateId=46|sbeSchemaId=1|sbeSchemaVersion=9|sbeBlockLength=11):TransactTime=630822816000000000|MatchEventIndicator={0}|NoMDEntries=[(MDEntryPx=(Mantissa=12|)|MDEntrySize=3|SecurityID=0|RptSeq=0|NumberOfOrders=0|MDPriceLevel=0|MDUpdateAction=New|MDEntryType=NULL_VALUE),(MDEntryPx=(Mantissa=15|)|MDEntrySize=7|SecurityID=0|RptSeq=0|NumberOfOrders=0|MDPriceLevel=0|MDUpdateAction=New|MDEntryType=NULL_VALUE)]|NoOrderIDEntries=[]"; + + var decoder = new MDIncrementalRefreshBook46() + .WrapForDecodeAndApplyHeader(_buffer, Offset, _messageHeader); + noMDEntries = decoder.NoMDEntries; + Assert.AreEqual(expectedString, decoder.ToString()); + int counter = 0; + while (noMDEntries.HasNext) + { + Assert.AreEqual(expectedString, decoder.ToString()); + ++counter; + noMDEntries.Next(); + Assert.AreEqual(expectedString, decoder.ToString()); + } + + Assert.AreEqual(2, counter); + Assert.AreEqual(expectedString, decoder.ToString()); + } + } +} diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java index 8d15021814..585c14873e 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java @@ -181,7 +181,7 @@ public void generate() throws IOException out.append(generateVarData(fieldPrecedenceModel, varData, BASE_INDENT + INDENT)); out.append(generateDisplay(toUpperFirstChar(msgToken.name()), - fields, groups, varData, fieldPrecedenceModel)); + className, fields, groups, varData, fieldPrecedenceModel)); out.append(INDENT + "}\n"); out.append("}\n"); @@ -2511,13 +2511,22 @@ private int writeTokenDisplay( return lengthBeforeFieldSeparator; } - private void appendToString(final StringBuilder sb, final String indent) + private void appendToString(final StringBuilder sb, final String indent, final String className) { sb.append('\n'); append(sb, indent, "public override string ToString()"); append(sb, indent, "{"); append(sb, indent, " var sb = new StringBuilder(100);"); - append(sb, indent, " this.BuildString(sb);"); + if(null != className) + { + append(sb, indent, " var m = new " + className + "();"); + append(sb, indent, " m.WrapForDecode(_buffer, _offset, _actingBlockLength, _actingVersion);"); + append(sb, indent, " m.BuildString(sb);"); + } + else + { + append(sb, indent, " this.BuildString(sb);"); + } append(sb, indent, " return sb.ToString();"); append(sb, indent, "}"); } @@ -2542,6 +2551,7 @@ private CharSequence generateChoiceDisplay(final String enumName) private CharSequence generateDisplay( final String name, + final String className, final List tokens, final List groups, final List varData, @@ -2549,7 +2559,7 @@ private CharSequence generateDisplay( { final StringBuilder sb = new StringBuilder(100); - appendToString(sb, TWO_INDENT); + appendToString(sb, TWO_INDENT, className); sb.append('\n'); append(sb, TWO_INDENT, "internal void BuildString(StringBuilder builder)"); append(sb, TWO_INDENT, "{"); @@ -2607,7 +2617,7 @@ private CharSequence generateCompositeDisplay(final List tokens) { final StringBuilder sb = new StringBuilder(); - appendToString(sb, TWO_INDENT); + appendToString(sb, TWO_INDENT, null); sb.append('\n'); append(sb, TWO_INDENT, "internal void BuildString(StringBuilder builder)"); append(sb, TWO_INDENT, "{");