|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using Prime31.Reflection;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Prime31
|
|
|
|
|
|
{
|
|
|
|
|
|
// Token: 0x0200001C RID: 28
|
|
|
|
|
|
public class PocoJsonSerializerStrategy : IJsonSerializerStrategy
|
|
|
|
|
|
{
|
|
|
|
|
|
// Token: 0x060000AA RID: 170 RVA: 0x0000749C File Offset: 0x0000569C
|
|
|
|
|
|
public PocoJsonSerializerStrategy()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.cacheResolver = new CacheResolver(new MemberMapLoader(this.buildMap));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Token: 0x060000AB RID: 171 RVA: 0x000074C0 File Offset: 0x000056C0
|
|
|
|
|
|
protected virtual void buildMap(Type type, SafeDictionary<string, CacheResolver.MemberMap> memberMaps)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
|
|
|
|
|
{
|
|
|
|
|
|
memberMaps.add(propertyInfo.Name, new CacheResolver.MemberMap(propertyInfo));
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
|
|
|
|
|
{
|
|
|
|
|
|
memberMaps.add(fieldInfo.Name, new CacheResolver.MemberMap(fieldInfo));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Token: 0x060000AC RID: 172 RVA: 0x00007544 File Offset: 0x00005744
|
|
|
|
|
|
public virtual bool serializeNonPrimitiveObject(object input, out object output)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.trySerializeKnownTypes(input, out output) || this.trySerializeUnknownTypes(input, out output);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Token: 0x060000AD RID: 173 RVA: 0x00007574 File Offset: 0x00005774
|
|
|
|
|
|
public virtual object deserializeObject(object value, Type type)
|
|
|
|
|
|
{
|
|
|
|
|
|
object obj = null;
|
|
|
|
|
|
if (value is string)
|
|
|
|
|
|
{
|
|
|
|
|
|
string text = value as string;
|
|
|
|
|
|
if (!string.IsNullOrEmpty(text) && (type == typeof(DateTime) || (ReflectionUtils.isNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime))))
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = DateTime.ParseExact(text, PocoJsonSerializerStrategy.Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = text;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (value is bool)
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (value == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if ((value is long && type == typeof(long)) || (value is double && type == typeof(double)))
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((!(value is double) || type == typeof(double)) && (!(value is long) || type == typeof(long)))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (value is IDictionary<string, object>)
|
|
|
|
|
|
{
|
|
|
|
|
|
IDictionary<string, object> dictionary = (IDictionary<string, object>)value;
|
|
|
|
|
|
if (ReflectionUtils.isTypeDictionary(type))
|
|
|
|
|
|
{
|
|
|
|
|
|
Type type2 = type.GetGenericArguments()[0];
|
|
|
|
|
|
Type type3 = type.GetGenericArguments()[1];
|
|
|
|
|
|
Type type4 = typeof(Dictionary<, >).MakeGenericType(new Type[]
|
|
|
|
|
|
{
|
|
|
|
|
|
type2,
|
|
|
|
|
|
type3
|
|
|
|
|
|
});
|
|
|
|
|
|
IDictionary dictionary2 = (IDictionary)CacheResolver.getNewInstance(type4);
|
|
|
|
|
|
foreach (KeyValuePair<string, object> keyValuePair in dictionary)
|
|
|
|
|
|
{
|
|
|
|
|
|
dictionary2.Add(keyValuePair.Key, this.deserializeObject(keyValuePair.Value, type3));
|
|
|
|
|
|
}
|
|
|
|
|
|
obj = dictionary2;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = CacheResolver.getNewInstance(type);
|
|
|
|
|
|
SafeDictionary<string, CacheResolver.MemberMap> safeDictionary = this.cacheResolver.loadMaps(type);
|
|
|
|
|
|
if (safeDictionary == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (KeyValuePair<string, CacheResolver.MemberMap> keyValuePair2 in safeDictionary)
|
|
|
|
|
|
{
|
|
|
|
|
|
CacheResolver.MemberMap value2 = keyValuePair2.Value;
|
|
|
|
|
|
if (value2.Setter != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
string key = keyValuePair2.Key;
|
|
|
|
|
|
if (dictionary.ContainsKey(key))
|
|
|
|
|
|
{
|
|
|
|
|
|
object value3 = this.deserializeObject(dictionary[key], value2.Type);
|
|
|
|
|
|
value2.Setter(obj, value3);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (value is IList<object>)
|
|
|
|
|
|
{
|
|
|
|
|
|
IList<object> list = (IList<object>)value;
|
|
|
|
|
|
IList list2 = null;
|
|
|
|
|
|
if (type.IsArray)
|
|
|
|
|
|
{
|
|
|
|
|
|
list2 = (IList)Activator.CreateInstance(type, new object[]
|
|
|
|
|
|
{
|
|
|
|
|
|
list.Count
|
|
|
|
|
|
});
|
|
|
|
|
|
int num = 0;
|
|
|
|
|
|
foreach (object value4 in list)
|
|
|
|
|
|
{
|
|
|
|
|
|
list2[num++] = this.deserializeObject(value4, type.GetElementType());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (ReflectionUtils.isTypeGenericeCollectionInterface(type) || typeof(IList).IsAssignableFrom(type))
|
|
|
|
|
|
{
|
|
|
|
|
|
Type type5 = type.GetGenericArguments()[0];
|
|
|
|
|
|
Type type6 = typeof(List<>).MakeGenericType(new Type[]
|
|
|
|
|
|
{
|
|
|
|
|
|
type5
|
|
|
|
|
|
});
|
|
|
|
|
|
list2 = (IList)CacheResolver.getNewInstance(type6);
|
|
|
|
|
|
foreach (object value5 in list)
|
|
|
|
|
|
{
|
|
|
|
|
|
list2.Add(this.deserializeObject(value5, type5));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
obj = list2;
|
|
|
|
|
|
}
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
obj = ((!typeof(IConvertible).IsAssignableFrom(type)) ? value : Convert.ChangeType(value, type, CultureInfo.InvariantCulture));
|
|
|
|
|
|
}
|
|
|
|
|
|
object result;
|
|
|
|
|
|
if (ReflectionUtils.isNullableType(type))
|
|
|
|
|
|
{
|
|
|
|
|
|
result = ReflectionUtils.toNullableType(obj, type);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
result = obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Token: 0x060000AE RID: 174 RVA: 0x000079E0 File Offset: 0x00005BE0
|
|
|
|
|
|
protected virtual object serializeEnum(Enum p)
|
|
|
|
|
|
{
|
|
|
|
|
|
return Convert.ToDouble(p, CultureInfo.InvariantCulture);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Token: 0x060000AF RID: 175 RVA: 0x00007A08 File Offset: 0x00005C08
|
|
|
|
|
|
protected virtual bool trySerializeKnownTypes(object input, out object output)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool result = true;
|
|
|
|
|
|
if (input is DateTime)
|
|
|
|
|
|
{
|
|
|
|
|
|
output = ((DateTime)input).ToUniversalTime().ToString(PocoJsonSerializerStrategy.Iso8601Format[0], CultureInfo.InvariantCulture);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (input is Guid)
|
|
|
|
|
|
{
|
|
|
|
|
|
output = ((Guid)input).ToString("D");
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (input is Uri)
|
|
|
|
|
|
{
|
|
|
|
|
|
output = input.ToString();
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (input is Enum)
|
|
|
|
|
|
{
|
|
|
|
|
|
output = this.serializeEnum((Enum)input);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
result = false;
|
|
|
|
|
|
output = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Token: 0x060000B0 RID: 176 RVA: 0x00007AB8 File Offset: 0x00005CB8
|
|
|
|
|
|
protected virtual bool trySerializeUnknownTypes(object input, out object output)
|
|
|
|
|
|
{
|
|
|
|
|
|
output = null;
|
|
|
|
|
|
Type type = input.GetType();
|
|
|
|
|
|
bool result;
|
|
|
|
|
|
if (type.FullName == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
result = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
IDictionary<string, object> dictionary = new JsonObject();
|
|
|
|
|
|
SafeDictionary<string, CacheResolver.MemberMap> safeDictionary = this.cacheResolver.loadMaps(type);
|
|
|
|
|
|
foreach (KeyValuePair<string, CacheResolver.MemberMap> keyValuePair in safeDictionary)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (keyValuePair.Value.Getter != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
dictionary.Add(keyValuePair.Key, keyValuePair.Value.Getter(input));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
output = dictionary;
|
|
|
|
|
|
result = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Token: 0x0400004F RID: 79
|
|
|
|
|
|
internal CacheResolver cacheResolver;
|
|
|
|
|
|
|
|
|
|
|
|
// Token: 0x04000050 RID: 80
|
|
|
|
|
|
private static readonly string[] Iso8601Format = new string[]
|
|
|
|
|
|
{
|
|
|
|
|
|
"yyyy-MM-dd\\THH:mm:ss.FFFFFFF\\Z",
|
|
|
|
|
|
"yyyy-MM-dd\\THH:mm:ss\\Z",
|
|
|
|
|
|
"yyyy-MM-dd\\THH:mm:ssK"
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|