Пример #1
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
        }
Пример #2
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));
        }
Пример #3
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);
        }