in Source/Tx.Network/Snmp/Dynamic/TrapTypeMap.cs [56:168]
internal static Func<SnmpDatagram, object> CreateTransform(Type outputTrapType)
{
var parameter = Expression.Parameter(typeof(SnmpDatagram), "snmpDatagram");
var receivedTimestampProperty = typeof (SnmpDatagram).GetProperty("ReceivedTime",
BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
var pduVarBindsField = typeof(SnmpDatagram).GetProperty(
"VarBinds",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
var sourceAddressProperty = typeof(SnmpDatagram).GetProperty(
"SourceIpAddress",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
var varbindVar = Expression.Variable(typeof(VarBind), "varBind");
var varbindValueField = typeof(VarBind).GetField("Value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
var getVarBindMethod = typeof(VarBindExtensions).GetMethod("SearchFirstSubOidWith");
var bindings = new List<MemberBinding>();
MemberAssignment notificationObjectsExpression = null, ipAddressExpresion = null, timestampExpression = null;
foreach (var p in outputTrapType.GetProperties())
{
var notificationObjectIdentifier =
p.GetCustomAttributes(typeof(SnmpOidAttribute), false).OfType<SnmpOidAttribute>().FirstOrDefault();
if (notificationObjectIdentifier == null)
{
var notificationObjects =
p.GetCustomAttributes(typeof(NotificationObjectsAttribute), false)
.OfType<NotificationObjectsAttribute>()
.FirstOrDefault();
if (notificationObjects != null && p.PropertyType.IsAssignableFrom(pduVarBindsField.PropertyType))
{
notificationObjectsExpression = Expression.Bind(p, Expression.Property(parameter, pduVarBindsField));
}
var ipAddressAttribute =
p.GetCustomAttributes(typeof(IpAddressAttribute), false)
.OfType<IpAddressAttribute>()
.FirstOrDefault();
if (ipAddressAttribute != null)
{
Expression ipAddress = Expression.Property(parameter, sourceAddressProperty);
if (p.PropertyType == typeof(IPAddress))
{
ipAddress = Expression.Call(typeof(IPAddress).GetMethod("Parse"), ipAddress);
}
ipAddressExpresion = Expression.Bind(p, ipAddress);
}
var timestampAttribute = p.GetCustomAttributes(typeof(TimestampAttribute), false)
.OfType<TimestampAttribute>()
.FirstOrDefault();
if (timestampAttribute != null && p.PropertyType.IsAssignableFrom(receivedTimestampProperty.PropertyType))
{
Expression timestamp = Expression.Property(parameter, receivedTimestampProperty);
timestampExpression = Expression.Bind(p, timestamp);
}
continue;
}
var foundValue = Expression.Call(getVarBindMethod, Expression.Property(parameter, pduVarBindsField), Expression.Constant(notificationObjectIdentifier.Oid), varbindVar);
Expression convertedValue = Expression.Field(varbindVar, varbindValueField);
if (p.PropertyType.IsEnum || typeof(int).IsAssignableFrom(p.PropertyType))
{
convertedValue = Expression.Convert(convertedValue, typeof(long));
}
else if (p.PropertyType == typeof(byte[]))
{
convertedValue = Expression.Call(
typeof(TrapTypeMap).GetMethod(
"GetRawOctetStringBytes",
BindingFlags.Static | BindingFlags.NonPublic), Expression.Convert(convertedValue, typeof(string)));
}
var conditional = Expression.Condition(
foundValue,
Expression.Convert(convertedValue, p.PropertyType),
Expression.Default(p.PropertyType));
var b = Expression.Bind(p, conditional);
bindings.Add(b);
}
if (notificationObjectsExpression != null)
{
bindings.Add(notificationObjectsExpression);
}
if (ipAddressExpresion != null)
{
bindings.Add(ipAddressExpresion);
}
if (timestampExpression != null)
{
bindings.Add(timestampExpression);
}
var newExpression = Expression.New(outputTrapType);
var memberInitialization = Expression.MemberInit(newExpression, bindings.ToArray());
var castToObject = Expression.Convert(memberInitialization, typeof(object));
var nullCheck = Expression.Condition(
Expression.Equal(Expression.Constant(null, typeof(SnmpDatagram)), parameter),
Expression.Constant(null, typeof(object)), castToObject);
var codeBlock = Expression.Block(new[] { varbindVar, }, nullCheck);
var transformExpression = Expression.Lambda<Func<SnmpDatagram, object>>(codeBlock, parameter);
return transformExpression.Compile();
}