forked from ServiceStack/ServiceStack.Text
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJsReader.cs
More file actions
123 lines (97 loc) · 4.69 KB
/
Copy pathJsReader.cs
File metadata and controls
123 lines (97 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
namespace ServiceStack.Text.Common
{
public class JsReader<TSerializer>
where TSerializer : ITypeSerializer
{
private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
public ParseStringDelegate GetParseFn<T>()
{
var onDeserializedFn = JsConfig<T>.OnDeserializedFn;
if (onDeserializedFn != null)
{
var parseFn = GetCoreParseFn<T>();
return value => onDeserializedFn((T)parseFn(value));
}
return GetCoreParseFn<T>();
}
private ParseStringDelegate GetCoreParseFn<T>()
{
var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
if (JsConfig<T>.HasDeserializeFn)
return value => JsConfig<T>.ParseFn(Serializer, value);
if (type.IsEnum())
return x => ParseUtils.TryParseEnum(type, Serializer.UnescapeSafeString(x));
if (type == typeof(string))
return Serializer.UnescapeString;
if (type == typeof(object))
return DeserializeType<TSerializer>.ObjectStringToType;
var specialParseFn = ParseUtils.GetSpecialParseMethod(type);
if (specialParseFn != null)
return specialParseFn;
if (type.IsArray)
{
return DeserializeArray<T, TSerializer>.Parse;
}
var builtInMethod = DeserializeBuiltin<T>.Parse;
if (builtInMethod != null)
return value => builtInMethod(Serializer.UnescapeSafeString(value));
if (type.HasGenericType())
{
if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList<>)))
return DeserializeList<T, TSerializer>.Parse;
if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary<,>)))
return DeserializeDictionary<TSerializer>.GetParseMethod(type);
if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection<>)))
return DeserializeCollection<TSerializer>.GetParseMethod(type);
if (type.HasAnyTypeDefinitionsOf(typeof(Queue<>))
|| type.HasAnyTypeDefinitionsOf(typeof(Stack<>)))
return DeserializeSpecializedCollections<T, TSerializer>.Parse;
if (type.IsOrHasGenericInterfaceTypeOf(typeof(KeyValuePair<,>)))
return DeserializeKeyValuePair<TSerializer>.GetParseMethod(type);
if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable<>)))
return DeserializeEnumerable<T, TSerializer>.Parse;
var customFn = DeserializeCustomGenericType<TSerializer>.GetParseMethod(type);
if (customFn != null)
return customFn;
}
var pclParseFn = PclExport.Instance.GetJsReaderParseMethod<TSerializer>(typeof(T));
if (pclParseFn != null)
return pclParseFn;
var isDictionary = typeof(T) != typeof(IEnumerable) && typeof(T) != typeof(ICollection)
&& (typeof(T).AssignableFrom(typeof(IDictionary)) || typeof(T).HasInterface(typeof(IDictionary)));
if (isDictionary)
{
return DeserializeDictionary<TSerializer>.GetParseMethod(type);
}
var isEnumerable = typeof(T).AssignableFrom(typeof(IEnumerable))
|| typeof(T).HasInterface(typeof(IEnumerable));
if (isEnumerable)
{
var parseFn = DeserializeSpecializedCollections<T, TSerializer>.Parse;
if (parseFn != null) return parseFn;
}
if (type.IsValueType())
{
var staticParseMethod = StaticParseMethod<T>.Parse;
if (staticParseMethod != null)
return value => staticParseMethod(Serializer.UnescapeSafeString(value));
}
else
{
var staticParseMethod = StaticParseRefTypeMethod<TSerializer, T>.Parse;
if (staticParseMethod != null)
return value => staticParseMethod(Serializer.UnescapeSafeString(value));
}
var typeConstructor = DeserializeType<TSerializer>.GetParseMethod(TypeConfig<T>.GetState());
if (typeConstructor != null)
return typeConstructor;
var stringConstructor = DeserializeTypeUtils.GetParseMethod(type);
if (stringConstructor != null) return stringConstructor;
return DeserializeType<TSerializer>.ParseAbstractType<T>;
}
}
}