11using System . ComponentModel ;
22using System . Reflection ;
3-
4- namespace parsley
5- {
3+
4+ namespace parsley
5+ {
66 public class Parser : IParser
77 {
8- protected char Delimiter { get ; set ; }
8+ protected char Delimiter { get ; set ; }
99
1010 public Parser ( ) : this ( ',' )
1111 {
@@ -28,134 +28,134 @@ public Parser(char delimiter)
2828
2929 public T [ ] Parse < T > ( string [ ] lines ) where T : IFileLine , new ( )
3030 {
31- if ( lines == null || lines . Length == 0 )
32- return [ ] ;
33-
34- var list = new T [ lines . Length ] ;
35-
36- var objLock = new object ( ) ;
37-
38- var index = 0 ;
39- var inputs = lines . Select ( line => new { Line = line , Index = index ++ } ) ;
40-
41- Parallel . ForEach ( inputs , ( ) => new List < T > ( ) ,
42- ( obj , loopstate , localStorage ) =>
43- {
44- var parsed = ParseLine < T > ( obj . Line ) ;
45-
31+ if ( lines == null || lines . Length == 0 )
32+ return [ ] ;
33+
34+ var list = new T [ lines . Length ] ;
35+
36+ var objLock = new object ( ) ;
37+
38+ var index = 0 ;
39+ var inputs = lines . Select ( line => new { Line = line , Index = index ++ } ) ;
40+
41+ Parallel . ForEach ( inputs , ( ) => new List < T > ( ) ,
42+ ( obj , loopstate , localStorage ) =>
43+ {
44+ var parsed = ParseLine < T > ( obj . Line ) ;
45+
4646 parsed . Index = obj . Index ;
4747
48- localStorage . Add ( parsed ) ;
49- return localStorage ;
50- } ,
51- finalStorage =>
52- {
53- if ( finalStorage == null )
54- return ;
55-
56- lock ( objLock )
57- finalStorage . ForEach ( f => list [ f . Index ] = f ) ;
58- } ) ;
59-
60- return list ;
48+ localStorage . Add ( parsed ) ;
49+ return localStorage ;
50+ } ,
51+ finalStorage =>
52+ {
53+ if ( finalStorage == null )
54+ return ;
55+
56+ lock ( objLock )
57+ finalStorage . ForEach ( f => list [ f . Index ] = f ) ;
58+ } ) ;
59+
60+ return list ;
6161 }
6262
63- private string [ ] ReadToLines ( string path )
64- {
63+ private string [ ] ReadToLines ( string path )
64+ {
6565 var lines = new List < string > ( ) ;
6666
6767 foreach ( var line in File . ReadLines ( path ) )
6868 {
69- if ( line != null )
69+ if ( line != null )
7070 lines . Add ( line ) ;
7171 }
72-
73- return lines . ToArray ( ) ;
74- }
75-
76- private T ParseLine < T > ( string line ) where T : IFileLine , new ( )
77- {
78- var obj = new T ( ) ;
79-
80- var values = GetDelimiterSeparatedValues ( line ) ;
81-
82- if ( values . Length == 0 || values . Length == 1 )
83- {
84- obj . SetError ( Resources . InvalidLineFormat ) ;
85- return obj ;
86- }
87-
88- var propInfos = GetLineClassPropertyInfos < T > ( ) ;
89-
90- if ( propInfos . Length == 0 )
91- {
92- obj . SetError ( string . Format ( Resources . NoColumnAttributesFoundFormat , typeof ( T ) . Name ) ) ;
93- return obj ;
94- }
95-
96- if ( propInfos . Length != values . Length )
97- {
98- obj . SetError ( Resources . InvalidLengthErrorFormat ) ;
99- return obj ;
100- }
101-
102- foreach ( var propInfo in propInfos )
103- try
104- {
105- var attribute = ( ColumnAttribute ) propInfo . GetCustomAttributes ( typeof ( ColumnAttribute ) , true ) . First ( ) ;
106-
107- var pvalue = values [ attribute . Index ] ;
108-
109- if ( string . IsNullOrWhiteSpace ( pvalue ) && attribute . DefaultValue != null )
110- pvalue = attribute . DefaultValue . ToString ( ) ;
111-
112- if ( propInfo . PropertyType . IsEnum )
113- {
114- if ( string . IsNullOrWhiteSpace ( pvalue ) )
115- {
116- obj . SetError ( string . Format ( Resources . InvalidEnumValueErrorFormat , propInfo . Name ) ) ;
117- continue ;
118- }
119-
120- if ( long . TryParse ( pvalue , out var enumLong ) )
121- {
122- var numeric = Enum . ToObject ( propInfo . PropertyType , enumLong ) ;
123- propInfo . SetValue ( obj , numeric , null ) ;
124- continue ;
125- }
126-
127- var val = Enum . Parse ( propInfo . PropertyType , pvalue , true ) ;
128- propInfo . SetValue ( obj , val , null ) ;
129- continue ;
130- }
131-
132- var converter = TypeDescriptor . GetConverter ( propInfo . PropertyType ) ;
133- var value = converter . ConvertFrom ( pvalue ) ;
134-
135- propInfo . SetValue ( obj , value , null ) ;
136- }
137- catch ( Exception e )
138- {
139- obj . SetError ( string . Format ( Resources . LineExceptionFormat , propInfo . Name , e . Message ) ) ;
140- }
141-
142- return obj ;
143- }
144-
145- private static PropertyInfo [ ] GetLineClassPropertyInfos < T > ( ) where T : IFileLine , new ( )
146- {
147- var propInfos = typeof ( T ) . GetProperties ( )
148- . Where ( p => p . GetCustomAttributes ( typeof ( ColumnAttribute ) , true ) . Any ( ) && p . CanWrite )
149- . ToArray ( ) ;
150- return propInfos ;
151- }
152-
153- private string [ ] GetDelimiterSeparatedValues ( string line )
154- {
155- var values = line . Split ( Delimiter )
156- . Select ( x => ! string . IsNullOrWhiteSpace ( x ) ? x . Trim ( ) : x )
157- . ToArray ( ) ;
158- return values ;
72+
73+ return lines . ToArray ( ) ;
74+ }
75+
76+ private T ParseLine < T > ( string line ) where T : IFileLine , new ( )
77+ {
78+ var obj = new T ( ) ;
79+
80+ var values = GetDelimiterSeparatedValues ( line ) ;
81+
82+ if ( values . Length == 0 || values . Length == 1 )
83+ {
84+ obj . SetError ( Resources . InvalidLineFormat ) ;
85+ return obj ;
86+ }
87+
88+ var propInfos = GetLineClassPropertyInfos < T > ( ) ;
89+
90+ if ( propInfos . Length == 0 )
91+ {
92+ obj . SetError ( string . Format ( Resources . NoColumnAttributesFoundFormat , typeof ( T ) . Name ) ) ;
93+ return obj ;
94+ }
95+
96+ if ( propInfos . Length != values . Length )
97+ {
98+ obj . SetError ( Resources . InvalidLengthErrorFormat ) ;
99+ return obj ;
100+ }
101+
102+ foreach ( var propInfo in propInfos )
103+ try
104+ {
105+ var attribute = ( ColumnAttribute ) propInfo . GetCustomAttributes ( typeof ( ColumnAttribute ) , true ) . First ( ) ;
106+
107+ var pvalue = values [ attribute . Index ] ;
108+
109+ if ( string . IsNullOrWhiteSpace ( pvalue ) && attribute . DefaultValue != null )
110+ pvalue = attribute . DefaultValue . ToString ( ) ;
111+
112+ if ( propInfo . PropertyType . IsEnum )
113+ {
114+ if ( string . IsNullOrWhiteSpace ( pvalue ) )
115+ {
116+ obj . SetError ( string . Format ( Resources . InvalidEnumValueErrorFormat , propInfo . Name ) ) ;
117+ continue ;
118+ }
119+
120+ if ( long . TryParse ( pvalue , out var enumLong ) )
121+ {
122+ var numeric = Enum . ToObject ( propInfo . PropertyType , enumLong ) ;
123+ propInfo . SetValue ( obj , numeric , null ) ;
124+ continue ;
125+ }
126+
127+ var val = Enum . Parse ( propInfo . PropertyType , pvalue , true ) ;
128+ propInfo . SetValue ( obj , val , null ) ;
129+ continue ;
130+ }
131+
132+ var converter = TypeDescriptor . GetConverter ( propInfo . PropertyType ) ;
133+ var value = converter . ConvertFrom ( pvalue ) ;
134+
135+ propInfo . SetValue ( obj , value , null ) ;
136+ }
137+ catch ( Exception e )
138+ {
139+ obj . SetError ( string . Format ( Resources . LineExceptionFormat , propInfo . Name , e . Message ) ) ;
140+ }
141+
142+ return obj ;
143+ }
144+
145+ private static PropertyInfo [ ] GetLineClassPropertyInfos < T > ( ) where T : IFileLine , new ( )
146+ {
147+ var propInfos = typeof ( T ) . GetProperties ( )
148+ . Where ( p => p . GetCustomAttributes ( typeof ( ColumnAttribute ) , true ) . Any ( ) && p . CanWrite )
149+ . ToArray ( ) ;
150+ return propInfos ;
151+ }
152+
153+ private string [ ] GetDelimiterSeparatedValues ( string line )
154+ {
155+ var values = line . Split ( Delimiter )
156+ . Select ( x => ! string . IsNullOrWhiteSpace ( x ) ? x . Trim ( ) : x )
157+ . ToArray ( ) ;
158+ return values ;
159159 }
160160 }
161161}
0 commit comments