You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
6.8 KiB
C#

4 years ago
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"
};
}
}