[Mono-list] SoapFormatter diff

Tim Haynes thaynes@openlinksw.com (Tim Haynes)
Thu, 17 Oct 2002 15:53:50 +0100


--=-=-=

Hi,

We've made System.Runtime.Serialization.Formatters.Soap.SoapFormatter work
- it now correctly executes the attached sample under mono/linux.

Please find a diff attached :)

Cheers,

~Tim
-- 
Product Development Consultant
OpenLink Software
Tel: +44 (0) 20 8681 7701
Web: <http://www.openlinksw.com>
Universal Data Access & Data Integration Technology Providers


--=-=-=
Content-Disposition: attachment; filename=SoapFormatter.diff
Content-Description: diff for SoapFormatter

Index: class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectDeserializer.cs
===================================================================
RCS file: /mono/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectDeserializer.cs,v
retrieving revision 1.2
diff -u -b -r1.2 ObjectDeserializer.cs
--- class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectDeserializer.cs	24 Aug 2002 10:39:22 -0000	1.2
+++ class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectDeserializer.cs	17 Oct 2002 13:33:39 -0000
@@ -13,6 +13,9 @@
 		const string basicassembly      = "mscorlib";
 		const string xmlnsassem         = "http://schemas.microsoft.com/clr/nsassem/";
 		const string xmlns              = "http://schemas.microsoft.com/clr/ns/";				
+		const string xmlns_SOAP_ENC	= "http://schemas.xmlsoap.org/soap/encoding/";
+		const string xmlns_SOAP_ENV	= "http://schemas.xmlsoap.org/soap/envelope/";
+
 		const string cTarget            = "Target";
 		const string cDelegatesClass    = "System.MulticastDelegate";
 		const string cMethodName        = "MethodName";
@@ -410,7 +413,7 @@
 
 		private string GetMainAssemblyFullNameFromXml(out string AssemblyName)
 		{
-			XmlNode SoapEnvNode= FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0);
+			XmlNode SoapEnvNode= FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0);
 			XmlNode MainObjectNode= SoapEnvNode.ChildNodes.Item(0);	
 			int StartIndex= MainObjectNode.Name.IndexOf(":");
 			string ClassName= MainObjectNode.Name.Substring(StartIndex + 1, MainObjectNode.Name.Length - StartIndex - 1);		
Index: class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectSerializer.cs
===================================================================
RCS file: /mono/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectSerializer.cs,v
retrieving revision 1.3
diff -u -b -r1.3 ObjectSerializer.cs
--- class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectSerializer.cs	24 Aug 2002 10:39:22 -0000	1.3
+++ class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectSerializer.cs	17 Oct 2002 13:33:44 -0000
@@ -9,6 +9,7 @@
 using System.Xml;
 using System.Reflection;
 using System.Collections;
+using System.Text;
 
 namespace System.Runtime.Serialization.Formatters.Soap
 {
@@ -17,15 +18,18 @@
 		/*******const's section******/		
 		const string cStringType       = "System.String";
 		const string startxmlns        = "xmlns:a";
-		const string startdoc          =  "<SOAP-ENV:Envelope " + 
+		const string startdoc_start    =  "<SOAP-ENV:Envelope " + 
 			"xmlns:xsi= \"http://www.w3.org/2001/XMLSchema-instance\""  + " " + 
 			"xmlns:xsd= \"http://www.w3.org/2001/XMLSchema\""            + " " + 
 			"xmlns:SOAP-ENC= \"http://schemas.xmlsoap.org/soap/encoding/\""  + " " + 
 			"xmlns:SOAP-ENV= \"http://schemas.xmlsoap.org/soap/envelope/\""  + " " + 
-			"SOAP-ENV:encodingStyle= \"http://schemas.xmlsoap.org/soap/encoding/\">" + " " + 
-			"<SOAP-ENV:Body>"    + " " + 
-			"</SOAP-ENV:Body>"   + " " + 
+			"SOAP-ENV:encodingStyle= \"http://schemas.xmlsoap.org/soap/encoding/\"" + " ";
+		const string startdoc_middle = ">" + " " + 
+			"<SOAP-ENV:Body>";
+		const string startdoc_end      =  "</SOAP-ENV:Body>"   + " " + 
 			"</SOAP-ENV:Envelope>";
+		const string xmlns_SOAP_ENC	= "http://schemas.xmlsoap.org/soap/encoding/";
+		const string xmlns_SOAP_ENV	= "http://schemas.xmlsoap.org/soap/envelope/";
 		const string xmlnsassem         = "http://schemas.microsoft.com/clr/nsassem/";
 		const string xmlns              = "http://schemas.microsoft.com/clr/ns/";
 		const string basicassembly      = "mscorlib";
@@ -45,18 +49,21 @@
 		public  ArrayList XmlObjectList; //the list of the xml representation of all objects 			    
 		private ArrayList FObjectList;   //the listof  the object been seralized
 		private SoapWriter ObjectWrt;
-		private string FCurrentXml;// the object's xml representation 
 		/******method's section******/
-		private void AddAssemblyToXml(string assemns)
+		private string ConcatAssembliesToXml()
 		{
-			XmlDocument xmldoc = new XmlDocument();			
-			xmldoc.LoadXml(FCurrentXml);
-			XmlElement RootElemt = xmldoc.DocumentElement;
-			string xmlns = startxmlns + AssemblyList.Count.ToString();
-			XmlAttribute NewAttr= xmldoc.CreateAttribute(xmlns);
-			RootElemt.SetAttributeNode(NewAttr);
-			RootElemt.SetAttribute(xmlns, assemns);
-			FCurrentXml= xmldoc.InnerXml;
+		  StringBuilder bld = new StringBuilder ();
+		  for (int inx = 1; inx <= AssemblyList.Count; inx++)
+		    {
+			string xmlns = startxmlns + inx.ToString();
+			string assemns = AssemblyList[inx - 1] as string;
+
+			bld.Append (xmlns);
+			bld.Append ("='");
+			bld.Append (assemns);
+			bld.Append ("'");
+		    }
+		  return bld.ToString();
 		}
 
 		private int AddAssembly(string assname, string nespname)			
@@ -71,7 +78,6 @@
 			if(Result< 0)	
 			{
 				Result= AssemblyList.Add(XmlAssNs);	 			  
-				AddAssemblyToXml(XmlAssNs);
 			}
 			return Result;
 		}
@@ -343,7 +349,6 @@
 
 		public void BeginWrite() //writes the basic elements of a soap message
 		{
-			FCurrentXml = startdoc;			
 		}
 
 		public ObjectSerializer(Stream store) //assign the current stream
@@ -361,13 +366,22 @@
 			AssemblyList.Clear();
 			XmlObjectList.Clear();			
 			FObjectList.Clear();			
-			FCurrentXml= "";
 		}
 
 		public void Serialize(object graph)
 		{ 			
 			SerializeObject(graph, 0); 
-			ObjectWrt.WriteObjectListToXml(FCurrentXml, FCurrentStream);                                                                                                                                                              
+	  		String FCurrentXml = 
+			    startdoc_start + 
+			    ConcatAssembliesToXml() +
+			    startdoc_middle +
+			    ObjectWrt.ConcatenateObjectList () +
+			    startdoc_end;
+			XmlDocument XmlDoc = new XmlDocument();
+			XmlDoc.LoadXml (FCurrentXml);
+			UTF8Encoding enc = new UTF8Encoding (false, true);
+			byte [] bytes = enc.GetBytes (XmlDoc.InnerXml);
+			FCurrentStream.Write (bytes, 0, bytes.Length);
 			CleatLists();
 		}
 	}
Index: class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs
===================================================================
RCS file: /mono/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs,v
retrieving revision 1.2
diff -u -b -r1.2 SoapReader.cs
--- class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs	24 Aug 2002 10:39:22 -0000	1.2
+++ class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs	17 Oct 2002 13:33:52 -0000
@@ -10,6 +10,8 @@
 	internal class SoapReader
 	{
 		/******const section******/
+		const string xmlns_SOAP_ENC	= "http://schemas.xmlsoap.org/soap/encoding/";
+		const string xmlns_SOAP_ENV	= "http://schemas.xmlsoap.org/soap/envelope/";
 
 		const string cSoapRef           = "href";
 		const string cObjectRef         = "ref-";
@@ -65,7 +67,7 @@
 		public string ReadReferenceFullNameFromXml(string RefereneId)
 		{
 			string RefId= cObjectRef + RefereneId;
-			XmlNodeList NodeList = FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0).ChildNodes;
+			XmlNodeList NodeList = FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0).ChildNodes;
 			bool Continue= true;
 			int index= 0;
 			string Result= "";
@@ -457,7 +459,7 @@
 		/**Assemblies reader**/
 		public string GetAssemblyNameFromId(int id)
 		{		  
-			XmlNodeList ObjList= ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0)).ChildNodes;
+			XmlNodeList ObjList= ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0)).ChildNodes;
 			bool Continue= true;
 			int index= 0;
 			string AssemblyName= "";
@@ -479,7 +481,7 @@
 
 		private string GetReferenceNameFromId(int id, ref XmlElement RefElement)
 		{
-			XmlNodeList ObjList= ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0)).ChildNodes;
+			XmlNodeList ObjList= ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0)).ChildNodes;
 			bool Continue= true;
 			int index= 0;
 			string Result= "";
@@ -536,7 +538,7 @@
 		public XmlElement GetCurrentElement(string ElementName, string ElementId)
 		{
 			string RefId= cObjectRef + ElementId;
-			XmlNodeList NodeList = ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("SOAP-ENV:Body").Item(0)).GetElementsByTagName(ElementName);
+			XmlNodeList NodeList = ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0)).GetElementsByTagName(ElementName);
 			bool Continue= true;
 			int index= 0;
 			string Result= "";
Index: class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs
===================================================================
RCS file: /mono/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs,v
retrieving revision 1.3
diff -u -b -r1.3 SoapWriter.cs
--- class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs	24 Aug 2002 10:39:22 -0000	1.3
+++ class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs	17 Oct 2002 13:33:55 -0000
@@ -17,7 +17,10 @@
 		{		
 			/******const section******/
 			const string cNullObject     = "xsi:null=\"1\"/";
-			const string cSoapEnv        = "SOAP-ENV:Body";
+			const string cSoapEnv        = "Body";
+			const string xmlns_SOAP_ENC	= "http://schemas.xmlsoap.org/soap/encoding/";
+			const string xmlns_SOAP_ENV	= "http://schemas.xmlsoap.org/soap/envelope/";
+			
 			const string cStartTag       = "<";
 			const string cEndTag         = ">";
 			const string cNumber         = "#";
@@ -37,7 +40,7 @@
 			public ArrayList FXmlObjectList;
 			public  int FReferenceNumber;
 			/******method's section******/
-			private string ConcatenateObjectList()
+			public string ConcatenateObjectList()
 			{
 				string XmlResult= "";
 				object[] XmlList= FXmlObjectList.ToArray();
@@ -160,18 +163,6 @@
 			public void WriteStructTypeToXml(string StructName)
 			{
 			}		
-
-			public void WriteObjectListToXml(string SoapDoc, Stream SoapStream)
-			{
-				string XmlResult= ConcatenateObjectList();
-				XmlDocument XmlDoc= new XmlDocument();
-				XmlDoc.LoadXml(SoapDoc);			
-				XmlNode XNode= XmlDoc.DocumentElement.GetElementsByTagName(cSoapEnv).Item(0);
-				XNode.InnerXml= XmlResult;
-				StreamWriter SoapWrt= new StreamWriter(SoapStream);
-				SoapWrt.Write(XmlDoc.InnerXml);
-				SoapWrt.Close();				
-			}
 
 			public string GenerateSchemaArrayType(string ArrayType, int ArrayLength, int AssemblyIndex)
 			{
Index: class/System.XML/System.Xml/XmlDocument.cs
===================================================================
RCS file: /mono/mcs/class/System.XML/System.Xml/XmlDocument.cs,v
retrieving revision 1.38
diff -u -b -r1.38 XmlDocument.cs
--- class/System.XML/System.Xml/XmlDocument.cs	12 Oct 2002 22:17:24 -0000	1.38
+++ class/System.XML/System.Xml/XmlDocument.cs	17 Oct 2002 13:34:17 -0000
@@ -349,8 +349,20 @@
 		public virtual XmlNodeList GetElementsByTagName (string name)
 		{
 			ArrayList nodeArrayList = new ArrayList ();
-			this.searchNodesRecursively (this, name, String.Empty, nodeArrayList);
+			this.searchNodesRecursively (this, name, nodeArrayList);
 			return new XmlNodeArrayList (nodeArrayList);
+		}
+
+		private void searchNodesRecursively (XmlNode argNode, string argName, 
+			ArrayList argArrayList)
+		{
+			XmlNodeList xmlNodeList = argNode.ChildNodes;
+			foreach (XmlNode node in xmlNodeList){
+				if (node.Name.Equals (argName))
+					argArrayList.Add (node);
+				else	
+					this.searchNodesRecursively (node, argName, argArrayList);
+			}
 		}
 
 		private void searchNodesRecursively (XmlNode argNode, string argName, string argNamespaceURI, 
Index: class/System.XML/System.Xml/XmlElement.cs
===================================================================
RCS file: /mono/mcs/class/System.XML/System.Xml/XmlElement.cs,v
retrieving revision 1.30
diff -u -b -r1.30 XmlElement.cs
--- class/System.XML/System.Xml/XmlElement.cs	21 Sep 2002 04:20:31 -0000	1.30
+++ class/System.XML/System.Xml/XmlElement.cs	17 Oct 2002 13:34:17 -0000
@@ -178,8 +178,20 @@
 		public virtual XmlNodeList GetElementsByTagName (string name)
 		{
 			ArrayList nodeArrayList = new ArrayList ();
-			this.searchNodesRecursively (this, name, String.Empty, nodeArrayList);
+			this.searchNodesRecursively (this, name, nodeArrayList);
 			return new XmlNodeArrayList (nodeArrayList);
+		}
+
+		private void searchNodesRecursively (XmlNode argNode, string argName, 
+			ArrayList argArrayList)
+		{
+			XmlNodeList xmlNodeList = argNode.ChildNodes;
+			foreach (XmlNode node in xmlNodeList){
+				if (node.Name.Equals (argName))
+					argArrayList.Add (node);
+				else	
+					this.searchNodesRecursively (node, argName, argArrayList);
+			}
 		}
 
 		private void searchNodesRecursively (XmlNode argNode, string argName, string argNamespaceURI, 
Index: class/System.XML/System.Xml/XmlTextWriter.cs
===================================================================
RCS file: /mono/mcs/class/System.XML/System.Xml/XmlTextWriter.cs,v
retrieving revision 1.24
diff -u -b -r1.24 XmlTextWriter.cs
--- class/System.XML/System.Xml/XmlTextWriter.cs	23 Sep 2002 00:39:30 -0000	1.24
+++ class/System.XML/System.Xml/XmlTextWriter.cs	17 Oct 2002 13:34:22 -0000
@@ -556,6 +556,8 @@
 				{
 					string existingPrefix = namespaceManager.LookupPrefix (ns);
 
+					if (existingPrefix == String.Empty && !namespaceManager.HasNamespace (prefix))
+					  namespaceManager.AddNamespace (prefix, ns);
 					if (prefix == String.Empty)
 						prefix = existingPrefix;
 
Index: class/System.XML/System.Xml/XmlWriter.cs
===================================================================
RCS file: /mono/mcs/class/System.XML/System.Xml/XmlWriter.cs,v
retrieving revision 1.11
diff -u -b -r1.11 XmlWriter.cs
--- class/System.XML/System.Xml/XmlWriter.cs	26 Aug 2002 03:14:30 -0000	1.11
+++ class/System.XML/System.Xml/XmlWriter.cs	17 Oct 2002 13:34:22 -0000
@@ -63,7 +63,13 @@
 		public void WriteAttributeString (string prefix, string localName, string ns, string value)
 		{
 			if ((prefix == "xmlns") || (localName == "xmlns"))
+			  {
 				ns = value;
+				if (prefix == "xmlns" && namespaceManager.HasNamespace (localName))
+				  return;
+				else if (localName == "xmlns" && namespaceManager.HasNamespace (String.Empty))
+				  return;
+			  }
 			
 			WriteStartAttribute (prefix, localName, ns);
 			WriteString (value);

--=-=-=
Content-Disposition: attachment; filename=Class1.cs
Content-Description: sample to test SoapFormatter

using System;
using System.IO;

namespace testit
{
  [Serializable] public class SPoint
    {
      public Double x = 1;
      public Double y = 2;
      public SPoint () {;}
    }
  class Class1
    {

      static void serialize()
	{
	  System.Runtime.Serialization.IFormatter xx = 
	      new System.Runtime.Serialization.Formatters.Soap.SoapFormatter ();
	  FileStream _out = new FileStream ("out.xml", FileMode.Create, FileAccess.Write, FileShare.None);
	  xx.Serialize (_out, new SPoint());
	}
      static void deserialize()
	{
	  System.Runtime.Serialization.IFormatter xx = 
	      new System.Runtime.Serialization.Formatters.Soap.SoapFormatter ();
	  FileStream _out = new FileStream ("out.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
	  SPoint ob = xx.Deserialize (_out) as SPoint;
	  Console.WriteLine (ob.x);
	}
      public static void Main (String [] args)
	{
	  if (args.Length > 0)
	    deserialize();
	  else
	    serialize();
	}
    }
}

--=-=-=--