Skip to content

Commit

Permalink
Merge pull request #886 from gbirchmeier/tostring
Browse files Browse the repository at this point in the history
change Message.ToString() to not change object state anymore
  • Loading branch information
gbirchmeier authored Sep 17, 2024
2 parents 0497c2a + d635d24 commit 5400f87
Show file tree
Hide file tree
Showing 15 changed files with 152 additions and 82 deletions.
2 changes: 1 addition & 1 deletion Examples/JsonToFix/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ static void JsonMsgToFix(string json, QuickFix.DataDictionary.DataDictionary ses
{
var msg = new Message();
msg.FromJson(json, true, sessionDataDictionary, appDataDictionary, msgFactory);
Console.WriteLine(msg.ToString());
Console.WriteLine(msg.ConstructString());
}

static void JsonToFix(string fname, QuickFix.DataDictionary.DataDictionary sessionDataDictionary, QuickFix.DataDictionary.DataDictionary appDataDictionary)
Expand Down
4 changes: 2 additions & 2 deletions Examples/TradeClient/TradeClientApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void ToAdmin(Message message, SessionID sessionID) { }

public void FromApp(Message message, SessionID sessionID)
{
Console.WriteLine("IN: " + message.ToString());
Console.WriteLine("IN: " + message.ConstructString());
try
{
Crack(message, sessionID);
Expand Down Expand Up @@ -57,7 +57,7 @@ public void ToApp(Message message, SessionID sessionID)
{ }

Console.WriteLine();
Console.WriteLine("OUT: " + message.ToString());
Console.WriteLine("OUT: " + message.ConstructString());
}
#endregion

Expand Down
13 changes: 11 additions & 2 deletions QuickFIXn/Fields/Converters/CheckSumConverter.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@

namespace QuickFix.Fields.Converters
namespace QuickFix.Fields.Converters
{
public static class CheckSumConverter
{
/// <summary>
/// Convert input string to int
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public static int Convert(string i)
{
return IntConverter.Convert(i);
}

/// <summary>
/// Convert input int to 3-character string
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public static string Convert(int i)
{
return i.ToString("000");
Expand Down
10 changes: 10 additions & 0 deletions QuickFIXn/Message/FieldMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -579,11 +579,21 @@ public int CalculateLength()
return total;
}

/// <summary>
/// Creates a FIX (ish) string representation of this FieldMap (does not change the object state)
/// </summary>
/// <returns></returns>
public virtual string CalculateString()
{
return CalculateString(new StringBuilder(), FieldOrder);
}

/// <summary>
/// Creates a FIX (ish) string representation of this FieldMap (does not change the object state)
/// </summary>
/// <param name="sb"></param>
/// <param name="preFields"></param>
/// <returns></returns>
public virtual string CalculateString(StringBuilder sb, int[] preFields)
{
HashSet<int> groupCounterTags = new HashSet<int>(_groups.Keys);
Expand Down
4 changes: 4 additions & 0 deletions QuickFIXn/Message/Group.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public virtual Group Clone()
/// </summary>
public int Delim { get; }

/// <summary>
/// Creates a FIX (ish) string representation of this FieldMap (does not change the object state)
/// </summary>
/// <returns></returns>
public override string CalculateString() {
return base.CalculateString(new StringBuilder(), FieldOrder ?? new[] { Delim });
}
Expand Down
10 changes: 10 additions & 0 deletions QuickFIXn/Message/Header.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,20 @@ public Header(Header src)
: base(src) {
}

/// <summary>
/// Creates a FIX (ish) string representation of this FieldMap (does not change the object state)
/// </summary>
/// <returns></returns>
public override string CalculateString() {
return base.CalculateString(new StringBuilder(), HEADER_FIELD_ORDER);
}

/// <summary>
/// Creates a FIX (ish) string representation of this FieldMap (does not change the object state)
/// </summary>
/// <param name="sb"></param>
/// <param name="preFields"></param>
/// <returns></returns>
public override string CalculateString(StringBuilder sb, int[] preFields) {
return base.CalculateString(sb, HEADER_FIELD_ORDER);
}
Expand Down
21 changes: 18 additions & 3 deletions QuickFIXn/Message/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -793,10 +793,15 @@ public SessionID GetSessionID(Message m)
m.Header.GetString(Tags.TargetCompID));
}

private Object lock_ToString = new Object();
public override string ToString()
private Object lock_ConstructString = new Object();
/// <summary>
/// Update BodyLength in Header, update CheckSum in Trailer, and return a FIX string.
/// (This function changes the object state!)
/// </summary>
/// <returns></returns>
public string ConstructString()
{
lock (lock_ToString)
lock (lock_ConstructString)
{
Header.SetField(new BodyLength(BodyLength()), true);
Trailer.SetField(new CheckSum(Fields.Converters.CheckSumConverter.Convert(CheckSum())), true);
Expand All @@ -805,6 +810,16 @@ public override string ToString()
}
}

/// <summary>
/// Create a FIX-style string from the message.
/// This does NOT add/update BodyLength or CheckSum to the message header, or otherwise change the object state.
/// (Use <see cref="ConstructString"/> to compute and add/update BodyLength &amp; CheckSum.)
/// </summary>
/// <returns></returns>
public override string ToString() {
return Header.CalculateString() + CalculateString() + Trailer.CalculateString();
}

protected int BodyLength()
{
return Header.CalculateLength() + CalculateLength() + Trailer.CalculateLength();
Expand Down
10 changes: 10 additions & 0 deletions QuickFIXn/Message/Trailer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,20 @@ public Trailer(Trailer src)
: base(src) {
}

/// <summary>
/// Creates a FIX (ish) string representation of this FieldMap (does not change the object state)
/// </summary>
/// <returns></returns>
public override string CalculateString() {
return base.CalculateString(new StringBuilder(), TRAILER_FIELD_ORDER);
}

/// <summary>
/// Creates a FIX (ish) string representation of this FieldMap (does not change the object state)
/// </summary>
/// <param name="sb"></param>
/// <param name="preFields"></param>
/// <returns></returns>
public override string CalculateString(StringBuilder sb, int[] preFields) {
return base.CalculateString(sb, TRAILER_FIELD_ORDER);
}
Expand Down
6 changes: 3 additions & 3 deletions QuickFIXn/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ protected void NextResendRequest(Message resendReq)
{
GenerateSequenceReset(resendReq, begin, msgSeqNum);
}
Send(msg.ToString());
Send(msg.ConstructString());
begin = 0;
}
current = msgSeqNum + 1;
Expand Down Expand Up @@ -1517,7 +1517,7 @@ protected bool NextQueued(SeqNumType num)
}
else
{
NextMessage(msg.ToString());
NextMessage(msg.ConstructString());
}
return true;
}
Expand Down Expand Up @@ -1567,7 +1567,7 @@ protected bool SendRaw(Message message, SeqNumType seqNum)
}
}

string messageString = message.ToString();
string messageString = message.ConstructString();
if (0 == seqNum)
Persist(message, messageString);
return Send(messageString);
Expand Down
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ What's New
* #878 - corrections to tag 45 "Side" in various DDs (gbirchmeier) - most people won't notice, easy fix if they do
* fix typo in FIX50 and FIX50SP1: `CROSS_SHORT_EXXMPT` fixed to `CROSS_SHORT_EXEMPT`
* correction in FIX41 and FIX42: `D` to `UNDISCLOSED`
* #863 - Change Message.ToString() to not alter object state anymore. (gbirchmeier)
Use new function Message.ConstructString() if you need BodyLength/CheckSum to be updated.

**Non-breaking changes**
* #864 - when multiple threads race to init DefaultMessageFactory,
Expand Down
2 changes: 1 addition & 1 deletion UnitTests/DataDictionaryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ public void CheckGroupCountTest()
//verify that FromString didn't correct the counter
//HEY YOU, READ THIS NOW: if these fail, first check if MessageTests::FromString_DoNotCorrectCounter() passes
Assert.AreEqual("386=3", n.NoTradingSessions.toStringField());
StringAssert.Contains("386=3", n.ToString());
StringAssert.Contains("386=3", n.ConstructString());

Assert.Throws<QuickFix.RepeatingGroupCountMismatch>(delegate { dd.CheckGroupCount(n.NoTradingSessions, n, "D"); });
}
Expand Down
22 changes: 22 additions & 0 deletions UnitTests/Fields/Converters/CheckSumConverterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using NUnit.Framework;
using QuickFix.Fields.Converters;

namespace UnitTests.Fields.Converters;

[TestFixture]
public class CheckSumConverterTests {
[Test]
public void ConvertStringToInt() {
Assert.AreEqual(1, CheckSumConverter.Convert("1"));
Assert.AreEqual(123, CheckSumConverter.Convert("123"));
Assert.AreEqual(12, CheckSumConverter.Convert("012"));
}

[Test]
public void ConvertIntToString() {
Assert.AreEqual("001", CheckSumConverter.Convert(1));
Assert.AreEqual("012", CheckSumConverter.Convert(12));
Assert.AreEqual("123", CheckSumConverter.Convert(123));
Assert.AreEqual("1234", CheckSumConverter.Convert(1234));
}
}
Loading

0 comments on commit 5400f87

Please sign in to comment.