public Func GetTransform()

in Source/Tx.Windows.Logs/EvtxTypeMap.cs [34:99]


        public Func<EventRecord, object> GetTransform(Type outputType)
        {
            Expression<Func<EventRecord, SystemEvent>> template = e => new SystemEvent
                {
                    Header = new SystemHeader
                        {
                            ActivityId = e.ActivityId.HasValue ? e.ActivityId.Value : Guid.Empty,
                            Channel = 0,
                            Context = e.LogName,
                            Level = e.Level.Value,
                            EventId = (ushort) e.Id,
                            Keywords = e.Keywords.HasValue ? (ulong) e.Keywords.Value : (ulong) 0,
                            Opcode = e.Opcode.HasValue ? (byte) e.Opcode.Value : (byte) 0,
                            ProcessId = e.ProcessId.HasValue ? (uint) e.ProcessId.Value : 0,
                            ProviderId = e.ProviderId.HasValue ? e.ProviderId.Value : Guid.Empty,
                            RelatedActivityId = e.RelatedActivityId.HasValue ? e.RelatedActivityId.Value : Guid.Empty,
                            Task = e.Task.HasValue ? (ushort) e.Task.Value : (ushort) 0,
                            ThreadId = e.ThreadId.HasValue ? (uint) e.ThreadId.Value : (uint) 0,
                            Timestamp = e.TimeCreated.HasValue ? e.TimeCreated.Value : DateTime.MinValue,
                            Version = e.Version.HasValue ? e.Version.Value : (byte) 0
                        }
                };

            if (outputType == typeof (SystemEvent))
                return template.Compile();

            LambdaExpression ex = template;
            var mi = (MemberInitExpression) ex.Body;
            var bindings = new List<MemberBinding>(mi.Bindings);
            ParameterExpression record = ex.Parameters[0];

            PropertyInfo[] properties = outputType.GetProperties();
            int index = 0;
            foreach (PropertyInfo p in properties)
            {
                var attribute = p.GetCustomAttribute<EventFieldAttribute>();
                if (attribute == null) continue;

                // the following is to handle value maps, that were emitted as enumerations
                Type t; 
                if (p.PropertyType.IsEnum)
                    t=p.PropertyType;
                else
                    t = GetSimpleType(attribute.OriginalType);

                MemberAssignment b = Expression.Bind(p, Expression.Convert(
                                                            Expression.Property(
                                                                Expression.Call(
                                                                    Expression.Property(record,
                                                                                        typeof(EventRecord).GetProperty(
                                                                                            "Properties")),
                                                                    typeof(IList<EventProperty>).GetMethod("get_Item"),
                                                                    Expression.Constant(index++)),
                                                                typeof(EventProperty).GetProperty("Value")),
                                                            t));

                bindings.Add(b);
            }

            NewExpression n = Expression.New(outputType);
            MemberInitExpression m = Expression.MemberInit(n, bindings.ToArray());
            UnaryExpression cast = Expression.Convert(m, typeof (object));
            Expression<Func<EventRecord, object>> exp = Expression.Lambda<Func<EventRecord, object>>(cast, ex.Parameters);

            return exp.Compile();
        }