private T OnStack <T>(string p, MappingStack mappingStack, Func <T> func) { (mappingStack).Push(p); try { return(func()); } finally { mappingStack.Pop(); } }
protected object MapHashtable(IEnumerator <Node> iter, Type valType, MappingStack mappingStack, MappingAction mappingAction, out Type mappedType) { mappedType = null; var xmlRpcStruct = new XmlRpcStruct(); (mappingStack).Push("struct mapped to XmlRpcStruct"); try { while (iter.MoveNext()) { if (iter.Current is StructMember) { string str = (iter.Current as StructMember).Value; if (xmlRpcStruct.ContainsKey(str) && !IgnoreDuplicateMembers) { throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType + " contains struct value with duplicate member " + str + " " + StackDump(mappingStack)); } else { iter.MoveNext(); object obj = OnStack(string.Format("member {0}", str), mappingStack, (() => MapValueNode(iter, null, mappingStack, mappingAction))); if (!xmlRpcStruct.ContainsKey(str)) { xmlRpcStruct[str] = obj; } } } else { break; } } } finally { mappingStack.Pop(); } return(xmlRpcStruct); }
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); } }
private object MapArray(IEnumerator <Node> iter, Type valType, MappingStack mappingStack, MappingAction mappingAction, out Type mappedType) { mappedType = null; if (valType != null && !valType.IsArray && (valType != typeof(Array) && valType != typeof(object))) { throw new XmlRpcTypeMismatchException(mappingStack.MappingType + " contains array value where " + XmlRpcTypeInfo.GetXmlRpcTypeString(valType) + " expected " + StackDump(mappingStack)); } if (valType != null) { if (XmlRpcTypeInfo.GetXmlRpcType(valType) == XmlRpcType.tMultiDimArray) { (mappingStack).Push("array mapped to type " + valType.Name); return(MapMultiDimArray(iter, valType, mappingStack, mappingAction)); } else { (mappingStack).Push("array mapped to type " + valType.Name); } } else { (mappingStack).Push("array"); } List <object> list = new List <object>(); Type valType1 = DetermineArrayItemType(valType); bool flag = false; Type elementType = null; while (iter.MoveNext() && iter.Current is ValueNode) { (mappingStack).Push(string.Format("element {0}", list.Count)); object obj = MapValueNode(iter, valType1, mappingStack, mappingAction); list.Add(obj); mappingStack.Pop(); } foreach (object obj in list) { if (obj != null) { if (!flag) { elementType = obj.GetType(); flag = true; } else if (elementType != obj.GetType()) { elementType = null; } } } object[] args = new object[1] { list.Count }; object obj1 = valType == null || valType == typeof(Array) || valType == typeof(object) ? (elementType != null ? Array.CreateInstance(elementType, (int)args[0]) : CreateArrayInstance(typeof(object[]), args)) : CreateArrayInstance(valType, args); for (int index = 0; index < list.Count; ++index) { ((Array)obj1).SetValue(list[index], index); } mappingStack.Pop(); return(obj1); }
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) { if (valueType.GetGenericTypeDefinition() == typeof(Nullable <>)) { valueType = valueType.GetGenericArguments()[0]; } } object instance; try { instance = Activator.CreateInstance(valueType); } catch (Exception ex) { throw new XmlRpcTypeMismatchException(mappingStack.MappingType + " contains struct value where " + XmlRpcTypeInfo.GetXmlRpcTypeString(valueType) + " expected (as type " + valueType.Name + ") " + StackDump(mappingStack)); } MappingAction mappingAction1 = mappingAction; if (valueType != null) { (mappingStack).Push("struct mapped to type " + valueType.Name); mappingAction1 = StructMappingAction(valueType, mappingAction); } else { (mappingStack).Push("struct"); } List <string> names = new List <string>(); CreateFieldNamesMap(valueType, names); int num = 0; List <string> list = new List <string>(); try { while (iter.MoveNext()) { if (iter.Current is StructMember) { string XmlRpcName = (iter.Current as StructMember).Value; if (list.Contains(XmlRpcName)) { if (!IgnoreDuplicateMembers) { throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType + " contains struct value with duplicate member " + XmlRpcName + " " + StackDump(mappingStack)); } } else { list.Add(XmlRpcName); string name = GetStructName(valueType, XmlRpcName) ?? XmlRpcName; MemberInfo element = valueType.GetField(name) ?? (MemberInfo)valueType.GetProperty(name); if (element == null) { iter.MoveNext(); //If this is a table object, then we need to populate // the value in the custom fields dictionary. if (valueType.IsSubclassOf(typeof(Table))) { AddCustomField(iter, mappingStack, mappingAction, name, instance); } if (iter.Current is ComplexValueNode) { int depth = iter.Current.Depth; while (!(iter.Current is EndComplexValueNode) || iter.Current.Depth != depth) { iter.MoveNext(); } } } else { if (names.Contains(name)) { names.Remove(name); } else if (Attribute.IsDefined(element, 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 = element.MemberType == MemberTypes.Field ? (element as FieldInfo).FieldType : (element as PropertyInfo).PropertyType; string p = valueType == null ? string.Format("member {0}", name) : string.Format("member {0} mapped to type {1}", name, memberType.Name); iter.MoveNext(); object obj = OnStack(p, mappingStack, (() => MapValueNode(iter, memberType, mappingStack, mappingAction))); if (element.MemberType == MemberTypes.Field) { (element as FieldInfo).SetValue(instance, obj); } else { (element as PropertyInfo).SetValue(instance, obj, null); } ++num; } } } else { break; } } if (mappingAction1 == MappingAction.Error && names.Count > 0) { ReportMissingMembers(valueType, names, mappingStack); } return(instance); } finally { mappingStack.Pop(); } }