private static string GetShortTypeName(Type t) { return(SafeType.GetShortTypeName(t)); }
private static object Deserialize(TextReader r, Type desiredType, bool isRoot, ObjectGraphContext context = null, StringBuilder log = null) { // set up our serialization context if we haven't already if (context == null) { context = new ObjectGraphContext(); } if (isRoot) { // clear out our tasks propertySetterTasks = new List <Task>(); } // find data type var typename = r.ReadTo(':', log).Trim(); Type type; if (string.IsNullOrWhiteSpace(typename)) { type = desiredType; } else { type = ObjectGraphContext.KnownTypes[typename]; if (type == null) { try { // HACK - for old savegame compatibility typename = Regex.Replace(typename, @"IOrder`1\[\[.*?\]\]", "IOrder"); typename = Regex.Replace(typename, @"AddOrderCommand`1\[\[.*?\]\]", "AddOrderCommand"); typename = Regex.Replace(typename, @"RemoveOrderCommand`1\[\[.*?\]\]", "RemoveOrderCommand"); type = new SafeType(typename).Type; } catch (Exception ex) { try { typename = typename.Replace("mscorlib", "System.Private.CoreLib"); // in case we have a legacy .NET Framework generated save type = new SafeType(typename).Type; } catch (Exception ex2) { throw new SerializationException("Unknown data type '" + typename + "'. Perhaps this data was serialized with an incompatible version of the application?", ex2); } } } if (type == null) { throw new SerializationException("Unable to determine object type from type string \"" + typename + "\""); } } if (!ObjectGraphContext.KnownTypes.ContainsKey(GetShortTypeName(type))) { // add to known types ObjectGraphContext.KnownTypes.Add(GetShortTypeName(type), type); } // check type so we don't bother trying to create an object only to find it's the wrong type later if (!desiredType.IsAssignableFrom(type)) { #if DEBUG return(null); #endif #if RELEASE throw new SerializationException("Expected " + desiredType + ", got " + type + " when parsing new object."); #endif } // the object! object o; if (StringifierLibrary.Instance.All?.Any(x => x.SupportedType.IsAssignableFrom(type)) ?? false) { o = DeserializeStringifiedObject(r, type, context, log); } else if (type.IsPrimitive || type == typeof(decimal)) { // parse primitive types var val = r.ReadToEndOfLine(';', log); o = Convert.ChangeType(val, type); } else if (type == typeof(string)) { // parse strings o = DeserializeString(r, context, log); } else if (type == typeof(Color)) { // HACK - Color implmentation varies between .NET and Mono, so treat it as raw ARGB values var argb = r.ReadToEndOfLine(';', log).Split(','); if (argb.Length != 4) { throw new SerializationException("Colors must have 4 ARGB values."); } byte a, rv, g, b; if (!byte.TryParse(argb[0], out a) || !byte.TryParse(argb[1], out rv) || !byte.TryParse(argb[2], out g) || !byte.TryParse(argb[3], out b)) { throw new SerializationException("Could not parse one of the ARGB values in \"" + argb + "\"."); } o = Color.FromArgb(a, rv, g, b); } else if (typeof(Enum).IsAssignableFrom(type)) { // parse enums var val = r.ReadToEndOfLine(';', log); o = val.ParseEnum(type); } else if (typeof(Array).IsAssignableFrom(type)) { // parse arrays o = DeserializeArray(r, type, context, log); } else if (typeof(IEnumerable).IsAssignableFrom(type) && type.GetMethods().Where(m => m.Name == "Add" && m.GetParameters().Length == 1 || m.GetParameters().Length == 2).Any() && !typeof(IReferenceEnumerable).IsAssignableFrom(type)) { // parse collections o = DeserializeCollection(r, type, context, log); } else { // parse objects o = DeserializeObject(r, type, context, log); } /*if (isRoot) * { * // wait for tasks to complete * Action<Task> awaitTask = async t => await t; * propertySetterTasks.RunTasks(awaitTask); * }*/ // return our new object return(o); }