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)); }
/// <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('`', '"'))); }
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); }
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); }