Пример #1
0
 private void CheckImplictString(Type valType, MappingStack mappingStack)
 {
     if (valType != null && valType != typeof(string) && !valType.IsEnum)
     {
         throw new XmlRpcTypeMismatchException(mappingStack.MappingType
                                               + " contains implicit string value where "
                                               + XmlRpcTypeInfo.GetXmlRpcTypeString(valType)
                                               + " expected " + StackDump(mappingStack));
     }
 }
Пример #2
0
        private void CheckExpectedType(Type expectedType, Type actualType, MappingStack mappingStack)
        {
            if (expectedType != null && expectedType.IsEnum)
            {
                Type[] i4Types = { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int) };
                Type[] i8Types = { typeof(uint), typeof(long) };

                var underlyingType = Enum.GetUnderlyingType(expectedType);

                if (Array.IndexOf(i4Types, underlyingType) >= 0)
                {
                    expectedType = typeof(int);
                }
                else if (Array.IndexOf(i8Types, underlyingType) >= 0)
                {
                    expectedType = typeof(long);
                }
                else
                {
                    throw new XmlRpcInvalidEnumValue(mappingStack.MappingType +
                                                     " contains "
                                                     + XmlRpcTypeInfo.GetXmlRpcTypeString(actualType)
                                                     + " which cannot be mapped to  "
                                                     + XmlRpcTypeInfo.GetXmlRpcTypeString(expectedType)
                                                     + " " + StackDump(mappingStack));
                }
            }
            // TODO: throw exception for invalid enum type
            if (expectedType != null && expectedType != typeof(object) && expectedType != actualType &&
                (actualType.IsValueType && expectedType != typeof(Nullable <>).MakeGenericType(actualType)))
            {
                throw new XmlRpcTypeMismatchException(mappingStack.MappingType +
                                                      " contains "
                                                      + XmlRpcTypeInfo.GetXmlRpcTypeString(actualType)
                                                      + " value where "
                                                      + XmlRpcTypeInfo.GetXmlRpcTypeString(expectedType)
                                                      + " expected " + StackDump(mappingStack));
            }
        }
Пример #3
0
        private object MapArray(IEnumerator <Node> iter, Type valType, MappingStack mappingStack, MappingAction mappingAction, out Type mappedType)
        {
            mappedType = null;
            // required type must be an array
            if (valType != null && !(valType.IsArray == true || valType == typeof(Array) || valType == typeof(object)))
            {
                throw new XmlRpcTypeMismatchException(mappingStack.MappingType
                                                      + $" contains array value where{XmlRpcTypeInfo.GetXmlRpcTypeString(valType)}"
                                                      + $" expected {StackDump(mappingStack)}");
            }

            if (valType != null)
            {
                XmlRpcType xmlRpcType = XmlRpcTypeInfo.GetXmlRpcType(valType);
                if (xmlRpcType == XmlRpcType.tMultiDimArray)
                {
                    mappingStack.Push("array mapped to type " + valType.Name);
                    return(MapMultiDimArray(iter, valType, mappingStack, mappingAction));
                }
                mappingStack.Push("array mapped to type " + valType.Name);
            }
            else
            {
                mappingStack.Push("array");
            }

            var values   = new List <object>();
            var elemType = DetermineArrayItemType(valType);

            while (iter.MoveNext() && iter.Current is ValueNode)
            {
                mappingStack.Push(string.Format("element {0}", values.Count));
                var value = MapValueNode(iter, elemType, mappingStack, mappingAction);
                values.Add(value);
                mappingStack.Pop();
            }

            var  bGotType = false;
            Type useType  = null;

            foreach (object value in values)
            {
                if (value == null)
                {
                    continue;
                }

                if (bGotType)
                {
                    if (useType != value.GetType())
                    {
                        useType = null;
                    }

                    continue;
                }

                useType  = value.GetType();
                bGotType = true;
            }

            var args = new object[1];

            args[0] = values.Count;
            object retObj = null;

            if (valType != null && valType != typeof(Array) && valType != typeof(object))
            {
                retObj = CreateArrayInstance(valType, args);
            }
            else
            {
                if (useType == null)
                {
                    retObj = CreateArrayInstance(typeof(object[]), args);
                }
                else
                {
                    retObj = Array.CreateInstance(useType, (int)args[0]);
                }
            }

            for (int j = 0; j < values.Count; j++)
            {
                ((Array)retObj).SetValue(values[j], j);
            }

            mappingStack.Pop();

            return(retObj);
        }
Пример #4
0
        private object MapStruct(IEnumerator <Node> iter, Type valueType, MappingStack mappingStack, MappingAction mappingAction, out Type mappedType)
        {
            mappedType = null;

            if (valueType.IsPrimitive)
            {
                throw new XmlRpcTypeMismatchException(mappingStack.MappingType
                                                      + " contains struct value where "
                                                      + XmlRpcTypeInfo.GetXmlRpcTypeString(valueType)
                                                      + " expected " + StackDump(mappingStack));
            }
            if (valueType.IsGenericType &&
                valueType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                valueType = valueType.GetGenericArguments()[0];
            }
            object retObj;

            try
            {
                retObj = Activator.CreateInstance(valueType);
            }
            catch (Exception)
            {
                throw new XmlRpcTypeMismatchException(mappingStack.MappingType
                                                      + " contains struct value where "
                                                      + XmlRpcTypeInfo.GetXmlRpcTypeString(valueType)
                                                      + $" expected (as type {valueType.Name}) "
                                                      + StackDump(mappingStack));
            }
            // Note: mapping action on a struct is only applied locally - it
            // does not override the global mapping action when members of the
            // struct are mapped
            var localAction = mappingAction;

            if (valueType != null)
            {
                mappingStack.Push("struct mapped to type " + valueType.Name);
                localAction = StructMappingAction(valueType, mappingAction);
            }
            else
            {
                mappingStack.Push("struct");
            }
            // create map of field names and remove each name from it as
            // processed so we can determine which fields are missing
            var names = new List <string>();

            CreateFieldNamesMap(valueType, names);

            var fieldCount = 0;
            var rpcNames   = new List <string>();

            try
            {
                while (iter.MoveNext())
                {
                    if (!(iter.Current is StructMember))
                    {
                        break;
                    }

                    var rpcName = (iter.Current as StructMember).Value;
                    if (rpcNames.Contains(rpcName))
                    {
                        if (!IgnoreDuplicateMembers)
                        {
                            throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType
                                                                   + $" contains struct value with duplicate member {rpcName} {StackDump(mappingStack)}");
                        }

                        continue;
                    }
                    rpcNames.Add(rpcName);

                    var        name = GetStructName(valueType, rpcName) ?? rpcName;
                    MemberInfo mi   = valueType.GetField(name);
                    if (mi == null)
                    {
                        mi = valueType.GetProperty(name);
                    }

                    if (mi == null)
                    {
                        iter.MoveNext();  // move to value
                        if (iter.Current is ComplexValueNode)
                        {
                            int depth = iter.Current.Depth;
                            while (!(iter.Current is EndComplexValueNode && iter.Current.Depth == depth))
                            {
                                iter.MoveNext();
                            }
                        }
                        continue;
                    }
                    if (names.Contains(name))
                    {
                        names.Remove(name);
                    }
                    else
                    {
                        if (Attribute.IsDefined(mi, typeof(NonSerializedAttribute)))
                        {
                            mappingStack.Push($"member {name}");
                            throw new XmlRpcNonSerializedMember("Cannot map XML-RPC struct member onto member marked as [NonSerialized]: " + StackDump(mappingStack));
                        }
                    }

                    var memberType = mi.MemberType == MemberTypes.Field ? (mi as FieldInfo).FieldType : (mi as PropertyInfo).PropertyType;

                    var mappingMsg = valueType == null
                        ? $"member {name}"
                        : $"member {name} mapped to type {memberType.Name}";

                    iter.MoveNext();
                    var valObj = OnStack(mappingMsg, mappingStack, () => MapValueNode(iter, memberType, mappingStack, mappingAction));

                    if (mi.MemberType == MemberTypes.Field)
                    {
                        (mi as FieldInfo).SetValue(retObj, valObj);
                    }
                    else
                    {
                        (mi as PropertyInfo).SetValue(retObj, valObj, null);
                    }

                    fieldCount++;
                }

                if (localAction == MappingAction.Error && names.Count > 0)
                {
                    ReportMissingMembers(valueType, names, mappingStack);
                }

                return(retObj);
            }
            finally
            {
                mappingStack.Pop();
            }
        }