1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-12-13 09:08:59 +00:00
This commit is contained in:
Jkorf 2025-11-21 15:52:34 +01:00
parent 2b1872a868
commit ca685dadff
4 changed files with 83 additions and 35 deletions

View File

@ -51,6 +51,7 @@ namespace CryptoExchange.Net.Converters.MessageParsing.DynamicConverters
public class PropertyFieldReference : MessageFieldReference
{
public byte[] PropertyName { get; set; }
public bool ArrayValues { get; set; }
public PropertyFieldReference(string propertyName) : base(propertyName)
{
@ -72,6 +73,7 @@ namespace CryptoExchange.Net.Converters.MessageParsing.DynamicConverters
public class MessageEvalutorFieldReference
{
public bool SkipReading { get; set; }
public bool OverlappingField { get; set; }
public MessageFieldReference Field { get; set; }
public MessageEvaluator? ForceEvaluator { get; set; }
}

View File

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
namespace CryptoExchange.Net.Converters.SystemTextJson
@ -27,7 +28,6 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
private bool _hasArraySearches;
private bool _initialized;
private int _maxSearchDepth;
private bool _overlappingFields;
private MessageEvaluator? _topEvaluator;
private List<MessageEvalutorFieldReference>? _searchFields;
@ -43,68 +43,75 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
_topEvaluator ??= evaluator;
foreach (var field in evaluator.Fields)
{
if (MessageEvaluators.Where(x => x != evaluator).SelectMany(x => x.Fields).Any(otherField =>
if (field.SearchName == "event")
{
}
var overlapping = _searchFields.Where(otherField =>
{
if (field is PropertyFieldReference propRef
&& otherField is PropertyFieldReference otherPropRef)
&& otherField.Field is PropertyFieldReference otherPropRef)
{
return field.Depth == otherPropRef.Depth && propRef.PropertyName.SequenceEqual(otherPropRef.PropertyName);
}
else if (field is ArrayFieldReference arrayRef
&& otherField is ArrayFieldReference otherArrayPropRef)
&& otherField.Field is ArrayFieldReference otherArrayPropRef)
{
return field.Depth == otherArrayPropRef.Depth && arrayRef.ArrayIndex == otherArrayPropRef.ArrayIndex;
}
return false;
}))
}).ToList();
if (overlapping.Any())
{
_overlappingFields = true;
foreach (var overlap in overlapping)
overlap.OverlappingField = true;
}
MessageEvalutorFieldReference? existingSameSearchField = null;
List<MessageEvalutorFieldReference>? existingSameSearchField = new();
if (field is ArrayFieldReference arrayField)
{
_hasArraySearches = true;
existingSameSearchField = _searchFields.SingleOrDefault(x =>
existingSameSearchField = _searchFields.Where(x =>
x.Field is ArrayFieldReference arrayFieldRef
&& arrayFieldRef.ArrayIndex == arrayField.ArrayIndex
&& arrayFieldRef.Depth == arrayField.Depth
&& (arrayFieldRef.Constraint == null && arrayField.Constraint == null));
&& (arrayFieldRef.Constraint == null && arrayField.Constraint == null)).ToList();
}
else if (field is PropertyFieldReference propField)
{
existingSameSearchField = _searchFields.SingleOrDefault(x =>
existingSameSearchField = _searchFields.Where(x =>
x.Field is PropertyFieldReference propFieldRef
&& propFieldRef.PropertyName.SequenceEqual(propField.PropertyName)
&& propFieldRef.Depth == propField.Depth
&& (propFieldRef.Constraint == null && propFieldRef.Constraint == null));
&& (propFieldRef.Constraint == null && propFieldRef.Constraint == null)).ToList();
}
if (existingSameSearchField != null)
foreach(var sameSearchField in existingSameSearchField)
{
if (existingSameSearchField.SkipReading == true
&& (evaluator.IdentifyMessageCallback != null
|| field.Constraint != null))
if (sameSearchField.SkipReading == true
&& (evaluator.IdentifyMessageCallback != null || field.Constraint != null))
{
existingSameSearchField.SkipReading = false;
sameSearchField.SkipReading = false;
}
if (evaluator.ForceIfFound)
{
if (evaluator.Fields.Length > 1 || existingSameSearchField.ForceEvaluator != null)
if (evaluator.Fields.Length > 1 || sameSearchField.ForceEvaluator != null)
throw new Exception("Invalid config");
existingSameSearchField.ForceEvaluator = evaluator;
//sameSearchField.ForceEvaluator = evaluator;
}
}
_searchFields.Add(new MessageEvalutorFieldReference
{
SkipReading = evaluator.IdentifyMessageCallback == null && field.Constraint == null,
ForceEvaluator = evaluator.ForceIfFound ? evaluator : null,
ForceEvaluator = !existingSameSearchField.Any() ? (evaluator.ForceIfFound ? evaluator : null) : null,
OverlappingField = overlapping.Any(),
Field = field
});
});
if (field.Depth > _maxSearchDepth)
_maxSearchDepth = field.Depth;
@ -153,6 +160,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
if (field.Field.Depth != reader.CurrentDepth)
continue;
bool readArrayValues = false;
if (field.Field is PropertyFieldReference propFieldRef)
{
if (propName == null)
@ -164,6 +172,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
continue;
propName = propFieldRef.PropertyName;
readArrayValues = propFieldRef.ArrayValues;
reader.Read();
}
else if (!propFieldRef.PropertyName.SequenceEqual(propName))
@ -187,14 +196,40 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
{
if (value == null)
{
if (reader.TokenType == JsonTokenType.Number)
value = reader.GetDecimal().ToString();
else if (reader.TokenType == JsonTokenType.String)
value = reader.GetString()!;
else if (reader.TokenType == JsonTokenType.Null)
value = null;
if (readArrayValues)
{
if (reader.TokenType != JsonTokenType.StartArray)
{
// error
return null;
}
var sb = new StringBuilder();
reader.Read();// Read start array
bool first = true;
while(reader.TokenType != JsonTokenType.EndArray)
{
if (!first)
sb.Append(",");
first = false;
sb.Append(reader.GetString());
reader.Read();
}
value = first ? null : sb.ToString();
}
else
continue;
{
if (reader.TokenType == JsonTokenType.Number)
value = reader.GetDecimal().ToString();
else if (reader.TokenType == JsonTokenType.String)
value = reader.GetString()!;
else if (reader.TokenType == JsonTokenType.Null)
value = null;
else
continue;
}
}
if (field.Field.Constraint != null
@ -216,7 +251,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
}
written = true;
if (!_overlappingFields)
if (!field.OverlappingField)
break;
}

View File

@ -385,21 +385,32 @@ namespace CryptoExchange.Net
return new ReadOnlyMemory<byte>(decompressedStream.GetBuffer(), 0, (int)decompressedStream.Length);
}
/// <summary>
/// Decompress using GzipStream
/// </summary>
public static ReadOnlySpan<byte> Decompress(this ReadOnlySpan<byte> input)
{
using var output = new MemoryStream();
using var compressStream = new MemoryStream(input.ToArray());
using var decompressor = new DeflateStream(compressStream, CompressionMode.Decompress);
decompressor.CopyTo(output);
return new ReadOnlySpan<byte>(output.GetBuffer(), 0, (int)output.Length);
}
/// <summary>
/// Decompress using DeflateStream
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static ReadOnlySpan<byte> Decompress(this ReadOnlyMemory<byte> input)
public static ReadOnlyMemory<byte> Decompress(this ReadOnlyMemory<byte> input)
{
var output = new MemoryStream();
using (var compressStream = new MemoryStream(input.ToArray()))
using (var decompressor = new DeflateStream(compressStream, CompressionMode.Decompress))
decompressor.CopyTo(output);
using var compressStream = new MemoryStream(input.ToArray());
using var decompressor = new DeflateStream(compressStream, CompressionMode.Decompress);
decompressor.CopyTo(output);
output.Position = 0;
return new ReadOnlySpan<byte>(output.GetBuffer(), 0, (int)output.Length);
return new ReadOnlyMemory<byte>(output.GetBuffer(), 0, (int)output.Length);
}
/// <summary>

View File

@ -80,7 +80,7 @@ namespace CryptoExchange.Net.Objects.Sockets
/// </summary>
/// <param name="symbol"></param>
/// <returns></returns>
public DataEvent<T> WithSymbol(string symbol)
public DataEvent<T> WithSymbol(string? symbol)
{
Symbol = symbol;
return this;