+// created on 24/04/2003 at 15:35\r
+//\r
+// System.Runtime.Serialization.Formatters.Soap.SoapReader\r
+//\r
+// Authors:\r
+// Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
+//\r
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+\r
using System;\r
+using System.IO;\r
using System.Xml;\r
+using System.Xml.Schema;\r
using System.Reflection;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap\r
-{ \r
-\r
- public enum ReferenceTypes {Array_Type, Object_Type, Interface_Type, Delegate_Type, String_Type};\r
-\r
- internal class SoapReader\r
- {\r
- /******const section******/\r
-\r
- const string cSoapRef = "href";\r
- const string cObjectRef = "ref-";\r
- const string cId = "id";\r
- const string cXsiNull = "xsi:null";\r
- const string basicassembly = "mscorlib";\r
- const string startxmlns = "xmlns:a"; \r
- const string Systemns = "http://schemas.microsoft.com/clr/ns/System"; \r
- const string cDefaultValue = "_0x00_";\r
- /******Array's serialization section******/\r
- const string cItem = "item";\r
- const string cSoapEncArray = "SOAP-ENC:Array";\r
- const string cSoapArrayType = "SOAP-ENC:arrayType"; \r
- const string cXsiType = "xsi:type";\r
- const string cNullObject = "xsi:null=\"1\"/";\r
- /******Delegate's serialization section******/\r
- const string cDelegateSerClass = "DelegateSerializationHolder";\r
- const string cDelegateType = "DelegateType";\r
- const string cDelegateAssembly = "DelegateAssembly";\r
- /******fields's section******/ \r
- public XmlDocument FXmlDoc; \r
- public XmlElement DeepElement; //the current Xml Struct Element\r
- //public Utils FUtils;\r
-\r
- public SoapReader()\r
- { \r
- //FUtils= new Utils();\r
+using System.Collections;\r
+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
+\r
+ #region Fields\r
+\r
+ private SerializationBinder _binder;\r
+ private SoapTypeMapper mapper;\r
+ private ObjectManager objMgr;\r
+ private StreamingContext _context;\r
+ private long _nextAvailableId = long.MaxValue;\r
+ private ISurrogateSelector _surrogateSelector;\r
+ private XmlTextReader xmlReader;\r
+ private Hashtable _fieldIndices;\r
+ private long _topObjectId = 1;\r
+ \r
+ class TypeMetadata\r
+ {\r
+ public MemberInfo[] MemberInfos;\r
+ public Hashtable Indices;\r
}\r
\r
- /**Reference Types reader**/\r
- public int ReadObjectIndexFromXml(string ObjectElemt)\r
- {\r
- XmlNodeList ObjectElement= FXmlDoc.DocumentElement.GetElementsByTagName(ObjectElemt);\r
- XmlElement FCurrentElement= (XmlElement)ObjectElement.Item(0);\r
- string refid= (FCurrentElement).GetAttribute(cId);\r
- int startindex= refid.IndexOf("-");\r
- refid= refid.Substring(startindex + 1, refid.Length - startindex - 1); \r
- return Convert.ToInt32(refid);\r
- } \r
-\r
- private string ReadReferenceFullNameFromXmlNode(XmlNode ReferenceNode)\r
+ #endregion\r
+\r
+ #region Properties\r
+\r
+ private long NextAvailableId\r
{\r
- int StartIndex= ReferenceNode.Name.IndexOf(":");\r
- string ClassName= ReferenceNode.Name.Substring(StartIndex + 1, ReferenceNode.Name.Length - StartIndex - 1); \r
- string AttributeName= FXmlDoc.DocumentElement.Attributes.GetNamedItem("xmlns:" + ReferenceNode.Name.Substring(0, StartIndex)).Value;\r
- StartIndex= AttributeName.LastIndexOf("/"); \r
- string TempStr= AttributeName.Substring(0, StartIndex);\r
- StartIndex= TempStr.LastIndexOf("/");\r
- string ReferenceFullName= TempStr.Substring(StartIndex + 1, TempStr.Length - StartIndex - 1);\r
- return ReferenceFullName + "." + ClassName; \r
+ get \r
+ {\r
+ _nextAvailableId--;\r
+ return _nextAvailableId;\r
+ }\r
}\r
\r
- public string ReadReferenceFullNameFromXml(string RefereneId)\r
+ #endregion\r
+\r
+ #region Constructors\r
+ \r
+ public SoapReader(SerializationBinder binder, ISurrogateSelector selector, StreamingContext context) \r
{\r
- string RefId= cObjectRef + RefereneId;\r
- XmlNodeList NodeList = FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0).ChildNodes;\r
- bool Continue= true;\r
- int index= 0;\r
- string Result= "";\r
- while((Continue)&&(index <= NodeList.Count - 1))\r
+ _binder = binder;\r
+ objMgr = new ObjectManager(selector, context);\r
+ _context = context;\r
+ _surrogateSelector = selector;\r
+ _fieldIndices = new Hashtable();\r
+ }\r
+\r
+ #endregion\r
+\r
+ #region Public Methods\r
+\r
+ public object Deserialize(Stream inStream, ISoapMessage soapMessage) \r
+ {
+ ArrayList headers = null;\r
+ xmlReader = new XmlTextReader(inStream);\r
+ xmlReader.WhitespaceHandling = WhitespaceHandling.None;\r
+ mapper = new SoapTypeMapper(_binder);\r
+\r
+ try\r
{\r
- XmlElement ActElement= (XmlElement)NodeList.Item(index);\r
- if(ActElement.GetAttribute("id")== RefId)//the attributes match\r
+ // SOAP-ENV:Envelope\r
+ xmlReader.MoveToContent();\r
+ xmlReader.ReadStartElement ();
+ xmlReader.MoveToContent();
+
+ // Read headers
+ while (!(xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Body" && xmlReader.NamespaceURI == SoapTypeMapper.SoapEnvelopeNamespace))
{\r
- Result= ReadReferenceFullNameFromXmlNode(ActElement);\r
- Continue= false;\r
+ if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Header" && xmlReader.NamespaceURI == SoapTypeMapper.SoapEnvelopeNamespace)\r
+ {\r
+ if (headers == null) headers = new ArrayList ();\r
+ DeserializeHeaders (headers);\r
+ }\r
+ else
+ xmlReader.Skip ();\r
+ xmlReader.MoveToContent();\r
+ }
+ \r
+ // SOAP-ENV:Body\r
+ xmlReader.ReadStartElement();\r
+ xmlReader.MoveToContent();\r
+\r
+ // The root object\r
+ if (soapMessage != null)\r
+ {\r
+ if (DeserializeMessage (soapMessage)) {\r
+ _topObjectId = NextAvailableId;\r
+ RegisterObject (_topObjectId, soapMessage, null, 0, null, null);\r
+ }\r
+ xmlReader.MoveToContent();\r
+ \r
+ if (headers != null)\r
+ soapMessage.Headers = (Header[]) headers.ToArray (typeof(Header));\r
}\r
- else\r
- index++;\r
+ \r
+ while (xmlReader.NodeType != XmlNodeType.EndElement)\r
+ Deserialize();\r
+ \r
+ // SOAP-ENV:Body\r
+ xmlReader.ReadEndElement ();\r
+ xmlReader.MoveToContent();\r
+\r
+ // SOAP-ENV:Envelope\r
+ xmlReader.ReadEndElement ();\r
}\r
- return Result;\r
- }\r
-\r
- /**ReadReferenceIndexFromXml**/\r
- public int ReadReferenceIndexFromXml(string FieldName, XmlElement ParentElement)\r
- {\r
- XmlElement FieldElement= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0); \r
- if(FieldElement.GetAttribute(cXsiNull)== "") //if it is not a null field\r
+ finally \r
{\r
- string hrefvalue= FieldElement.GetAttribute(cSoapRef);\r
- int StartIndex= hrefvalue.IndexOf("-");\r
- return Convert.ToInt32(hrefvalue.Substring(StartIndex + 1, hrefvalue.Length - 1 - StartIndex));\r
+ if(xmlReader != null) xmlReader.Close();\r
}\r
- else\r
- return -1;\r
+\r
+ return TopObject;\r
+ }\r
+ \r
+ #endregion
+
+ public SoapTypeMapper Mapper {
+ get { return mapper; }
+ }
+ \r
+ public XmlTextReader XmlReader {
+ get { return xmlReader; }
}\r
\r
- public int ReadReferenceIndexFromXml(int ItemIndex, XmlElement ParentElement)\r
+ #region Private Methods\r
+\r
+ private object TopObject \r
{\r
- XmlElement FieldElement= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);\r
- if(FieldElement.GetAttribute(cXsiNull)== "") //if it is not a null field\r
+ get \r
{\r
- string hrefvalue= FieldElement.GetAttribute(cSoapRef);\r
- int StartIndex= hrefvalue.IndexOf("-");\r
- return Convert.ToInt32(hrefvalue.Substring(StartIndex + 1, hrefvalue.Length - 1 - StartIndex));\r
+ objMgr.DoFixups();\r
+ objMgr.RaiseDeserializationEvent();\r
+ return objMgr.GetObject(_topObjectId);\r
}\r
- else\r
- return -1;\r
}\r
\r
-\r
-\r
- /**String reader**/\r
- public int ReadStringIdFromXml(/*string XmlParentElement, */string FieldName,/* string XmlParentElementId, */XmlElement ParentElement)\r
+ private bool IsNull()\r
{\r
- XmlElement FieldElement= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0);//(XmlElement)GetCurrentElement(XmlParentElement, XmlParentElementId).GetElementsByTagName(FieldName).Item(0);\r
- if(FieldElement.GetAttribute(cId)== "")\r
- return ReadReferenceIndexFromXml(FieldName, ParentElement);\r
- else\r
- return ReadFieldIdValueFromXml(FieldName, ParentElement);\r
+ string tmp = xmlReader["null", XmlSchema.InstanceNamespace];\r
+ return (tmp == null || tmp == string.Empty)?false:true;\r
}\r
\r
- public int ReadStringIdFromXml(int ItemIndex, XmlElement ParentElement)\r
+ private long GetId()\r
{\r
- XmlElement FieldElement= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);\r
- string StrId= FieldElement.GetAttribute(cId);\r
- if(StrId == "")\r
- return ReadReferenceIndexFromXml(ItemIndex, ParentElement);\r
- else\r
- return ReadFieldIdValueFromXml(ItemIndex, ParentElement);\r
+ long id = 0;\r
+\r
+ string strId = xmlReader["id"];\r
+ if(strId == null || strId == String.Empty) return 0;\r
+ id = Convert.ToInt64(strId.Substring(4));\r
+ return id;\r
}\r
- \r
- public string ReadStringTypeFromXml(string FieldName, XmlElement ParentElement)\r
+\r
+ private long GetHref()\r
{\r
- XmlNode XmlField= ParentElement.GetElementsByTagName(FieldName).Item(0);\r
- if(XmlField!= null)\r
- return XmlField.InnerXml;\r
- else\r
- return null;\r
+ long href = 0;\r
+ \r
+ string strHref = xmlReader["href"];\r
+ if(strHref == null || strHref == string.Empty) return 0;\r
+ href = Convert.ToInt64(strHref.Substring(5));\r
+ return href;\r
}\r
\r
- public string ReadStringTypeFromXml(int ItemIndex, XmlElement ParentElement)\r
+ private Type GetComponentType()\r
{\r
- XmlNode XmlField= ParentElement.ChildNodes.Item(ItemIndex);\r
- if(XmlField!= null)\r
- return XmlField.InnerXml;\r
- else\r
+ string strValue = xmlReader["type", XmlSchema.InstanceNamespace];\r
+ if(strValue == null) {\r
+ if(GetId() != 0) return typeof(string);\r
return null;\r
+ }\r
+ return GetTypeFromQName (strValue);\r
}\r
\r
- /**Delegates reader**/\r
- public string GetDelegateElementName(int DelegateId)\r
- { \r
- XmlAttributeCollection XmlAttrCollection= FXmlDoc.DocumentElement.Attributes;\r
- bool Continue= true;\r
- int i= 0;\r
- string ItemName= "";\r
- while((Continue)&&(i<= XmlAttrCollection.Count - 1))\r
+ private bool DeserializeMessage(ISoapMessage message) \r
+ {\r
+ string typeNamespace, assemblyName;\r
+\r
+ if(xmlReader.Name == SoapTypeMapper.SoapEnvelopePrefix + ":Fault")\r
{\r
- string AttrValue= XmlAttrCollection.Item(i).Value; \r
- if(AttrValue == Systemns)\r
- {\r
- ItemName= XmlAttrCollection.Item(i).Name;\r
- ItemName= ItemName.Substring(ItemName.LastIndexOf(":") + 1, ItemName.Length - 1 - ItemName.LastIndexOf(":"));\r
- Continue= false;\r
- }\r
- i++;\r
+ Deserialize();\r
+ return false;\r
}\r
- return ItemName + ":" + cDelegateSerClass;\r
- }\r
\r
- public Type GetDelegateTypeFromXml(XmlElement ParentElement)\r
- {\r
- string DelegateAssembly= ParentElement.GetElementsByTagName(cDelegateAssembly).Item(0).InnerXml;\r
- DelegateAssembly= DelegateAssembly.Substring(0, DelegateAssembly.IndexOf(","));\r
- string DelegateType= ParentElement.GetElementsByTagName(cDelegateType).Item(0).InnerXml;\r
- return Assembly.Load(DelegateAssembly).GetType(DelegateType); \r
- }\r
- \r
- /**Arrays reader**/\r
- public string ReadArrayTypeFromXml(XmlElement ArrayElement, out string AssemblyName)\r
- { \r
- string ArrayTypeAttr= ArrayElement.GetAttribute(cSoapArrayType);\r
- int StartIndex= ArrayTypeAttr.LastIndexOf(":");\r
- string Result;\r
- if(ArrayTypeAttr.Substring(0, 4) == "xsd:") \r
+ SoapServices.DecodeXmlNamespaceForClrTypeNamespace(\r
+ xmlReader.NamespaceURI,\r
+ out typeNamespace,\r
+ out assemblyName);\r
+ message.MethodName = xmlReader.LocalName;\r
+ message.XmlNameSpace = xmlReader.NamespaceURI;\r
+\r
+ ArrayList paramNames = new ArrayList();\r
+ ArrayList paramValues = new ArrayList();\r
+ long paramValuesId = NextAvailableId;\r
+ int[] indices = new int[1];\r
+\r
+ if (!xmlReader.IsEmptyElement)\r
{\r
- Result= "System";\r
- string CLRType= GetCLRTypeFromXsdType(ArrayTypeAttr.Substring(0, ArrayTypeAttr.IndexOf("[")));\r
- StartIndex= ArrayTypeAttr.IndexOf("[");\r
- Result= "System." + CLRType + ArrayTypeAttr.Substring(StartIndex, ArrayTypeAttr.Length - StartIndex);\r
- AssemblyName= basicassembly;\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
+ xmlReader.ReadEndElement();\r
}\r
else\r
{\r
- AssemblyName= ReadAssemblyNameFromXml(ArrayTypeAttr); \r
- string NsIndex= ArrayTypeAttr.Substring(1, StartIndex - 1);\r
- Result= ReadNamespaceFromXml(NsIndex); \r
- Result= Result + "." + ArrayTypeAttr.Substring(StartIndex + 1, ArrayTypeAttr.Length - StartIndex - 1);\r
- } \r
- return Result;\r
- } \r
- \r
-\r
- public bool IsArrayItemValueType(XmlElement ParentElement, int ItemIndex, ref bool IsNull, ref bool IsStruct)\r
+ xmlReader.Read();\r
+ }\r
+ \r
+ message.ParamNames = (string[]) paramNames.ToArray(typeof(string));\r
+ message.ParamValues = paramValues.ToArray();\r
+ RegisterObject(paramValuesId, message.ParamValues, null, 0, null, null);\r
+ return true;\r
+ }
+\r
+ void DeserializeHeaders (ArrayList headers)\r
{\r
- XmlElement ArrayItem= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex); \r
- bool Result= false;\r
- if(ArrayItem.GetAttribute(cXsiNull)== "")//is not null\r
+ xmlReader.ReadStartElement ();\r
+ xmlReader.MoveToContent ();\r
+ \r
+ while (xmlReader.NodeType != XmlNodeType.EndElement) \r
{\r
- IsNull= false;\r
- if((ArrayItem.InnerXml != "")&&(ArrayItem.GetAttribute(cId) == ""))\r
- {\r
- Result= true; \r
- if(ArrayItem.InnerXml.Substring(0, 1)== "<") //is an atruct\r
- IsStruct= true;\r
- }\r
+ if (xmlReader.NodeType != XmlNodeType.Element) { xmlReader.Skip(); continue; }\r
+ \r
+ if (xmlReader.GetAttribute ("root", SoapTypeMapper.SoapEncodingNamespace) == "1")\r
+ headers.Add (DeserializeHeader ());\r
+ else\r
+ Deserialize ();\r
+\r
+ xmlReader.MoveToContent ();\r
}\r
- else\r
- IsNull= true; \r
- return Result;\r
+ \r
+ xmlReader.ReadEndElement ();\r
+ }
+ \r Header DeserializeHeader ()
+ {
+ Header h = new Header (xmlReader.LocalName, null);
+ h.HeaderNamespace = xmlReader.NamespaceURI;\r
+ h.MustUnderstand = xmlReader.GetAttribute ("mustUnderstand", SoapTypeMapper.SoapEnvelopeNamespace) == "1";\r
+ \r
+ object value;\r
+ long fieldId, fieldHref;\r
+ long idHeader = NextAvailableId;\r
+ FieldInfo fieldInfo = typeof(Header).GetField ("Value");\r
+\r
+ value = DeserializeComponent (null, out fieldId, out fieldHref, idHeader, fieldInfo, null);\r
+ h.Value = value;\r
+\r
+ if(fieldHref != 0 && value == null)\r
+ {\r
+ RecordFixup (idHeader, fieldHref, h, null, null, fieldInfo, null);\r
+ }\r
+ else if(value != null && value.GetType().IsValueType && fieldId != 0)\r
+ {\r
+ RecordFixup (idHeader, fieldId, h, null, null, fieldInfo, null);\r
+ }\r
+ else if(fieldId != 0)\r
+ {\r
+ RegisterObject (fieldId, value, null, idHeader, fieldInfo, null);\r
+ }\r
+ \r
+ RegisterObject (idHeader, h, null, 0, null, null);\r
+ return h;\r
}\r
\r
- public ValueType ReadArrayItemSimpleTypeFromXml(XmlElement ParentElement, int ItemIndex, string ItemTypeName)\r
+ \r
+ private object DeserializeArray(long id)\r
{\r
- XmlElement ArrayItem= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);//at this moment you know that this field is a value type\r
- string ItemValue= ArrayItem.InnerXml;\r
- string XsiType= ((XmlElement)ArrayItem).GetAttribute(cXsiType);\r
- if(XsiType != "")\r
- return GetValueTypeFromXsdType(XsiType, ItemValue);\r
- else\r
- return GetValueTypeFromString(ItemTypeName, ItemValue);\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];
+ 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
+ }\r
\r
- public ReferenceTypes GetReferenceType(string FieldName, XmlElement ParentElement, ref XmlElement RefElement)\r
- { \r
- XmlElement ArrayItem= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0);\r
- RefElement= ArrayItem;\r
- ReferenceTypes Result= ReferenceTypes.Object_Type;\r
- if(ArrayItem.GetAttribute(cId) != "") //is an string \r
- Result= ReferenceTypes.String_Type;\r
- else\r
+ int[] indices = new int[numberOfDims];\r
+\r
+ // Create the array\r
+ Type arrayType = mapper.GetType (arrayElementType, xmlReader.LookupNamespace(arrayInfo[0]));\r
+ Array array = Array.CreateInstance(\r
+ arrayType,\r
+ lengths);
+\r
+ for(int i = 0; i < numberOfDims; i++) \r
{\r
- string RefIndex= ArrayItem.GetAttribute(cSoapRef);\r
- if(RefIndex != "") //is a other reference\r
- { \r
- int Id= RefIndex.IndexOf("-");\r
- Id= Convert.ToInt32(RefIndex.Substring(Id + 1, RefIndex.Length - 1 - Id));\r
- string RefName= GetReferenceNameFromId(Convert.ToInt32(Id), ref RefElement); \r
- if(RefName== cSoapEncArray) //is an array \r
- Result= ReferenceTypes.Array_Type;\r
- else\r
- if(RefName == "")\r
- Result= ReferenceTypes.String_Type;\r
- else\r
- {\r
- if((RefName.IndexOf(cDelegateSerClass) != -1)&&(RefElement.ChildNodes.Item(0).Name== cDelegateType)) //is a delegates\r
- Result= ReferenceTypes.Delegate_Type;\r
- else\r
- Result= ReferenceTypes.Object_Type;\r
- }\r
- }\r
- } \r
- return Result;\r
- }\r
+ indices[i] = array.GetLowerBound(i);\r
+ }\r
\r
- public ReferenceTypes GetReferenceType(int index, XmlElement ParentElement, ref XmlElement RefElement)\r
- {\r
- XmlElement ArrayItem= (XmlElement)ParentElement.ChildNodes.Item(index);\r
- RefElement= ArrayItem;\r
- ReferenceTypes Result= ReferenceTypes.Object_Type;\r
- if(ArrayItem.GetAttribute(cId) != "") //is an string \r
- Result= ReferenceTypes.String_Type;\r
- else\r
+ // Deserialize the array items\r
+ int arrayDepth = xmlReader.Depth;\r
+ xmlReader.Read();\r
+ while(xmlReader.Depth > arrayDepth)\r
{\r
- string RefIndex= ArrayItem.GetAttribute(cSoapRef);\r
- if(RefIndex != "") //is a other reference\r
- { \r
- int Id= RefIndex.IndexOf("-");\r
- Id= Convert.ToInt32(RefIndex.Substring(Id + 1, RefIndex.Length - 1 - Id));\r
- string RefName= GetReferenceNameFromId(Convert.ToInt32(Id), ref RefElement);\r
- if(RefName== cSoapEncArray) //is an array \r
- Result= ReferenceTypes.Array_Type;\r
- else\r
- if(RefName == "")\r
- Result= ReferenceTypes.String_Type;\r
+ Type itemType = GetComponentType();\r
+ if(itemType == null) \r
+ itemType = array.GetType().GetElementType();\r
+ long itemId, itemHref;\r
+\r
+ object objItem = DeserializeComponent(itemType,\r
+ out itemId,\r
+ out itemHref,\r
+ id,\r
+ null,\r
+ indices);\r
+ if(itemHref != 0)\r
+ {\r
+ object obj = objMgr.GetObject(itemHref);\r
+ if(obj != null)\r
+ array.SetValue(obj, indices);\r
else\r
+ RecordFixup(id, itemHref, array, null, null, null, indices);\r
+ }\r
+ else if(objItem != null && objItem.GetType().IsValueType && itemId != 0)\r
+ {\r
+ RecordFixup(id, itemId, array, null, null, null, indices);\r
+ }\r
+ else if(itemId != 0)\r
+ {\r
+ RegisterObject(itemId, objItem, null, id, null, indices);\r
+ array.SetValue(objItem, indices);\r
+ }\r
+ else \r
+ {\r
+ array.SetValue(objItem, indices);\r
+ }\r
+\r
+ // Get the next indice\r
+ for(int dim = array.Rank - 1; dim >= 0; dim--)\r
+ {\r
+ indices[dim]++;\r
+ if(indices[dim] > array.GetUpperBound(dim))\r
{\r
- if((RefName.IndexOf(cDelegateSerClass) != -1)&&(RefElement.ChildNodes.Item(0).Name== cDelegateType)) //is a delegates\r
- Result= ReferenceTypes.Delegate_Type;\r
- else\r
- Result= ReferenceTypes.Object_Type;\r
+ if(dim > 0)\r
+ {\r
+ indices[dim] = array.GetLowerBound(dim);\r
+ continue;\r
+ }\r
+ \r
}\r
+ break;\r
}\r
- } \r
- return Result;\r
- }\r
+ }\r
+\r
+ RegisterObject(id, array, null, 0, null, null);\r
+ xmlReader.ReadEndElement();\r
+ return array;\r
\r
- public string GetFullObjectLocation(string XsdType, out string NsName)\r
- {\r
- string AssemblyName= ReadAssemblyNameFromXml(XsdType);\r
- int StartIndex= XsdType.LastIndexOf(":");\r
- string NsIndex= XsdType.Substring(1, StartIndex - 1);\r
- NsName= ReadNamespaceFromXml(NsIndex);\r
- NsName= NsName + "." + XsdType.Substring(StartIndex + 1, XsdType.Length - StartIndex - 1);\r
- return AssemblyName; \r
}\r
\r
- private ValueType GetValueTypeFromNotSimpleType(string XsdType, string ItemValue)\r
+\r
+ private object Deserialize()\r
{\r
- string NsName;\r
- string AssemblyName= GetFullObjectLocation(XsdType, out NsName); \r
- Type ItemType= Assembly.Load(AssemblyName).GetType(NsName);\r
- object Result;\r
- if(ItemType.IsEnum)//is an enum\r
- Result= Enum.Parse(ItemType, ItemValue);\r
- else //is a char\r
+ object objReturn = null;\r
+ Type type = mapper.GetType (xmlReader.LocalName, xmlReader.NamespaceURI);\r
+\r
+ // Get the Id\r
+ long id = GetId();\r
+ id = (id == 0)?1:id;\r
+\r
+ if(type == typeof(Array))\r
{\r
- if(ItemValue == cDefaultValue) \r
- Result= new char();\r
- else \r
- Result= Char.Parse(ItemValue); \r
+ objReturn = DeserializeArray(id);\r
}\r
- return (ValueType)Result; \r
- }\r
+ else\r
+ {\r
+ objReturn = DeserializeObject(type, id, 0, null, null);\r
\r
- private string GetCLRTypeFromXsdType(string XsdType)\r
- {\r
- string Result= "";\r
- switch(XsdType)\r
- { \r
- case "xsd:int" :Result= "Int32";\r
- break;\r
- case "xsd:short" :Result= "Int16";\r
- break;\r
- case "xsd:long" :Result= "Int64";\r
- break;\r
- case "xsd:unsignedInt" :Result= "UInt32";\r
- break;\r
- case "xsd:unsignedShort":Result= "UInt16";\r
- break;\r
- case "xsd:unsignedLong" :Result= "UInt64";\r
- break;\r
- case "xsd:byte" :Result= "Byte";\r
- break;\r
- case "xsd:decimal" :Result= "Decimal";\r
- break;\r
- case "xsd:double" :Result= "Double"; \r
- break; \r
- case "xsd:boolean" :Result= "Boolean";\r
- break;\r
- case "xsd:dateTime" :Result= "DateTime";\r
- break;\r
- case "xsd:string" :Result= "String";\r
- break;\r
}\r
- return Result;\r
+\r
+ return objReturn;\r
}\r
\r
- public ValueType GetValueTypeFromXsdType(string XsdType, string ItemValue)\r
+\r
+ private object DeserializeObject(\r
+ Type type, \r
+ long id, \r
+ long parentId, \r
+ MemberInfo parentMemberInfo,\r
+ int[] indices)\r
{\r
- ValueType Result= null;\r
- switch(XsdType)\r
- { \r
- case "xsd:int" : Result= Convert.ToInt32(ItemValue);\r
- break;\r
- case "xsd:short" :Result= Convert.ToInt16(ItemValue);\r
- break;\r
- case "xsd:long" :Result= Convert.ToInt64(ItemValue);\r
- break;\r
- case "xsd:unsignedInt" :Result= Convert.ToUInt32(ItemValue);\r
- break;\r
- case "xsd:unsignedShort":Result= Convert.ToUInt16(ItemValue);\r
- break;\r
- case "xsd:unsignedLong" :Result= Convert.ToUInt64(ItemValue);\r
- break;\r
- case "xsd:byte" :Result= Convert.ToByte(ItemValue);\r
- break;\r
- case "xsd:decimal" :Result= Convert.ToDecimal(ItemValue);\r
- break;\r
- case "xsd:double" :Result= Convert.ToDouble(ItemValue); \r
- break; \r
- case "xsd:boolean" :Result= Convert.ToBoolean(ItemValue);\r
- break;\r
- case "xsd:dateTime" :Result= Convert.ToDateTime(ItemValue);\r
- break;\r
- default :Result= GetValueTypeFromNotSimpleType(XsdType, ItemValue);\r
- break;\r
+ SerializationInfo info = null;\r
+ bool NeedsSerializationInfo = false;\r
+ bool hasFixup;\r
+\r
+ if(mapper.IsInternalSoapType (type)) \r
+ {\r
+ object obj = mapper.ReadInternalSoapValue (this, type);\r
+ \r
+ if(id != 0) \r
+ RegisterObject(id, obj, info, parentId, parentMemberInfo, indices);\r
+\r
+ return obj;\r
}\r
- return Result;\r
- }\r
+ object objReturn = \r
+ FormatterServices.GetUninitializedObject(type);\r
+ if(objReturn is ISerializable)\r
+ NeedsSerializationInfo = true;\r
\r
- /**Value types reader**/\r
- public string ReadValueTypeFromXml(string FieldName, XmlElement ParentElement/*string ParentElement, string ParentElementId*/)\r
- {\r
- XmlNode XmlField= ParentElement.GetElementsByTagName(FieldName).Item(0);///*FCurrentElement*/GetCurrentElement(ParentElement, ParentElementId).GetElementsByTagName(FieldName).Item(0); \r
- if(XmlField!= null)\r
- return XmlField.InnerXml;\r
- else\r
- return null;\r
- }\r
- \r
- public ValueType GetValueTypeFromString(string fieldtype, string fieldvalue)\r
- {\r
- ValueType result= null;\r
- switch(fieldtype)\r
+ if(_surrogateSelector != null && NeedsSerializationInfo == false)\r
{\r
- case "Int32" : result= Convert.ToInt32(fieldvalue);\r
- break;\r
- case "Int16" : result= Convert.ToInt16(fieldvalue);\r
- break;\r
- case "Int64" : result= Convert.ToInt64(fieldvalue);\r
- break;\r
- case "UInt32" : result= Convert.ToUInt32(fieldvalue);\r
- break;\r
- case "UInt16" : result= Convert.ToUInt16(fieldvalue);\r
- break;\r
- case "UInt64" : result= Convert.ToUInt64(fieldvalue);\r
- break;\r
- case "Byte" : result= Convert.ToByte(fieldvalue);\r
- break;\r
- case "Decimal" : result= Convert.ToDecimal(fieldvalue);\r
- break;\r
- case "Double" : result= Convert.ToDouble(fieldvalue);\r
- break; \r
- case "Boolean" : result= Convert.ToBoolean(fieldvalue);\r
- break;\r
- case "DateTime" : result= Convert.ToDateTime(fieldvalue);\r
- break;\r
- case "Char" : result= Convert.ToChar(fieldvalue);\r
- break;\r
+ ISurrogateSelector selector;\r
+ ISerializationSurrogate surrogate = _surrogateSelector.GetSurrogate(\r
+ type,\r
+ _context,\r
+ out selector);\r
+ NeedsSerializationInfo |= (surrogate != null);\r
}\r
- return result;\r
- } \r
\r
- /**Structs reader**/\r
- public string ReadStructValueFieldFromXml(/*string XmlParentElement, */string FieldName, XmlElement ParentElement/*string XmlParentElementId, */, string StructName, bool NestedStruct)\r
- {\r
- XmlElement FieldElement; \r
- FieldElement= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0); \r
- if(FieldElement != null)\r
- return FieldElement.InnerXml;\r
+ if(NeedsSerializationInfo)\r
+ {\r
+ objReturn = \r
+ DeserializeISerializableObject(objReturn, id, out info, out hasFixup);\r
+ }\r
else\r
- return null;\r
- }\r
+ {\r
+ objReturn = \r
+ DeserializeSimpleObject(objReturn, id, out hasFixup);\r
+ if(!hasFixup && objReturn is IObjectReference)\r
+ objReturn = ((IObjectReference)objReturn).GetRealObject(_context);\r
+ }\r
\r
- public void ReadStructParentElementFromXml(string StructName, XmlElement ParentElement, bool NestedStruct)\r
- {\r
- if(!NestedStruct)//is not a nested struct\r
- DeepElement= (XmlElement)ParentElement.GetElementsByTagName(StructName).Item(0);//GetCurrentElement(XmlParentElement, XmlParentElementId).GetElementsByTagName(StructName).Item(0);\r
- else \r
- DeepElement= (XmlElement)DeepElement.GetElementsByTagName(StructName).Item(0);\r
+ RegisterObject(id, objReturn, info, parentId, parentMemberInfo, indices);\r
+ xmlReader.ReadEndElement();\r
+ return objReturn;\r
}\r
\r
- /**Assemblies reader**/\r
- public string GetAssemblyNameFromId(int id)\r
- { \r
- XmlNodeList ObjList= ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0)).ChildNodes;\r
- bool Continue= true;\r
- int index= 0;\r
- string AssemblyName= "";\r
- while((Continue)&&(index<= ObjList.Count - 1))\r
+\r
+ private object DeserializeSimpleObject(\r
+ object obj,\r
+ long id,\r
+ out bool hasFixup\r
+ )\r
+ {\r
+ hasFixup = false;\r
+ Type currentType = obj.GetType();\r
+ TypeMetadata tm = GetTypeMetadata (currentType);\r
+\r
+ object[] data = new object[tm.MemberInfos.Length];\r
+ xmlReader.Read();\r
+ xmlReader.MoveToContent ();\r
+ while (xmlReader.NodeType != XmlNodeType.EndElement)\r
{\r
- string refid= ((XmlElement)ObjList.Item(index)).GetAttribute(cId); \r
- int StartIndex= refid.IndexOf("-");\r
- refid= refid.Substring(StartIndex + 1, refid.Length - 1 - StartIndex);\r
- if(refid== id.ToString())\r
+ if (xmlReader.NodeType != XmlNodeType.Element) {\r
+ xmlReader.Skip ();\r
+ continue;\r
+ }\r
+ \r
+ object fieldObject;\r
+ long fieldId, fieldHref;\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
+\r
+ fieldObject = \r
+ DeserializeComponent(fieldInfo.FieldType,\r
+ out fieldId,\r
+ out fieldHref,\r
+ id,\r
+ fieldInfo,\r
+ null);\r
+\r
+ data[index] = fieldObject;\r
+\r
+ if(fieldHref != 0 && fieldObject == null)\r
{\r
- Continue= false; \r
- AssemblyName= ReadAssemblyNameFromXml(((XmlElement)ObjList.Item(index)).Name);\r
+ RecordFixup(id, fieldHref, obj, null, null, fieldInfo, null);\r
+ hasFixup = true;\r
+ continue;\r
+ }\r
+ if(fieldObject != null && fieldObject.GetType().IsValueType && fieldId != 0)\r
+ {\r
+ RecordFixup(id, fieldId, obj, null, null, fieldInfo, null);\r
+ hasFixup = true;\r
+ continue;\r
+ }\r
+\r
+ if(fieldId != 0)\r
+ {\r
+ RegisterObject(fieldId, fieldObject, null, id, fieldInfo, null);\r
}\r
- else\r
- index++;\r
}\r
- return AssemblyName;\r
+\r
+ FormatterServices.PopulateObjectMembers (obj, tm.MemberInfos, data);\r
+ return obj;\r
}\r
\r
- private string GetReferenceNameFromId(int id, ref XmlElement RefElement)\r
+\r
+ private object DeserializeISerializableObject(\r
+ object obj, \r
+ long id, \r
+ out SerializationInfo info,\r
+ out bool hasFixup\r
+ )\r
{\r
- XmlNodeList ObjList= ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0)).ChildNodes;\r
- bool Continue= true;\r
- int index= 0;\r
- string Result= "";\r
- while((Continue)&&(index<= ObjList.Count - 1))\r
+ long fieldId, fieldHref;\r
+ info = new SerializationInfo(obj.GetType(), new FormatterConverter());\r
+ hasFixup = false;\r
+ \r
+ int initialDepth = xmlReader.Depth;\r
+ xmlReader.Read();\r
+ while(xmlReader.Depth > initialDepth) \r
{\r
- string refid= ((XmlElement)ObjList.Item(index)).GetAttribute(cId); \r
- int StartIndex= refid.IndexOf("-");\r
- refid= refid.Substring(StartIndex + 1, refid.Length - 1 - StartIndex);\r
- if(refid== id.ToString())\r
+ Type fieldType = GetComponentType();\r
+ string fieldName = XmlConvert.DecodeName (xmlReader.LocalName);\r
+ object objField = DeserializeComponent(\r
+ fieldType,\r
+ out fieldId,\r
+ out fieldHref,\r
+ id,\r
+ null,\r
+ null);\r
+ if(fieldHref != 0 && objField == null) \r
{\r
- Continue= false; \r
- Result= ((XmlElement)ObjList.Item(index)).Name;\r
- RefElement= (XmlElement)ObjList.Item(index);\r
+ RecordFixup(id, fieldHref, obj, info, fieldName, null, null);\r
+ hasFixup = true;\r
+ continue;\r
}\r
- else\r
- index++;\r
+ else if(fieldId != 0 && objField.GetType().IsValueType)\r
+ {\r
+ RecordFixup(id, fieldId, obj, info, fieldName, null, null);\r
+ hasFixup = true;\r
+ continue;\r
+ }\r
+ \r
+ if(fieldId != 0) \r
+ {\r
+ RegisterObject(fieldId, objField, null, id, null, null);\r
+ }\r
+\r
+ info.AddValue(fieldName, objField, (fieldType != null)?fieldType:typeof(object));\r
}\r
- return Result;\r
- }\r
\r
- public string ReadAssemblyNameFromXml(string ParentElementName)\r
- {\r
- string RefName= ParentElementName.Substring(1, ParentElementName.LastIndexOf(":") - 1);\r
- string XmlNamespaceName= startxmlns + RefName;\r
- string AttributeName= FXmlDoc.DocumentElement.Attributes.GetNamedItem(XmlNamespaceName).Value;\r
- int StartIndex= AttributeName.LastIndexOf("/");\r
- string AssemblyName= AttributeName.Substring(StartIndex + 1, AttributeName.Length - StartIndex - 1);\r
- if(AssemblyName == "System")\r
- AssemblyName= basicassembly;\r
- return AssemblyName;\r
+ return obj;\r
}\r
\r
- /**Namespace reader**/\r
- public string ReadNamespaceFromXml(string ReferenceName)\r
+\r
+ private object DeserializeComponent(\r
+ Type componentType, \r
+ out long componentId,\r
+ out long componentHref,\r
+ long parentId,\r
+ MemberInfo parentMemberInfo,\r
+ int[] indices)\r
{\r
- string XmlNamespaceName= startxmlns + ReferenceName; \r
- string AttributeName= FXmlDoc.DocumentElement.Attributes.GetNamedItem(XmlNamespaceName).Value;\r
- int StartIndex= AttributeName.LastIndexOf("/");\r
- string Result= "";\r
- string NsName= AttributeName.Substring(StartIndex + 1, AttributeName.Length - StartIndex - 1);\r
- if(NsName == "System")\r
- Result= NsName;\r
- else\r
+ object objReturn;\r
+ componentId = 0;\r
+ componentHref = 0;\r
+\r
+ if(IsNull())\r
{\r
- string TmpStr= AttributeName.Substring(0, StartIndex);\r
- StartIndex= TmpStr.LastIndexOf("/");\r
- Result= TmpStr.Substring(StartIndex + 1, TmpStr.Length - StartIndex - 1);\r
+ xmlReader.Read();\r
+ return null;\r
}\r
- return Result;\r
- \r
+\r
+ Type xsiType = GetComponentType();\r
+ if(xsiType != null) componentType = xsiType;\r
+\r
+ if(xmlReader.HasAttributes)\r
+ {\r
+ componentId = GetId();\r
+ componentHref = GetHref();\r
+ }\r
+\r
+ if(componentId != 0)\r
+ {\r
+ // It's a string\r
+ return xmlReader.ReadElementString();\r
+ }\r
+ if(componentHref != 0)\r
+ {\r
+ // Move the cursor to the next node\r
+ xmlReader.Read();\r
+ return objMgr.GetObject(componentHref);\r
+ }\r
+\r
+ if(componentType == null)\r
+ return xmlReader.ReadElementString();\r
+\r
+ componentId = NextAvailableId;\r
+ objReturn = DeserializeObject(\r
+ componentType,\r
+ componentId,\r
+ parentId,\r
+ parentMemberInfo,\r
+ indices);\r
+ return objReturn;\r
}\r
\r
- /**Utils**/\r
- public XmlElement GetCurrentElement(string ElementName, string ElementId)\r
+ public void RecordFixup(\r
+ long parentObjectId, \r
+ long childObjectId,\r
+ object parentObject,\r
+ SerializationInfo info,\r
+ string fieldName,\r
+ MemberInfo memberInfo,\r
+ int[] indices)\r
{\r
- string RefId= cObjectRef + ElementId;\r
- XmlNodeList NodeList = ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0)).GetElementsByTagName(ElementName);\r
- bool Continue= true;\r
- int index= 0;\r
- string Result= "";\r
- XmlElement ActElement = null;\r
- while((Continue)&&(index <= NodeList.Count - 1))\r
+ if(info != null)\r
+ {\r
+ objMgr.RecordDelayedFixup(parentObjectId, fieldName, childObjectId);\r
+ }\r
+ else if (parentObject is Array) \r
{\r
- ActElement= (XmlElement)NodeList.Item(index);\r
- if(ActElement.GetAttribute("id")== RefId)//the attributes match\r
- Continue= false; \r
+ if (indices.Length == 1)\r
+ objMgr.RecordArrayElementFixup (parentObjectId, indices[0], childObjectId);\r
else\r
- index++;\r
+ objMgr.RecordArrayElementFixup (parentObjectId, (int[])indices.Clone(), childObjectId);\r
+ }\r
+ else \r
+ {\r
+ objMgr.RecordFixup (parentObjectId, memberInfo, childObjectId);\r
}\r
- if(!Continue)\r
- return ActElement;\r
- else\r
- return null;\r
}\r
- \r
- private int ReadFieldIdValueFromXml(string FieldName, XmlElement ParentElement)\r
+\r
+ private void RegisterObject (\r
+ long objectId, \r
+ object objectInstance, \r
+ SerializationInfo info, \r
+ long parentObjectId, \r
+ MemberInfo parentObjectMember, \r
+ int[] indices)\r
{\r
- XmlElement FieldElement= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0);//(XmlElement)GetCurrentElement(XmlParentElement, XmlParentElementId).GetElementsByTagName(FieldName).Item(0);\r
- if(FieldElement.GetAttribute(cXsiNull)== "") //if it is not a null field\r
+ if (parentObjectId == 0) indices = null;\r
+\r
+ if (!objectInstance.GetType().IsValueType || parentObjectId == 0)\r
+ objMgr.RegisterObject (objectInstance, objectId, info, 0, null, null);\r
+ else\r
{\r
- string refvalue= FieldElement.GetAttribute(cId);\r
- int StartIndex= refvalue.IndexOf("-");\r
- return Convert.ToInt32(refvalue.Substring(StartIndex + 1, refvalue.Length - 1 - StartIndex));\r
+ if(objMgr.GetObject(objectId) != null)\r
+ throw new SerializationException("Object already registered");\r
+ if (indices != null) indices = (int[])indices.Clone();\r
+ objMgr.RegisterObject (\r
+ objectInstance, \r
+ objectId, \r
+ info, \r
+ parentObjectId, \r
+ parentObjectMember, \r
+ indices);\r
}\r
- else\r
- return -1;\r
}\r
\r
- private int ReadFieldIdValueFromXml(int ItemIndex, XmlElement ParentElement)\r
+ TypeMetadata GetTypeMetadata (Type type)\r
{\r
- XmlElement FieldElement= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);\r
- if(FieldElement.GetAttribute(cXsiNull)== "") //if it is not a null field\r
- {\r
- string refvalue= FieldElement.GetAttribute(cId);\r
- int StartIndex= refvalue.IndexOf("-");\r
- return Convert.ToInt32(refvalue.Substring(StartIndex + 1, refvalue.Length - 1 - StartIndex));\r
+ TypeMetadata tm = _fieldIndices[type] as TypeMetadata;\r
+ if (tm != null) return tm;\r
+ \r
+ tm = new TypeMetadata ();\r
+ tm.MemberInfos = FormatterServices.GetSerializableMembers (type, _context);\r
+ \r
+ tm.Indices = new Hashtable();\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
- else\r
- return -1;\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
+ \r
+ #endregion\r
+ }\r
}\r