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 
 | 
    } 
 | 
  
 | 
} 
 |