77using System . Linq . Expressions ;
88using static RecordParser . Engines . ExpressionHelper ;
99
10- internal delegate T FuncSpanIntT < T > ( ReadOnlySpan < T > span , int index ) ;
1110public delegate T FuncSpanT < T > ( ReadOnlySpan < char > text ) ;
11+ internal delegate T FuncSpanTSafe < T > ( ReadOnlySpan < char > text , Action < Exception , int > exceptionHandler ) ;
12+
1213internal delegate T FuncSpanArrayT < T > ( in TextFindHelper finder ) ;
14+ internal delegate T FuncSpanArrayTSafe < T > ( in TextFindHelper finder , Action < Exception , int > exceptionHandler ) ;
1315
1416namespace RecordParser . Engines . Reader
1517{
@@ -23,7 +25,7 @@ public static Expression<FuncSpanArrayT<T>> RecordParserSpanCSV<T>(IEnumerable<M
2325 // variables
2426 var instanceVariable = Expression . Variable ( typeof ( T ) , "inst" ) ;
2527
26- var blockThatSetProperties = MountSetProperties ( instanceVariable , mappedColumns , ( i , mapConfig ) =>
28+ var blockThatSetProperties = MountSetProperties ( instanceVariable , mappedColumns , mapConfig =>
2729 {
2830 return Expression . Call ( configParameter , nameof ( TextFindHelper . GetValue ) , Type . EmptyTypes , Expression . Constant ( mapConfig . start ) ) ;
2931 } ) ;
@@ -34,6 +36,32 @@ public static Expression<FuncSpanArrayT<T>> RecordParserSpanCSV<T>(IEnumerable<M
3436 return result ;
3537 }
3638
39+ public static Expression < FuncSpanArrayTSafe < T > > RecordParserSpanCSVSafe < T > ( IEnumerable < MappingReadConfiguration > mappedColumns , Func < T > factory )
40+ {
41+ // parameters
42+ var configParameter = Expression . Parameter ( typeof ( TextFindHelper ) . MakeByRefType ( ) , "config" ) ;
43+ var exceptionHandler = Expression . Parameter ( typeof ( Action < Exception , int > ) , "exceptionHandler" ) ;
44+
45+ // variables
46+ var instanceVariable = Expression . Variable ( typeof ( T ) , "inst" ) ;
47+
48+ var blockThatSetProperties = MountSetProperties ( instanceVariable , mappedColumns , mapConfig =>
49+ {
50+ return Expression . Call ( configParameter , nameof ( TextFindHelper . GetValue ) , Type . EmptyTypes , Expression . Constant ( mapConfig . start ) ) ;
51+ } ,
52+ ( mapConfig , assign ) =>
53+ {
54+ var visitor = new TryCatchVisitor ( exceptionHandler , mapConfig . start ) ;
55+ var result = visitor . Visit ( assign ) ;
56+ return result ;
57+ } ) ;
58+
59+ var body = MountBody ( instanceVariable , blockThatSetProperties , mappedColumns , factory ) ;
60+ var result = Expression . Lambda < FuncSpanArrayTSafe < T > > ( body , configParameter , exceptionHandler ) ;
61+
62+ return result ;
63+ }
64+
3765 public static Expression < FuncSpanT < T > > RecordParserSpanFlat < T > ( IEnumerable < MappingReadConfiguration > mappedColumns , Func < T > factory )
3866 {
3967 // parameters
@@ -42,7 +70,7 @@ public static Expression<FuncSpanT<T>> RecordParserSpanFlat<T>(IEnumerable<Mappi
4270 // variables
4371 var instanceVariable = Expression . Variable ( typeof ( T ) , "inst" ) ;
4472
45- var blockThatSetProperties = MountSetProperties ( instanceVariable , mappedColumns , ( i , mapConfig ) =>
73+ var blockThatSetProperties = MountSetProperties ( instanceVariable , mappedColumns , mapConfig =>
4674 {
4775 return Slice ( line , Expression . Constant ( mapConfig . start ) , Expression . Constant ( mapConfig . length . Value ) ) ;
4876 } ) ;
@@ -53,6 +81,32 @@ public static Expression<FuncSpanT<T>> RecordParserSpanFlat<T>(IEnumerable<Mappi
5381 return result ;
5482 }
5583
84+ public static Expression < FuncSpanTSafe < T > > RecordParserSpanFlatSafe < T > ( IEnumerable < MappingReadConfiguration > mappedColumns , Func < T > factory )
85+ {
86+ // parameters
87+ var line = Expression . Parameter ( typeof ( ReadOnlySpan < char > ) , "span" ) ;
88+ var exceptionHandler = Expression . Parameter ( typeof ( Action < Exception , int > ) , "exceptionHandler" ) ;
89+
90+ // variables
91+ var instanceVariable = Expression . Variable ( typeof ( T ) , "inst" ) ;
92+
93+ var blockThatSetProperties = MountSetProperties ( instanceVariable , mappedColumns , mapConfig =>
94+ {
95+ return Slice ( line , Expression . Constant ( mapConfig . start ) , Expression . Constant ( mapConfig . length . Value ) ) ;
96+ } ,
97+ ( mapConfig , assign ) =>
98+ {
99+ var visitor = new TryCatchVisitor ( exceptionHandler , mapConfig . start ) ;
100+ var result = visitor . Visit ( assign ) ;
101+ return result ;
102+ } ) ;
103+
104+ var body = MountBody ( instanceVariable , blockThatSetProperties , mappedColumns , factory ) ;
105+ var result = Expression . Lambda < FuncSpanTSafe < T > > ( body , line , exceptionHandler ) ;
106+
107+ return result ;
108+ }
109+
56110 private static BlockExpression MountBody < T > (
57111 ParameterExpression instanceVariable ,
58112 BlockExpression blockThatSetProperties ,
@@ -75,17 +129,15 @@ private static BlockExpression MountBody<T>(
75129 private static BlockExpression MountSetProperties (
76130 ParameterExpression objectParameter ,
77131 IEnumerable < MappingReadConfiguration > mappedColumns ,
78- Func < int , MappingReadConfiguration , Expression > getTextValue )
132+ Func < MappingReadConfiguration , Expression > getTextValue ,
133+ Func < MappingReadConfiguration , BinaryExpression , Expression > assignHandler = null )
79134 {
80135 var replacer = new ParameterReplacerVisitor ( objectParameter ) ;
81136 var assignsExpressions = new List < Expression > ( ) ;
82- var i = - 1 ;
83137
84138 foreach ( var x in mappedColumns )
85139 {
86- i ++ ;
87-
88- Expression textValue = getTextValue ( i , x ) ;
140+ Expression textValue = getTextValue ( x ) ;
89141
90142 if ( x . ShouldTrim )
91143 textValue = Trim ( textValue ) ;
@@ -115,7 +167,7 @@ private static BlockExpression MountSetProperties(
115167
116168 var assign = Expression . Assign ( replacer . Visit ( x . prop ) , valueToBeSetExpression ) ;
117169
118- assignsExpressions . Add ( assign ) ;
170+ assignsExpressions . Add ( assignHandler ? . Invoke ( x , assign ) ?? assign ) ;
119171 }
120172
121173 assignsExpressions . Add ( objectParameter ) ;
0 commit comments