1- //
2- // http://code.google.com/p/servicestack/wiki/TypeSerializer
3- // ServiceStack.Text: .NET C# POCO Type Text Serializer.
4- //
5- // Authors:
6- // Demis Bellot (demis.bellot@gmail.com)
7- //
8- // Copyright 2010 Liquidbit Ltd.
9- //
10- // Licensed under the same terms of ServiceStack: new BSD license.
11- //
12-
13- using System ;
14- using System . Collections . Generic ;
15- using System . Linq . Expressions ;
16- using System . Reflection ;
17- using System . Runtime . Serialization ;
18- using System . Text ;
19-
20- namespace ServiceStack . Text . Common
21- {
22- internal static class DeserializeType < TSerializer >
23- where TSerializer : ITypeSerializer
24- {
25- private static readonly ITypeSerializer Serializer = JsWriter . GetTypeSerializer < TSerializer > ( ) ;
26-
27- public static ParseStringDelegate GetParseMethod ( Type type )
28- {
29- if ( ! type . IsClass ) return null ;
30-
31- var propertyInfos = type . GetProperties ( ) ;
32- if ( propertyInfos . Length == 0 )
33- {
34- if ( type . IsDto ( ) )
35- {
36- var emptyCtorFn = ReflectionExtensions . GetConstructorMethodToCache ( type ) ;
37- return value => emptyCtorFn ( ) ;
38- }
39- return null ;
40- }
41-
42-
43- var setterMap = new Dictionary < string , SetPropertyDelegate > ( ) ;
44- var map = new Dictionary < string , ParseStringDelegate > ( ) ;
45-
46- foreach ( var propertyInfo in propertyInfos )
47- {
48- map [ propertyInfo . Name ] = Serializer . GetParseFn ( propertyInfo . PropertyType ) ;
49- setterMap [ propertyInfo . Name ] = GetSetPropertyMethod ( type , propertyInfo ) ;
50- }
51-
52- var ctorFn = ReflectionExtensions . GetConstructorMethodToCache ( type ) ;
53- return value => StringToType ( type , value , ctorFn , setterMap , map ) ;
54- }
55-
56- private static object StringToType ( Type type , string strType ,
57- EmptyCtorDelegate ctorFn ,
58- IDictionary < string , SetPropertyDelegate > setterMap ,
59- IDictionary < string , ParseStringDelegate > parseStringFnMap )
60- {
61- var index = 0 ;
62-
63- if ( ! Serializer . EatMapStartChar ( strType , ref index ) )
64- throw new SerializationException ( string . Format (
65- "Type definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}" ,
66- JsWriter . MapStartChar , type . Name , strType . Substring ( 0 , strType . Length < 50 ? strType . Length : 50 ) ) ) ;
67-
68-
69- var instance = ctorFn ( ) ;
70- string propertyName ;
71- ParseStringDelegate parseStringFn ;
72- SetPropertyDelegate setterFn ;
73-
74- if ( strType == JsWriter . EmptyMap ) return instance ;
75- var strTypeLength = strType . Length ;
76-
77- while ( index < strTypeLength )
78- {
79- propertyName = Serializer . EatMapKey ( strType , ref index ) ;
80-
81- Serializer . EatMapKeySeperator ( strType , ref index ) ;
82-
83- var propertyValueString = Serializer . EatValue ( strType , ref index ) ;
84-
85- parseStringFnMap . TryGetValue ( propertyName , out parseStringFn ) ;
86-
87- if ( parseStringFn != null )
88- {
89- var propertyValue = parseStringFn ( propertyValueString ) ;
90-
91- setterMap . TryGetValue ( propertyName , out setterFn ) ;
92-
93- if ( setterFn != null )
94- {
95- setterFn ( instance , propertyValue ) ;
96- }
97- }
98-
99- Serializer . EatItemSeperatorOrMapEndChar ( strType , ref index ) ;
100- }
101-
102- return instance ;
103- }
104-
105- public static SetPropertyDelegate GetSetPropertyMethod ( Type type , PropertyInfo propertyInfo )
106- {
107- var setMethodInfo = propertyInfo . GetSetMethod ( true ) ;
108- if ( setMethodInfo == null ) return null ;
109- var oInstanceParam = Expression . Parameter ( typeof ( object ) , "oInstanceParam" ) ;
110- var oValueParam = Expression . Parameter ( typeof ( object ) , "oValueParam" ) ;
111-
112- var instanceParam = Expression . Convert ( oInstanceParam , type ) ;
113- var useType = propertyInfo . PropertyType ;
114-
115- var valueParam = Expression . Convert ( oValueParam , useType ) ;
116- var exprCallPropertySetFn = Expression . Call ( instanceParam , setMethodInfo , valueParam ) ;
117-
118- var propertySetFn = Expression . Lambda < SetPropertyDelegate >
119- (
120- exprCallPropertySetFn ,
121- oInstanceParam ,
122- oValueParam
123- ) . Compile ( ) ;
124-
125- return propertySetFn ;
126- }
127- }
1+ //
2+ // http://code.google.com/p/servicestack/wiki/TypeSerializer
3+ // ServiceStack.Text: .NET C# POCO Type Text Serializer.
4+ //
5+ // Authors:
6+ // Demis Bellot (demis.bellot@gmail.com)
7+ //
8+ // Copyright 2010 Liquidbit Ltd.
9+ //
10+ // Licensed under the same terms of ServiceStack: new BSD license.
11+ //
12+
13+ using System ;
14+ using System . Collections . Generic ;
15+ using System . Linq . Expressions ;
16+ using System . Reflection ;
17+ using System . Runtime . Serialization ;
18+ using System . Text ;
19+
20+ namespace ServiceStack . Text . Common
21+ {
22+ internal static class DeserializeType < TSerializer >
23+ where TSerializer : ITypeSerializer
24+ {
25+ private static readonly ITypeSerializer Serializer = JsWriter . GetTypeSerializer < TSerializer > ( ) ;
26+
27+ public static ParseStringDelegate GetParseMethod ( Type type )
28+ {
29+ if ( ! type . IsClass ) return null ;
30+
31+ var propertyInfos = type . GetProperties ( ) ;
32+ if ( propertyInfos . Length == 0 )
33+ {
34+ var emptyCtorFn = ReflectionExtensions . GetConstructorMethodToCache ( type ) ;
35+ return value => emptyCtorFn ( ) ;
36+ }
37+
38+
39+ var setterMap = new Dictionary < string , SetPropertyDelegate > ( ) ;
40+ var map = new Dictionary < string , ParseStringDelegate > ( ) ;
41+
42+ foreach ( var propertyInfo in propertyInfos )
43+ {
44+ map [ propertyInfo . Name ] = Serializer . GetParseFn ( propertyInfo . PropertyType ) ;
45+ setterMap [ propertyInfo . Name ] = GetSetPropertyMethod ( type , propertyInfo ) ;
46+ }
47+
48+ var ctorFn = ReflectionExtensions . GetConstructorMethodToCache ( type ) ;
49+ return value => StringToType ( type , value , ctorFn , setterMap , map ) ;
50+ }
51+
52+ private static object StringToType ( Type type , string strType ,
53+ EmptyCtorDelegate ctorFn ,
54+ IDictionary < string , SetPropertyDelegate > setterMap ,
55+ IDictionary < string , ParseStringDelegate > parseStringFnMap )
56+ {
57+ var index = 0 ;
58+
59+ if ( ! Serializer . EatMapStartChar ( strType , ref index ) )
60+ throw new SerializationException ( string . Format (
61+ "Type definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}" ,
62+ JsWriter . MapStartChar , type . Name , strType . Substring ( 0 , strType . Length < 50 ? strType . Length : 50 ) ) ) ;
63+
64+
65+ var instance = ctorFn ( ) ;
66+ string propertyName ;
67+ ParseStringDelegate parseStringFn ;
68+ SetPropertyDelegate setterFn ;
69+
70+ if ( strType == JsWriter . EmptyMap ) return instance ;
71+ var strTypeLength = strType . Length ;
72+
73+ while ( index < strTypeLength )
74+ {
75+ propertyName = Serializer . EatMapKey ( strType , ref index ) ;
76+
77+ Serializer . EatMapKeySeperator ( strType , ref index ) ;
78+
79+ var propertyValueString = Serializer . EatValue ( strType , ref index ) ;
80+
81+ parseStringFnMap . TryGetValue ( propertyName , out parseStringFn ) ;
82+
83+ if ( parseStringFn != null )
84+ {
85+ var propertyValue = parseStringFn ( propertyValueString ) ;
86+
87+ setterMap . TryGetValue ( propertyName , out setterFn ) ;
88+
89+ if ( setterFn != null )
90+ {
91+ setterFn ( instance , propertyValue ) ;
92+ }
93+ }
94+
95+ Serializer . EatItemSeperatorOrMapEndChar ( strType , ref index ) ;
96+ }
97+
98+ return instance ;
99+ }
100+
101+ public static SetPropertyDelegate GetSetPropertyMethod ( Type type , PropertyInfo propertyInfo )
102+ {
103+ var setMethodInfo = propertyInfo . GetSetMethod ( true ) ;
104+ if ( setMethodInfo == null ) return null ;
105+ var oInstanceParam = Expression . Parameter ( typeof ( object ) , "oInstanceParam" ) ;
106+ var oValueParam = Expression . Parameter ( typeof ( object ) , "oValueParam" ) ;
107+
108+ var instanceParam = Expression . Convert ( oInstanceParam , type ) ;
109+ var useType = propertyInfo . PropertyType ;
110+
111+ var valueParam = Expression . Convert ( oValueParam , useType ) ;
112+ var exprCallPropertySetFn = Expression . Call ( instanceParam , setMethodInfo , valueParam ) ;
113+
114+ var propertySetFn = Expression . Lambda < SetPropertyDelegate >
115+ (
116+ exprCallPropertySetFn ,
117+ oInstanceParam ,
118+ oValueParam
119+ ) . Compile ( ) ;
120+
121+ return propertySetFn ;
122+ }
123+ }
128124}
0 commit comments