Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions fastJSON/JSON.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@

namespace fastJSON
{
public delegate string Serialize(object data);
public delegate object Deserialize(string data);
public delegate T2 ConvertDelegate<T1, T2>(T1 t1);

public sealed class JSONParameters
{
Expand Down Expand Up @@ -308,9 +307,9 @@ public static string Beautify(string input, byte spaces)
/// <param name="type"></param>
/// <param name="serializer"></param>
/// <param name="deserializer"></param>
public static void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer)
public static void RegisterCustomType<T1, T2>(ConvertDelegate<T1, T2> serializer, ConvertDelegate<T2, T1> deserializer)
{
Reflection.Instance.RegisterCustomType(type, serializer, deserializer);
Reflection.Instance.RegisterCustomType(typeof(T1), typeof(T2), a => serializer((T1)a), a => deserializer((T2)a));
}
/// <summary>
/// Clear the internal reflection cache so you can start from new (you will loose performance)
Expand Down Expand Up @@ -450,6 +449,7 @@ private object RootHashTable(List<object> o)

private object ChangeType(object value, Type conversionType)
{
CustomConverter cc;
if (conversionType == typeof(int))
{
string s = value as string;
Expand Down Expand Up @@ -478,8 +478,9 @@ private object ChangeType(object value, Type conversionType)
else if (conversionType == typeof(DateTimeOffset))
return CreateDateTimeOffset((string)value);

else if (Reflection.Instance.IsTypeRegistered(conversionType))
return Reflection.Instance.CreateCustom((string)value, conversionType);
else if (Reflection.Instance.customTypes.TryGetValue(conversionType, out cc))
return cc.deserialize(value);


// 8-30-2014 - James Brooks - Added code for nullable types.
if (IsNullable(conversionType))
Expand Down Expand Up @@ -773,7 +774,6 @@ internal object ParseDictionary(Dictionary<string, object> d, Dictionary<string,
case myPropInfoType.StringKeyDictionary: oset = CreateStringKeyDictionary((Dictionary<string, object>)v, pi.pt, pi.GenericTypes, globaltypes); break;
case myPropInfoType.NameValue: oset = CreateNV((Dictionary<string, object>)v); break;
case myPropInfoType.StringDictionary: oset = CreateSD((Dictionary<string, object>)v); break;
case myPropInfoType.Custom: oset = Reflection.Instance.CreateCustom((string)v, pi.pt); break;
default:
{
if (pi.IsGenericType && pi.IsValueType == false && v is List<object>)
Expand All @@ -793,6 +793,9 @@ internal object ParseDictionary(Dictionary<string, object> d, Dictionary<string,
}
break;
}
CustomConverter cc;
if (Reflection.Instance.customTypes.TryGetValue(pi.pt, out cc))
oset = cc.deserialize(oset);

o = pi.setter(o, oset);
}
Expand Down
8 changes: 5 additions & 3 deletions fastJSON/JsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,11 @@ private void WriteSD(StringDictionary stringDictionary)

private void WriteCustom(object obj)
{
Serialize s;
Reflection.Instance._customSerializer.TryGetValue(obj.GetType(), out s);
WriteStringFast(s(obj));
CustomConverter s;
Reflection.Instance.customTypes.TryGetValue(obj.GetType(), out s);
WriteValue(s.serialize(obj));
//_output.Append(s(obj));
//WriteStringFast(s(obj));
}

private void WriteEnum(Enum e)
Expand Down
42 changes: 23 additions & 19 deletions fastJSON/Reflection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal enum myPropInfoType
DataSet,
DataTable,
#endif
Custom,
//Custom,
Unknown,
}

Expand All @@ -66,6 +66,14 @@ internal struct myPropInfo
public bool IsStruct;
public bool IsInterface;
}
//public delegate object Serialize(object data);
//public delegate object Deserialize(object data);
public class CustomConverter
{
public Type t;
public ConvertDelegate<object,object> serialize;
public ConvertDelegate<object, object> deserialize;
}

internal sealed class Reflection
{
Expand Down Expand Up @@ -100,33 +108,26 @@ private Reflection()

#region json custom types
// JSON custom
internal SafeDictionary<Type, Serialize> _customSerializer = new SafeDictionary<Type, Serialize>();
internal SafeDictionary<Type, Deserialize> _customDeserializer = new SafeDictionary<Type, Deserialize>();

internal object CreateCustom(string v, Type type)
{
Deserialize d;
_customDeserializer.TryGetValue(type, out d);
return d(v);
}
//internal SafeDictionary<Type, Serialize> _customSerializer = new SafeDictionary<Type, Serialize>();
//internal SafeDictionary<Type, Deserialize> _customDeserializer = new SafeDictionary<Type, Deserialize>();
internal Dictionary<Type, CustomConverter> customTypes = new Dictionary<Type, CustomConverter>();

internal void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer)
internal void RegisterCustomType(Type type, Type t, ConvertDelegate<object, object> serializer, ConvertDelegate<object, object> deserializer)
{
if (type != null && serializer != null && deserializer != null)
{
_customSerializer.Add(type, serializer);
_customDeserializer.Add(type, deserializer);
customTypes.Add(type, new CustomConverter() { deserialize = deserializer, serialize = serializer, t = t });
// reset property cache
Instance.ResetPropertyCache();
}
}

internal bool IsTypeRegistered(Type t)
{
if (_customSerializer.Count == 0)
if (customTypes.Count == 0)
return false;
Serialize s;
return _customSerializer.TryGetValue(t, out s);
CustomConverter s;
return customTypes.TryGetValue(t, out s);
}
#endregion

Expand Down Expand Up @@ -234,6 +235,11 @@ private myPropInfo CreateMyProp(Type t, string name)
myPropInfo d = new myPropInfo();
myPropInfoType d_type = myPropInfoType.Unknown;

d.pt = t;
CustomConverter cc;
if (customTypes.TryGetValue(t, out cc))
t = cc.t;

if (t == typeof(int) || t == typeof(int?)) d_type = myPropInfoType.Int;
else if (t == typeof(long) || t == typeof(long?)) d_type = myPropInfoType.Long;
else if (t == typeof(string)) d_type = myPropInfoType.String;
Expand Down Expand Up @@ -264,8 +270,7 @@ private myPropInfo CreateMyProp(Type t, string name)
else if (t == typeof(DataSet)) d_type = myPropInfoType.DataSet;
else if (t == typeof(DataTable)) d_type = myPropInfoType.DataTable;
#endif
else if (IsTypeRegistered(t))
d_type = myPropInfoType.Custom;


if (t.IsValueType && !t.IsPrimitive && !t.IsEnum && t != typeof(decimal))
d.IsStruct = true;
Expand All @@ -279,7 +284,6 @@ private myPropInfo CreateMyProp(Type t, string name)
d.bt = t.GetGenericArguments()[0];
}

d.pt = t;
d.Name = name;
d.changeType = GetChangeType(t);
d.Type = d_type;
Expand Down