| using System; | 
| using System.Collections; | 
| using System.Collections.Generic; | 
| #if !SILVERLIGHT | 
| using System.Data; | 
| #endif | 
| using System.Globalization; | 
| using System.IO; | 
| using System.Reflection; | 
| using System.Reflection.Emit; | 
| using System.Collections.Specialized; | 
|   | 
| namespace FastJSON | 
| { | 
|     public delegate string Serialize(object data); | 
|     public delegate object Deserialize(string data); | 
|   | 
|     public sealed class JSONParameters | 
|     { | 
|         /// <summary> | 
|         /// Use the optimized fast Dataset Schema format (default = True) | 
|         /// </summary> | 
|         public bool UseOptimizedDatasetSchema = true; | 
|         /// <summary> | 
|         /// Use the fast GUID format (default = True) | 
|         /// </summary> | 
|         public bool UseFastGuid = true; | 
|         /// <summary> | 
|         /// Serialize null values to the output (default = True) | 
|         /// </summary> | 
|         public bool SerializeNullValues = true; | 
|         /// <summary> | 
|         /// Use the UTC date format (default = True) | 
|         /// </summary> | 
|         public bool UseUTCDateTime = true; | 
|         /// <summary> | 
|         /// Show the readonly properties of types in the output (default = False) | 
|         /// </summary> | 
|         public bool ShowReadOnlyProperties = false; | 
|         /// <summary> | 
|         /// Use the $types extension to optimise the output json (default = True) | 
|         /// </summary> | 
|         public bool UsingGlobalTypes = true; | 
|         /// <summary> | 
|         /// Ignore case when processing json and deserializing  | 
|         /// </summary> | 
|         [Obsolete("Not needed anymore and will always match")] | 
|         public bool IgnoreCaseOnDeserialize = false; | 
|         /// <summary> | 
|         /// Anonymous types have read only properties  | 
|         /// </summary> | 
|         public bool EnableAnonymousTypes = false; | 
|         /// <summary> | 
|         /// Enable fastJSON extensions $types, $type, $map (default = True) | 
|         /// </summary> | 
|         public bool UseExtensions = true; | 
|         /// <summary> | 
|         /// Use escaped unicode i.e. \uXXXX format for non ASCII characters (default = True) | 
|         /// </summary> | 
|         public bool UseEscapedUnicode = false; | 
|         /// <summary> | 
|         /// Output string key dictionaries as "k"/"v" format (default = False)  | 
|         /// </summary> | 
|         public bool KVStyleStringDictionary = false; | 
|         /// <summary> | 
|         /// Output Enum values instead of names (default = False) | 
|         /// </summary> | 
|         public bool UseValuesOfEnums = false; | 
|         /// <summary> | 
|         /// Ignore attributes to check for (default : XmlIgnoreAttribute) | 
|         /// </summary> | 
|         public List<Type> IgnoreAttributes = new List<Type> { typeof(System.Xml.Serialization.XmlIgnoreAttribute) }; | 
|         /// <summary> | 
|         /// If you have parametric and no default constructor for you classes (default = False) | 
|         ///  | 
|         /// IMPORTANT NOTE : If True then all initial values within the class will be ignored and will be not set | 
|         /// </summary> | 
|         public bool ParametricConstructorOverride = false; | 
|         /// <summary> | 
|         /// Serialize DateTime milliseconds i.e. yyyy-MM-dd HH:mm:ss.nnn (default = false) | 
|         /// </summary> | 
|         public bool DateTimeMilliseconds = false; | 
|         /// <summary> | 
|         /// Maximum depth for circular references in inline mode (default = 20) | 
|         /// </summary> | 
|         public byte SerializerMaxDepth = 20; | 
|         /// <summary> | 
|         /// Inline circular or already seen objects instead of replacement with $i (default = False)  | 
|         /// </summary> | 
|         public bool InlineCircularReferences = false; | 
|         /// <summary> | 
|         /// Save property/field names as lowercase (default = false) | 
|         /// </summary> | 
|         public bool SerializeToLowerCaseNames = false; | 
|         /// <summary> | 
|         /// Serialize property name with underline style | 
|         /// </summary> | 
|         public bool UseApiNamingStyle = false; | 
|   | 
|         public void FixValues() | 
|         { | 
|             if (UseExtensions == false) // disable conflicting params | 
|             { | 
|                 UsingGlobalTypes = false; | 
|                 InlineCircularReferences = true; | 
|             } | 
|             if (EnableAnonymousTypes) | 
|                 ShowReadOnlyProperties = true; | 
|         } | 
|     } | 
|   | 
|     public static class JSON | 
|     { | 
|         /// <summary> | 
|         /// Globally set-able parameters for controlling the serializer | 
|         /// </summary> | 
|         public static JSONParameters Parameters = new JSONParameters(); | 
|         /// <summary> | 
|         /// Create a formatted json string (beautified) from an object | 
|         /// </summary> | 
|         /// <param name="obj"></param> | 
|         /// <param name="param"></param> | 
|         /// <returns></returns> | 
|         public static string ToNiceJSON(object obj, JSONParameters param) | 
|         { | 
|             string s = ToJSON(obj, param); | 
|   | 
|             return Beautify(s); | 
|         } | 
|         /// <summary> | 
|         /// Create a json representation for an object | 
|         /// </summary> | 
|         /// <param name="obj"></param> | 
|         /// <returns></returns> | 
|         public static string ToJSON(object obj) | 
|         { | 
|             return ToJSON(obj, JSON.Parameters); | 
|         } | 
|         /// <summary> | 
|         /// Create a json representation for an object with parameter override on this call | 
|         /// </summary> | 
|         /// <param name="obj"></param> | 
|         /// <param name="param"></param> | 
|         /// <returns></returns> | 
|         public static string ToJSON(object obj, JSONParameters param) | 
|         { | 
|             param.FixValues(); | 
|             Type t = null; | 
|   | 
|             if (obj == null) | 
|                 return "null"; | 
|   | 
|             if (obj.GetType().IsGenericType) | 
|                 t = Reflection.Instance.GetGenericTypeDefinition(obj.GetType()); | 
|             if (t == typeof(Dictionary<,>) || t == typeof(List<>)) | 
|                 param.UsingGlobalTypes = false; | 
|   | 
|             // FEATURE : enable extensions when you can deserialize anon types | 
|             if (param.EnableAnonymousTypes) { param.UseExtensions = false; param.UsingGlobalTypes = false; } | 
|             return new JSONSerializer(param).ConvertToJSON(obj); | 
|         } | 
|         /// <summary> | 
|         /// Parse a json string and generate a Dictionary<string,object> or List<object> structure | 
|         /// </summary> | 
|         /// <param name="json"></param> | 
|         /// <returns></returns> | 
|         public static object Parse(string json) | 
|         { | 
|             return new JsonParser(json).Decode(); | 
|         } | 
| #if net4 | 
|         /// <summary> | 
|         /// Create a .net4 dynamic object from the json string | 
|         /// </summary> | 
|         /// <param name="json"></param> | 
|         /// <returns></returns> | 
|         public static dynamic ToDynamic(string json) | 
|         { | 
|             return new DynamicJson(json); | 
|         } | 
| #endif | 
|         /// <summary> | 
|         /// Create a typed generic object from the json | 
|         /// </summary> | 
|         /// <typeparam name="T"></typeparam> | 
|         /// <param name="json"></param> | 
|         /// <returns></returns> | 
|         public static T ToObject<T>(string json) | 
|         { | 
|             return new deserializer(Parameters).ToObject<T>(json); | 
|         } | 
|         /// <summary> | 
|         /// Create a typed generic object from the json with parameter override on this call | 
|         /// </summary> | 
|         /// <typeparam name="T"></typeparam> | 
|         /// <param name="json"></param> | 
|         /// <param name="param"></param> | 
|         /// <returns></returns> | 
|         public static T ToObject<T>(string json, JSONParameters param) | 
|         { | 
|             return new deserializer(param).ToObject<T>(json); | 
|         } | 
|         /// <summary> | 
|         /// Create an object from the json | 
|         /// </summary> | 
|         /// <param name="json"></param> | 
|         /// <returns></returns> | 
|         public static object ToObject(string json) | 
|         { | 
|             return new deserializer(Parameters).ToObject(json, null); | 
|         } | 
|         /// <summary> | 
|         /// Create an object from the json with parameter override on this call | 
|         /// </summary> | 
|         /// <param name="json"></param> | 
|         /// <param name="param"></param> | 
|         /// <returns></returns> | 
|         public static object ToObject(string json, JSONParameters param) | 
|         { | 
|             return new deserializer(param).ToObject(json, null); | 
|         } | 
|         /// <summary> | 
|         /// Create an object of type from the json | 
|         /// </summary> | 
|         /// <param name="json"></param> | 
|         /// <param name="type"></param> | 
|         /// <returns></returns> | 
|         public static object ToObject(string json, Type type) | 
|         { | 
|             return new deserializer(Parameters).ToObject(json, type); | 
|         } | 
|         /// <summary> | 
|         /// Fill a given object with the json represenation | 
|         /// </summary> | 
|         /// <param name="input"></param> | 
|         /// <param name="json"></param> | 
|         /// <returns></returns> | 
|         public static object FillObject(object input, string json) | 
|         { | 
|             Dictionary<string, object> ht = new JsonParser(json).Decode() as Dictionary<string, object>; | 
|             if (ht == null) return null; | 
|             return new deserializer(Parameters).ParseDictionary(ht, null, input.GetType(), input); | 
|         } | 
|         /// <summary> | 
|         /// Deep copy an object i.e. clone to a new object | 
|         /// </summary> | 
|         /// <param name="obj"></param> | 
|         /// <returns></returns> | 
|         public static object DeepCopy(object obj) | 
|         { | 
|             return new deserializer(Parameters).ToObject(ToJSON(obj)); | 
|         } | 
|         /// <summary> | 
|         ///  | 
|         /// </summary> | 
|         /// <typeparam name="T"></typeparam> | 
|         /// <param name="obj"></param> | 
|         /// <returns></returns> | 
|         public static T DeepCopy<T>(T obj) | 
|         { | 
|             return new deserializer(Parameters).ToObject<T>(ToJSON(obj)); | 
|         } | 
|   | 
|         /// <summary> | 
|         /// Create a human readable string from the json  | 
|         /// </summary> | 
|         /// <param name="input"></param> | 
|         /// <returns></returns> | 
|         public static string Beautify(string input) | 
|         { | 
|             return Formatter.PrettyPrint(input); | 
|         } | 
|         /// <summary> | 
|         /// Register custom type handlers for your own types not natively handled by fastJSON | 
|         /// </summary> | 
|         /// <param name="type"></param> | 
|         /// <param name="serializer"></param> | 
|         /// <param name="deserializer"></param> | 
|         public static void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer) | 
|         { | 
|             Reflection.Instance.RegisterCustomType(type, serializer, deserializer); | 
|         } | 
|         /// <summary> | 
|         /// Clear the internal reflection cache so you can start from new (you will loose performance) | 
|         /// </summary> | 
|         public static void ClearReflectionCache() | 
|         { | 
|             Reflection.Instance.ClearReflectionCache(); | 
|         } | 
|   | 
|         internal static long CreateLong(out long num, string s, int index, int count) | 
|         { | 
|             num = 0; | 
|             bool neg = false; | 
|             for (int x = 0; x < count; x++, index++) | 
|             { | 
|                 char cc = s[index]; | 
|   | 
|                 if (cc == '-') | 
|                     neg = true; | 
|                 else if (cc == '+') | 
|                     neg = false; | 
|                 else | 
|                 { | 
|                     num *= 10; | 
|                     num += (int)(cc - '0'); | 
|                 } | 
|             } | 
|             if (neg) num = -num; | 
|   | 
|             return num; | 
|         } | 
|     } | 
|   | 
|     internal class deserializer | 
|     { | 
|         public deserializer(JSONParameters param) | 
|         { | 
|             _params = param; | 
|         } | 
|   | 
|         private JSONParameters _params; | 
|         private bool _usingglobals = false; | 
|         private Dictionary<object, int> _circobj = new Dictionary<object, int>(); | 
|         private Dictionary<int, object> _cirrev = new Dictionary<int, object>(); | 
|   | 
|         public T ToObject<T>(string json) | 
|         { | 
|             Type t = typeof(T); | 
|             var o = ToObject(json, t); | 
|   | 
|             if (t.IsArray) | 
|             { | 
|                 if ((o as ICollection).Count == 0) // edge case for "[]" -> T[] | 
|                 { | 
|                     Type tt = t.GetElementType(); | 
|                     object oo = Array.CreateInstance(tt, 0); | 
|                     return (T)oo; | 
|                 } | 
|                 else | 
|                     return (T)o; | 
|             } | 
|             else | 
|                 return (T)o; | 
|         } | 
|   | 
|         public object ToObject(string json) | 
|         { | 
|             return ToObject(json, null); | 
|         } | 
|   | 
|         public object ToObject(string json, Type type) | 
|         { | 
|             //_params = Parameters; | 
|             _params.FixValues(); | 
|             Type t = null; | 
|             if (type != null && type.IsGenericType) | 
|                 t = Reflection.Instance.GetGenericTypeDefinition(type); | 
|             if (t == typeof(Dictionary<,>) || t == typeof(List<>)) | 
|                 _params.UsingGlobalTypes = false; | 
|             _usingglobals = _params.UsingGlobalTypes; | 
|   | 
|             object o = new JsonParser(json).Decode(); | 
|             if (o == null) | 
|                 return null; | 
| #if !SILVERLIGHT | 
|             if (type != null && type == typeof(DataSet)) | 
|                 return CreateDataset(o as Dictionary<string, object>, null); | 
|             else if (type != null && type == typeof(DataTable)) | 
|                 return CreateDataTable(o as Dictionary<string, object>, null); | 
| #endif | 
|             if (o is IDictionary) | 
|             { | 
|                 if (type != null && t == typeof(Dictionary<,>)) // deserialize a dictionary | 
|                     return RootDictionary(o, type); | 
|                 else // deserialize an object | 
|                     return ParseDictionary(o as Dictionary<string, object>, null, type, null); | 
|             } | 
|             else if (o is List<object>) | 
|             { | 
|                 if (type != null && t == typeof(Dictionary<,>)) // kv format | 
|                     return RootDictionary(o, type); | 
|                 else if (type != null && t == typeof(List<>)) // deserialize to generic list | 
|                     return RootList(o, type); | 
|                 else if (type == typeof(Hashtable)) | 
|                     return RootHashTable((List<object>)o); | 
|                 else | 
|                     return (o as List<object>).ToArray(); | 
|             } | 
|             else if (type != null && o.GetType() != type) | 
|                 return ChangeType(o, type); | 
|   | 
|             return o; | 
|         } | 
|   | 
|         #region [   p r i v a t e   m e t h o d s   ] | 
|         private object RootHashTable(List<object> o) | 
|         { | 
|             Hashtable h = new Hashtable(); | 
|   | 
|             foreach (Dictionary<string, object> values in o) | 
|             { | 
|                 object key = values["k"]; | 
|                 object val = values["v"]; | 
|                 if (key is Dictionary<string, object>) | 
|                     key = ParseDictionary((Dictionary<string, object>)key, null, typeof(object), null); | 
|   | 
|                 if (val is Dictionary<string, object>) | 
|                     val = ParseDictionary((Dictionary<string, object>)val, null, typeof(object), null); | 
|   | 
|                 h.Add(key, val); | 
|             } | 
|   | 
|             return h; | 
|         } | 
|   | 
|         private object ChangeType(object value, Type conversionType) | 
|         { | 
|             if (conversionType == typeof(int)) | 
|                 return (int)((long)value); | 
|   | 
|             else if (conversionType == typeof(long)) | 
|                 return (long)value; | 
|   | 
|             else if (conversionType == typeof(string)) | 
|                 return (string)value; | 
|   | 
|             else if (conversionType.IsEnum) | 
|                 return CreateEnum(conversionType, value); | 
|   | 
|             else if (conversionType == typeof(DateTime)) | 
|                 return CreateDateTime((string)value); | 
|   | 
|             else if (Reflection.Instance.IsTypeRegistered(conversionType)) | 
|                 return Reflection.Instance.CreateCustom((string)value, conversionType); | 
|   | 
|             // 8-30-2014 - James Brooks - Added code for nullable types. | 
|             if (IsNullable(conversionType)) | 
|             { | 
|                 if (value == null) | 
|                 { | 
|                     return value; | 
|                 } | 
|                 conversionType = UnderlyingTypeOf(conversionType); | 
|             } | 
|   | 
|             // 8-30-2014 - James Brooks - Nullable Guid is a special case so it was moved after the "IsNullable" check. | 
|             if (conversionType == typeof(Guid)) | 
|                 return CreateGuid((string)value); | 
|   | 
|             return Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture); | 
|         } | 
|   | 
|         private bool IsNullable(Type t) | 
|         { | 
|             if (!t.IsGenericType) return false; | 
|             Type g = t.GetGenericTypeDefinition(); | 
|             return (g.Equals(typeof(Nullable<>))); | 
|         } | 
|   | 
|         private Type UnderlyingTypeOf(Type t) | 
|         { | 
|             return t.GetGenericArguments()[0]; | 
|         } | 
|   | 
|         private object RootList(object parse, Type type) | 
|         { | 
|             Type[] gtypes = Reflection.Instance.GetGenericArguments(type); | 
|             IList o = (IList)Reflection.Instance.FastCreateInstance(type); | 
|             foreach (var k in (IList)parse) | 
|             { | 
|                 _usingglobals = false; | 
|                 object v = k; | 
|                 if (k is Dictionary<string, object>) | 
|                     v = ParseDictionary(k as Dictionary<string, object>, null, gtypes[0], null); | 
|                 else | 
|                     v = ChangeType(k, gtypes[0]); | 
|   | 
|                 o.Add(v); | 
|             } | 
|             return o; | 
|         } | 
|   | 
|         private object RootDictionary(object parse, Type type) | 
|         { | 
|             Type[] gtypes = Reflection.Instance.GetGenericArguments(type); | 
|             Type t1 = null; | 
|             Type t2 = null; | 
|             if (gtypes != null) | 
|             { | 
|                 t1 = gtypes[0]; | 
|                 t2 = gtypes[1]; | 
|             } | 
|             if (parse is Dictionary<string, object>) | 
|             { | 
|                 IDictionary o = (IDictionary)Reflection.Instance.FastCreateInstance(type); | 
|   | 
|                 foreach (var kv in (Dictionary<string, object>)parse) | 
|                 { | 
|                     object v; | 
|                     object k = ChangeType(kv.Key, t1); | 
|   | 
|                     if (kv.Value is Dictionary<string, object>) | 
|                         v = ParseDictionary(kv.Value as Dictionary<string, object>, null, t2, null); | 
|   | 
|                     else if (t2.IsArray) | 
|                         v = CreateArray((List<object>)kv.Value, t2, t2.GetElementType(), null); | 
|   | 
|                     else if (kv.Value is IList) | 
|                         v = CreateGenericList((List<object>)kv.Value, t2, t1, null); | 
|   | 
|                     else | 
|                         v = ChangeType(kv.Value, t2); | 
|   | 
|                     o.Add(k, v); | 
|                 } | 
|   | 
|                 return o; | 
|             } | 
|             if (parse is List<object>) | 
|                 return CreateDictionary(parse as List<object>, type, gtypes, null); | 
|   | 
|             return null; | 
|         } | 
|   | 
|         internal object ParseDictionary(Dictionary<string, object> d, Dictionary<string, object> globaltypes, Type type, object input) | 
|         { | 
|             object tn = ""; | 
|             if (type == typeof(NameValueCollection)) | 
|                 return CreateNV(d); | 
|             if (type == typeof(StringDictionary)) | 
|                 return CreateSD(d); | 
|   | 
|             if (d.TryGetValue("$i", out tn)) | 
|             { | 
|                 object v = null; | 
|                 _cirrev.TryGetValue((int)(long)tn, out v); | 
|                 return v; | 
|             } | 
|   | 
|             if (d.TryGetValue("$types", out tn)) | 
|             { | 
|                 _usingglobals = true; | 
|                 globaltypes = new Dictionary<string, object>(); | 
|                 foreach (var kv in (Dictionary<string, object>)tn) | 
|                 { | 
|                     globaltypes.Add((string)kv.Value, kv.Key); | 
|                 } | 
|             } | 
|   | 
|             bool found = d.TryGetValue("$type", out tn); | 
| #if !SILVERLIGHT | 
|             if (found == false && type == typeof(System.Object)) | 
|             { | 
|                 return d;   // CreateDataset(d, globaltypes); | 
|             } | 
| #endif | 
|             if (found) | 
|             { | 
|                 if (_usingglobals) | 
|                 { | 
|                     object tname = ""; | 
|                     if (globaltypes != null && globaltypes.TryGetValue((string)tn, out tname)) | 
|                         tn = tname; | 
|                 } | 
|                 type = Reflection.Instance.GetTypeFromCache((string)tn); | 
|             } | 
|   | 
|             if (type == null) | 
|                 throw new Exception("Cannot determine type"); | 
|   | 
|             string typename = type.FullName; | 
|             object o = input; | 
|             if (o == null) | 
|             { | 
|                 if (_params.ParametricConstructorOverride) | 
|                     o = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type); | 
|                 else | 
|                     o = Reflection.Instance.FastCreateInstance(type); | 
|             } | 
|             int circount = 0; | 
|             if (_circobj.TryGetValue(o, out circount) == false) | 
|             { | 
|                 circount = _circobj.Count + 1; | 
|                 _circobj.Add(o, circount); | 
|                 _cirrev.Add(circount, o); | 
|             } | 
|   | 
|             Dictionary<string, myPropInfo> props = Reflection.Instance.Getproperties(type, typename, Reflection.Instance.IsTypeRegistered(type)); | 
|             foreach (var kv in d) | 
|             { | 
|                 var n = kv.Key; | 
|                 var v = kv.Value; | 
|                 string name = n.ToLower(); | 
|                 if (name == "$map") | 
|                 { | 
|                     ProcessMap(o, props, (Dictionary<string, object>)d[name]); | 
|                     continue; | 
|                 } | 
|                 myPropInfo pi; | 
|                 if (props.TryGetValue(name, out pi) == false) | 
|                     continue; | 
|                 if (pi.CanWrite) | 
|                 { | 
|                     //object v = d[n]; | 
|   | 
|                     if (v != null) | 
|                     { | 
|                         object oset = null; | 
|   | 
|                         switch (pi.Type) | 
|                         { | 
|                             case myPropInfoType.Int: oset = (int)((long)v); break; | 
|                             case myPropInfoType.Long: oset = (long)v; break; | 
|                             case myPropInfoType.String: oset = (string)v; break; | 
|                             case myPropInfoType.Bool: oset = (bool)v; break; | 
|                             case myPropInfoType.DateTime: oset = CreateDateTime((string)v); break; | 
|                             case myPropInfoType.Enum: oset = CreateEnum(pi.pt, v); break; | 
|                             case myPropInfoType.Guid: oset = CreateGuid((string)v); break; | 
|   | 
|                             case myPropInfoType.Array: | 
|                                 if (!pi.IsValueType) | 
|                                     oset = CreateArray((List<object>)v, pi.pt, pi.bt, globaltypes); | 
|                                 // what about 'else'? | 
|                                 break; | 
|                             case myPropInfoType.ByteArray: oset = Convert.FromBase64String((string)v); break; | 
| #if !SILVERLIGHT | 
|                             case myPropInfoType.DataSet: oset = CreateDataset((Dictionary<string, object>)v, globaltypes); break; | 
|                             case myPropInfoType.DataTable: oset = CreateDataTable((Dictionary<string, object>)v, globaltypes); break; | 
|                             case myPropInfoType.Hashtable: // same case as Dictionary | 
| #endif | 
|                             case myPropInfoType.Dictionary: oset = CreateDictionary((List<object>)v, pi.pt, pi.GenericTypes, globaltypes); break; | 
|                             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>) | 
|                                         oset = CreateGenericList((List<object>)v, pi.pt, pi.bt, globaltypes); | 
|   | 
|                                     else if ((pi.IsClass || pi.IsStruct) && v is Dictionary<string, object>) | 
|                                         oset = ParseDictionary((Dictionary<string, object>)v, globaltypes, pi.pt, pi.getter(o)); | 
|   | 
|                                     else if (v is List<object>) | 
|                                         oset = CreateArray((List<object>)v, pi.pt, typeof(object), globaltypes); | 
|   | 
|                                     else if (pi.IsValueType) | 
|                                         oset = ChangeType(v, pi.changeType); | 
|   | 
|                                     else | 
|                                         oset = v; | 
|                                 } | 
|                                 break; | 
|                         } | 
|   | 
|                         o = pi.setter(o, oset); | 
|                     } | 
|                 } | 
|             } | 
|             return o; | 
|         } | 
|   | 
|         private StringDictionary CreateSD(Dictionary<string, object> d) | 
|         { | 
|             StringDictionary nv = new StringDictionary(); | 
|   | 
|             foreach (var o in d) | 
|                 nv.Add(o.Key, (string)o.Value); | 
|   | 
|             return nv; | 
|         } | 
|   | 
|         private NameValueCollection CreateNV(Dictionary<string, object> d) | 
|         { | 
|             NameValueCollection nv = new NameValueCollection(); | 
|   | 
|             foreach (var o in d) | 
|                 nv.Add(o.Key, (string)o.Value); | 
|   | 
|             return nv; | 
|         } | 
|   | 
|         private void ProcessMap(object obj, Dictionary<string, myPropInfo> props, Dictionary<string, object> dic) | 
|         { | 
|             foreach (KeyValuePair<string, object> kv in dic) | 
|             { | 
|                 myPropInfo p = props[kv.Key]; | 
|                 object o = p.getter(obj); | 
|                 Type t = Type.GetType((string)kv.Value); | 
|                 if (t == typeof(Guid)) | 
|                     p.setter(obj, CreateGuid((string)o)); | 
|             } | 
|         } | 
|   | 
|         private int CreateInteger(string s, int index, int count) | 
|         { | 
|             int num = 0; | 
|             bool neg = false; | 
|             for (int x = 0; x < count; x++, index++) | 
|             { | 
|                 char cc = s[index]; | 
|   | 
|                 if (cc == '-') | 
|                     neg = true; | 
|                 else if (cc == '+') | 
|                     neg = false; | 
|                 else | 
|                 { | 
|                     num *= 10; | 
|                     num += (int)(cc - '0'); | 
|                 } | 
|             } | 
|             if (neg) num = -num; | 
|   | 
|             return num; | 
|         } | 
|   | 
|         private object CreateEnum(Type pt, object v) | 
|         { | 
|             // TODO : optimize create enum | 
| #if !SILVERLIGHT | 
|             return Enum.Parse(pt, v.ToString()); | 
| #else | 
|             return Enum.Parse(pt, v, true); | 
| #endif | 
|         } | 
|   | 
|         private Guid CreateGuid(string s) | 
|         { | 
|             if (s.Length > 30) | 
|                 return new Guid(s); | 
|             else | 
|                 return new Guid(Convert.FromBase64String(s)); | 
|         } | 
|   | 
|         private DateTime CreateDateTime(string value) | 
|         { | 
|             bool utc = false; | 
|             //                   0123456789012345678 9012 9/3 | 
|             // datetime format = yyyy-MM-ddTHH:mm:ss .nnn  Z | 
|             int year; | 
|             int month; | 
|             int day; | 
|             int hour; | 
|             int min; | 
|             int sec; | 
|             int ms = 0; | 
|   | 
|             year = CreateInteger(value, 0, 4); | 
|             month = CreateInteger(value, 5, 2); | 
|             day = CreateInteger(value, 8, 2); | 
|             hour = CreateInteger(value, 11, 2); | 
|             min = CreateInteger(value, 14, 2); | 
|             sec = CreateInteger(value, 17, 2); | 
|             if (value.Length > 21 && value[19] == '.') | 
|                 ms = CreateInteger(value, 20, 3); | 
|   | 
|             if (value[value.Length - 1] == 'Z') | 
|                 utc = true; | 
|   | 
|             if (_params.UseUTCDateTime == false && utc == false) | 
|                 return new DateTime(year, month, day, hour, min, sec, ms); | 
|             else | 
|                 return new DateTime(year, month, day, hour, min, sec, ms, DateTimeKind.Utc).ToLocalTime(); | 
|         } | 
|   | 
|         private object CreateArray(List<object> data, Type pt, Type bt, Dictionary<string, object> globalTypes) | 
|         { | 
|             Array col = Array.CreateInstance(bt, data.Count); | 
|             // create an array of objects | 
|             for (int i = 0; i < data.Count; i++) | 
|             { | 
|                 object ob = data[i]; | 
|                 if (ob == null) | 
|                 { | 
|                     continue; | 
|                 } | 
|                 if (ob is IDictionary) | 
|                     col.SetValue(ParseDictionary((Dictionary<string, object>)ob, globalTypes, bt, null), i); | 
|                 else if (ob is ICollection) | 
|                     col.SetValue(CreateArray((List<object>)ob, bt, bt.GetElementType(), globalTypes), i); | 
|                 else | 
|                     col.SetValue(ChangeType(ob, bt), i); | 
|             } | 
|   | 
|             return col; | 
|         } | 
|   | 
|   | 
|         private object CreateGenericList(List<object> data, Type pt, Type bt, Dictionary<string, object> globalTypes) | 
|         { | 
|             IList col = (IList)Reflection.Instance.FastCreateInstance(pt); | 
|             // create an array of objects | 
|             foreach (object ob in data) | 
|             { | 
|   | 
|                 if (ob is IDictionary) | 
|                     col.Add(ParseDictionary((Dictionary<string, object>)ob, globalTypes, bt, null)); | 
|   | 
|                 else if (ob is List<object>) | 
|                 { | 
|                     if (bt.IsGenericType) | 
|                         col.Add((List<object>)ob);//).ToArray()); | 
|                     else | 
|                         col.Add(((List<object>)ob).ToArray()); | 
|                 } | 
|                 else | 
|                     col.Add(ChangeType(ob, bt)); | 
|             } | 
|             return col; | 
|         } | 
|   | 
|         private object CreateStringKeyDictionary(Dictionary<string, object> reader, Type pt, Type[] types, Dictionary<string, object> globalTypes) | 
|         { | 
|             var col = (IDictionary)Reflection.Instance.FastCreateInstance(pt); | 
|             Type t1 = null; | 
|             Type t2 = null; | 
|             if (types != null) | 
|             { | 
|                 t1 = types[0]; | 
|                 t2 = types[1]; | 
|             } | 
|   | 
|             foreach (KeyValuePair<string, object> values in reader) | 
|             { | 
|                 var key = values.Key; | 
|                 object val = null; | 
|   | 
|                 if (values.Value is Dictionary<string, object>) | 
|                     val = ParseDictionary((Dictionary<string, object>)values.Value, globalTypes, t2, null); | 
|   | 
|                 else if (types != null && t2.IsArray) | 
|                 { | 
|                     if (values.Value is Array) | 
|                         val = values.Value; | 
|                     else | 
|                         val = CreateArray((List<object>)values.Value, t2, t2.GetElementType(), globalTypes); | 
|                 } | 
|                 else if (values.Value is IList) | 
|                     val = CreateGenericList((List<object>)values.Value, t2, t1, globalTypes); | 
|   | 
|                 else | 
|                     val = ChangeType(values.Value, t2); | 
|   | 
|                 col.Add(key, val); | 
|             } | 
|   | 
|             return col; | 
|         } | 
|   | 
|         private object CreateDictionary(List<object> reader, Type pt, Type[] types, Dictionary<string, object> globalTypes) | 
|         { | 
|             IDictionary col = (IDictionary)Reflection.Instance.FastCreateInstance(pt); | 
|             Type t1 = null; | 
|             Type t2 = null; | 
|             if (types != null) | 
|             { | 
|                 t1 = types[0]; | 
|                 t2 = types[1]; | 
|             } | 
|   | 
|             foreach (Dictionary<string, object> values in reader) | 
|             { | 
|                 object key = values["k"]; | 
|                 object val = values["v"]; | 
|   | 
|                 if (key is Dictionary<string, object>) | 
|                     key = ParseDictionary((Dictionary<string, object>)key, globalTypes, t1, null); | 
|                 else | 
|                     key = ChangeType(key, t1); | 
|   | 
|                 if (val is Dictionary<string, object>) | 
|                     val = ParseDictionary((Dictionary<string, object>)val, globalTypes, t2, null); | 
|                 else | 
|                     val = ChangeType(val, t2); | 
|   | 
|                 col.Add(key, val); | 
|             } | 
|   | 
|             return col; | 
|         } | 
|   | 
| #if !SILVERLIGHT | 
|         private DataSet CreateDataset(Dictionary<string, object> reader, Dictionary<string, object> globalTypes) | 
|         { | 
|             DataSet ds = new DataSet(); | 
|             ds.EnforceConstraints = false; | 
|             ds.BeginInit(); | 
|   | 
|             // read dataset schema here | 
|             var schema = reader["$schema"]; | 
|   | 
|             if (schema is string) | 
|             { | 
|                 TextReader tr = new StringReader((string)schema); | 
|                 ds.ReadXmlSchema(tr); | 
|             } | 
|             else | 
|             { | 
|                 DatasetSchema ms = (DatasetSchema)ParseDictionary((Dictionary<string, object>)schema, globalTypes, typeof(DatasetSchema), null); | 
|                 ds.DataSetName = ms.Name; | 
|                 for (int i = 0; i < ms.Info.Count; i += 3) | 
|                 { | 
|                     if (ds.Tables.Contains(ms.Info[i]) == false) | 
|                         ds.Tables.Add(ms.Info[i]); | 
|                     ds.Tables[ms.Info[i]].Columns.Add(ms.Info[i + 1], Type.GetType(ms.Info[i + 2])); | 
|                 } | 
|             } | 
|   | 
|             foreach (KeyValuePair<string, object> pair in reader) | 
|             { | 
|                 if (pair.Key == "$type" || pair.Key == "$schema") continue; | 
|   | 
|                 List<object> rows = (List<object>)pair.Value; | 
|                 if (rows == null) continue; | 
|   | 
|                 DataTable dt = ds.Tables[pair.Key]; | 
|                 ReadDataTable(rows, dt); | 
|             } | 
|   | 
|             ds.EndInit(); | 
|   | 
|             return ds; | 
|         } | 
|   | 
|         private void ReadDataTable(List<object> rows, DataTable dt) | 
|         { | 
|             dt.BeginInit(); | 
|             dt.BeginLoadData(); | 
|             List<int> guidcols = new List<int>(); | 
|             List<int> datecol = new List<int>(); | 
|   | 
|             foreach (DataColumn c in dt.Columns) | 
|             { | 
|                 if (c.DataType == typeof(Guid) || c.DataType == typeof(Guid?)) | 
|                     guidcols.Add(c.Ordinal); | 
|                 if (_params.UseUTCDateTime && (c.DataType == typeof(DateTime) || c.DataType == typeof(DateTime?))) | 
|                     datecol.Add(c.Ordinal); | 
|             } | 
|   | 
|             foreach (List<object> row in rows) | 
|             { | 
|                 object[] v = new object[row.Count]; | 
|                 row.CopyTo(v, 0); | 
|                 foreach (int i in guidcols) | 
|                 { | 
|                     string s = (string)v[i]; | 
|                     if (s != null && s.Length < 36) | 
|                         v[i] = new Guid(Convert.FromBase64String(s)); | 
|                 } | 
|                 if (_params.UseUTCDateTime) | 
|                 { | 
|                     foreach (int i in datecol) | 
|                     { | 
|                         string s = (string)v[i]; | 
|                         if (s != null) | 
|                             v[i] = CreateDateTime(s); | 
|                     } | 
|                 } | 
|                 dt.Rows.Add(v); | 
|             } | 
|   | 
|             dt.EndLoadData(); | 
|             dt.EndInit(); | 
|         } | 
|   | 
|         DataTable CreateDataTable(Dictionary<string, object> reader, Dictionary<string, object> globalTypes) | 
|         { | 
|             var dt = new DataTable(); | 
|   | 
|             // read dataset schema here | 
|             var schema = reader["$schema"]; | 
|   | 
|             if (schema is string) | 
|             { | 
|                 TextReader tr = new StringReader((string)schema); | 
|                 dt.ReadXmlSchema(tr); | 
|             } | 
|             else | 
|             { | 
|                 var ms = (DatasetSchema)this.ParseDictionary((Dictionary<string, object>)schema, globalTypes, typeof(DatasetSchema), null); | 
|                 dt.TableName = ms.Info[0]; | 
|                 for (int i = 0; i < ms.Info.Count; i += 3) | 
|                 { | 
|                     dt.Columns.Add(ms.Info[i + 1], Type.GetType(ms.Info[i + 2])); | 
|                 } | 
|             } | 
|   | 
|             foreach (var pair in reader) | 
|             { | 
|                 if (pair.Key == "$type" || pair.Key == "$schema") | 
|                     continue; | 
|   | 
|                 var rows = (List<object>)pair.Value; | 
|                 if (rows == null) | 
|                     continue; | 
|   | 
|                 if (!dt.TableName.Equals(pair.Key, StringComparison.InvariantCultureIgnoreCase)) | 
|                     continue; | 
|   | 
|                 ReadDataTable(rows, dt); | 
|             } | 
|   | 
|             return dt; | 
|         } | 
| #endif | 
|         #endregion | 
|     } | 
|   | 
| } |