public IStreamParser <TRecord> CreateInstance() { if (_attribute.GetType() == typeof(DelimitedRecordAttribute)) { return(new DelimitedStreamParser <TRecord>()); } else if (_attribute.GetType() == typeof(FixedWidthRecordAttribute)) { return(new FixedWidthStreamParser <TRecord>()); } throw new NotImplementedException(); }
private static Func <String, TRecord> CreateLineParser(IRecordAttribute attribute) { ParameterExpression lineExpression = Expression.Parameter(typeof(String), "line"); ParameterExpression returnExpression = Expression.Variable(typeof(TRecord), "ret"); ParameterExpression stringsExpression = Expression.Variable(typeof(String[]), "strings"); List <Expression> expressions = new List <Expression> { Expression.Assign(returnExpression, Expression.New(typeof(TRecord))) }; if (attribute.GetType() == typeof(DelimitedRecordAttribute)) { DelimitedRecordAttribute delimitedRecordAttribute = (DelimitedRecordAttribute)attribute; Expression seperatorArray = Expression.NewArrayInit(typeof(String), Expression.Constant(delimitedRecordAttribute.Delimiter)); expressions.Add(Expression.Assign(stringsExpression, Expression.Call(lineExpression, typeof(String).GetMethod("Split", new[] { typeof(String[]), typeof(StringSplitOptions) }), seperatorArray, Expression.Constant(StringSplitOptions.None)))); } int i = 0; foreach (PropertyInfo propertyInfo in typeof(TRecord).GetProperties()) { DelimitedFieldAttribute delimitedFieldAttribute = propertyInfo.GetCustomAttribute <DelimitedFieldAttribute>(false); FixedWidthFieldAttribute fixedWidthFieldAttribute = propertyInfo.GetCustomAttribute <FixedWidthFieldAttribute>(false); if (delimitedFieldAttribute == null && fixedWidthFieldAttribute == null) { // If property has no derivative of FieldAttribute then we do not include it in parsing. break; } else if (delimitedFieldAttribute != null && attribute.GetType() != typeof(DelimitedRecordAttribute)) { throw new Exception($"{propertyInfo.Name} cannot have a DelimitedField attribute."); } else if (fixedWidthFieldAttribute != null && attribute.GetType() != typeof(FixedWidthRecordAttribute)) { throw new Exception($"{propertyInfo.Name} cannot have a FixedWidthField attribute."); } if (delimitedFieldAttribute != null) { //If we are missing delimiters then we assume that it is missing. Expression valueExpression = Expression.Condition(Expression.GreaterThan(Expression.ArrayLength(stringsExpression), Expression.Constant(i)), Expression.ArrayIndex(stringsExpression, Expression.Constant(i)), Expression.Constant("")); expressions.AddRange(CreateFieldExpression(propertyInfo, delimitedFieldAttribute, returnExpression, valueExpression)); i++; } else { Expression substring = Expression.Call(lineExpression, typeof(string).GetMethod("Substring", new[] { typeof(int), typeof(int) }) ?? throw new InvalidOperationException(), Expression.Constant(i), Expression.Constant(fixedWidthFieldAttribute.FieldSize)); expressions.AddRange(CreateFieldExpression(propertyInfo, fixedWidthFieldAttribute, returnExpression, substring)); i += fixedWidthFieldAttribute.FieldSize; } } expressions.Add(returnExpression); Expression body = Expression.Block(new List <ParameterExpression> { returnExpression, stringsExpression }, expressions); LambdaExpression lambda = Expression.Lambda <Func <String, TRecord> >(body, lineExpression); return((Func <String, TRecord>)lambda.Compile()); }