New test.
[mono.git] / mcs / class / System.Runtime.Serialization.Formatters.Soap / System.Runtime.Serialization.Formatters.Soap / SoapReader.cs
index 394d668310f56fc81144be143317c1576ab8dbae..90b9e578dd414f8c162e56bd04c83f022fecf080 100644 (file)
@@ -5,27 +5,27 @@
 //     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
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+// \r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
 \r
 using System;\r
 using System.IO;\r
@@ -90,7 +90,7 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                #region Public Methods\r
 \r
                public object Deserialize(Stream inStream, ISoapMessage soapMessage) \r
-               {
+               {\r
                        ArrayList headers = null;\r
                        xmlReader = new XmlTextReader(inStream);\r
                        xmlReader.WhitespaceHandling = WhitespaceHandling.None;\r
@@ -100,21 +100,21 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        {\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))
+                               xmlReader.ReadStartElement ();\r
+                               xmlReader.MoveToContent();\r
+                               \r
+                               // Read headers\r
+                               while (!(xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Body" && xmlReader.NamespaceURI == SoapTypeMapper.SoapEnvelopeNamespace))\r
                                {\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
+                                       else\r
                                                xmlReader.Skip ();\r
                                        xmlReader.MoveToContent();\r
-                               }
+                               }\r
                                \r
                                // SOAP-ENV:Body\r
                                xmlReader.ReadStartElement();\r
@@ -152,6 +152,14 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                }\r
                \r
                #endregion\r
+               \r
+               public SoapTypeMapper Mapper {\r
+                       get { return mapper; }\r
+               }\r
+               \r
+               public XmlTextReader XmlReader {\r
+                       get { return xmlReader; }\r
+               }\r
 \r
                #region Private Methods\r
 \r
@@ -193,18 +201,12 @@ namespace System.Runtime.Serialization.Formatters.Soap {
 \r
                private Type GetComponentType()\r
                {\r
-                       Type type = null;\r
-                       \r
                        string strValue = xmlReader["type", XmlSchema.InstanceNamespace];\r
                        if(strValue == null) {\r
                                if(GetId() != 0) return typeof(string);\r
                                return null;\r
                        }\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
+                       return GetTypeFromQName (strValue);\r
                }\r
 \r
                private bool DeserializeMessage(ISoapMessage message) \r
@@ -280,7 +282,7 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        message.ParamValues = paramValues.ToArray();\r
                        RegisterObject(paramValuesId, message.ParamValues, null, 0, null, null);\r
                        return true;\r
-               }
+               }\r
 \r
                void DeserializeHeaders (ArrayList headers)\r
                {\r
@@ -300,10 +302,11 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        }\r
                        \r
                        xmlReader.ReadEndElement ();\r
-               }
-               \r               Header DeserializeHeader ()
-               {
-                       Header h = new Header (xmlReader.LocalName, null);
+               }\r
+               \r
+               Header DeserializeHeader ()\r
+               {\r
+                       Header h = new Header (xmlReader.LocalName, null);\r
                        h.HeaderNamespace = xmlReader.NamespaceURI;\r
                        h.MustUnderstand = xmlReader.GetAttribute ("mustUnderstand", SoapTypeMapper.SoapEnvelopeNamespace) == "1";\r
                        \r
@@ -344,11 +347,14 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        \r
                        // Get the array properties\r
                        string strArrayType = xmlReader["arrayType", SoapTypeMapper.SoapEncodingNamespace];\r
-                       string[] arrayInfo = strArrayType.Split(':','[',',',']');\r
-                       int numberOfDims = arrayInfo.Length - 3;\r
+                       string[] arrayInfo = strArrayType.Split(':');\r
+                       int arraySuffixInfo = arrayInfo[1].LastIndexOf('[');\r
+                       String arrayElementType = arrayInfo[1].Substring(0, arraySuffixInfo);\r
+                       String arraySuffix = arrayInfo[1].Substring(arraySuffixInfo);\r
+                       string[] arrayDims = arraySuffix.Substring(1,arraySuffix.Length-2).Trim().Split(',');\r
+                       int numberOfDims = arrayDims.Length;\r
                        int[] lengths = new int[numberOfDims];\r
-                       string[] arrayDims = new String[numberOfDims];\r
-                       Array.Copy(arrayInfo, 2, arrayDims, 0, numberOfDims);\r
+                       \r
                        for (int i=0; i < numberOfDims; i++)\r
                        {\r
                                lengths[i] = Convert.ToInt32(arrayDims[i]);\r
@@ -357,7 +363,7 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        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
@@ -432,13 +438,7 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                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
@@ -469,10 +469,13 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        bool NeedsSerializationInfo = false;\r
                        bool hasFixup;\r
 \r
-                       if(SoapTypeMapper.CanBeValue(type)) \r
+                       // in case of String & TimeSpan we should allways use 'ReadInternalSoapValue' method\r
+                       // in case of other internal types, we should use ReadInternalSoapValue' only if it is NOT\r
+                       // the root object, means it is a data member of another object that is being serialized.\r
+                       bool shouldReadInternal = (type == typeof(String) || type == typeof(TimeSpan) );\r
+                       if(shouldReadInternal || mapper.IsInternalSoapType (type) && (indices != null || parentMemberInfo != null) ) \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
@@ -593,7 +596,7 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        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
@@ -656,7 +659,9 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        if(componentId != 0)\r
                        {\r
                                // It's a string\r
-                               return xmlReader.ReadElementString();\r
+                               string str = xmlReader.ReadElementString();\r
+                               objMgr.RegisterObject (str, componentId);\r
+                               return str;\r
                        }\r
                        if(componentHref != 0)\r
                        {\r
@@ -749,6 +754,13 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        return tm;\r
                }\r
                \r
+               public Type GetTypeFromQName (string qname)\r
+               {\r
+                       string[] strName = qname.Split(':');\r
+                       string namespaceURI = xmlReader.LookupNamespace (strName[0]);\r
+                       return mapper.GetType (strName[1], namespaceURI);\r
+               }\r
+               \r
                #endregion\r
        }\r
 }\r