Created
August 15, 2014 21:09
-
-
Save lbv/87aa07d4f187743ef8ad to your computer and use it in GitHub Desktop.
LitJSON patched mapper, by @oddgames-david
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Originally from: https://github.com/lbv/litjson/pull/7#issuecomment-28179440 | |
#region Header | |
/** | |
* JsonMapper.cs | |
* JSON to .Net object and object to JSON conversions. | |
* | |
* The authors disclaim copyright to this source code. For more details, see | |
* the COPYING file included with this distribution. | |
**/ | |
#endregion | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.IO; | |
using System.Reflection; | |
namespace LitJson | |
{ | |
internal struct PropertyMetadata | |
{ | |
public MemberInfo Info; | |
public bool IsField; | |
public Type Type; | |
public JsonIgnoreWhen Ignore; | |
} | |
internal struct ArrayMetadata | |
{ | |
private Type element_type; | |
private bool is_array; | |
private bool is_list; | |
public Type ElementType { | |
get { | |
if (element_type == null) | |
return typeof (JsonData); | |
return element_type; | |
} | |
set { element_type = value; } | |
} | |
public bool IsArray { | |
get { return is_array; } | |
set { is_array = value; } | |
} | |
public bool IsList { | |
get { return is_list; } | |
set { is_list = value; } | |
} | |
} | |
internal struct ObjectMetadata | |
{ | |
private Type element_type; | |
private bool is_dictionary; | |
private IDictionary<string, PropertyMetadata> properties; | |
public Type ElementType { | |
get { | |
if (element_type == null) | |
return typeof (JsonData); | |
return element_type; | |
} | |
set { element_type = value; } | |
} | |
public bool IsDictionary { | |
get { return is_dictionary; } | |
set { is_dictionary = value; } | |
} | |
public IDictionary<string, PropertyMetadata> Properties { | |
get { return properties; } | |
set { properties = value; } | |
} | |
} | |
internal delegate void ExporterFunc (object obj, JsonWriter writer); | |
public delegate void ExporterFunc<T> (T obj, JsonWriter writer); | |
internal delegate object ImporterFunc (object input); | |
public delegate TValue ImporterFunc<TJson, TValue> (TJson input); | |
public delegate IJsonWrapper WrapperFactory (); | |
public class JsonMapper | |
{ | |
#region Fields | |
private static int max_nesting_depth; | |
private static IFormatProvider datetime_format; | |
private static IDictionary<Type, ExporterFunc> base_exporters_table; | |
private static IDictionary<Type, ExporterFunc> custom_exporters_table; | |
private static IDictionary<Type, | |
IDictionary<Type, ImporterFunc>> base_importers_table; | |
private static IDictionary<Type, | |
IDictionary<Type, ImporterFunc>> custom_importers_table; | |
private static IDictionary<Type, ArrayMetadata> array_metadata; | |
private static readonly object array_metadata_lock = new Object (); | |
private static IDictionary<Type, | |
IDictionary<Type, MethodInfo>> conv_ops; | |
private static readonly object conv_ops_lock = new Object (); | |
private static IDictionary<Type, ObjectMetadata> object_metadata; | |
private static readonly object object_metadata_lock = new Object (); | |
private static IDictionary<Type, | |
IList<PropertyMetadata>> type_properties; | |
private static readonly object type_properties_lock = new Object (); | |
private static JsonWriter static_writer; | |
private static readonly object static_writer_lock = new Object (); | |
#endregion | |
#region Constructors | |
static JsonMapper () | |
{ | |
max_nesting_depth = 100; | |
array_metadata = new Dictionary<Type, ArrayMetadata> (); | |
conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>> (); | |
object_metadata = new Dictionary<Type, ObjectMetadata> (); | |
type_properties = new Dictionary<Type, | |
IList<PropertyMetadata>> (); | |
static_writer = new JsonWriter (); | |
datetime_format = DateTimeFormatInfo.InvariantInfo; | |
base_exporters_table = new Dictionary<Type, ExporterFunc> (); | |
custom_exporters_table = new Dictionary<Type, ExporterFunc> (); | |
base_importers_table = new Dictionary<Type, | |
IDictionary<Type, ImporterFunc>> (); | |
custom_importers_table = new Dictionary<Type, | |
IDictionary<Type, ImporterFunc>> (); | |
RegisterBaseExporters (); | |
RegisterBaseImporters (); | |
} | |
#endregion | |
#region Private Methods | |
private static void AddArrayMetadata (Type type) | |
{ | |
if (array_metadata.ContainsKey (type)) | |
return; | |
ArrayMetadata data = new ArrayMetadata (); | |
data.IsArray = type.IsArray; | |
if (type.GetInterface ("System.Collections.IList") != null) | |
data.IsList = true; | |
foreach (PropertyInfo p_info in type.GetProperties ()) { | |
if (p_info.Name != "Item") | |
continue; | |
ParameterInfo[] parameters = p_info.GetIndexParameters (); | |
if (parameters.Length != 1) | |
continue; | |
if (parameters[0].ParameterType == typeof (int)) | |
data.ElementType = p_info.PropertyType; | |
} | |
lock (array_metadata_lock) { | |
try { | |
array_metadata.Add (type, data); | |
} catch (ArgumentException) { | |
return; | |
} | |
} | |
} | |
private static void AddObjectMetadata (Type type) | |
{ | |
if (object_metadata.ContainsKey (type)) | |
return; | |
ObjectMetadata data = new ObjectMetadata (); | |
if (type.GetInterface ("System.Collections.IDictionary") != null) | |
data.IsDictionary = true; | |
data.Properties = new Dictionary<string, PropertyMetadata> (); | |
foreach (PropertyInfo p_info in type.GetProperties ()) { | |
if (p_info.Name == "Item") { | |
ParameterInfo[] parameters = p_info.GetIndexParameters (); | |
if (parameters.Length != 1) | |
continue; | |
if (parameters[0].ParameterType == typeof (string)) | |
data.ElementType = p_info.PropertyType; | |
continue; | |
} | |
PropertyMetadata p_data = new PropertyMetadata (); | |
p_data.Info = p_info; | |
p_data.Type = p_info.PropertyType; | |
ProcessAttributes(ref p_data, p_info); | |
data.Properties.Add (p_info.Name, p_data); | |
} | |
foreach (FieldInfo f_info in type.GetFields ()) { | |
PropertyMetadata p_data = new PropertyMetadata (); | |
p_data.Info = f_info; | |
p_data.IsField = true; | |
p_data.Type = f_info.FieldType; | |
ProcessAttributes(ref p_data, f_info); | |
data.Properties.Add (f_info.Name, p_data); | |
} | |
lock (object_metadata_lock) { | |
try { | |
object_metadata.Add (type, data); | |
} catch (ArgumentException) { | |
return; | |
} | |
} | |
} | |
private static void AddTypeProperties (Type type) | |
{ | |
if (type_properties.ContainsKey (type)) | |
return; | |
IList<PropertyMetadata> props = new List<PropertyMetadata> (); | |
foreach (PropertyInfo p_info in type.GetProperties ()) { | |
if (p_info.Name == "Item") | |
continue; | |
PropertyMetadata p_data = new PropertyMetadata (); | |
p_data.Info = p_info; | |
p_data.IsField = false; | |
ProcessAttributes(ref p_data, p_info); | |
props.Add (p_data); | |
} | |
foreach (FieldInfo f_info in type.GetFields ()) { | |
PropertyMetadata p_data = new PropertyMetadata (); | |
p_data.Info = f_info; | |
p_data.IsField = true; | |
ProcessAttributes(ref p_data, f_info); | |
props.Add (p_data); | |
} | |
lock (type_properties_lock) { | |
try { | |
type_properties.Add (type, props); | |
} catch (ArgumentException) { | |
return; | |
} | |
} | |
} | |
private static void ProcessAttributes (ref PropertyMetadata p_data, MemberInfo m_info) | |
{ | |
foreach (Attribute attr in m_info.GetCustomAttributes(true)) { | |
if (attr is JsonIgnore) { | |
JsonIgnore ignore_attr = (JsonIgnore)attr; | |
p_data.Ignore = ignore_attr.Usage; | |
} | |
} | |
} | |
private static MethodInfo GetConvOp (Type t1, Type t2) | |
{ | |
lock (conv_ops_lock) { | |
if (! conv_ops.ContainsKey (t1)) | |
conv_ops.Add (t1, new Dictionary<Type, MethodInfo> ()); | |
} | |
if (conv_ops[t1].ContainsKey (t2)) | |
return conv_ops[t1][t2]; | |
MethodInfo op = t1.GetMethod ( | |
"op_Implicit", new Type[] { t2 }); | |
lock (conv_ops_lock) { | |
try { | |
conv_ops[t1].Add (t2, op); | |
} catch (ArgumentException) { | |
return conv_ops[t1][t2]; | |
} | |
} | |
return op; | |
} | |
private static object ReadValue (Type inst_type, JsonReader reader) | |
{ | |
reader.Read (); | |
if (reader.Token == JsonToken.ArrayEnd) | |
return null; | |
if (reader.Token == JsonToken.Null) { | |
if (! inst_type.IsClass) | |
throw new JsonException (String.Format ( | |
"Can't assign null to an instance of type {0}", | |
inst_type)); | |
return null; | |
} | |
if (reader.Token == JsonToken.Double || | |
reader.Token == JsonToken.Int || | |
reader.Token == JsonToken.Long || | |
reader.Token == JsonToken.String || | |
reader.Token == JsonToken.Boolean) { | |
Type json_type = reader.Value.GetType (); | |
if (inst_type.IsAssignableFrom (json_type)) | |
return reader.Value; | |
// If there's a custom importer that fits, use it | |
if (custom_importers_table.ContainsKey (json_type) && | |
custom_importers_table[json_type].ContainsKey ( | |
inst_type)) { | |
ImporterFunc importer = | |
custom_importers_table[json_type][inst_type]; | |
return importer (reader.Value); | |
} | |
// Maybe there's a base importer that works | |
if (base_importers_table.ContainsKey (json_type) && | |
base_importers_table[json_type].ContainsKey ( | |
inst_type)) { | |
ImporterFunc importer = | |
base_importers_table[json_type][inst_type]; | |
return importer (reader.Value); | |
} | |
// Maybe it's an enum | |
if (inst_type.IsEnum) | |
return Enum.ToObject (inst_type, reader.Value); | |
// Try using an implicit conversion operator | |
MethodInfo conv_op = GetConvOp (inst_type, json_type); | |
if (conv_op != null) | |
return conv_op.Invoke (null, | |
new object[] { reader.Value }); | |
// No luck | |
throw new JsonException (String.Format ( | |
"Can't assign value '{0}' (type {1}) to type {2}", | |
reader.Value, json_type, inst_type)); | |
} | |
object instance = null; | |
if (reader.Token == JsonToken.ArrayStart) { | |
AddArrayMetadata (inst_type); | |
ArrayMetadata t_data = array_metadata[inst_type]; | |
if (! t_data.IsArray && ! t_data.IsList) | |
throw new JsonException (String.Format ( | |
"Type {0} can't act as an array", | |
inst_type)); | |
IList list; | |
Type elem_type; | |
if (! t_data.IsArray) { | |
list = (IList) Activator.CreateInstance (inst_type); | |
elem_type = t_data.ElementType; | |
} else { | |
list = new ArrayList (); | |
elem_type = inst_type.GetElementType (); | |
} | |
while (true) { | |
object item = ReadValue (elem_type, reader); | |
if (item == null && reader.Token == JsonToken.ArrayEnd) | |
break; | |
list.Add (item); | |
} | |
if (t_data.IsArray) { | |
int n = list.Count; | |
instance = Array.CreateInstance (elem_type, n); | |
for (int i = 0; i < n; i++) | |
((Array) instance).SetValue (list[i], i); | |
} else | |
instance = list; | |
} else if (reader.Token == JsonToken.ObjectStart) { | |
AddObjectMetadata (inst_type); | |
ObjectMetadata t_data = object_metadata[inst_type]; | |
instance = Activator.CreateInstance (inst_type); | |
while (true) { | |
reader.Read (); | |
if (reader.Token == JsonToken.ObjectEnd) | |
break; | |
string property = (string) reader.Value; | |
if (t_data.Properties.ContainsKey (property)) { | |
PropertyMetadata prop_data = | |
t_data.Properties[property]; | |
// Don't deserialize a field or property that has a JsonIgnore attribute with deserialization usage. | |
if ((prop_data.Ignore & JsonIgnoreWhen.Deserializing) > 0) { | |
ReadSkip (reader); | |
continue; | |
} | |
if (prop_data.IsField) { | |
((FieldInfo) prop_data.Info).SetValue ( | |
instance, ReadValue (prop_data.Type, reader)); | |
} else { | |
PropertyInfo p_info = | |
(PropertyInfo) prop_data.Info; | |
if (p_info.CanWrite) | |
p_info.SetValue ( | |
instance, | |
ReadValue (prop_data.Type, reader), | |
null); | |
else | |
ReadValue (prop_data.Type, reader); | |
} | |
} else { | |
if (! t_data.IsDictionary) { | |
if (! reader.SkipNonMembers) { | |
throw new JsonException (String.Format ( | |
"The type {0} doesn't have the " + | |
"property '{1}'", | |
inst_type, property)); | |
} else { | |
ReadSkip (reader); | |
continue; | |
} | |
} | |
((IDictionary) instance).Add ( | |
property, ReadValue ( | |
t_data.ElementType, reader)); | |
} | |
} | |
} | |
return instance; | |
} | |
private static IJsonWrapper ReadValue (WrapperFactory factory, | |
JsonReader reader) | |
{ | |
reader.Read (); | |
if (reader.Token == JsonToken.ArrayEnd || | |
reader.Token == JsonToken.Null) | |
return null; | |
IJsonWrapper instance = factory (); | |
if (reader.Token == JsonToken.String) { | |
instance.SetString ((string) reader.Value); | |
return instance; | |
} | |
if (reader.Token == JsonToken.Double) { | |
instance.SetDouble ((double) reader.Value); | |
return instance; | |
} | |
if (reader.Token == JsonToken.Int) { | |
instance.SetInt ((int) reader.Value); | |
return instance; | |
} | |
if (reader.Token == JsonToken.Long) { | |
instance.SetLong ((long) reader.Value); | |
return instance; | |
} | |
if (reader.Token == JsonToken.Boolean) { | |
instance.SetBoolean ((bool) reader.Value); | |
return instance; | |
} | |
if (reader.Token == JsonToken.ArrayStart) { | |
instance.SetJsonType (JsonType.Array); | |
while (true) { | |
IJsonWrapper item = ReadValue (factory, reader); | |
if (item == null && reader.Token == JsonToken.ArrayEnd) | |
break; | |
((IList) instance).Add (item); | |
} | |
} | |
else if (reader.Token == JsonToken.ObjectStart) { | |
instance.SetJsonType (JsonType.Object); | |
while (true) { | |
reader.Read (); | |
if (reader.Token == JsonToken.ObjectEnd) | |
break; | |
string property = (string) reader.Value; | |
((IDictionary) instance)[property] = ReadValue ( | |
factory, reader); | |
} | |
} | |
return instance; | |
} | |
private static void ReadSkip (JsonReader reader) | |
{ | |
ToWrapper ( | |
delegate { return new JsonMockWrapper (); }, reader); | |
} | |
private static void RegisterBaseExporters () | |
{ | |
base_exporters_table[typeof (byte)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write (Convert.ToInt32 ((byte) obj)); | |
}; | |
base_exporters_table[typeof (char)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write (Convert.ToString ((char) obj)); | |
}; | |
base_exporters_table[typeof (DateTime)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write (Convert.ToString ((DateTime) obj, | |
datetime_format)); | |
}; | |
base_exporters_table[typeof (decimal)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write ((decimal) obj); | |
}; | |
base_exporters_table[typeof (sbyte)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write (Convert.ToInt32 ((sbyte) obj)); | |
}; | |
base_exporters_table[typeof (short)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write (Convert.ToInt32 ((short) obj)); | |
}; | |
base_exporters_table[typeof (ushort)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write (Convert.ToInt32 ((ushort) obj)); | |
}; | |
base_exporters_table[typeof (uint)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write (Convert.ToUInt64 ((uint) obj)); | |
}; | |
base_exporters_table[typeof (ulong)] = | |
delegate (object obj, JsonWriter writer) { | |
writer.Write ((ulong) obj); | |
}; | |
} | |
private static void RegisterBaseImporters () | |
{ | |
ImporterFunc importer; | |
importer = delegate (object input) { | |
return Convert.ToByte ((int) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (int), | |
typeof (byte), importer); | |
importer = delegate (object input) { | |
return Convert.ToUInt64 ((int) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (int), | |
typeof (ulong), importer); | |
importer = delegate (object input) { | |
return Convert.ToSByte ((int) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (int), | |
typeof (sbyte), importer); | |
importer = delegate (object input) { | |
return Convert.ToInt16 ((int) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (int), | |
typeof (short), importer); | |
importer = delegate (object input) { | |
return Convert.ToUInt16 ((int) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (int), | |
typeof (ushort), importer); | |
importer = delegate (object input) { | |
return Convert.ToUInt32 ((int) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (int), | |
typeof (uint), importer); | |
importer = delegate (object input) { | |
return Convert.ToSingle ((int) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (int), | |
typeof (float), importer); | |
importer = delegate (object input) { | |
return Convert.ToDouble ((int) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (int), | |
typeof (double), importer); | |
importer = delegate (object input) { | |
return Convert.ToDecimal ((double) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (double), | |
typeof (decimal), importer); | |
importer = delegate (object input) { | |
return Convert.ToUInt32 ((long) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (long), | |
typeof (uint), importer); | |
importer = delegate (object input) { | |
return Convert.ToChar ((string) input); | |
}; | |
RegisterImporter (base_importers_table, typeof (string), | |
typeof (char), importer); | |
importer = delegate (object input) { | |
return Convert.ToDateTime ((string) input, datetime_format); | |
}; | |
RegisterImporter (base_importers_table, typeof (string), | |
typeof (DateTime), importer); | |
} | |
private static void RegisterImporter ( | |
IDictionary<Type, IDictionary<Type, ImporterFunc>> table, | |
Type json_type, Type value_type, ImporterFunc importer) | |
{ | |
if (! table.ContainsKey (json_type)) | |
table.Add (json_type, new Dictionary<Type, ImporterFunc> ()); | |
table[json_type][value_type] = importer; | |
} | |
private static void WriteValue (object obj, JsonWriter writer, | |
bool writer_is_private, | |
int depth) | |
{ | |
if (depth > max_nesting_depth) | |
throw new JsonException ( | |
String.Format ("Max allowed object depth reached while " + | |
"trying to export from type {0}", | |
obj.GetType ())); | |
if (obj == null) { | |
writer.Write (null); | |
return; | |
} | |
if (obj is IJsonWrapper) { | |
if (writer_is_private) | |
writer.TextWriter.Write (((IJsonWrapper) obj).ToJson ()); | |
else | |
((IJsonWrapper) obj).ToJson (writer); | |
return; | |
} | |
if (obj is String) { | |
writer.Write ((string) obj); | |
return; | |
} | |
if (obj is Double) { | |
writer.Write ((double) obj); | |
return; | |
} | |
if (obj is Int32) { | |
writer.Write ((int) obj); | |
return; | |
} | |
if (obj is Boolean) { | |
writer.Write ((bool) obj); | |
return; | |
} | |
if (obj is Int64) { | |
writer.Write ((long) obj); | |
return; | |
} | |
if (obj is Array) { | |
writer.WriteArrayStart (); | |
foreach (object elem in (Array) obj) | |
WriteValue (elem, writer, writer_is_private, depth + 1); | |
writer.WriteArrayEnd (); | |
return; | |
} | |
if (obj is IList) { | |
writer.WriteArrayStart (); | |
foreach (object elem in (IList) obj) | |
WriteValue (elem, writer, writer_is_private, depth + 1); | |
writer.WriteArrayEnd (); | |
return; | |
} | |
if (obj is IDictionary) { | |
writer.WriteObjectStart (); | |
foreach (DictionaryEntry entry in (IDictionary) obj) { | |
writer.WritePropertyName ((string) entry.Key); | |
WriteValue (entry.Value, writer, writer_is_private, | |
depth + 1); | |
} | |
writer.WriteObjectEnd (); | |
return; | |
} | |
Type obj_type = obj.GetType (); | |
// See if there's a custom exporter for the object | |
if (custom_exporters_table.ContainsKey (obj_type)) { | |
ExporterFunc exporter = custom_exporters_table[obj_type]; | |
exporter (obj, writer); | |
return; | |
} | |
// If not, maybe there's a base exporter | |
if (base_exporters_table.ContainsKey (obj_type)) { | |
ExporterFunc exporter = base_exporters_table[obj_type]; | |
exporter (obj, writer); | |
return; | |
} | |
// Last option, let's see if it's an enum | |
if (obj is Enum) { | |
Type e_type = Enum.GetUnderlyingType (obj_type); | |
if (e_type == typeof (long) | |
|| e_type == typeof (uint) | |
|| e_type == typeof (ulong)) | |
writer.Write ((ulong) obj); | |
else | |
writer.Write ((int) obj); | |
return; | |
} | |
// Okay, so it looks like the input should be exported as an | |
// object | |
AddTypeProperties (obj_type); | |
IList<PropertyMetadata> props = type_properties[obj_type]; | |
writer.WriteObjectStart (); | |
foreach (PropertyMetadata p_data in props) { | |
// Don't serialize a field or property with the JsonIgnore attribute with serialization usage | |
if ((p_data.Ignore & JsonIgnoreWhen.Serializing) > 0) | |
continue; | |
if (p_data.IsField) { | |
writer.WritePropertyName (p_data.Info.Name); | |
WriteValue (((FieldInfo) p_data.Info).GetValue (obj), | |
writer, writer_is_private, depth + 1); | |
} | |
else { | |
PropertyInfo p_info = (PropertyInfo) p_data.Info; | |
if (p_info.CanRead) { | |
writer.WritePropertyName (p_data.Info.Name); | |
WriteValue (p_info.GetValue (obj, null), | |
writer, writer_is_private, depth + 1); | |
} | |
} | |
} | |
writer.WriteObjectEnd (); | |
} | |
#endregion | |
public static string ToJson (object obj) | |
{ | |
lock (static_writer_lock) { | |
static_writer.Reset (); | |
WriteValue (obj, static_writer, true, 0); | |
return static_writer.ToString (); | |
} | |
} | |
public static void ToJson (object obj, JsonWriter writer) | |
{ | |
WriteValue (obj, writer, false, 0); | |
} | |
public static JsonData ToObject (JsonReader reader) | |
{ | |
return (JsonData) ToWrapper ( | |
delegate { return new JsonData (); }, reader); | |
} | |
public static JsonData ToObject (TextReader reader) | |
{ | |
JsonReader json_reader = new JsonReader (reader); | |
return (JsonData) ToWrapper ( | |
delegate { return new JsonData (); }, json_reader); | |
} | |
public static JsonData ToObject (string json) | |
{ | |
return (JsonData) ToWrapper ( | |
delegate { return new JsonData (); }, json); | |
} | |
public static T ToObject<T> (JsonReader reader) | |
{ | |
return (T) ReadValue (typeof (T), reader); | |
} | |
public static T ToObject<T> (TextReader reader) | |
{ | |
JsonReader json_reader = new JsonReader (reader); | |
return (T) ReadValue (typeof (T), json_reader); | |
} | |
public static T ToObject<T> (string json) | |
{ | |
JsonReader reader = new JsonReader (json); | |
return (T) ReadValue (typeof (T), reader); | |
} | |
public static IJsonWrapper ToWrapper (WrapperFactory factory, | |
JsonReader reader) | |
{ | |
return ReadValue (factory, reader); | |
} | |
public static IJsonWrapper ToWrapper (WrapperFactory factory, | |
string json) | |
{ | |
JsonReader reader = new JsonReader (json); | |
return ReadValue (factory, reader); | |
} | |
public static void RegisterExporter<T> (ExporterFunc<T> exporter) | |
{ | |
ExporterFunc exporter_wrapper = | |
delegate (object obj, JsonWriter writer) { | |
exporter ((T) obj, writer); | |
}; | |
custom_exporters_table[typeof (T)] = exporter_wrapper; | |
} | |
public static void RegisterImporter<TJson, TValue> ( | |
ImporterFunc<TJson, TValue> importer) | |
{ | |
ImporterFunc importer_wrapper = | |
delegate (object input) { | |
return importer ((TJson) input); | |
}; | |
RegisterImporter (custom_importers_table, typeof (TJson), | |
typeof (TValue), importer_wrapper); | |
} | |
public static void UnregisterExporters () | |
{ | |
custom_exporters_table.Clear (); | |
} | |
public static void UnregisterImporters () | |
{ | |
custom_importers_table.Clear (); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment