JSONParser: Parse to strongly typed objects.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Scrummer.Code.JSON
|
namespace Scrummer.Code.JSON
|
||||||
@@ -11,10 +12,87 @@ namespace Scrummer.Code.JSON
|
|||||||
private ParserContext ctx;
|
private ParserContext ctx;
|
||||||
private bool tainted = false;
|
private bool tainted = false;
|
||||||
|
|
||||||
|
private List<Type> _knownTypes = new List<Type>();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public bool Tainted
|
||||||
|
{
|
||||||
|
get { return tainted; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Type> KnownTypes
|
||||||
|
{
|
||||||
|
get { return _knownTypes; }
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private methods
|
#region Private methods
|
||||||
|
|
||||||
|
private static Dictionary<Type, PropertyInfo[]> _dictProperties = new Dictionary<Type, PropertyInfo[]>();
|
||||||
|
|
||||||
|
private PropertyInfo[] Type_GetProperties(Type type)
|
||||||
|
{
|
||||||
|
PropertyInfo[] typeProperties = null;
|
||||||
|
if (_dictProperties.ContainsKey(type)) { typeProperties = _dictProperties[type]; }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock(_dictProperties){
|
||||||
|
|
||||||
|
if (_dictProperties.ContainsKey(type)) { typeProperties = _dictProperties[type]; }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typeProperties = type.GetProperties(BindingFlags.Public | BindingFlags.OptionalParamBinding | BindingFlags.Instance);
|
||||||
|
_dictProperties.Add(type, typeProperties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CompareToType(Dictionary<string, object> obj, Type type)
|
||||||
|
{
|
||||||
|
PropertyInfo[] typeProperties = Type_GetProperties(type);
|
||||||
|
int count = 0;
|
||||||
|
foreach (PropertyInfo prop in typeProperties)
|
||||||
|
{
|
||||||
|
if (obj.ContainsKey(prop.Name))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (count == typeProperties.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ConvertToType(Dictionary<string, object> obj, Type type)
|
||||||
|
{
|
||||||
|
PropertyInfo[] typeProperties = Type_GetProperties(type);
|
||||||
|
object newObj = Activator.CreateInstance(type);
|
||||||
|
foreach (PropertyInfo prop in typeProperties)
|
||||||
|
{
|
||||||
|
if (obj.ContainsKey(prop.Name))
|
||||||
|
{
|
||||||
|
prop.SetValue(newObj, Convert.ChangeType(obj[prop.Name], prop.PropertyType), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private object TryConvertToTypes(Dictionary<string, object> obj)
|
||||||
|
{
|
||||||
|
foreach (Type type in _knownTypes)
|
||||||
|
{
|
||||||
|
if (CompareToType(obj, type))
|
||||||
|
{
|
||||||
|
return ConvertToType(obj, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
private int ParseHexShort()
|
private int ParseHexShort()
|
||||||
{
|
{
|
||||||
int value = 0;
|
int value = 0;
|
||||||
@@ -265,6 +343,7 @@ namespace Scrummer.Code.JSON
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +357,8 @@ namespace Scrummer.Code.JSON
|
|||||||
token = ParseQuotedString();
|
token = ParseQuotedString();
|
||||||
break;
|
break;
|
||||||
case '{':
|
case '{':
|
||||||
token = ParseObject();
|
Dictionary<string, object> obj = ParseObject();
|
||||||
|
token = TryConvertToTypes(obj);
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
token = ParseArray();
|
token = ParseArray();
|
||||||
|
|||||||
Reference in New Issue
Block a user