예제 #1
0
        object DeserializeToBoolean(INode node, NodeKindWrapped targetKind, Type targetType, State state, Type tag)
        {
            if (node is NullNode)
            {
                if (!TypeHelper.IsBoxed(targetType))
                {
                    var msg = state.CreateNodeConversionFailureMessage(node, targetType);
                    throw new DeserializeFailureException(msg);
                }

                return(targetKind.Wrapped
                    ? NullNode.Null
                    : null);
            }

            var bNode = node as BooleanNode;

            if (bNode != null)
            {
                return(targetKind.Wrapped
                    ? node
                    : CreateInstanceIfConstrucutable <bool>(targetType, bNode.Value, state));
            }

            var msg0 = state.CreateNodeConversionFailureMessage(node, targetType);

            throw new DeserializeFailureException(msg0);
        }
예제 #2
0
        object DeserializeValueAs(INode node, NodeKindWrapped targetKind, Type targetType, State state, Type tag)
        {
            switch (targetKind.Kind)
            {
            case NodeKind.Boolean:
                return(DeserializeToBoolean(node, targetKind, targetType, state, tag));

            case NodeKind.Integer:
            case NodeKind.Float:
                return(DeserializeToNumber(node, targetKind, targetType, state, tag));

            case NodeKind.String:
                return(DeserializeToString(node, targetKind, targetType, state, tag));

            case NodeKind.Array:
                return(DeserializeToArray(node, targetKind, targetType, state, tag));

            case NodeKind.Object:
                return(DeserializeToObject(node, targetKind, targetType, state, tag));

            case NodeKind.Null:
                return(DeserializeToNull(node, targetKind, targetType, state, tag));

            default:
                throw new NotImplementedException("Unmatched kind: " + targetKind.Kind);
            }
        }
예제 #3
0
        object DeserializeToNull(INode node, NodeKindWrapped targetKind, Type targetType, State state, Type tag)
        {
            if (node is NullNode)
            {
                // TODO: type check of targetType
                return(targetKind.Wrapped
                    ? NullNode.Null
                    : null);
            }

            // TODO: Should raise error?
            throw new NotImplementedException();
        }
예제 #4
0
        object DeserializeToNumber(INode node, NodeKindWrapped targetKind, Type targetType, State state, Type tag)
        {
            if (node is NullNode)
            {
                if (!TypeHelper.IsBoxed(targetType))
                {
                    var msg = state.CreateNodeConversionFailureMessage(node, targetType);
                    throw new DeserializeFailureException(msg);
                }

                return(targetKind.Wrapped
                    ? NullNode.Null
                    : null);
            }

            var iNode = node as IntegerNode;

            if (iNode != null)
            {
                return(targetKind.Wrapped
                    ? node
                    : CreateInstanceIfConstrucutable <long>(targetType, iNode.Value, state));
            }

            var fNode = node as FloatNode;

            if (fNode != null)
            {
                return(targetKind.Wrapped
                    ? node
                    : CreateInstanceIfConstrucutable <double>(targetType, fNode.Value, state));
            }

            var msg0 = state.CreateNodeConversionFailureMessage(node, targetType);

            throw new DeserializeFailureException(msg0);
        }
예제 #5
0
        object DeserializeToObject(INode node, NodeKindWrapped targetKind, Type targetType, State state, Type tag)
        {
            if (targetKind.Kind != NodeKind.Object)
            {
                var msg = state.CreateNodeConversionFailureMessage(node, targetType);
                throw new DeserializeFailureException(msg);
            }

            if (node is NullNode)
            {
                return(targetKind.Wrapped
                    ? NullNode.Null
                    : null);
            }

            var oNode = node as ObjectNode;

            if (oNode != null)
            {
                bool asDictionary =
                    targetType == typeof(object) ||
                    (TypeHelper.TypeWrap(targetType).IsGenericType&& targetType.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                ;
                if (asDictionary)
                {
                    // To Dictionary
                    Type containerTy = targetType;
                    if (containerTy == typeof(object))
                    {
                        containerTy = targetKind.Wrapped
                            ? typeof(Dictionary <string, INode>)
                            : typeof(Dictionary <string, object>);
                    }

                    var keyType = TypeHelper.TypeWrap(containerTy).GetGenericArguments()[0];
                    if (keyType != typeof(string))
                    {
                        throw new NotImplementedException();
                    }

                    var container = (IDictionary)Activator.CreateInstance(containerTy);

                    if (oNode.Elems == null)
                    {
                        goto dictionaryDecoded;
                    }

                    var allElemType = TypeHelper.TypeWrap(containerTy).GetGenericArguments()[1];
                    foreach (var elem in oNode.Elems)
                    {
                        var elemType = allElemType;
                        if (tag != null)
                        {
                            Type typeForKey;
                            if (DynamicResolver.Find(tag, elem.Key, out typeForKey))
                            {
                                elemType = typeForKey;
                            }
                        }

                        // TODO: duplication check
                        var v = DeserializeValue(elem.Value, elemType, state.NestAsElem(elem.Key), tag);
                        container.Add(elem.Key, v);
                    }

dictionaryDecoded:
                    if (targetKind.Wrapped)
                    {
                        return(new ObjectNode(container as Dictionary <string, INode>));
                    }
                    else
                    {
                        return(container);
                    }
                }
                else
                {
                    // Mapping to the structure (class | struct)

                    // TODO: add type check
                    var container = Activator.CreateInstance(targetType);
                    var fields    = TypeHelper.TypeWrap(targetType).GetFields();
                    foreach (var field in fields)
                    {
                        var attr = TypeHelper.GetCustomAttribute <JsonFieldAttribute>(field);

                        // TODO: duplication check
                        var elemName = JsonFieldAttribute.FieldName(attr, field);

                        INode elem = null;
                        if (oNode.Elems == null || !oNode.Elems.TryGetValue(elemName, out elem))
                        {
                            // TODO: ignore or raise errors?
                            continue;
                        }

                        var elemState = state.NestAsElem(elemName);

                        if (attr != null && attr.TypeHints != null)
                        {
                            bool resolved = false;
                            foreach (var hint in attr.TypeHints)
                            {
                                var elemType = hint;
                                try
                                {
                                    var v = DeserializeValue(elem, elemType, elemState, tag);
                                    field.SetValue(container, v);

                                    resolved = true;
                                    break;
                                }
                                catch (Exception)
                                {
                                }
                            }
                            if (!resolved)
                            {
                                var msg = elemState.CreateNodeConversionFailureMessage(elem, attr.TypeHints);
                                throw new DeserializeFailureException(msg);
                            }
                        }
                        else
                        {
                            var elemType = field.FieldType;
                            var elemTag  = tag;

                            if (attr != null && attr.DynamicResolverTag != null)
                            {
                                if (!TypeHelper.TypeWrap(elemType).IsGenericType || elemType.GetGenericTypeDefinition() != typeof(Dictionary <,>))
                                {
                                    var baseMsg = "A type of the field which has DynamicResolver must be a Dictionary<,>";
                                    var msg     = elemState.CreateMessage("{0}: Type = {1}", baseMsg, elemType);
                                    throw new DeserializeFailureException(msg);
                                }

                                var keyType = TypeHelper.TypeWrap(elemType).GetGenericArguments()[0];
                                if (keyType != typeof(string))
                                {
                                    var baseMsg = "A key of the dictionary which has DynamicResolver must be a string type";
                                    var msg     = elemState.CreateMessage("{0}: KeyType = {1}", baseMsg, keyType);
                                    throw new DeserializeFailureException(msg);
                                }

                                elemTag = attr.DynamicResolverTag;
                            }

                            var v = DeserializeValue(elem, elemType, elemState, elemTag);
                            field.SetValue(container, v);
                        }
                    }

                    return(container);
                }
            }

            // A json node type is NOT an object but the target type is an object.
            // Thus, change a target kind and retry.
            var nodeKindWrapped = new NodeKindWrapped {
                Kind    = node.Kind,
                Wrapped = targetKind.Wrapped,
            };

            if (targetKind.Wrapped)
            {
                targetType = Node.ValueTypeOfKind(node.Kind);
            }
            return(DeserializeValueAs(node, nodeKindWrapped, targetType, state, tag));
        }
예제 #6
0
        object DeserializeToArray(INode node, NodeKindWrapped targetKind, Type targetType, State state, Type tag)
        {
            bool isConvertible =
                targetType == typeof(object) ||
                (targetType.IsArray) ||
                (TypeHelper.TypeWrap(targetType).IsGenericType&& targetType.GetGenericTypeDefinition() == typeof(List <>))
            ;

            if (!isConvertible)
            {
                var msg = state.CreateNodeConversionFailureMessage(node, targetType);
                throw new DeserializeFailureException(msg);
            }

            if (node is NullNode)
            {
                return(targetKind.Wrapped
                    ? NullNode.Null
                    : null);
            }

            var aNode = node as ArrayNode;

            if (aNode != null)
            {
                if (targetType.IsArray || targetType == typeof(object))
                {
                    // To Array
                    var conteinerTy = targetType;
                    if (conteinerTy == typeof(object))
                    {
                        conteinerTy = typeof(object[]);
                    }

                    var len       = aNode.Elems != null ? aNode.Elems.Count : 0;
                    var container = (Array)Activator.CreateInstance(conteinerTy, new object[] { len });

                    var elemType = conteinerTy.GetElementType();
                    for (int i = 0; i < len; ++i)
                    {
                        var v = DeserializeValue(aNode.Elems[i], elemType, state.NestAsElem(i), tag);
                        container.SetValue(v, i);
                    }

                    return(container);
                }
                else
                {
                    // To List
                    var conteinerTy = targetType;

                    var len       = aNode.Elems != null ? aNode.Elems.Count : 0;
                    var container = (IList)Activator.CreateInstance(conteinerTy);

                    var elemType = TypeHelper.TypeWrap(conteinerTy).GetGenericArguments()[0];
                    for (int i = 0; i < len; ++i)
                    {
                        var v = DeserializeValue(aNode.Elems[i], elemType, state.NestAsElem(i), tag);
                        container.Add(v);
                    }

                    if (targetKind.Wrapped)
                    {
                        return(new ArrayNode(container as List <INode>));
                    }
                    else
                    {
                        return(container);
                    }
                }
            }

            var msg0 = state.CreateNodeConversionFailureMessage(node, targetType);

            throw new DeserializeFailureException(msg0);
        }