66using QuickFix . DataDictionary ;
77using DD = QuickFix . DataDictionary . DataDictionary ;
88using QuickFix . ObjectPooling ;
9+ using System . IO ;
910
1011namespace QuickFix ;
1112
@@ -888,8 +889,8 @@ private static string FieldMapToXml(DD? dd, FieldMap fields)
888889 /// <summary>
889890 /// ToJSON() helper method.
890891 /// </summary>
891- /// <returns>an XML string</returns>
892- private static StringBuilder FieldMapToJson ( StringBuilder sb , DD ? dd , FieldMap fields , bool humanReadableValues , List < int > ? tagsToMask , string maskText )
892+ /// <returns>a JSON string</returns>
893+ private static void FieldMapToJson ( Utf8JsonWriter writer , DD ? dd , FieldMap fields , bool humanReadableValues , List < int > ? tagsToMask , string maskText )
893894 {
894895 IList < int > numInGroupTagList = fields . GetGroupTags ( ) ;
895896 IList < IField > numInGroupFieldList = new List < IField > ( ) ;
@@ -908,27 +909,28 @@ private static StringBuilder FieldMapToJson(StringBuilder sb, DD? dd, FieldMap f
908909
909910 if ( dd is not null && dd . FieldsByTag . TryGetValue ( field . Tag , out DDField ? ddField ) )
910911 {
911- sb . Append ( "\" " + ddField . Name + "\" :" ) ;
912+ writer . WritePropertyName ( ddField . Name ) ;
913+
912914 if ( tagsToMask != null && tagsToMask . Contains ( field . Tag ) )
913915 {
914- sb . Append ( " \" " + maskText + " \" ," ) ;
916+ writer . WriteStringValue ( maskText ) ;
915917 }
916918 else if ( humanReadableValues )
917919 {
918920 if ( dd . FieldsByTag [ field . Tag ] . EnumDict . TryGetValue ( field . ToString ( ) , out var valueDescription ) )
919- sb . Append ( " \" " + valueDescription + " \" ," ) ;
921+ writer . WriteStringValue ( valueDescription ) ;
920922 else
921- sb . Append ( " \" " + field + " \" ," ) ;
923+ writer . WriteStringValue ( field . ToString ( ) ) ;
922924 }
923925 else
924926 {
925- sb . Append ( " \" " + field + " \" ," ) ;
927+ writer . WriteStringValue ( field . ToString ( ) ) ;
926928 }
927929 }
928930 else
929931 {
930- sb . Append ( " \" " + field . Tag + " \" :" ) ;
931- sb . Append ( " \" " + field + " \" ," ) ;
932+ writer . WritePropertyName ( field . Tag . ToString ( ) ) ;
933+ writer . WriteStringValue ( field . ToString ( ) ) ;
932934 }
933935 }
934936
@@ -937,29 +939,20 @@ private static StringBuilder FieldMapToJson(StringBuilder sb, DD? dd, FieldMap f
937939 {
938940 // The name of the NumInGroup field is the key of the JSON list containing the Group items
939941 if ( dd is not null && dd . FieldsByTag . TryGetValue ( numInGroupField . Tag , out DDField ? field ) )
940- sb . Append ( " \" " + field . Name + " \" :[" ) ;
942+ writer . WriteStartArray ( field . Name ) ;
941943 else
942- sb . Append ( " \" " + numInGroupField . Tag + " \" :[" ) ;
944+ writer . WriteStartArray ( numInGroupField . Tag . ToString ( ) ) ;
943945
944946 // Populate the JSON list with the Group items
945947 for ( int counter = 1 ; counter <= fields . GroupCount ( numInGroupField . Tag ) ; counter ++ )
946948 {
947- sb . Append ( '{' ) ;
948- FieldMapToJson ( sb , dd , fields . GetGroup ( counter , numInGroupField . Tag ) , humanReadableValues , tagsToMask , maskText ) ;
949- sb . Append ( "}," ) ;
949+ writer . WriteStartObject ( ) ;
950+ FieldMapToJson ( writer , dd , fields . GetGroup ( counter , numInGroupField . Tag ) , humanReadableValues , tagsToMask , maskText ) ;
951+ writer . WriteEndObject ( ) ;
950952 }
951953
952- // Remove trailing comma
953- if ( sb . Length > 0 && sb [ ^ 1 ] == ',' )
954- sb . Remove ( sb . Length - 1 , 1 ) ;
955-
956- sb . Append ( "]," ) ;
954+ writer . WriteEndArray ( ) ;
957955 }
958- // Remove trailing comma
959- if ( sb . Length > 0 && sb [ ^ 1 ] == ',' )
960- sb . Remove ( sb . Length - 1 , 1 ) ;
961-
962- return sb ;
963956 }
964957
965958 /// <summary>
@@ -1007,11 +1000,28 @@ public string ToJSON(DD? dataDictionary = null, bool convertEnumsToDescriptions
10071000 $ "Must be non-null if '{ nameof ( convertEnumsToDescriptions ) } ' is true.") ;
10081001 }
10091002
1010- using PooledStringBuilder pooledSb = new PooledStringBuilder ( ) ;
1011- StringBuilder sb = pooledSb . Builder . Append ( '{' ) . Append ( "\" Header\" :{" ) ;
1012- FieldMapToJson ( sb , dataDictionary , Header , convertEnumsToDescriptions , tagsToMask , maskText ) . Append ( "},\" Body\" :{" ) ;
1013- FieldMapToJson ( sb , dataDictionary , this , convertEnumsToDescriptions , tagsToMask , maskText ) . Append ( "},\" Trailer\" :{" ) ;
1014- FieldMapToJson ( sb , dataDictionary , Trailer , convertEnumsToDescriptions , tagsToMask , maskText ) . Append ( "}}" ) ;
1015- return sb . ToString ( ) ;
1003+ using MemoryStream stream = new ( ) ;
1004+ using Utf8JsonWriter writer = new ( stream ) ;
1005+
1006+ writer . WriteStartObject ( ) ;
1007+ writer . WriteStartObject ( "Header" ) ;
1008+
1009+ FieldMapToJson ( writer , dataDictionary , Header , convertEnumsToDescriptions , tagsToMask , maskText ) ;
1010+
1011+ writer . WriteEndObject ( ) ;
1012+ writer . WriteStartObject ( "Body" ) ;
1013+
1014+ FieldMapToJson ( writer , dataDictionary , this , convertEnumsToDescriptions , tagsToMask , maskText ) ;
1015+
1016+ writer . WriteEndObject ( ) ;
1017+ writer . WriteStartObject ( "Trailer" ) ;
1018+
1019+ FieldMapToJson ( writer , dataDictionary , Trailer , convertEnumsToDescriptions , tagsToMask , maskText ) ;
1020+
1021+ writer . WriteEndObject ( ) ;
1022+ writer . WriteEndObject ( ) ;
1023+ writer . Flush ( ) ;
1024+
1025+ return Encoding . UTF8 . GetString ( stream . GetBuffer ( ) , 0 , ( int ) stream . Length ) ;
10161026 }
10171027}
0 commit comments