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); }
//#endif void Serialize( XmlWriter xtw, Object o, MappingActions mappingActions, List <object> nestedObjs) { if (nestedObjs.Contains(o)) { throw new XmlRpcUnsupportedTypeException(nestedObjs[0].GetType(), "Cannot serialize recursive data structure"); } nestedObjs.Add(o); try { xtw.WriteStartElement("", "value", ""); XmlRpcType xType = XmlRpcTypeInfo.GetXmlRpcType(o); if (xType == XmlRpcType.tArray) { xtw.WriteStartElement("", "array", ""); xtw.WriteStartElement("", "data", ""); Array a = (Array)o; foreach (Object aobj in a) { //if (aobj == null) // throw new XmlRpcMappingSerializeException(String.Format( // "Items in array cannot be null ({0}[]).", //o.GetType().GetElementType())); Serialize(xtw, aobj, mappingActions, nestedObjs); } WriteFullEndElement(xtw); WriteFullEndElement(xtw); } else if (xType == XmlRpcType.tMultiDimArray) { Array mda = (Array)o; int[] indices = new int[mda.Rank]; BuildArrayXml(xtw, mda, 0, indices, mappingActions, nestedObjs); } else if (xType == XmlRpcType.tBase64) { byte[] buf = (byte[])o; xtw.WriteStartElement("", "base64", ""); xtw.WriteBase64(buf, 0, buf.Length); WriteFullEndElement(xtw); } else if (xType == XmlRpcType.tBoolean) { bool boolVal = (bool)o; if (boolVal) { WriteFullElementString(xtw, "boolean", "1"); } else { WriteFullElementString(xtw, "boolean", "0"); } } else if (xType == XmlRpcType.tDateTime) { DateTime dt = (DateTime)o; string sdt = dt.ToString("yyyyMMdd'T'HH':'mm':'ss", DateTimeFormatInfo.InvariantInfo); WriteFullElementString(xtw, "dateTime.iso8601", sdt); } else if (xType == XmlRpcType.tDouble) { double doubleVal = (double)o; WriteFullElementString(xtw, "double", doubleVal.ToString(null, CultureInfo.InvariantCulture)); } else if (xType == XmlRpcType.tHashtable) { xtw.WriteStartElement("", "struct", ""); XmlRpcStruct xrs = o as XmlRpcStruct; foreach (object obj in xrs.Keys) { string skey = obj as string; xtw.WriteStartElement("", "member", ""); WriteFullElementString(xtw, "name", skey); Serialize(xtw, xrs[skey], mappingActions, nestedObjs); WriteFullEndElement(xtw); } WriteFullEndElement(xtw); } else if (xType == XmlRpcType.tInt32) { o = SerializeInt32(xtw, o, mappingActions); } else if (xType == XmlRpcType.tInt64) { o = SerializeInt64(xtw, o, mappingActions); } else if (xType == XmlRpcType.tString) { SerializeString(xtw, o); } else if (xType == XmlRpcType.tStruct) { MappingActions structActions = GetMappingActions(o.GetType().GetTypeInfo(), mappingActions); xtw.WriteStartElement("", "struct", ""); MemberInfo[] mis = o.GetType().GetMembers(); foreach (MemberInfo mi in mis) { if (mi.GetCustomAttribute <IgnoreDataMemberAttribute>() != null) { continue; } if (mi is FieldInfo) { FieldInfo fi = (FieldInfo)mi; string member = fi.Name; Attribute attrchk = fi.GetCustomAttribute <XmlRpcMemberAttribute>(); if (attrchk != null && attrchk is XmlRpcMemberAttribute) { string mmbr = ((XmlRpcMemberAttribute)attrchk).Member; if (mmbr != "") { member = mmbr; } } MappingActions memberActions = MemberMappingActions(o.GetType(), fi.Name, structActions); if (fi.GetValue(o) == null) { if (memberActions.NullMappingAction == NullMappingAction.Ignore) { continue; } else if (memberActions.NullMappingAction == NullMappingAction.Error) { throw new XmlRpcMappingSerializeException(@"Member """ + member + @""" of struct """ + o.GetType().Name + @""" cannot be null."); } } xtw.WriteStartElement("", "member", ""); WriteFullElementString(xtw, "name", member); Serialize(xtw, fi.GetValue(o), memberActions, nestedObjs); WriteFullEndElement(xtw); } else if (mi is PropertyInfo) { PropertyInfo pi = (PropertyInfo)mi; string member = pi.Name; Attribute attrchk = pi.GetCustomAttribute <XmlRpcMemberAttribute>(); if (attrchk != null && attrchk is XmlRpcMemberAttribute) { string mmbr = ((XmlRpcMemberAttribute)attrchk).Member; if (mmbr != "") { member = mmbr; } } MappingActions memberActions = MemberMappingActions(o.GetType(), pi.Name, structActions); if (pi.GetValue(o, null) == null) { if (memberActions.NullMappingAction == NullMappingAction.Ignore) { continue; } else if (memberActions.NullMappingAction == NullMappingAction.Error) { throw new XmlRpcMappingSerializeException(@"Member """ + member + @""" of struct """ + o.GetType().Name + @""" cannot be null."); } } xtw.WriteStartElement("", "member", ""); WriteFullElementString(xtw, "name", member); Serialize(xtw, pi.GetValue(o, null), memberActions, nestedObjs); WriteFullEndElement(xtw); } } WriteFullEndElement(xtw); } else if (xType == XmlRpcType.tVoid) { WriteFullElementString(xtw, "string", ""); } else if (xType == XmlRpcType.tNil) { xtw.WriteStartElement("nil"); WriteFullEndElement(xtw); } else { throw new XmlRpcUnsupportedTypeException(o.GetType()); } WriteFullEndElement(xtw); } catch (global::System.NullReferenceException) { throw new XmlRpcNullReferenceException("Attempt to serialize data " + "containing null reference"); } finally { nestedObjs.RemoveAt(nestedObjs.Count - 1); } }