示例#1
0
 private static string GetShortTypeName(Type t)
 {
     return(SafeType.GetShortTypeName(t));
 }
示例#2
0
        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);
        }