示例#1
0
        public void SetObjectData(ref object obj, IObjectGraphNode node)
        {
            IDictionary d         = (IDictionary)obj;
            Type        objType   = d.GetType();
            Type        keyType   = typeof(object);
            Type        valueType = typeof(object);

            if (objType.IsGenericType)
            {
                Type[] gen = objType.GetGenericArguments();
                keyType   = gen[0];
                valueType = gen[1];
            }

            //TODO missing add comparer

            ISequenceGraphNode elements = node["dictionary"] as ISequenceGraphNode;

            foreach (var e in elements)
            {
                IObjectGraphNode entry = e as IObjectGraphNode;
                object           key   = entry["key"].RebuildObject(keyType);
                object           value = entry["value"].RebuildObject(valueType);
                d.Add(key, value);
            }
        }
示例#2
0
        public void GetObjectData(object obj, IObjectGraphNode holder)
        {
            IDictionary e         = (IDictionary)obj;
            Type        objType   = e.GetType();
            Type        keyType   = typeof(object);
            Type        valueType = typeof(object);

            if (objType.IsGenericType)
            {
                Type[] gen = objType.GetGenericArguments();
                keyType   = gen[0];
                valueType = gen[1];
            }

            ISequenceGraphNode elements = holder.ParentGraph.BuildSequenceNode();

            holder["dictionary"] = elements;
            IDictionaryEnumerator it = e.GetEnumerator();

            while (it.MoveNext())
            {
                IObjectGraphNode entry = holder.ParentGraph.CreateObjectData();
                entry["key"]   = holder.ParentGraph.BuildNode(it.Key, keyType);
                entry["value"] = holder.ParentGraph.BuildNode(it.Value, valueType);
                elements.Add(entry);
            }

            //TODO missing add comparer
        }
示例#3
0
        public void SetObjectData(ref object obj, IObjectGraphNode node)
        {
            Type objType  = obj.GetType();
            Type elemType = objType.GetGenericArguments()[0];

            IGraphNode comparerData = node["comparer"];

            if (comparerData != null)
            {
                Type comparerType   = typeof(IEqualityComparer <>).MakeGenericType(elemType);
                var  comparerObject = comparerData.RebuildObject(comparerType);
                var  f = objType.GetField("m_comparer", BindingFlags.NonPublic | BindingFlags.Instance);
                f.SetValue(obj, comparerObject);
            }

            ISequenceGraphNode elements = node["elements"] as ISequenceGraphNode;

            if (elements != null)
            {
                var m = objType.GetMethod("UnionWith");
                var a = Array.CreateInstance(elemType, elements.Length);
                elements.Select(e => e.RebuildObject(elemType)).ToArray().CopyTo(a, 0);
                m.Invoke(obj, new object[] { a });
            }
        }
示例#4
0
        public void SetObjectData(ref object obj, IObjectGraphNode node)
        {
            Type objType  = obj.GetType();
            Type elemType = TypeTools.GetGenericArguments(objType)[0];

            IGraphNode comparerData = node["comparer"];

            if (comparerData != null)
            {
                Type comparerType = typeof(IEqualityComparer <>).MakeGenericType(elemType);
                var  comparer     = comparerData.RebuildObject(comparerType);
                objType.GetConstructor(false, comparerType).Invoke(obj, new[] { comparer });
            }
            else
            {
                objType.GetConstructor(false).Invoke(obj, null);
            }

            ISequenceGraphNode elements = node["elements"] as ISequenceGraphNode;

            if (elements != null)
            {
                var m = TypeTools.GetRuntimeMethod(objType, "UnionWith");
                var a = Array.CreateInstance(elemType, elements.Length);
                elements.Select(e => e.RebuildObject(elemType)).ToArray().CopyTo(a, 0);
                m.Invoke(obj, new object[] { a });
            }
        }
示例#5
0
        private IGraphNode ReadNode(JsonToken json, Graph parentGraph)
        {
            if (json == null)
            {
                return(null);
            }

            if (json is JsonString)
            {
                string val = ((JsonString)json).String;
                if (val.StartsWith("refId@"))
                {
                    int id = int.Parse(val.Substring(6));
                    return(parentGraph.GetObjectDataForRefId(id));
                }

                if (val.StartsWith("class@"))
                {
                    byte id = byte.Parse(val.Substring(6));
                    return(parentGraph.GetTypeEntry(id));
                }

                return(parentGraph.BuildStringNode(val));
            }

            if (json is JsonNumber)
            {
                return(parentGraph.BuildPrimitiveNode((json as JsonNumber).Value));
            }

            if (json is JsonBool)
            {
                return(parentGraph.BuildPrimitiveNode((json as JsonBool).Value));
            }

            if (json is JsonArray)
            {
                ISequenceGraphNode node = parentGraph.BuildSequenceNode();
                foreach (JsonToken t in ((JsonArray)json))
                {
                    var elem = ReadNode(t, parentGraph);
                    node.Add(elem);
                }
                return(node);
            }

            return(JsonToObjectNode(json as JsonObject, parentGraph));
        }
示例#6
0
        public void GetObjectData(object obj, IObjectGraphNode holder)
        {
            Type objType   = obj.GetType();
            var  allFields = objType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
            var  f         = allFields.FirstOrDefault(field => CompareRegex.IsMatch(field.Name));

            if (f != null)
            {
                var  comparator     = f.GetValue(obj);
                Type comparatorType = comparator.GetType();

                if (!(comparatorType.IsGenericType && DefaultComparatorTypes.Contains(comparatorType.GetGenericTypeDefinition())))
                {
                    holder["comparer"] = holder.ParentGraph.BuildNode(comparator, null);
                }
            }

            Type elementType            = objType.GetGenericArguments()[0];
            var  nodeSequence           = ((IEnumerable)obj).Cast <object>().Select(o => holder.ParentGraph.BuildNode(o, elementType));
            ISequenceGraphNode sequence = holder.ParentGraph.BuildSequenceNode();

            sequence.AddRange(nodeSequence);
            holder["elements"] = sequence;
        }
示例#7
0
        public IGraphNode BuildNode(object obj, Type fieldType)
        {
            if (obj == null)
            {
                return(null);
            }

            IGraphNode result;
            Type       objType = obj.GetType();

            if (typeof(Type).IsAssignableFrom(objType))
            {
                return(GetTypeEntry((Type)obj));
            }

            var formatter = GetFormatter(objType);

            if (formatter != null)
            {
                var node = formatter.ObjectToGraphNode(obj, this);
                var fieldTypeFormatter = fieldType != null?GetFormatter(fieldType) : null;

                if (formatter != fieldTypeFormatter)
                {
                    //Value needs to be boxed
                    ObjectGraphNode box = node as ObjectGraphNode;
                    if (box == null)
                    {
                        box = (ObjectGraphNode)CreateObjectData();
                        box[DEFAULT_BOXED_VALUE_FIELD_NAME] = node;
                    }

                    if (box.ObjectType == null)
                    {
                        box.ObjectType = GetTypeEntry(objType);
                    }
                    return(box);
                }
                return(node);
            }

            if (objType.IsArray || objType.IsPrimitiveData())
            {
                //Boxable Values (arrays, bools, numbers, strings)
                IGraphNode valueNode;
                if (objType.IsArray)
                {
                    Type elemType            = objType.GetElementType();
                    ISequenceGraphNode array = BuildSequenceNode();
                    IEnumerator        it    = ((IEnumerable)obj).GetEnumerator();
                    while (it.MoveNext())
                    {
                        IGraphNode elem = BuildNode(it.Current, elemType);
                        array.Add(elem);
                    }
                    valueNode = array;
                }
                else
                {
                    //Primitive data type
                    if (objType == typeof(string))
                    {
                        valueNode = BuildStringNode(obj as string);
                    }
                    else
                    {
                        if (objType.IsEnum)
                        {
                            obj = Convert.ChangeType(obj, ((Enum)obj).GetTypeCode());
                        }

                        valueNode = BuildPrimitiveNode(obj as ValueType);
                    }
                }

                if (objType != fieldType)
                {
                    //Value needs to be boxed
                    var boxNode = CreateObjectData();
                    boxNode.ObjectType = GetTypeEntry(objType);
                    boxNode[DEFAULT_BOXED_VALUE_FIELD_NAME] = valueNode;
                    valueNode = boxNode;
                }

                result = valueNode;
            }
            else
            {
                //Non-Boxable Values (structs and objects)
                IObjectGraphNode objReturnData;
                bool             extractData = true;
                if (objType.IsValueType)
                {
                    //Structure
                    objReturnData = CreateObjectData();
                }
                else
                {
                    //Classes
                    if (!GetObjectNode(obj, out objReturnData))
                    {
                        extractData = false;
                    }
                }

                if (extractData)
                {
                    var surrogate = SerializationServices.GetDefaultSerializationSurrogate(objType);
                    surrogate.GetObjectData(obj, objReturnData);
                }

                if ((objReturnData.ObjectType == null) && (objType != fieldType))
                {
                    objReturnData.ObjectType = GetTypeEntry(objType);
                }

                result = objReturnData;
            }
            return(result);
        }