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; XmlRpcStruct retObj = new XmlRpcStruct(); mappingStack.Push("struct mapped to XmlRpcStruct"); try { while (iter.MoveNext() && iter.Current is StructMember) { string rpcName = (iter.Current as StructMember).Value; if (retObj.ContainsKey(rpcName) && !IgnoreDuplicateMembers) { throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType + " contains struct value with duplicate member " + rpcName + " " + StackDump(mappingStack)); } iter.MoveNext(); object value = OnStack(String.Format("member {0}", rpcName), mappingStack, delegate() { return(MapValueNode(iter, null, mappingStack, mappingAction)); }); if (!retObj.ContainsKey(rpcName)) { retObj[rpcName] = value; } } } finally { mappingStack.Pop(); } return(retObj); }
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.GetTypeInfo().IsPrimitive) { throw new XmlRpcTypeMismatchException(mappingStack.MappingType + " contains struct value where " + XmlRpcTypeInfo.GetXmlRpcTypeString(valueType) + " expected " + StackDump(mappingStack)); } if (valueType.GetTypeInfo().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 is FieldInfo ? (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 is FieldInfo) { (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(); } }