У меня есть следующее JSON (получено как байт [] из веб-сокета):
{
"ev": "T", // Event Type
"sym": "MSFT", // Symbol Ticker
"x": 4, // Exchange ID
"i": "12345", // Trade ID
"z": 3, // Tape ( 1=A 2=B 3=C)
"p": 114.125, // Price
"s": 100, // Trade Size
"c": [0, 1], // Trade Conditions
"t": 1536036818784 // Trade Timestamp ( Unix MS )
}
И структура:
struct Trade
{
[JsonPropertyName("sym")]
public string Symbol { get; set; }
[JsonPropertyName("p")]
public decimal Price { get; set; }
...
}
В настоящее время я иду от JSON в структуру (используя удивительную Utf8Json
lib), затем из структуры в bytes[]
.
I * sh до go прямо из JSON в MessagePack
сериализованный байтовый объект - поскольку средний шаг кажется немного избыточным.
Как можно добиться этого, сохраняя сопоставления свойств выше?
В идеале, поскольку я получаю JSON в виде байта [], я хотел бы напрямую использовать байты (вместо кодирования в строку - или, если это необходимо сделать, по крайней мере, в кодировке, не требующей больших накладных расходов).
Я могу использовать атрибуты (для JSON mapping), если это сделает все проще!
В настоящее время я смотрю на MessagePackWriter
в необработанный буфер (отрабатывая управление памятью, если мне нужно будет использовать MemoryManager
или просто сделать свой собственный * 1022). * arrays et c).
Идея будет состоять в том, чтобы записать поток непосредственно во время декодирования, и полностью исключить структуру Trade
:
private void GetTrade(ref Utf8JsonReader reader, IBufferWriter<byte> bufferWriter)
{
var trade = new Trade
{
TradeConditions = new int[] { }
};
// working how to use writer out :)
var writer = new MessagePackWriter(bufferWriter);
while (Expect(ref reader, JsonTokenType.PropertyName, JsonTokenType.EndObject))
{
var property = reader.GetString();
switch (property)
{
default:
this.logger.LogError($"decoding {trade.GetType().Name} found unexpected property {property}, skipping");
reader.Skip();
break;
case StreamFieldNames.Symbol:
trade.Symbol = ExpectString(ref reader, StreamFieldNames.Symbol);
break;
case StreamFieldNames.ExchangeId:
trade.ExchangeId = ExpectInt(ref reader, StreamFieldNames.ExchangeId);
break;
case StreamFieldNames.TradeId:
trade.TradeId = ExpectString(ref reader, StreamFieldNames.TradeId);
break;
case StreamFieldNames.Tape:
trade.Tape = ExpectInt(ref reader, StreamFieldNames.Tape);
break;
case StreamFieldNames.Price:
trade.Price = ExpectDecimal(ref reader, StreamFieldNames.Price);
break;
case StreamFieldNames.TradeSize:
trade.TradeSize = ExpectDecimal(ref reader, StreamFieldNames.TradeSize);
break;
case StreamFieldNames.TradeConditions:
trade.TradeConditions = ExpectIntArray(ref reader, StreamFieldNames.TradeConditions);
break;
case StreamFieldNames.Timestamp:
trade.Timestamp = ExpectUnixTimeMilliseconds(ref reader, StreamFieldNames.Timestamp);
break;
}
}
return trade;
}