Beispiel #1
0
        private static byte[] ParseBase64(string value, MappingStack mappingStack)
        {
            if (value == string.Empty)
            {
                return(new byte[0]);
            }

            try {
                return(Convert.FromBase64String(value));
            }
            catch (Exception) {
                throw new XmlRpcInvalidXmlRpcException(
                          string.Format(
                              "{0} contains invalid base64 value {1}",
                              mappingStack.MappingType,
                              StackDump(mappingStack)));
            }
        }
Beispiel #2
0
        private static bool ParseBoolean(string value, MappingStack mappingStack)
        {
            switch (value)
            {
            case "1":
                return(true);

            case "0":
                return(false);

            default:
                throw new XmlRpcInvalidXmlRpcException(
                          string.Format(
                              "{0} contains invalid boolean value {1}",
                              mappingStack.MappingType,
                              StackDump(mappingStack)));
            }
        }
Beispiel #3
0
        private static object MapInt(
            string value,
            Type valType,
            MappingStack mappingStack,
            out Type mappedType)
        {
            CheckExpectedType(valType, typeof(int), mappingStack);
            if (valType != null && valType.IsEnum)
            {
                return(MapNumberToEnum(value, valType, "int", mappingStack, out mappedType));
            }

            mappedType = typeof(int);
            return(OnStack(
                       "integer",
                       mappingStack,
                       () => ParseInt(value, mappingStack)));
        }
Beispiel #4
0
        public static object Parse(
            XmlReader rdr,
            Type valueType,
            MappingAction action,
            XmlRpcDeserializer deserializer,
            out Type parsedType,
            out Type parsedArrayType)
        {
            parsedType = parsedArrayType = null;
            rdr.ReadToDescendant("value");
            var parseStack = new MappingStack("request");

            return(deserializer.ParseValueElement(
                       rdr,
                       valueType,
                       parseStack,
                       action));
        }
 private object MapDouble(string value, Type valType, MappingStack mappingStack,
                          MappingAction mappingAction, out Type mappedType)
 {
     CheckExpectedType(valType, typeof(double), mappingStack);
     mappedType = typeof(double);
     return(OnStack("double", mappingStack, delegate()
     {
         try
         {
             double ret = Double.Parse(value, CultureInfo.InvariantCulture.NumberFormat);
             return ret;
         }
         catch (Exception)
         {
             throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType
                                                    + " contains invalid double value " + StackDump(mappingStack));
         }
     }));
 }
Beispiel #6
0
        private static void CheckExpectedType(Type expectedType, Type actualType, MappingStack mappingStack)
        {
            if (expectedType != null && expectedType.IsEnum)
            {
                var fourBitTypes   = new[] { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int) };
                var eightBitTypes  = new[] { typeof(uint), typeof(long) };
                var underlyingType = Enum.GetUnderlyingType(expectedType);
                if (Array.IndexOf(fourBitTypes, underlyingType) >= 0)
                {
                    expectedType = typeof(int);
                }
                else if (Array.IndexOf(eightBitTypes, underlyingType) >= 0)
                {
                    expectedType = typeof(long);
                }
                else
                {
                    throw new XmlRpcInvalidEnumValue(
                              string.Format(
                                  "{0} contains {1} which cannot be mapped to  {2} {3}",
                                  mappingStack.MappingType,
                                  XmlRpcTypeInfo.GetXmlRpcTypeString(actualType),
                                  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(
                          string.Format(
                              "{0} contains {1} value where {2} expected {3}",
                              mappingStack.MappingType,
                              XmlRpcTypeInfo.GetXmlRpcTypeString(actualType),
                              XmlRpcTypeInfo.GetXmlRpcTypeString(expectedType),
                              StackDump(mappingStack)));
            }
        }
 private object MapNilValue(string p, Type type, MappingStack mappingStack,
                            MappingAction mappingAction, out Type mappedType)
 {
     if (type == null ||
         (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) ||
         (!type.IsPrimitive || !type.IsValueType) ||
         type == typeof(object))
     {
         mappedType = type;
         return(null);
     }
     else
     {
         throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType
                                                + " contains <nil> value which cannot be mapped to type "
                                                + (type != null && type != typeof(object) ? type.Name : "object")
                                                + " "
                                                + StackDump(mappingStack));
     }
 }
 private object MapInt(string value, Type valType, MappingStack mappingStack,
                       MappingAction mappingAction, out Type mappedType)
 {
     CheckExpectedType(valType, typeof(int), mappingStack);
     if (valType != null && valType.IsEnum)
     {
         return(MapNumberToEnum(value, valType, "int", mappingStack, mappingAction, out mappedType));
     }
     mappedType = typeof(int);
     return(OnStack("integer", mappingStack, delegate()
     {
         int ret;
         if (!Int32.TryParse(value, out ret))
         {
             throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType
                                                    + " contains invalid int value " + StackDump(mappingStack));
         }
         return ret;
     }));
 }
Beispiel #9
0
        private static object MapNilValue(
            Type type,
            MappingStack mappingStack,
            out Type mappedType)
        {
            if (type == null ||
                (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) ||
                (!type.IsPrimitive || !type.IsValueType) || type == typeof(object))
            {
                mappedType = type;
                return(null);
            }

            throw new XmlRpcInvalidXmlRpcException(
                      string.Format(
                          "{0} contains <nil> value which cannot be mapped to type {1} {2}",
                          mappingStack.MappingType,
                          type != typeof(object) ? type.Name : "object",
                          StackDump(mappingStack)));
        }
Beispiel #10
0
        private void MapMultiDimElements(
            IEnumerator <Node> iter,
            int rank,
            int curRank,
            Type elemType,
            ICollection <object> elements,
            IList <int> dimLengths,
            MappingStack mappingStack,
            MappingAction mappingAction)
        {
            var nodeCount = 0;

            if (curRank < (rank - 1))
            {
                while (iter.MoveNext() && iter.Current is ArrayValue)
                {
                    nodeCount++;
                    MapMultiDimElements(
                        iter,
                        rank,
                        curRank + 1,
                        elemType,
                        elements,
                        dimLengths,
                        mappingStack,
                        mappingAction);
                }
            }
            else
            {
                while (iter.MoveNext() && iter.Current is ValueNode)
                {
                    nodeCount++;
                    var value = MapValueNode(iter, elemType, mappingStack, mappingAction);
                    elements.Add(value);
                }
            }

            dimLengths[curRank] = nodeCount;
        }
 private void CheckExpectedType(Type expectedType, Type actualType, MappingStack mappingStack)
 {
     if (expectedType != null && expectedType.IsEnum)
     {
         Type[] i4Types = new Type[] { typeof(byte), typeof(sbyte), typeof(short),
                                       typeof(ushort), typeof(int) };
         Type[] i8Types        = new Type[] { typeof(uint), typeof(long) };
         Type   underlyingType = Enum.GetUnderlyingType(expectedType);
         if (Array.IndexOf(i4Types, underlyingType) >= 0)
         {
             expectedType = typeof(Int32);
         }
         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));
     }
 }
Beispiel #12
0
        protected object MapHashtable(
            IEnumerator <Node> iter,
            MappingStack mappingStack,
            MappingAction mappingAction,
            out Type mappedType)
        {
            mappedType = null;
            var retObj = new XmlRpcStruct();

            mappingStack.Push("struct mapped to XmlRpcStruct");
            try {
                while (iter.MoveNext() && iter.Current is StructMember)
                {
                    var rpcName = ((StructMember)iter.Current).Value;
                    if (retObj.ContainsKey(rpcName) && !IgnoreDuplicateMembers)
                    {
                        throw new XmlRpcInvalidXmlRpcException(
                                  mappingStack.MappingType + " contains struct value with duplicate member " + rpcName + " "
                                  + StackDump(mappingStack));
                    }

                    iter.MoveNext();

                    var value = OnStack(
                        string.Format("member {0}", rpcName),
                        mappingStack,
                        () => MapValueNode(iter, null, mappingStack, mappingAction));

                    if (!retObj.ContainsKey(rpcName))
                    {
                        retObj[rpcName] = value;
                    }
                }
            }
            finally {
                mappingStack.Pop();
            }

            return(retObj);
        }
Beispiel #13
0
 private object MapStringToEnum(string value, Type enumType, string xmlRpcType,
                                MappingStack mappingStack, MappingAction mappingAction, out Type mappedType)
 {
     mappedType = enumType;
     return(OnStack(xmlRpcType, mappingStack, delegate()
     {
         try
         {
             object ret = Enum.Parse(enumType, value, true);
             return ret;
         }
         catch (XmlRpcInvalidEnumValue)
         {
             throw;
         }
         catch (Exception ex)
         {
             throw new XmlRpcInvalidEnumValue(mappingStack.MappingType
                                              + " contains invalid or out of range " + xmlRpcType + " value mapped to enum "
                                              + StackDump(mappingStack));
         }
     }));
 }
Beispiel #14
0
        XmlRpcFaultException ParseFault(
            IEnumerator <Node> iter,
            MappingStack parseStack,
            MappingAction mappingAction)
        {
            iter.MoveNext();  // move to StructValue
            Type parsedType;
            var  faultStruct = MapHashtable(iter, null, parseStack, mappingAction,
                                            out parsedType) as XmlRpcStruct;
            object faultCode   = faultStruct["faultCode"];
            object faultString = faultStruct["faultString"];

            if (faultCode is string)
            {
                int value;
                if (!Int32.TryParse(faultCode as string, out value))
                {
                    throw new XmlRpcInvalidXmlRpcException("faultCode not int or string");
                }
                faultCode = value;
            }
            return(new XmlRpcFaultException((int)faultCode, (string)faultString));
        }
 private object MapBoolean(string value, Type valType, MappingStack mappingStack,
                           MappingAction mappingAction, out Type mappedType)
 {
     CheckExpectedType(valType, typeof(bool), mappingStack);
     mappedType = typeof(bool);
     return(OnStack("boolean", mappingStack, delegate()
     {
         if (value == "1")
         {
             return true;
         }
         else if (value == "0")
         {
             return false;
         }
         else
         {
             throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType
                                                    + " contains invalid boolean value "
                                                    + StackDump(mappingStack));
         }
     }));
 }
        void MapMultiDimElements(IEnumerator <Node> iter, int Rank, int CurRank,
                                 Type elemType, List <object> elements, int[] dimLengths,
                                 MappingStack mappingStack, MappingAction mappingAction)
        {
            //XmlNode dataNode = SelectSingleNode(node, "data");
            //XmlNode[] childNodes = SelectNodes(dataNode, "value");
            //int nodeCount = childNodes.Length;
            ////!! check that multi dim array is not jagged
            //if (dimLengths[CurRank] != 0 && nodeCount != dimLengths[CurRank])
            //{
            //  throw new XmlRpcNonRegularArrayException(
            //    "Multi-dimensional array must not be jagged.");
            //}
            //dimLengths[CurRank] = nodeCount;  // in case first array at this rank
            int nodeCount = 0;

            if (CurRank < (Rank - 1))
            {
                while (iter.MoveNext() && iter.Current is ArrayValue)
                {
                    nodeCount++;
                    MapMultiDimElements(iter, Rank, CurRank + 1, elemType,
                                        elements, dimLengths, mappingStack, mappingAction);
                }
            }
            else
            {
                while (iter.MoveNext() && iter.Current is ValueNode)
                {
                    nodeCount++;
                    object value = MapValueNode(iter, elemType, mappingStack, mappingAction);
                    elements.Add(value);
                }
            }
            dimLengths[CurRank] = nodeCount;
        }
Beispiel #17
0
 private static object ParseEnum(string value, Type enumType, string xmlRpcType, MappingStack mappingStack)
 {
     try {
         return(Enum.Parse(enumType, value, true));
     }
     catch (XmlRpcInvalidEnumValue) {
         throw;
     }
     catch {
         throw new XmlRpcInvalidEnumValue(
                   string.Format(
                       "{0} contains invalid or out of range {1} value mapped to enum {2}",
                       mappingStack.MappingType,
                       xmlRpcType,
                       StackDump(mappingStack)));
     }
 }
Beispiel #18
0
        public object MapValueNode(
            IEnumerator <Node> iter,
            Type valType,
            MappingStack mappingStack,
            MappingAction mappingAction)
        {
            var valueNode = iter.Current as ValueNode;

            // if suppplied type is System.Object then ignore it because
            // if doesn't provide any useful information (parsing methods
            // expect null in this case)
            if (valType != null && valType.BaseType == null)
            {
                valType = null;
            }

            if (valueNode is StringValue && valueNode.ImplicitValue)
            {
                CheckImplictString(valType, mappingStack);
            }

            Type mappedType;

            if (iter.Current is ArrayValue)
            {
                return(MapArray(iter, valType, mappingStack, mappingAction, out mappedType));
            }

            if (iter.Current is StructValue)
            {
                // if we don't know the expected struct type then we must
                // map the XML-RPC struct as an instance of XmlRpcStruct
                if (valType != null && valType != typeof(XmlRpcStruct) && !valType.IsSubclassOf(typeof(XmlRpcStruct)))
                {
                    return(MapStruct(iter, valType, mappingStack, mappingAction, out mappedType));
                }

                return(MapHashtable(iter, mappingStack, mappingAction, out mappedType));
            }

            if (iter.Current is Base64Value)
            {
                return(MapBase64(valueNode.Value, valType, mappingStack, out mappedType));
            }

            if (iter.Current is IntValue)
            {
                return(MapInt(valueNode.Value, valType, mappingStack, out mappedType));
            }

            if (iter.Current is LongValue)
            {
                return(MapLong(valueNode.Value, valType, mappingStack, out mappedType));
            }

            if (iter.Current is StringValue)
            {
                return(MapString(valueNode.Value, valType, mappingStack, out mappedType));
            }

            if (iter.Current is BooleanValue)
            {
                return(MapBoolean(valueNode.Value, valType, mappingStack, out mappedType));
            }

            if (iter.Current is DoubleValue)
            {
                return(MapDouble(valueNode.Value, valType, mappingStack, out mappedType));
            }

            if (iter.Current is DateTimeValue)
            {
                return(MapDateTime(valueNode.Value, valType, mappingStack, out mappedType));
            }

            if (iter.Current is NilValue)
            {
                return(MapNilValue(valType, mappingStack, out mappedType));
            }

            return(null);
        }
        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);
                    Object ret = MapMultiDimArray(iter, valType, mappingStack,
                                                  mappingAction);
                    return(ret);
                }
                mappingStack.Push("array mapped to type " + valType.Name);
            }
            else
            {
                mappingStack.Push("array");
            }

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

            bool bGotType = false;
            Type useType  = null;

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

            foreach (object value in values)
            {
                if (value == null)
                {
                    continue;
                }
                if (bGotType == false)
                {
                    useType  = value.GetType();
                    bGotType = true;
                }
                else
                {
                    if (useType != value.GetType())
                    {
                        useType = null;
                    }
                }
            }

            Object[] 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);
        }
        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
            MappingAction 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);
            int           fieldCount = 0;
            List <string> rpcNames   = new List <string>();

            try
            {
                while (iter.MoveNext())
                {
                    if (!(iter.Current is StructMember))
                    {
                        break;
                    }
                    string 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));
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        rpcNames.Add(rpcName);
                    }

                    string     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(String.Format("member {0}", name));
                            throw new XmlRpcNonSerializedMember("Cannot map XML-RPC struct "
                                                                + "member onto member marked as [NonSerialized]: "
                                                                + " " + StackDump(mappingStack));
                        }
                    }
                    Type memberType = mi.MemberType == MemberTypes.Field
                    ? (mi as FieldInfo).FieldType : (mi as PropertyInfo).PropertyType;
                    string mappingMsg = valueType == null
                        ? String.Format("member {0}", name)
                        : String.Format("member {0} mapped to type {1}", name, memberType.Name);

                    iter.MoveNext();
                    object valObj = OnStack(mappingMsg, mappingStack, delegate()
                    {
                        return(MapValueNode(iter, memberType, mappingStack, mappingAction));
                    });

                    if (mi.MemberType == MemberTypes.Field)
                    {
                        try
                        {
                            (mi as FieldInfo).SetValue(retObj, valObj);
                        }
                        catch
                        {
                            (mi as FieldInfo).SetValue(retObj, Enum.Parse((mi as FieldInfo).FieldType, (string)valObj, true));
                        }
                    }
                    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();
            }
        }
Beispiel #21
0
        public XmlRpcRequest DeserializeRequest(XmlReader rdr, Type svcType)
        {
            try
            {
                XmlRpcRequest      request = new XmlRpcRequest();
                IEnumerator <Node> iter    = new XmlRpcParser().ParseRequest(rdr).GetEnumerator();

                iter.MoveNext();
                string methodName = (iter.Current as MethodName).Name;
                request.method = methodName;

                request.mi = null;
                ParameterInfo[] pis = null;
                if (svcType != null)
                {
                    // retrieve info for the method which handles this XML-RPC method
                    XmlRpcServiceInfo svcInfo
                               = XmlRpcServiceInfo.CreateServiceInfo(svcType);
                    request.mi = svcInfo.GetMethodInfo(request.method);
                    // if a service type has been specified and we cannot find the requested
                    // method then we must throw an exception
                    if (request.mi == null)
                    {
                        string msg = String.Format("unsupported method called: {0}",
                                                   request.method);
                        throw new XmlRpcUnsupportedMethodException(msg);
                    }
                    // method must be marked with XmlRpcMethod attribute
                    Attribute attr = Attribute.GetCustomAttribute(request.mi,
                                                                  typeof(XmlRpcMethodAttribute));
                    if (attr == null)
                    {
                        throw new XmlRpcMethodAttributeException(
                                  "Method must be marked with the XmlRpcMethod attribute.");
                    }
                    pis = request.mi.GetParameters();
                }

                bool gotParams = iter.MoveNext();
                if (!gotParams)
                {
                    if (svcType != null)
                    {
                        if (pis.Length == 0)
                        {
                            request.args = new object[0];
                            return(request);
                        }
                        else
                        {
                            throw new XmlRpcInvalidParametersException(
                                      "Method takes parameters and params element is missing.");
                        }
                    }
                    else
                    {
                        request.args = new object[0];
                        return(request);
                    }
                }

                int paramsPos = pis != null?GetParamsPos(pis) : -1;

                Type paramsType = null;
                if (paramsPos != -1)
                {
                    paramsType = pis[paramsPos].ParameterType.GetElementType();
                }
                int minParamCount = pis == null ? int.MaxValue
          : (paramsPos == -1 ? pis.Length : paramsPos);
                MappingStack  mappingStack  = new MappingStack("request");
                MappingAction mappingAction = MappingAction.Error;
                var           objs          = new List <object>();
                var           paramsObjs    = new List <object>();
                int           paramCount    = 0;


                while (iter.MoveNext())
                {
                    paramCount++;
                    if (svcType != null && paramCount > minParamCount && paramsPos == -1)
                    {
                        throw new XmlRpcInvalidParametersException(
                                  "Request contains too many param elements based on method signature.");
                    }
                    if (paramCount <= minParamCount)
                    {
                        if (svcType != null)
                        {
                            mappingStack.Push(String.Format("parameter {0}", paramCount));
                            // TODO: why following commented out?
                            //          parseStack.Push(String.Format("parameter {0} mapped to type {1}",
                            //            i, pis[i].ParameterType.Name));
                            var obj = MapValueNode(iter,
                                                   pis[paramCount - 1].ParameterType, mappingStack, mappingAction);
                            objs.Add(obj);
                        }
                        else
                        {
                            mappingStack.Push(String.Format("parameter {0}", paramCount));
                            var obj = MapValueNode(iter, null, mappingStack, mappingAction);
                            objs.Add(obj);
                        }
                        mappingStack.Pop();
                    }
                    else
                    {
                        mappingStack.Push(String.Format("parameter {0}", paramCount + 1));
                        var paramsObj = MapValueNode(iter, paramsType, mappingStack, mappingAction);
                        paramsObjs.Add(paramsObj);
                        mappingStack.Pop();
                    }
                }

                if (svcType != null && paramCount < minParamCount)
                {
                    throw new XmlRpcInvalidParametersException(
                              "Request contains too few param elements based on method signature.");
                }

                if (paramsPos != -1)
                {
                    Object[] args = new Object[1];
                    args[0] = paramCount - minParamCount;
                    Array varargs = (Array)Activator.CreateInstance(pis[paramsPos].ParameterType, args);
                    for (int i = 0; i < paramsObjs.Count; i++)
                    {
                        varargs.SetValue(paramsObjs[i], i);
                    }
                    objs.Add(varargs);
                }
                request.args = objs.ToArray();
                return(request);
            }
            catch (XmlException ex)
            {
                throw new XmlRpcIllFormedXmlException("Request contains invalid XML", ex);
            }
        }
Beispiel #22
0
        private static void ReportMissingMembers(Type valueType, IEnumerable <string> names, MappingStack mappingStack)
        {
            var sb         = new StringBuilder();
            var errorCount = 0;
            var sep        = string.Empty;

            foreach (var s in from s in names let memberAction = MemberMappingAction(valueType, s, MappingAction.Error) where memberAction == MappingAction.Error select s)
            {
                sb.Append(sep);
                sb.Append(s);
                sep = " ";
                errorCount++;
            }

            if (errorCount <= 0)
            {
                return;
            }

            var plural = string.Empty;

            if (errorCount > 1)
            {
                plural = "s";
            }

            throw new XmlRpcTypeMismatchException(
                      string.Format(
                          "{0} contains struct value with missing non-optional member{1}: {2} {3}",
                          mappingStack.MappingType,
                          plural,
                          sb,
                          StackDump(mappingStack)));
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="iter"></param>
        /// <param name="valType"></param>
        /// <param name="mappingStack"></param>
        /// <param name="mappingAction"></param>
        /// <returns></returns>
        public Object MapValueNode(
            IEnumerator <Node> iter,
            Type valType,
            MappingStack mappingStack,
            MappingAction mappingAction)
        {
            var valueNode = iter.Current as ValueNode;

            // if suppplied type is System.Object then ignore it because
            // if doesn't provide any useful information (parsing methods
            // expect null in this case)
            if (valType != null && valType.BaseType == null)
            {
                valType = null;
            }
            object ret    = "";
            object retObj = null;

            if (valueNode is StringValue && valueNode.ImplicitValue)
            {
                try
                {
                    CheckImplictString(valType, mappingStack);
                }
                catch
                {
                    try
                    {
                        retObj = Enum.Parse(valType, valueNode.Value.Replace(" ", "_"), true);
                    }
                    catch
                    {
                        CheckImplictString(valType, mappingStack);
                    }
                }
            }

            Type mappedType;

            if (iter.Current is ArrayValue)
            {
                retObj = MapArray(iter, valType, mappingStack, mappingAction,
                                  out mappedType);
            }
            else if (iter.Current is StructValue)
            {
                // if we don't know the expected struct type then we must
                // map the XML-RPC struct as an instance of XmlRpcStruct
                if (valType != null && valType != typeof(XmlRpcStruct) &&
                    !valType.IsSubclassOf(typeof(XmlRpcStruct)))
                {
                    retObj = MapStruct(iter, valType, mappingStack, mappingAction,
                                       out mappedType);
                }
                else
                {
                    if (valType == null || valType == typeof(object))
                    {
                        valType = typeof(XmlRpcStruct);
                    }
                    // TODO: do we need to validate type here?
                    retObj = MapHashtable(iter, valType, mappingStack, mappingAction,
                                          out mappedType);
                }
            }
            else if (iter.Current is Base64Value)
            {
                retObj = MapBase64(valueNode.Value, valType, mappingStack, mappingAction,
                                   out mappedType);
            }
            else if (iter.Current is IntValue)
            {
                retObj = MapInt(valueNode.Value, valType, mappingStack, mappingAction,
                                out mappedType);
            }
            else if (iter.Current is LongValue)
            {
                retObj = MapLong(valueNode.Value, valType, mappingStack, mappingAction,
                                 out mappedType);
            }
            else if (iter.Current is StringValue)
            {
                retObj = MapString(valueNode.Value, valType, mappingStack, mappingAction,
                                   out mappedType);
            }
            else if (iter.Current is BooleanValue)
            {
                retObj = MapBoolean(valueNode.Value, valType, mappingStack, mappingAction,
                                    out mappedType);
            }
            else if (iter.Current is DoubleValue)
            {
                retObj = MapDouble(valueNode.Value, valType, mappingStack, mappingAction,
                                   out mappedType);
            }
            else if (iter.Current is DateTimeValue)
            {
                retObj = MapDateTime(valueNode.Value, valType, mappingStack, mappingAction,
                                     out mappedType);
            }
            else if (iter.Current is NilValue)
            {
                retObj = MapNilValue(valueNode.Value, valType, mappingStack, mappingAction,
                                     out mappedType);
            }

            return(retObj);
        }