byte[] ISnapshotSerializer <string, ExecutionMessage> .Serialize(Version version, ExecutionMessage message) { if (version == null) { throw new ArgumentNullException(nameof(version)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } if (message.ExecutionType != ExecutionTypes.Transaction) { throw new ArgumentOutOfRangeException(nameof(message), message.ExecutionType, LocalizedStrings.Str1695Params.Put(message)); } if (message.TransactionId == 0) { throw new InvalidOperationException("TransId == 0"); } var snapshot = new TransactionSnapshot { SecurityId = message.SecurityId.ToStringId(), Portfolio = message.PortfolioName, LastChangeServerTime = message.ServerTime.To <long>(), LastChangeLocalTime = message.LocalTime.To <long>(), //OriginalTransactionId = message.OriginalTransactionId, TransactionId = message.TransactionId, HasOrderInfo = message.HasOrderInfo, HasTradeInfo = message.HasTradeInfo, BrokerCode = message.BrokerCode, ClientCode = message.ClientCode, Comment = message.Comment, SystemComment = message.SystemComment, Currency = message.Currency == null ? (short?)null : (short)message.Currency.Value, DepoName = message.DepoName, Error = message.Error?.Message, ExpiryDate = message.ExpiryDate?.To <long>(), PortfolioName = message.PortfolioName, IsMarketMaker = message.IsMarketMaker == null ? (byte?)null : (byte)(message.IsMarketMaker.Value ? 1 : 0), IsMargin = message.IsMargin == null ? (byte?)null : (byte)(message.IsMargin.Value ? 1 : 0), Side = (byte)message.Side, OrderId = message.OrderId, OrderStringId = message.OrderStringId, OrderBoardId = message.OrderBoardId, OrderPrice = message.OrderPrice, OrderVolume = message.OrderVolume, VisibleVolume = message.VisibleVolume, OrderType = message.OrderType == null ? (byte?)null : (byte)message.OrderType.Value, OrderState = message.OrderState == null ? (byte?)null : (byte)message.OrderState.Value, OrderStatus = message.OrderStatus, Balance = message.Balance, UserOrderId = message.UserOrderId, OriginSide = message.OriginSide == null ? (byte?)null : (byte)message.OriginSide.Value, Latency = message.Latency?.Ticks, PnL = message.PnL, Position = message.Position, Slippage = message.Slippage, Commission = message.Commission, TradePrice = message.TradePrice, TradeVolume = message.TradeVolume, TradeStatus = message.TradeStatus, TradeId = message.TradeId, TradeStringId = message.TradeStringId, OpenInterest = message.OpenInterest, IsSystem = message.IsSystem == null ? (byte?)null : (byte)(message.IsSystem.Value ? 1 : 0), OrderTif = message.TimeInForce == null ? (byte?)null : (byte)message.TimeInForce.Value, ConditionType = message.Condition?.GetType().GetTypeName(false), }; var conParams = message.Condition?.Parameters.Where(p => p.Value != null).ToArray() ?? ArrayHelper.Empty <KeyValuePair <string, object> >(); snapshot.ConditionParamsCount = conParams.Length; var paramSize = typeof(TransactionConditionParam).SizeOf(); var snapshotSize = typeof(TransactionSnapshot).SizeOf(); var result = new List <byte>(); var buffer = new byte[snapshotSize]; var ptr = snapshot.StructToPtr(); Marshal.Copy(ptr, buffer, 0, snapshotSize); Marshal.FreeHGlobal(ptr); result.AddRange(buffer); foreach (var conParam in conParams) { buffer = new byte[paramSize]; var param = new TransactionConditionParam { Name = conParam.Key, ValueType = conParam.Value.GetType().GetTypeAsString(false), }; byte[] stringValue = null; switch (conParam.Value) { case byte b: param.NumValue = b; break; case sbyte sb: param.NumValue = sb; break; case int i: param.NumValue = i; break; case short s: param.NumValue = s; break; case long l: param.NumValue = l; break; case uint ui: param.NumValue = ui; break; case ushort us: param.NumValue = us; break; case ulong ul: param.NumValue = (long)ul; break; case DateTimeOffset dto: param.NumValue = dto.To <long>(); break; case DateTime dt: param.NumValue = dt.To <long>(); break; case TimeSpan ts: param.NumValue = ts.To <long>(); break; case float f: param.DecimalValue = (decimal)f; break; case double d: param.DecimalValue = (decimal)d; break; case decimal dec: param.DecimalValue = dec; break; case bool bln: param.BoolValue = bln; break; case Enum e: param.NumValue = e.To <long>(); break; case IPersistable p: stringValue = new XmlSerializer <SettingsStorage>().Serialize(p.Save()); break; default: stringValue = Encoding.UTF8.GetBytes(conParam.Value.To <string>()); break; } if (stringValue != null) { param.StringValueLen = stringValue.Length; } var rowPtr = param.StructToPtr(); Marshal.Copy(rowPtr, buffer, 0, paramSize); Marshal.FreeHGlobal(rowPtr); result.AddRange(buffer); if (stringValue == null) { continue; } result.AddRange(stringValue); } return(result.ToArray()); }
byte[] ISnapshotSerializer <long, ExecutionMessage> .Serialize(Version version, ExecutionMessage message) { if (version == null) { throw new ArgumentNullException(nameof(version)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } if (message.ExecutionType != ExecutionTypes.Transaction) { throw new ArgumentOutOfRangeException(nameof(message), message.ExecutionType, LocalizedStrings.Str1695Params.Put(message)); } var snapshot = new TransactionSnapshot { SecurityId = message.SecurityId.ToStringId(), Portfolio = message.PortfolioName, LastChangeServerTime = message.ServerTime.To <long>(), LastChangeLocalTime = message.LocalTime.To <long>(), OriginalTransactionId = message.OriginalTransactionId, TransactionId = message.TransactionId, BrokerCode = message.BrokerCode, ClientCode = message.ClientCode, Comment = message.Comment, SystemComment = message.SystemComment, Currency = message.Currency == null ? (short?)null : (short)message.Currency.Value, DepoName = message.DepoName, Error = message.Error?.Message, ExpiryDate = message.ExpiryDate?.To <long>(), PortfolioName = message.PortfolioName, IsMarketMaker = message.IsMarketMaker == null ? (byte?)null : (byte)(message.IsMarketMaker.Value ? 1 : 0), IsMargin = message.IsMargin == null ? (byte?)null : (byte)(message.IsMargin.Value ? 1 : 0), Side = (byte)message.Side, OrderId = message.OrderId, OrderStringId = message.OrderStringId, OrderBoardId = message.OrderBoardId, OrderPrice = message.OrderPrice, OrderVolume = message.OrderVolume, VisibleVolume = message.VisibleVolume, OrderType = message.OrderType == null ? (byte?)null : (byte)message.OrderType.Value, OrderState = message.OrderState == null ? (byte?)null : (byte)message.OrderState.Value, OrderStatus = message.OrderStatus, Balance = message.Balance, UserOrderId = message.UserOrderId, OriginSide = message.OriginSide == null ? (byte?)null : (byte)message.OriginSide.Value, Latency = message.Latency?.Ticks, PnL = message.PnL, Position = message.Position, Slippage = message.Slippage, Commission = message.Commission, TradePrice = message.TradePrice, TradeVolume = message.TradeVolume, TradeStatus = message.TradeStatus, TradeId = message.TradeId, TradeStringId = message.TradeStringId, OpenInterest = message.OpenInterest, IsSystem = message.IsSystem == null ? (byte?)null : (byte)(message.IsSystem.Value ? 1 : 0), OrderTif = message.TimeInForce == null ? (byte?)null : (byte)message.TimeInForce.Value, ConditionType = message.Condition?.GetType().GetTypeName(false), }; var conParams = message.Condition?.Parameters.Where(p => p.Value != null).ToArray() ?? ArrayHelper.Empty <KeyValuePair <string, object> >(); snapshot.ConditionParamsCount = conParams.Length; var paramSize = typeof(TransactionConditionParam).SizeOf(); var snapshotSize = typeof(TransactionSnapshot).SizeOf(); var buffer = new byte[snapshotSize + snapshot.ConditionParamsCount * paramSize]; var ptr = snapshot.StructToPtr(); Marshal.Copy(ptr, buffer, 0, snapshotSize); Marshal.FreeHGlobal(ptr); var offset = snapshotSize; foreach (var conParam in conParams) { var param = new TransactionConditionParam { Name = conParam.Key, ValueType = conParam.Value.GetType().GetTypeAsString(false), Value = conParam.Value.To <string>(), }; var rowPtr = param.StructToPtr(); Marshal.Copy(rowPtr, buffer, offset, paramSize); Marshal.FreeHGlobal(rowPtr); offset += paramSize; } return(buffer); }