using System.Runtime.Remoting;\r
using System.Runtime.Serialization;\r
using System.Runtime.Remoting.Messaging;\r
+using System.Runtime.Remoting.Metadata;\r
\r
namespace System.Runtime.Serialization.Formatters.Soap {\r
internal sealed class SoapReader {\r
return TopObject;\r
}\r
\r
- #endregion\r
+ #endregion
+
+ public SoapTypeMapper Mapper {
+ get { return mapper; }
+ }
+ \r
+ public XmlTextReader XmlReader {
+ get { return xmlReader; }
+ }\r
\r
#region Private Methods\r
\r
\r
private Type GetComponentType()\r
{\r
- Type type = null;\r
- if(GetId() != 0) return typeof(string);\r
- \r
string strValue = xmlReader["type", XmlSchema.InstanceNamespace];\r
- if(strValue == null) return null;\r
- string[] strName = strValue.Split(':');\r
- string namespaceURI = xmlReader.LookupNamespace(strName[0]);\r
- type = mapper[new Element(string.Empty, strName[1], namespaceURI)];\r
-\r
- return type;\r
+ if(strValue == null) {\r
+ if(GetId() != 0) return typeof(string);\r
+ return null;\r
+ }\r
+ return GetTypeFromQName (strValue);\r
}\r
\r
private bool DeserializeMessage(ISoapMessage message) \r
long paramValuesId = NextAvailableId;\r
int[] indices = new int[1];\r
\r
- int initialDepth = xmlReader.Depth;\r
- xmlReader.Read();\r
- int i = 0;\r
- while(xmlReader.Depth > initialDepth) \r
+ if (!xmlReader.IsEmptyElement)\r
{\r
- long paramId, paramHref;\r
- object objParam = null;\r
- paramNames.Add (xmlReader.Name);\r
- Type paramType = null;\r
- \r
- if (message.ParamTypes != null) {\r
- if (i >= message.ParamTypes.Length)\r
- throw new SerializationException ("Not enough parameter types in SoapMessages");\r
- paramType = message.ParamTypes [i];\r
- }\r
- \r
- indices[0] = i;\r
- objParam = DeserializeComponent(\r
- paramType,\r
- out paramId,\r
- out paramHref,\r
- paramValuesId,\r
- null,\r
- indices);\r
- indices[0] = paramValues.Add(objParam);\r
- if(paramHref != 0) \r
- {\r
- RecordFixup(paramValuesId, paramHref, paramValues.ToArray(), null, null, null, indices);\r
- }\r
- else if(paramId != 0) \r
- {\r
-// RegisterObject(paramId, objParam, null, paramValuesId, null, indices);\r
- }\r
- else \r
+ int initialDepth = xmlReader.Depth;\r
+ xmlReader.Read();\r
+ int i = 0;\r
+ while(xmlReader.Depth > initialDepth) \r
{\r
+ long paramId, paramHref;\r
+ object objParam = null;\r
+ paramNames.Add (xmlReader.Name);\r
+ Type paramType = null;\r
+ \r
+ if (message.ParamTypes != null) {\r
+ if (i >= message.ParamTypes.Length)\r
+ throw new SerializationException ("Not enough parameter types in SoapMessages");\r
+ paramType = message.ParamTypes [i];\r
+ }\r
+ \r
+ indices[0] = i;\r
+ objParam = DeserializeComponent(\r
+ paramType,\r
+ out paramId,\r
+ out paramHref,\r
+ paramValuesId,\r
+ null,\r
+ indices);\r
+ indices[0] = paramValues.Add(objParam);\r
+ if(paramHref != 0) \r
+ {\r
+ RecordFixup(paramValuesId, paramHref, paramValues.ToArray(), null, null, null, indices);\r
+ }\r
+ else if(paramId != 0) \r
+ {\r
+// RegisterObject(paramId, objParam, null, paramValuesId, null, indices);\r
+ }\r
+ else \r
+ {\r
+ }\r
+ i++;\r
}\r
- i++;\r
+ xmlReader.ReadEndElement();\r
}\r
-\r
+ else\r
+ {\r
+ xmlReader.Read();\r
+ }\r
+ \r
message.ParamNames = (string[]) paramNames.ToArray(typeof(string));\r
message.ParamValues = paramValues.ToArray();\r
- xmlReader.ReadEndElement();\r
RegisterObject(paramValuesId, message.ParamValues, null, 0, null, null);\r
return true;\r
}
\r
private object DeserializeArray(long id)\r
{\r
+ // Special case for base64 byte arrays\r
+ if (GetComponentType () == typeof(byte[])) {\r
+ byte[] data = Convert.FromBase64String (xmlReader.ReadElementString());\r
+ RegisterObject(id, data, null, 0, null, null);\r
+ return data;\r
+ }\r
+ \r
// Get the array properties\r
- string strArrayType = xmlReader["arrayType", SoapTypeMapper.SoapEncodingNamespace];\r
- string[] arrayInfo = strArrayType.Split(':','[',',',']');\r
- int numberOfDims = arrayInfo.Length - 3;\r
- int[] lengths = new int[numberOfDims];\r
- string[] arrayDims = new String[numberOfDims];\r
- Array.Copy(arrayInfo, 2, arrayDims, 0, numberOfDims);\r
+ string strArrayType = xmlReader["arrayType", SoapTypeMapper.SoapEncodingNamespace];
+ string[] arrayInfo = strArrayType.Split(':');
+ int arraySuffixInfo = arrayInfo[1].LastIndexOf('[');
+ String arrayElementType = arrayInfo[1].Substring(0, arraySuffixInfo);
+ String arraySuffix = arrayInfo[1].Substring(arraySuffixInfo);
+ string[] arrayDims = arraySuffix.Substring(1,arraySuffix.Length-2).Trim().Split(',');
+ int numberOfDims = arrayDims.Length;
+ int[] lengths = new int[numberOfDims];
+ \r
for (int i=0; i < numberOfDims; i++)\r
{\r
lengths[i] = Convert.ToInt32(arrayDims[i]);\r
int[] indices = new int[numberOfDims];\r
\r
// Create the array\r
- Type arrayType = mapper[new Element(arrayInfo[0], arrayInfo[1], xmlReader.LookupNamespace(arrayInfo[0]))];\r
+ Type arrayType = mapper.GetType (arrayElementType, xmlReader.LookupNamespace(arrayInfo[0]));\r
Array array = Array.CreateInstance(\r
arrayType,\r
- lengths);\r
+ lengths);
\r
for(int i = 0; i < numberOfDims; i++) \r
{\r
indices[i] = array.GetLowerBound(i);\r
}\r
\r
-\r
// Deserialize the array items\r
int arrayDepth = xmlReader.Depth;\r
xmlReader.Read();\r
while(xmlReader.Depth > arrayDepth)\r
{\r
-\r
Type itemType = GetComponentType();\r
if(itemType == null) \r
itemType = array.GetType().GetElementType();\r
private object Deserialize()\r
{\r
object objReturn = null;\r
- Element element = new Element(\r
- xmlReader.Prefix,\r
- xmlReader.LocalName,\r
- xmlReader.NamespaceURI);\r
-\r
-\r
- Type type = mapper[element];\r
+ Type type = mapper.GetType (xmlReader.LocalName, xmlReader.NamespaceURI);\r
\r
// Get the Id\r
long id = GetId();\r
bool NeedsSerializationInfo = false;\r
bool hasFixup;\r
\r
- if(SoapTypeMapper.CanBeValue(type)) \r
+ if(mapper.IsInternalSoapType (type)) \r
{\r
- string elementString = xmlReader.ReadElementString();\r
- object obj = SoapTypeMapper.ParseXsdValue (elementString, type);\r
+ object obj = mapper.ReadInternalSoapValue (this, type);\r
\r
if(id != 0) \r
RegisterObject(id, obj, info, parentId, parentMemberInfo, indices);\r
Type currentType = obj.GetType();\r
TypeMetadata tm = GetTypeMetadata (currentType);\r
\r
- int objDepth = xmlReader.Depth;\r
object[] data = new object[tm.MemberInfos.Length];\r
xmlReader.Read();\r
- for(int i = 0; i < tm.MemberInfos.Length; i++)\r
+ xmlReader.MoveToContent ();\r
+ while (xmlReader.NodeType != XmlNodeType.EndElement)\r
{\r
+ if (xmlReader.NodeType != XmlNodeType.Element) {\r
+ xmlReader.Skip ();\r
+ continue;\r
+ }\r
+ \r
object fieldObject;\r
long fieldId, fieldHref;\r
- int index = (int) tm.Indices[xmlReader.LocalName];\r
+\r
+ object indexob = tm.Indices [xmlReader.LocalName];\r
+ if (indexob == null)\r
+ throw new SerializationException ("Field \"" + xmlReader.LocalName + "\" not found in class " + currentType.FullName);\r
+ \r
+ int index = (int) indexob;\r
FieldInfo fieldInfo = (tm.MemberInfos[index]) as FieldInfo;\r
- if(fieldInfo == null) continue;\r
\r
fieldObject = \r
DeserializeComponent(fieldInfo.FieldType,\r
while(xmlReader.Depth > initialDepth) \r
{\r
Type fieldType = GetComponentType();\r
- string fieldName = xmlReader.LocalName;\r
+ string fieldName = XmlConvert.DecodeName (xmlReader.LocalName);\r
object objField = DeserializeComponent(\r
fieldType,\r
out fieldId,\r
tm.MemberInfos = FormatterServices.GetSerializableMembers (type, _context);\r
\r
tm.Indices = new Hashtable();\r
- for(int i = 0; i < tm.MemberInfos.Length; i++) \r
- tm.Indices.Add (tm.MemberInfos[i].Name, i);\r
+ for(int i = 0; i < tm.MemberInfos.Length; i++) {\r
+ SoapFieldAttribute at = (SoapFieldAttribute) InternalRemotingServices.GetCachedSoapAttribute (tm.MemberInfos[i]);\r
+ tm.Indices [XmlConvert.EncodeLocalName (at.XmlElementName)] = i;\r
+ }\r
\r
_fieldIndices[type] = tm;\r
return tm;\r
+ }
+
+ public Type GetTypeFromQName (string qname)
+ {
+ string[] strName = qname.Split(':');\r
+ string namespaceURI = xmlReader.LookupNamespace (strName[0]);\r
+ return mapper.GetType (strName[1], namespaceURI);\r
}\r
\r
#endregion\r