15
15
using System . Reflection ;
16
16
using System . Linq ;
17
17
using System . Threading ;
18
+ #if NETSTANDARD1_1
19
+ using Microsoft . Extensions . Primitives ;
20
+ #endif
21
+ using ServiceStack . Text . Support ;
18
22
19
23
namespace ServiceStack . Text . Common
20
24
{
@@ -24,15 +28,23 @@ public static class DeserializeArrayWithElements<TSerializer>
24
28
private static Dictionary < Type , ParseArrayOfElementsDelegate > ParseDelegateCache
25
29
= new Dictionary < Type , ParseArrayOfElementsDelegate > ( ) ;
26
30
27
- private delegate object ParseArrayOfElementsDelegate ( string value , ParseStringDelegate parseFn ) ;
31
+ private delegate object ParseArrayOfElementsDelegate ( StringSegment value , ParseStringSegmentDelegate parseFn ) ;
28
32
29
33
public static Func < string , ParseStringDelegate , object > GetParseFn ( Type type )
34
+ {
35
+ var func = GetParseStringSegmentFn ( type ) ;
36
+ return ( s , d ) => func ( new StringSegment ( s ) , v => d ( v . Value ) ) ;
37
+ }
38
+
39
+ private static readonly Type [ ] signature = { typeof ( StringSegment ) , typeof ( ParseStringSegmentDelegate ) } ;
40
+
41
+ public static Func < StringSegment , ParseStringSegmentDelegate , object > GetParseStringSegmentFn ( Type type )
30
42
{
31
43
ParseArrayOfElementsDelegate parseFn ;
32
44
if ( ParseDelegateCache . TryGetValue ( type , out parseFn ) ) return parseFn . Invoke ;
33
45
34
46
var genericType = typeof ( DeserializeArrayWithElements < , > ) . MakeGenericType ( type , typeof ( TSerializer ) ) ;
35
- var mi = genericType . GetStaticMethod ( "ParseGenericArray" ) ;
47
+ var mi = genericType . GetStaticMethod ( "ParseGenericArray" , signature ) ;
36
48
parseFn = ( ParseArrayOfElementsDelegate ) mi . CreateDelegate ( typeof ( ParseArrayOfElementsDelegate ) ) ;
37
49
38
50
Dictionary < Type , ParseArrayOfElementsDelegate > snapshot , newCache ;
@@ -54,14 +66,17 @@ public static class DeserializeArrayWithElements<T, TSerializer>
54
66
{
55
67
private static readonly ITypeSerializer Serializer = JsWriter . GetTypeSerializer < TSerializer > ( ) ;
56
68
57
- public static T [ ] ParseGenericArray ( string value , ParseStringDelegate elementParseFn )
69
+ public static T [ ] ParseGenericArray ( string value , ParseStringDelegate elementParseFn ) =>
70
+ ParseGenericArray ( new StringSegment ( value ) , v => elementParseFn ( v . Value ) ) ;
71
+
72
+ public static T [ ] ParseGenericArray ( StringSegment value , ParseStringSegmentDelegate elementParseFn )
58
73
{
59
- if ( ( value = DeserializeListWithElements < TSerializer > . StripList ( value ) ) == null ) return null ;
60
- if ( value == string . Empty ) return new T [ 0 ] ;
74
+ if ( ! ( value = DeserializeListWithElements < TSerializer > . StripList ( value ) ) . HasValue ) return null ;
75
+ if ( value . Length == 0 ) return new T [ 0 ] ;
61
76
62
- if ( value [ 0 ] == JsWriter . MapStartChar )
77
+ if ( value . GetChar ( 0 ) == JsWriter . MapStartChar )
63
78
{
64
- var itemValues = new List < string > ( ) ;
79
+ var itemValues = new List < StringSegment > ( ) ;
65
80
var i = 0 ;
66
81
do
67
82
{
@@ -104,25 +119,27 @@ public static T[] ParseGenericArray(string value, ParseStringDelegate elementPar
104
119
internal static class DeserializeArray < TSerializer >
105
120
where TSerializer : ITypeSerializer
106
121
{
107
- private static Dictionary < Type , ParseStringDelegate > ParseDelegateCache = new Dictionary < Type , ParseStringDelegate > ( ) ;
122
+ private static Dictionary < Type , ParseStringSegmentDelegate > ParseDelegateCache = new Dictionary < Type , ParseStringSegmentDelegate > ( ) ;
108
123
109
- public static ParseStringDelegate GetParseFn ( Type type )
124
+ public static ParseStringDelegate GetParseFn ( Type type ) => v => GetParseStringSegmentFn ( type ) ( new StringSegment ( v ) ) ;
125
+
126
+ public static ParseStringSegmentDelegate GetParseStringSegmentFn ( Type type )
110
127
{
111
- ParseStringDelegate parseFn ;
128
+ ParseStringSegmentDelegate parseFn ;
112
129
if ( ParseDelegateCache . TryGetValue ( type , out parseFn ) ) return parseFn ;
113
130
114
131
var genericType = typeof ( DeserializeArray < , > ) . MakeGenericType ( type , typeof ( TSerializer ) ) ;
115
132
116
- var mi = genericType . GetStaticMethod ( "GetParseFn " ) ;
117
- var parseFactoryFn = ( Func < ParseStringDelegate > ) mi . MakeDelegate (
118
- typeof ( Func < ParseStringDelegate > ) ) ;
133
+ var mi = genericType . GetStaticMethod ( "GetParseStringSegmentFn " ) ;
134
+ var parseFactoryFn = ( Func < ParseStringSegmentDelegate > ) mi . MakeDelegate (
135
+ typeof ( Func < ParseStringSegmentDelegate > ) ) ;
119
136
parseFn = parseFactoryFn ( ) ;
120
137
121
- Dictionary < Type , ParseStringDelegate > snapshot , newCache ;
138
+ Dictionary < Type , ParseStringSegmentDelegate > snapshot , newCache ;
122
139
do
123
140
{
124
141
snapshot = ParseDelegateCache ;
125
- newCache = new Dictionary < Type , ParseStringDelegate > ( ParseDelegateCache ) ;
142
+ newCache = new Dictionary < Type , ParseStringSegmentDelegate > ( ParseDelegateCache ) ;
126
143
newCache [ type ] = parseFn ;
127
144
128
145
} while ( ! ReferenceEquals (
@@ -137,19 +154,20 @@ internal static class DeserializeArray<T, TSerializer>
137
154
{
138
155
private static readonly ITypeSerializer Serializer = JsWriter . GetTypeSerializer < TSerializer > ( ) ;
139
156
140
- private static readonly ParseStringDelegate CacheFn ;
157
+ private static readonly ParseStringSegmentDelegate CacheFn ;
141
158
142
159
static DeserializeArray ( )
143
160
{
144
- CacheFn = GetParseFn ( ) ;
161
+ CacheFn = GetParseStringSegmentFn ( ) ;
145
162
}
146
163
147
- public static ParseStringDelegate Parse
148
- {
149
- get { return CacheFn ; }
150
- }
164
+ public static ParseStringDelegate Parse => v => CacheFn ( new StringSegment ( v ) ) ;
165
+
166
+ public static ParseStringSegmentDelegate ParseStringSegment => CacheFn ;
151
167
152
- public static ParseStringDelegate GetParseFn ( )
168
+ public static ParseStringDelegate GetParseFn ( ) => v => GetParseStringSegmentFn ( ) ( new StringSegment ( v ) ) ;
169
+
170
+ public static ParseStringSegmentDelegate GetParseStringSegmentFn ( )
153
171
{
154
172
var type = typeof ( T ) ;
155
173
if ( ! type . IsArray )
@@ -158,18 +176,27 @@ public static ParseStringDelegate GetParseFn()
158
176
if ( type == typeof ( string [ ] ) )
159
177
return ParseStringArray ;
160
178
if ( type == typeof ( byte [ ] ) )
161
- return ParseByteArray ;
179
+ return v => ParseByteArray ( v . Value ) ;
162
180
163
181
var elementType = type . GetElementType ( ) ;
164
- var elementParseFn = Serializer . GetParseFn ( elementType ) ;
182
+ var elementParseFn = Serializer . GetParseStringSegmentFn ( elementType ) ;
165
183
if ( elementParseFn != null )
166
184
{
167
- var parseFn = DeserializeArrayWithElements < TSerializer > . GetParseFn ( elementType ) ;
185
+ var parseFn = DeserializeArrayWithElements < TSerializer > . GetParseStringSegmentFn ( elementType ) ;
168
186
return value => parseFn ( value , elementParseFn ) ;
169
187
}
170
188
return null ;
171
189
}
172
190
191
+ public static string [ ] ParseStringArray ( StringSegment value )
192
+ {
193
+ if ( ! ( value = DeserializeListWithElements < TSerializer > . StripList ( value ) ) . HasValue ) return null ;
194
+ return value . Length == 0
195
+ ? TypeConstants . EmptyStringArray
196
+ : DeserializeListWithElements < TSerializer > . ParseStringList ( value ) . ToArray ( ) ;
197
+ }
198
+
199
+
173
200
public static string [ ] ParseStringArray ( string value )
174
201
{
175
202
if ( ( value = DeserializeListWithElements < TSerializer > . StripList ( value ) ) == null ) return null ;
0 commit comments