示例#1
0
		public static ISimpleDataObject Create(object o, ObjectGraphContext ctx = null)
		{
			if (o == null)
				return null;
			var t = o.GetType();
			return new SimpleDataObject(o, ctx);
		}
示例#2
0
        internal static T Deserialize <T>(Stream s, ObjectGraphContext context = null)
        {
            var sr     = new StreamReader(new BufferedStream(s));
            var result = Deserialize <T>(sr, context);

            return(result);
        }
示例#3
0
		public static ISimpleDataObject Load(SafeDictionary<string, IData> simpleData, ObjectGraphContext ctx = null)
		{
			if (simpleData == null)
				return null;
			var t = new SafeType(simpleData["!type"].Value as string).Type;
			return new SimpleDataObject(simpleData, ctx);
		}
示例#4
0
        private static void Serialize <T>(T o, Stream s, ObjectGraphContext context = null, int tabLevel = 0)
        {
            var sw = new StreamWriter(new BufferedStream(s));

            Serialize(o, sw, context);
            sw.Flush();
        }
示例#5
0
        public string SerializeToString(object o)
        {
            var ctx    = new ObjectGraphContext();
            var kos    = new List <object>();
            var parser = new ObjectGraphParser();

            if (o == null)
            {
                // do nothing
            }
            else if (o.GetType().IsScalar())
            {
                kos.Add(DataScalar.Create(o));
            }
            else
            {
                Action <object> Parser_StartObject = x =>
                {
                    if (!x.GetType().IsScalar())
                    {
                        var dobj = SimpleDataObject.Create(x, ctx);
                        kos.Add(dobj);
                    }
                };
                parser.StartObject += new ObjectGraphParser.ObjectDelegate(Parser_StartObject);
                parser.Parse(o);
            }
            foreach (var dobj in kos.OfType <ISimpleDataObject>())
            {
                dobj.InitializeData(ctx);
            }
            return(JsonConvert.SerializeObject(kos));
        }
示例#6
0
 private void ParseColor(Color c, ObjectGraphContext context)
 {
     // HACK - Mono's implmentation of Color is different from .NET's so we need to save just the ARGB values in a consistent format
     ParseProperty("A", c, c.A, context);
     ParseProperty("R", c, c.R, context);
     ParseProperty("G", c, c.G, context);
     ParseProperty("B", c, c.B, context);
 }
示例#7
0
        public static object Deserialize(Stream s, Type desiredType, ObjectGraphContext context = null, StringBuilder log = null)
        {
            var sr     = new StreamReader(s);
            var result = Deserialize(sr, desiredType, true, context, log);

            sr.Close();
            return(result);
        }
示例#8
0
        private void ParseObject(object o, ObjectGraphContext context)
        {
            var type  = o.GetType();
            var props = ObjectGraphContext.GetKnownProperties(type);

            foreach (var p in props.Values)
            {
                var val = p.GetValue(o, new object[] { });
                ParseProperty(p.Name, o, val, context);
            }
        }
示例#9
0
 internal static void Serialize <T>(T o, TextWriter w, ObjectGraphContext context = null, int tabLevel = 0)
 {
     if (o == null)
     {
         Serialize(o, w, typeof(T), context, tabLevel);
     }
     else
     {
         Serialize(o, w, o.GetType(), context, tabLevel);
     }
 }
示例#10
0
 private void ParseCollection(IEnumerable list, ObjectGraphContext context)
 {
     foreach (var item in list.Cast <object>().ToArray())
     {
         context.propertyStack.Push("(Collection Item)");
         if (Item != null)
         {
             Item(item);
         }
         context.ObjectQueue.Enqueue(item);
         context.propertyStack.Pop();
     }
 }
示例#11
0
        private void ParseProperty(string propertyName, object o, object val, ObjectGraphContext context)
        {
            context.propertyStack.Push(propertyName);
            bool recurse = true;             // if no event handler, assume we are parsing recursively (really adding subproperties to queue)

            if (Property != null)
            {
                recurse = Property(propertyName, o, val);
            }
            if (recurse)
            {
                context.ObjectQueue.Enqueue(val);
            }
            context.propertyStack.Pop();
        }
示例#12
0
        private static void WriteObject(object o, TextWriter w, ObjectGraphContext context, int tabLevel)
        {
            // serialize object type and field count
            if (o is IDataObject)
            {
                // use data object code! :D
                var type = o.GetType();
                var data = (o as IDataObject).Data;
                w.WriteLine("p" + data.Count + ":");
                foreach (var kvp in data)
                {
                    var pname = kvp.Key;
                    var val   = kvp.Value;
                    var prop  = ObjectGraphContext.GetKnownProperties(type)[pname];
                    if (prop != null)
                    {
                        var ptype = prop.PropertyType;
                        WriteProperty(w, o, ptype, pname, val, context, tabLevel);
                    }
                    else
                    {
                        // TODO - if property doesn't exist, log a warning somewhere?
                        WriteProperty(w, o, typeof(object), pname, val, context, tabLevel);
                    }
                }
            }
            else
            {
                // use reflection :(
                var type  = o.GetType();
                var props = ObjectGraphContext.GetKnownProperties(type).Values.Where(p =>
                                                                                     p.HasAttribute <ForceSerializationWhenDefaultValueAttribute>() || // force serialization of property even if value is null/default?
                                                                                     !p.GetValue(o, null).SafeEquals(p.PropertyType.DefaultValue()));  // property value is not null/default?
                w.WriteLine("p" + props.Count() + ":");
                foreach (var p in props.OrderBy(p => GetSerializationPriority(p)))
                {
                    WriteProperty(w, o, p.PropertyType, p.Name, context.GetObjectProperty(o, p), context, tabLevel);
                }
            }

            // write end object
            for (int i = 0; i < tabLevel; i++)
            {
                w.Write('\t');
            }
            w.WriteLine(";");
        }
示例#13
0
		public SimpleDataObject(object o, ObjectGraphContext ctx = null)
		{
			Context = ctx ?? new ObjectGraphContext();
			if (o != null)
			{
				Type = o.GetType();
				if (Context.GetID(o) == null)
					ID = Context.Add(o);
				Data = o.GetData(ctx);
			}
			else
			{
				Type = null;
				Data = new SafeDictionary<string, object>();
				ID = -1;
			}
		}
示例#14
0
        private static void WriteArray(Array array, TextWriter w, ObjectGraphContext context, int tabLevel)
        {
            var tabs = new string('\t', tabLevel);

            // arrays get size and elements listed out
            var bounds = new List <string>();

            for (var rank = 0; rank < array.Rank; rank++)
            {
                bounds.Add(array.GetLowerBound(rank) + "_" + array.GetUpperBound(rank));
            }
            w.WriteLine("a" + string.Join(",", bounds.ToArray()) + ":" + tabs);
            var type     = array.GetType();
            var itemtype = type.GetElementType();

            if (array.Rank == 1)
            {
                foreach (var item in array)
                {
                    Serialize(item, w, itemtype, context, tabLevel + 1);
                }
            }
            else if (array.Rank == 2)
            {
                for (int x = array.GetLowerBound(0); x <= array.GetUpperBound(0); x++)
                {
                    for (int y = array.GetLowerBound(1); y <= array.GetUpperBound(1); y++)
                    {
                        Serialize(array.GetValue(x, y), w, itemtype, context, tabLevel + 1);
                    }
                }
            }
            else
            {
                throw new SerializationException("Arrays with more than 2 dimensions are not supported.");
            }

            // write end object
            for (int i = 0; i < tabLevel; i++)
            {
                w.Write('\t');
            }
            w.WriteLine(";");
        }
示例#15
0
        private static object DeserializeObjectWithID(TextReader r, Type type, ObjectGraphContext context, StringBuilder log)
        {
            // ID - need to find known object
            int    id;
            string s = r.ReadToEndOfLine(';', log);

            if (!int.TryParse(s, out id))
            {
                throw new SerializationException("Expected integer, got \"" + s + "\" when parsing object ID.");
            }

            // do we have it?
            if (!context.KnownObjects.ContainsKey(type) || context.KnownObjects[type].Count <= id)
            {
                throw new SerializationException("No known object of type " + type + " has an ID of " + id + ".");
            }

            // found it!
            return(context.KnownObjects[type][id]);
        }
示例#16
0
        private static object DeserializeObject(TextReader r, Type type, ObjectGraphContext context, StringBuilder log)
        {
            // read property count or id number
            object o;
            var    fin = r.Read();

            while (fin != 0 && char.IsWhiteSpace((char)fin))
            {
                if (log != null)
                {
                    log.Append((char)fin);
                }
                fin = r.Read();
            }
            if (fin != 0 && log != null)
            {
                log.Append((char)fin);
            }
            if (fin == 'p')
            {
                o = DeserializeObjectWithProperties(r, type, context, log);
            }
            else if (fin == 'i')
            {
                o = DeserializeObjectWithID(r, type, context, log);
            }
            else if (fin == 'n')
            {
                // null object!
                o = null;

                // clean up
                ReadSemicolon(r, type, log);
            }
            else
            {
                throw new SerializationException("Expected 'p'/'i'/'n', got '" + (char)fin + "' when parsing " + type + ".");
            }
            return(o);
        }
示例#17
0
 private void ParseArray(Array array, ObjectGraphContext context)
 {
     if (ArrayDimensions != null)
     {
         var bounds = new List <int>();
         for (var rank = 0; rank < array.Rank; rank++)
         {
             bounds.Add(array.GetLength(rank));
         }
         ArrayDimensions(bounds);
     }
     foreach (var item in array)
     {
         context.propertyStack.Push("(Array Item)");
         if (Item != null)
         {
             Item(item);
         }
         context.ObjectQueue.Enqueue(item);
         context.propertyStack.Pop();
     }
 }
示例#18
0
        private static string DeserializeString(TextReader r, ObjectGraphContext context, StringBuilder log)
        {
            string        o;
            bool          foundRealSemicolon = false;
            StringBuilder sb     = new StringBuilder();
            int           quotes = 0;

            while (!foundRealSemicolon)
            {
                var ns = r.ReadToEndOfLine(';', log);
                quotes += ns.Count(c => c == '"');                 // TODO - don't count escaped quotes
                sb.Append(ns);
                if (!ns.EndsWith("\\") && quotes % 2 == 0)
                {
                    foundRealSemicolon = true;
                }
            }
            var s = sb.ToString();

            if (s == "n")
            {
                o = null;
            }
            else
            {
                o = s.Trim();
                if (o.StartsWith("\""))
                {
                    o = o.Substring(1);
                }
                if (o.EndsWith("\""))
                {
                    o = o.Substring(0, o.Length - 1);
                }
                o = o.Replace("\\\"", "\"").Replace("\\;", ";").Replace("\\\\", "\\");
            }
            return(o);
        }
示例#19
0
        public IDictionary <Type, IList <object> > Parse(object o, ObjectGraphContext context = null)
        {
            // set up our context if we haven't already
            if (context == null)
            {
                context = new ObjectGraphContext();
            }

            // fire up the queue
            context.ObjectQueue.Enqueue(o);
            while (context.ObjectQueue.Any())
            {
                o = context.ObjectQueue.Dequeue();
                context.objectStack.Push(o);

                // deal with nulls
                if (o == null)
                {
                    if (Null != null)
                    {
                        Null(null);
                    }
                    context.objectStack.Pop();
                    continue;
                }

                var type = o.GetType();

                int?id = null;
                if (!type.IsValueType && type != typeof(string))
                {
                    id = context.GetID(o);
                }

                if (!ObjectGraphContext.KnownTypes.ContainsKey(type.AssemblyQualifiedName))
                {
                    // register type
                    ObjectGraphContext.KnownTypes.Add(type.AssemblyQualifiedName, type);
                    ObjectGraphContext.AddProperties(type);
                }

                if (!type.IsValueType && type != typeof(string) && !typeof(Array).IsAssignableFrom(type))
                {
                    if (id == null)
                    {
                        // add to context
                        context.Add(o);
                    }
                    else
                    {
                        if (KnownObject != null)
                        {
                            KnownObject(o);
                        }

                        // done
                        context.objectStack.Pop();
                        continue;
                    }
                }

                // object was found
                if (StartObject != null)
                {
                    StartObject(o);
                }

                // parse sub objects
                if (type.IsPrimitive || typeof(Enum).IsAssignableFrom(type) || type == typeof(string))
                {
                    // nothing to do, no sub objects
                }
                else if (type == typeof(Color))
                {
                    ParseColor((Color)o, context);
                }
                else if (typeof(Array).IsAssignableFrom(type))
                {
                    ParseArray((Array)o, context);
                }
                else if (typeof(IEnumerable).IsAssignableFrom(type) && type.GetMethods().Where(m => m.Name == "Add" && m.GetParameters().Length == 1 || m.GetParameters().Length == 2).Any())
                {
                    ParseCollection((IEnumerable)o, context);
                }
                else
                {
                    ParseObject(o, context);
                }

                // done parsing object
                if (EndObject != null)
                {
                    EndObject(o);
                }
                context.objectStack.Pop();
            }

            return(context.KnownObjects);
        }
示例#20
0
		public SimpleDataObject(SafeDictionary<string, IData> simpleData, ObjectGraphContext ctx = null)
		{
			SimpleData = simpleData;
			Context = ctx ?? new ObjectGraphContext();
		}
示例#21
0
		public SimpleDataObject()
		{
			Context = new ObjectGraphContext();
			Type = typeof(object);
		}
示例#22
0
        private static void WriteCollection(IEnumerable list, TextWriter w, ObjectGraphContext context, int tabLevel)
        {
            var tabs = new string('\t', tabLevel);

            // collections get size and elements listed out
            Type itemType;
            var  type   = list.GetType();
            bool isDict = false;

            if (type.GetGenericArguments().Length == 2)
            {
                // HACK - assume it's a dictionary, no real way to test
                itemType = typeof(KeyValuePair <,>).MakeGenericType(type.GetGenericArguments());
                w.WriteLine("d" + list.Cast <object>().Count() + ":" + tabs);
                isDict = true;
            }
            else if (type.BaseType.GetGenericArguments().Length == 2)
            {
                // HACK - Resources inherits from a dictionary type
                itemType = typeof(KeyValuePair <,>).MakeGenericType(type.BaseType.GetGenericArguments());
                w.WriteLine("d" + list.Cast <object>().Count() + ":" + tabs);
                isDict = true;
            }
            else if (type == typeof(DynamicDictionary))
            {
                itemType = typeof(KeyValuePair <object, object>);
                w.WriteLine("d" + list.Cast <object>().Count() + ":" + tabs);
                isDict = true;
            }
            else if (type.GetGenericArguments().Length == 1)
            {
                // HACK - assume it's a collection, no real way to test
                itemType = type.GetGenericArguments()[0];
                w.WriteLine("c" + list.Cast <object>().Count() + ":" + tabs);
            }
            else
            {
                // no generic type? probably a list of objects?
                itemType = typeof(object);
                w.WriteLine("c" + list.Cast <object>().Count() + ":" + tabs);
            }
            foreach (var item in list)
            {
                if (isDict)
                {
                    var keyprop = ObjectGraphContext.GetKnownProperties(itemType)["Key"];
                    var valprop = ObjectGraphContext.GetKnownProperties(itemType)["Value"];
                    Serialize(context.GetObjectProperty(item, keyprop), w, keyprop.PropertyType, context, tabLevel + 1);
                    Serialize(context.GetObjectProperty(item, valprop), w, valprop.PropertyType, context, tabLevel + 1);
                }
                else
                {
                    Serialize(item, w, itemType, context, tabLevel + 1);
                }
            }

            // write end object
            for (int i = 0; i < tabLevel; i++)
            {
                w.Write('\t');
            }
            w.WriteLine(";");
        }
示例#23
0
        private static object DeserializeStringifiedObject(TextReader r, Type type, ObjectGraphContext context, StringBuilder log)
        {
            object o;
            // read tag to see if it's actually a stringified object
            var fin = r.Read();

            while (fin != 0 && char.IsWhiteSpace((char)fin))
            {
                if (log != null)
                {
                    log.Append((char)fin);
                }
                fin = r.Read();
            }
            if (fin != 0 && log != null)
            {
                log.Append((char)fin);
            }
            if (fin == 's')
            {
                IStringifier stringifier = null;
                var          t           = type;
                while (stringifier == null && t != null)
                {
                    stringifier = StringifierLibrary.Instance.All.SingleOrDefault(x => x.SupportedType == t);
                    t           = t.BaseType;
                }
                if (stringifier == null)
                {
                    throw new Exception("Can't find stringifier to deserialize " + type);
                }
                var dummy = r.ReadTo(':', log);
                var val   = r.ReadToEndOfLine(';', log);
                o = stringifier.Destringify(val);
            }
            else if (fin == 'p')
            {
                o = DeserializeObjectWithProperties(r, type, context, log);
            }
            else if (fin == 'i')
            {
                o = DeserializeObjectWithID(r, type, context, log);
            }
            else if (fin == 'n')
            {
                // null object!
                o = null;

                // clean up
                ReadSemicolon(r, type, log);
            }
            else if (fin == 'd')
            {
                o = DeserializeDictionary(r, type, context, log);
            }
            else if (fin == 'c')
            {
                o = DeserializeList(r, type, context, log);
            }
            else
            {
                throw new Exception("Unknown data tag " + fin + ", was expecting s/p/i/n/d/c.");
            }
            if (!context.KnownObjects.ContainsKey(type) || !context.KnownObjects[type].Contains(o))
            {
                context.Add(o);
            }
            return(o);
        }
示例#24
0
		public void InitializeData(ObjectGraphContext ctx = null)
		{
			Data = Value.GetData(ctx ?? Context);
		}
示例#25
0
 public DataReference(ObjectGraphContext ctx, T t = default(T))
 {
     Context = ctx;
     Value   = t;
 }
示例#26
0
 public DataReference()
 {
     Context = new ObjectGraphContext();
 }
示例#27
0
        private static object DeserializeObjectWithProperties(TextReader r, Type type, ObjectGraphContext context, StringBuilder log)
        {
            // create object and add it to our context
            var o = type.Instantiate();

            context.Add(o);

            // properties count - need to create object and populate properties
            int    count;
            string s = r.ReadTo(':', log);

            if (!int.TryParse(s, out count))
            {
                throw new SerializationException("Expected integer, got \"" + s + "\" when parsing property count.");
            }


            var dict = new SafeDictionary <string, object>();

            // deserialize the properties
            var props = ObjectGraphContext.GetKnownProperties(type, true);

            for (int i = 0; i < count; i++)
            {
                var pname = r.ReadTo(':', log).Trim();
                if (type == typeof(Game.Objects.Civilization.Empire) && pname == "StoredResources")
                {
                }
                if (props.ContainsKey(pname))
                {
                    // TODO - get base class recursively, not just derived class and declaring type
                    var prop = type.GetProperty(pname, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) ?? props[pname];                     // get concrete type property in case it has DoNotSerialize and the abstract type doesn't
                    if (prop != null)
                    {
                        if (prop.Name == "StarSystemNames")
                        {
                        }
                        var data = Deserialize(r, prop.PropertyType, false, context, log);
                        if (prop.HasAttribute <SerializationPriorityAttribute>())
                        {
                            prop.SetValue(o, data);                             // TODO - use cached reflection lambdas
                        }
                        if (!prop.HasAttribute <DoNotSerializeAttribute>())
                        {
                            dict[pname] = data;
                        }
                    }
                    else
                    {
                        r.ReadToEndOfLine(';', log);                         // throw away this property, we don't need it
                    }
                    // if p is null or has do not serialize attribute, it must be data from an old version with different property names, so don't crash
                }
            }

            //propertySetterTasks.Add(Task.Factory.StartNew(() =>
            //{
            o.SetData(dict, context);
            //}));

            // clean up
            ReadSemicolon(r, type, log);

            return(o);
        }
示例#28
0
		public void InitializeValue(ObjectGraphContext ctx = null)
		{
			if (Context.GetID(Value) == null)
				Context.Add(Value);
			Value.SetData(Data, ctx ?? Context);
		}
示例#29
0
 public DataReference(ObjectGraphContext ctx, int id = -1)
 {
     Context = ctx;
     ID      = id;
 }
示例#30
0
		public T Reconstitute<T>(ObjectGraphContext ctx = null)
		{
			var result = (T)typeof(T).Instantiate();
			result.SetData(Data, ctx ?? new ObjectGraphContext());
			return result;
		}