예제 #1
0
        public static T Deserialise <T>(GenericStructure structure)
        {
            var obj = DeserialiseHelper(typeof(T), structure, new Dictionary <int, object>());

            if (obj is T)
            {
                return((T)obj);
            }
            obj = Convert.ChangeType(obj, typeof(T));
            if (obj is T)
            {
                return((T)obj);
            }
            return(default(T));
        }
예제 #2
0
        /// <summary>
        /// Parse a property string in the format: "key" "value", and add it to the structure
        /// </summary>
        /// <param name="gs">The structure to add the property to</param>
        /// <param name="prop">The property string to parse</param>
        private static void ParseProperty(GenericStructure gs, string prop)
        {
            var split = prop.SplitWithQuotes();

            gs.Properties.Add(new GenericStructureProperty(split[0], (split[1] ?? "").Replace('`', '"')));
        }
예제 #3
0
        private static object DeserialiseHelper(Type bindingType, GenericStructure structure, Dictionary <int, object> encounteredObjects)
        {
            // Null values
            if (structure.Name == "Serialise.Null" || structure["Serialise.Null.Value"] == "null")
            {
                return(bindingType.IsValueType ? Activator.CreateInstance(bindingType) : null);
            }

            // Referenced values
            var indexProp = structure.Properties.FirstOrDefault(x => x.Key == "Serialise.Reference.Index");

            if (indexProp != null)
            {
                return(encounteredObjects[int.Parse(indexProp.Value)]);
            }

            // Primitive objects
            if (structure.Name.StartsWith("Primitives."))
            {
                return(ConvertPrimitive(structure));
            }

            //var instance = Activator.CreateInstance(bindingType);
            var refProp = structure.Properties.FirstOrDefault(x => x.Key == "Serialise.Reference");
            var refVal  = refProp != null?int.Parse(refProp.Value) : -1;

            // List objects
            if (structure.Name == "Serialise.List" || typeof(IEnumerable).IsAssignableFrom(bindingType))
            {
                var list = Activator.CreateInstance(bindingType);
                if (refVal >= 0)
                {
                    encounteredObjects[refVal] = list;
                }
                DeserialiseList(list, bindingType, structure, encounteredObjects);
                return(list);
            }

            // Complex types
            var ctor     = bindingType.GetConstructor(Type.EmptyTypes) ?? bindingType.GetConstructors().First();
            var args     = ctor.GetParameters().Select(x => x.ParameterType.IsValueType ? Activator.CreateInstance(x.ParameterType) : null).ToArray();
            var instance = ctor.Invoke(args);

            if (refVal >= 0)
            {
                encounteredObjects[refVal] = instance;
            }

            foreach (var pi in bindingType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!pi.CanWrite)
                {
                    continue;
                }
                var prop  = structure.Properties.FirstOrDefault(x => x.Key == pi.Name);
                var child = structure.Children.FirstOrDefault(x => x.Name == pi.Name);
                if (prop != null)
                {
                    var prim = ConvertPrimitive(pi.PropertyType, prop.Value);
                    pi.SetValue(instance, Convert.ChangeType(prim, pi.PropertyType), null);
                }
                else if (child != null)
                {
                    var obj = DeserialiseHelper(pi.PropertyType, child, encounteredObjects);
                    pi.SetValue(instance, obj, null);
                }
            }

            return(instance);
        }
예제 #4
0
        private static GenericStructure SerialiseHelper(object obj, List <object> encounteredObjects)
        {
            // Handle null
            if (Equals(obj, null))
            {
                return new GenericStructure("Serialise.Null")
                       {
                           Properties = { new GenericStructureProperty("Serialise.Null.Value", "null") }
                       }
            }
            ;

            if (encounteredObjects.Contains(obj))
            {
                var rf = new GenericStructure("Serialise.Reference");

                rf.AddProperty("Serialise.Reference.Index", (encounteredObjects.IndexOf(obj) + 1).ToString());
                return(rf);
            }

            var ty = obj.GetType();

            // Handle primitive types
            if (ty.IsPrimitive || ty == typeof(string) || ty == typeof(decimal))
            {
                var name = "Primitives.";
                if (ty == typeof(bool))
                {
                    name += "Boolean";
                }
                else if (ty == typeof(char) || ty == typeof(string))
                {
                    name += "String";
                }
                else
                {
                    name += "Numeric";
                }
                return(new GenericStructure(name)
                {
                    Properties = { new GenericStructureProperty("Primitive.Value", Convert.ToString(obj)) }
                });
            }

            if (ty == typeof(DateTime))
            {
                return(new GenericStructure("Primitives.DateTime")
                {
                    Properties = { new GenericStructureProperty("Primitive.Value", ((DateTime)obj).ToString("u")) }
                });
            }

            if (ty == typeof(Color))
            {
                var color = (Color)obj;
                var col   = String.Format("{0} {1} {2} {3}", color.R, color.G, color.B, color.A);
                return(new GenericStructure("Primitives.Colour")
                {
                    Properties = { new GenericStructureProperty("Primitive.Value", col) }
                });
            }

            if (ty == typeof(Coordinate))
            {
                return(new GenericStructure("Primitives.Coordinate")
                {
                    Properties = { new GenericStructureProperty("Primitive.Value", obj.ToString()) }
                });
            }

            if (ty == typeof(Box))
            {
                var b = (Box)obj;
                return(new GenericStructure("Primitives.Box")
                {
                    Properties = { new GenericStructureProperty("Primitive.Value", b.Start + " " + b.End) }
                });
            }

            if (ty == typeof(Rectangle))
            {
                var r = (Rectangle)obj;
                return(new GenericStructure("Primitives.Rectangle")
                {
                    Properties = { new GenericStructureProperty("Primitive.Value", r.X + " " + r.Y + " " + r.Width + " " + r.Height) }
                });
            }

            if (ty == typeof(Plane))
            {
                var p = (Plane)obj;
                return(new GenericStructure("Primitives.Plane")
                {
                    Properties = { new GenericStructureProperty("Primitive.Value", p.Normal + " " + p.DistanceFromOrigin) }
                });
            }

            encounteredObjects.Add(obj);
            var index = encounteredObjects.Count;

            // Handle list
            var enumerable = obj as IEnumerable;

            if (enumerable != null)
            {
                var children = enumerable.OfType <object>().Select(x => SerialiseHelper(x, encounteredObjects));
                var list     = new GenericStructure("Serialise.List");
                list.AddProperty("Serialise.Reference", index.ToString());
                list.Children.AddRange(children);
                return(list);
            }

            // Handle complex types
            var gs = new GenericStructure(ty.FullName);

            gs.AddProperty("Serialise.Reference", index.ToString());
            foreach (var pi in ty.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!pi.CanRead)
                {
                    continue;
                }
                var val = pi.GetValue(obj, null);
                var pv  = SerialiseHelper(val, encounteredObjects);
                if (pv.Name.StartsWith("Primitives."))
                {
                    gs.AddProperty(pi.Name, pv["Primitive.Value"]);
                }
                else
                {
                    pv.Name = pi.Name;
                    gs.Children.Add(pv);
                }
            }
            return(gs);
        }