public static dynamic DeserializeDictionary(string json, Type typ)
        {
            // This function is also a mess as it needs to make a Dictionary<T, T> not Dictionary<object, object> and lots of other things like that!

            Type[] arguments = typ.GetGenericArguments();
            Type   keyType   = arguments[0];
            Type   valueType = arguments[1];

            json = json.Trim().TrimStart('{').TrimEnd().TrimEnd('}');

            var dictionary       = typeof(Dictionary <,>);
            var dictionaryOfType = dictionary.MakeGenericType(keyType, valueType);

            dynamic result = Activator.CreateInstance(dictionaryOfType);

            string[] dictionaryItems = JsonReader.GetAllKeyValues(json);

            foreach (string str in dictionaryItems)
            {
                JsonKeyValuePair jkvp     = JsonReader.GetKeyValueData(str);
                dynamic          newValue = Deserialize(jkvp.value.ToString(), valueType, true).value;

                bool    IsNumeric = keyType.IsNumericType();
                dynamic name      = (IsNumeric) ? Convert.ChangeType(Convert.ToDouble(jkvp.name), keyType) : jkvp.name;
                result.Add(name, newValue);
            }

            return(result);
        }
        internal static object DeserializeObjectInternal(string json, Type type, bool GuessInheritance = false)
        {
            // Now get each value seperately
            string newJson = json;

            // Strip out the starting "{" and "}"
            newJson = json.Trim().TrimStart(',').Trim().TrimStart('{').TrimEnd().TrimEnd('}');
            string[] newJsonLines;

            List <JsonKeyValuePair> jsonObjects = new List <JsonKeyValuePair>();

            newJsonLines = JsonReader.GetAllKeyValues(newJson);
            //foreach (string str in newJsonLines) System.Windows.Forms.MessageBox.Show(str);
            if (string.IsNullOrEmpty(newJsonLines[newJsonLines.Length - 1]))
            {
                Array.Resize(ref newJsonLines, newJsonLines.Length - 1);                                                              // Remove the last one if it is blank (essentially if some idiot puts "," at the end of the whole thing!)
            }
            List <string> names = new List <string>();

            foreach (string str in newJsonLines)
            {
                //Console.WriteLine("ULTRA-DEBUG STUFFS: " + str);

                JsonKeyValuePair jkvp = JsonReader.GetKeyValueData(str);
                jsonObjects.Add(jkvp);
                names.Add(jkvp.name.ToString());
            }

            if (GuessInheritance)
            {
                if (ABInheritanceGuesser.HasInheriter(type))
                {
                    type = ABInheritanceGuesser.GetBestInheritanceInternal(type, names.ToArray(), null);
                }
            }

            object obj = Activator.CreateInstance(type);

            var bindingFlags = BindingFlags.Instance |
                               BindingFlags.NonPublic |
                               BindingFlags.Public;

            List <string> fieldNames = type.GetFields(bindingFlags)
                                       .Select(field => field.Name)
                                       .ToList();

            List <Type> fieldTypes = type.GetFields(bindingFlags)
                                     .Select(field => field.FieldType)
                                     .ToList();

            for (int a = 0; a < fieldNames.Count; a++)
            {
                if (fieldNames[a].StartsWith("<"))
                {
                    fieldNames[a] = fieldNames[a].Split('<')[1].Split('>')[0];
                }
            }

            for (int j = 0; j < newJsonLines.Length; j++)
            {
                JsonKeyValuePair data = jsonObjects[j];

                //string fname = fieldNames.Find(item => item == JsonReader.GetKeyValueData(str).name);
                for (int i = 0; i < fieldNames.Count; i++)
                {
                    if (fieldNames[i] == data.name.ToString())
                    {
                        JsonKeyValuePair jkvp = JsonDeserializer.Deserialize(newJsonLines[j], fieldTypes[i], false, data);

                        try { type.GetField(jkvp.name.ToString(), bindingFlags).SetValue(obj, jkvp.value); } catch { }
                    }
                }
            }

            return(obj);
        }
        public static JsonKeyValuePair Deserialize(string json, Type typ, bool onlyValue = false, JsonKeyValuePair existing_jkvp = null)
        {
            JsonKeyValuePair ret = new JsonKeyValuePair();

            if (existing_jkvp == null)
            {
                if (onlyValue)
                {
                    ret.value = json;
                }
                else
                {
                    ret = JsonReader.GetKeyValueData(json);
                }
            }
            else
            {
                ret = existing_jkvp;
            }

            if (ret.value.ToString() == "null")
            {
                ret.value = null;
            }
            else
            {
                if (typ.IsNumericType())
                {
                    ret.value = Convert.ChangeType(Convert.ToDouble(ret.value.ToString()), typ);
                }

                else if (Type.GetTypeCode(typ) == TypeCode.Boolean)
                {
                    ret.value = (ret.value.ToString().ToLower() == "true") ? true : false;
                }

                // TODO: DATETIME
                else if (typ.IsList()) // A List<>
                {
                    ret.value = DeserializeArray(ret.value.ToString(), typ);
                }

                else if (typ.IsArray) // An Array - same as list but without .ToList();
                {
                    ret.value = DeserializeArray(ret.value.ToString(), typ).ToArray();
                }

                else if (typ.IsDictionary())
                {
                    ret.value = DeserializeDictionary(ret.value.ToString(), typ);
                }

                else if (typ == typeof(Bitmap))
                {
                    ret.value = ImageToText.ConvertTextToImage(ret.value.ToString());
                }

                else if (typ == typeof(Image))
                {
                    ret.value = ImageToText.ConvertTextToImage(ret.value.ToString());
                }

                else if (typ == typeof(Point))
                {
                    ret.value = new PointConverter().ConvertFromString(ret.value.ToString());
                }

                else if (typ == typeof(Size))
                {
                    ret.value = new SizeConverter().ConvertFromString(ret.value.ToString());
                }

                else if (typ == typeof(Rectangle))
                {
                    ret.value = new RectangleConverter().ConvertFromString(ret.value.ToString());
                }

                else if (typ == typeof(DateTime))
                {
                    ret.value = DeserializeDateTime(ret.value.ToString());
                }

                else if (typ == typeof(Color))
                {
                    ret.value = new ColorConverter().ConvertFromString(ret.value.ToString());
                }

                else if (typ == typeof(Font))
                {
                    ret.value = new FontConverter().ConvertFromString(ret.value.ToString());
                }

                else if (typ == typeof(char))
                {
                    ret.value = new CharConverter().ConvertFromString(ret.value.ToString());
                }

                else if (typ == typeof(Guid))
                {
                    ret.value = new GuidConverter().ConvertFromString(ret.value.ToString());
                }

                else if (typ != typeof(string))
                {
                    ret.value = DeserializeObject(ret.value.ToString(), typ);
                }

                //else if (Activator.CreateInstance(typ) is Bitmap)
                //    ret.value = ImageToText.ConvertTextToImage(ret.value.ToString());

                //else if (Activator.CreateInstance(typ) is Image)
                //    ret.value = ImageToText.ConvertTextToImage(ret.value.ToString());

                //else if (Activator.CreateInstance(typ) is Point)
                //    ret.value = new Point(int.Parse(ret.value.ToString().Split(',')[0]), int.Parse(ret.value.ToString().Split(',')[1]));
            }
            return(ret);
        }
示例#4
0
        public static JsonKeyValuePair GetKeyValueData(string json)
        {
            JsonKeyValuePair jkvp            = new JsonKeyValuePair();
            string           BuildUp         = "";
            char             EndChar         = '"';
            bool             Building        = false;
            bool             hasFinishedName = false;
            bool             IsInValue       = false;
            bool             nextIsEscape    = false; // Used to skip \" and \'

            foreach (char ch in json)
            {
                if (nextIsEscape)
                {
                    nextIsEscape = false;
                    if (Building)
                    {
                        if (ch == '"' || ch == '\'')
                        {
                            BuildUp = BuildUp.Substring(0, BuildUp.Length - 1);                          // Removes the "\" if it's a " or '
                        }
                        BuildUp += ch;
                    }
                }
                else
                {
                    if (Building)
                    {
                        switch (ch)
                        {
                        case '}':
                        case ']':
                        case '"':
                        case '\'':
                            if (ch == EndChar)
                            {
                                IsInValue = false;
                                Building  = false;
                                if (hasFinishedName)
                                {
                                    jkvp.value = BuildUp;
                                }
                                else
                                {
                                    jkvp.name = BuildUp;
                                }
                                BuildUp = "";
                                continue;
                            }
                            break;

                        case '\\':
                            nextIsEscape = true;
                            break;

                        case ':':
                        case ',':
                            if (!IsInValue)
                            {
                                Building = false;
                                if (hasFinishedName)
                                {
                                    jkvp.value = BuildUp;
                                }
                                else
                                {
                                    jkvp.name = BuildUp;
                                }
                                BuildUp = "";
                                if (ch == ':')
                                {
                                    hasFinishedName = true;
                                }
                                continue;
                            }
                            break;
                        }
                        BuildUp += ch;
                    }
                    else
                    {
                        switch (ch)
                        {
                        case ',':
                            try { if (hasFinishedName)
                                  {
                                      if (string.IsNullOrEmpty(jkvp.value.ToString()))
                                      {
                                          jkvp.value = BuildUp;
                                      }
                                  }
                            } catch { }
                            break;     // This is here so it doesn't go into the default!

                        case '"':
                        case '\'':
                        case '{':
                        case '[':
                            IsInValue = true;
                            Building  = true;
                            if (ch == '"' || ch == '\'')
                            {
                                EndChar = ch;
                            }
                            else if (ch == '{')
                            {
                                EndChar = '}';
                            }
                            else if (ch == '[')
                            {
                                EndChar = ']';
                            }
                            break;

                        case ':':
                            hasFinishedName = true;
                            break;

                        default:
                            if (!char.IsWhiteSpace(ch))
                            {
                                Building = true;
                                BuildUp += ch.ToString();
                            }

                            break;
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(BuildUp))
            {
                Building = false;
                if (hasFinishedName)
                {
                    jkvp.value = BuildUp;
                }
                else
                {
                    jkvp.name = BuildUp;
                }
                BuildUp = "";
            }

            return(jkvp);
        }