2004-04-15 Jean-Marc Andre <jeanmarc.andre@cpe.fr>
authorJean-Marc Andre <jeanmarc@mono-cvs.ximian.com>
Thu, 15 Apr 2004 21:48:37 +0000 (21:48 -0000)
committerJean-Marc Andre <jeanmarc@mono-cvs.ximian.com>
Thu, 15 Apr 2004 21:48:37 +0000 (21:48 -0000)
* SoapFormatter.cs, SoapWriter.cs, SoapReader.cs, SoapTypeMapper.cs:
Some parts of the code have been rewritten to make it easier
to understand and maintain.
AssemblyFormat and TypeFormat are implemented.
* ISoapParser.cs, ISoapReader.cs, ISoapWriter.cs, SoapCommon.cs,
ObjectReader.cs, ObjectWriter.cs, SoapParser.cs, SoapTypeMapping.cs:
Removed for the same reasons as above.
* SerializationTest.cs:
New unit test.

svn path=/trunk/mcs/; revision=25570

19 files changed:
mcs/class/System.Runtime.Serialization.Formatters.Soap/ChangeLog
mcs/class/System.Runtime.Serialization.Formatters.Soap/Soap.cmbx [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap.dll.sources
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapParser.cs [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapReader.cs [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapWriter.cs [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectReader.cs [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectWriter.cs [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapCommon.cs [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapFormatter.cmbx [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapFormatter.cs
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapFormatter.prjx [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapParser.cs [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapReader.cs
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapTypeMapper.cs
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapTypeMapping.cs [deleted file]
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs
mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap_test.dll.sources
mcs/class/System.Runtime.Serialization.Formatters.Soap/Test/SerializationTest.cs [new file with mode: 0644]

index af47fbf379ac727adce70aeb5dd5dcfb0ab3aaed..574ae0e104bf1fdcd0e62377e8697e279cfea659 100644 (file)
@@ -1,3 +1,15 @@
+2004-04-15  Jean-Marc Andre <jeanmarc.andre@cpe.fr>
+       * SoapFormatter.cs, SoapReader.cs, SoapWriter.cs, SoapTypeMapper.cs:
+               Rewrote almost completly to make the code easier to understand
+               and maintain.
+               AssemblyFormat and TypeFormat are now implemented.
+       * SoapParser.cs, ObjectReader.cs, ObjectWriter.cs, SoapCommon.cs,
+       ISoapParser.cs, ISoapReader.cs, ISoapWriter.cs:
+               Removed for the same reasons as above.
+       * SerializationTest.cs:
+               New unit test inspired by the one developped by Lluis Sanchez
+               for the BinaryFormatter.
+
 2004-03-31  Andreas Nahr <ClassDevelopment@A-SoftTech.com>
 
        * System.Runtime.Serialization.Formatters.Soap.dll.sources:
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/Soap.cmbx b/mcs/class/System.Runtime.Serialization.Formatters.Soap/Soap.cmbx
deleted file mode 100644 (file)
index a8bef79..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<Combine fileversion="1.0" name="Soap" description="">\r
-  <StartMode startupentry="Test" single="True">\r
-    <Execute entry="SoapFormatter" type="None" />\r
-    <Execute entry="Test" type="None" />\r
-  </StartMode>\r
-  <Entries>\r
-    <Entry filename=".\System.Runtime.Serialization.Formatters.Soap\SoapFormatter.prjx" />\r
-    <Entry filename=".\Test\Test.prjx" />\r
-  </Entries>\r
-  <Configurations active="Debug">\r
-    <Configuration name="Release">\r
-      <Entry name="SoapFormatter" configurationname="Debug" build="False" />\r
-      <Entry name="SoapFormatter" configurationname="Debug" build="False" />\r
-    </Configuration>\r
-    <Configuration name="Debug">\r
-      <Entry name="SoapFormatter" configurationname="Debug" build="False" />\r
-      <Entry name="SoapFormatter" configurationname="Debug" build="False" />\r
-    </Configuration>\r
-  </Configurations>\r
-</Combine>
\ No newline at end of file
index cbbb2d82b168ef39f91110fad2ea9d4b55c81a2d..7fd87f5c68974922ab554346f5d1f2c3751c4b99 100644 (file)
@@ -1,15 +1,7 @@
 Assembly/AssemblyInfo.cs
 Assembly/Locale.cs
 System.Runtime.Serialization.Formatters.Soap/SoapWriter.cs
-System.Runtime.Serialization.Formatters.Soap/ISoapParser.cs
-System.Runtime.Serialization.Formatters.Soap/ISoapReader.cs
-System.Runtime.Serialization.Formatters.Soap/ISoapWriter.cs
-System.Runtime.Serialization.Formatters.Soap/ObjectReader.cs
-System.Runtime.Serialization.Formatters.Soap/ObjectWriter.cs
-System.Runtime.Serialization.Formatters.Soap/SoapCommon.cs
-System.Runtime.Serialization.Formatters.Soap/SoapParser.cs
 System.Runtime.Serialization.Formatters.Soap/SoapReader.cs
 System.Runtime.Serialization.Formatters.Soap/SoapTypeMapper.cs
-System.Runtime.Serialization.Formatters.Soap/SoapTypeMapping.cs
 System.Runtime.Serialization.Formatters.Soap/SoapFormatter.cs
 System.Runtime.Serialization.Formatters.Soap/TODOAttribute.cs
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapParser.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapParser.cs
deleted file mode 100644 (file)
index b5e10bc..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// created on 23/04/2003 at 12:05\r
-//\r
-//     System.Runtime.Serialization.Formatters.Soap.ISoapParser\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-using System;\r
-using System.Collections;\r
-using System.IO;\r
-\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       internal interface ISoapParser {\r
-               void Run();\r
-               Stream InStream {\r
-                       set;\r
-               }\r
-               event SoapElementReadEventHandler SoapElementReadEvent;\r
-       }\r
-}\r
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapReader.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapReader.cs
deleted file mode 100644 (file)
index 8ce8283..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// created on 24/04/2003 at 15:37\r
-//\r
-//     System.Runtime.Serialization.Formatters.Soap.ISoapReader\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Runtime.Serialization;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       \r
-       internal interface ISoapReader {\r
-               event ElementReadEventHandler ElementReadEvent;\r
-               ISoapMessage TopObject {\r
-                       get; set;\r
-               }\r
-       }\r
-}\r
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapWriter.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ISoapWriter.cs
deleted file mode 100644 (file)
index 94b2e3f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// created on 07/04/2003 at 17:49\r
-//\r
-//     System.Runtime.Serialization.Formatters.Soap.ISoapWriter\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Reflection;\r
-using System.Runtime.Serialization;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       interface ISoapWriter {\r
-               void WriteRoot(object objValue, Type objType, bool getIntoFields);\r
-               void WriteFields(SerializationInfo info);\r
-               \r
-               void WriteArrayItem(Type itemType, object itemValue);\r
-               object TopObject {\r
-                       set;\r
-               }\r
-               void Run();\r
-               event DoneWithElementEventHandler DoneWithElementEvent;\r
-               event DoneWithElementEventHandler DoneWithArray;\r
-               event DoneWithElementEventHandler GetRootInfo;\r
-               ObjectWriter Writer {\r
-                       get; set;\r
-               }\r
-               \r
-               Stack CurrentArrayType {\r
-                       get;\r
-               }\r
-       }\r
-}\r
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectReader.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectReader.cs
deleted file mode 100644 (file)
index cee7b81..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-// created on 20/04/2003 at 19:51\r
-//\r
-//     System.Runtime.Serialization.Formatters.Soap.ObjectReader\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Reflection;\r
-using System.Runtime.Remoting;\r
-using System.Runtime.Serialization;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       internal sealed class ObjectReader {\r
-               private object _topObject;\r
-               private ObjectManager _manager;\r
-               private ISurrogateSelector _surrogateSelector;\r
-               private StreamingContext _context;\r
-               private long _nonId = 0;\r
-               private long _topObjectId =0;\r
-               private const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;\r
-               \r
-               public ObjectReader(ISurrogateSelector selector, StreamingContext context, ISoapReader reader) {\r
-                       \r
-                       _topObject = null;\r
-                       reader.ElementReadEvent += new ElementReadEventHandler(RootElementRead);\r
-                       _surrogateSelector = selector;\r
-                       _context = context;\r
-                       _manager = new ObjectManager(selector, context);\r
-               }\r
-\r
-               public object TopObject {\r
-                       get {\r
-//                             _manager.RaiseDeserializationEvent();\r
-                               _manager.DoFixups();\r
-                               _manager.RaiseDeserializationEvent();\r
-                               _topObject =_manager.GetObject(_topObjectId);\r
-                               return _topObject;\r
-                       }\r
-               }\r
-               \r
-               private long GetNextId() {\r
-                       return Int64.MaxValue ^ ++_nonId;\r
-               }\r
-               \r
-               // sometimes, the root object doesn't have an id\r
-               // An id has to be created to register the object\r
-               // with the ObjectManager\r
-               // If the root object is a SoapMessage. It has to be handle\r
-               // in a different way\r
-               public void RootElementRead(ISoapReader sender, ElementReadEventArgs e) {\r
-                       ElementReadEventArgs args = e;\r
-                       sender.ElementReadEvent -= new ElementReadEventHandler(RootElementRead);\r
-                       sender.ElementReadEvent += new ElementReadEventHandler(ElementRead);\r
-                       ElementInfo rootInfo = e.RootElement;\r
-                       rootInfo._i = (rootInfo._i !=0)?rootInfo._i:GetNextId();\r
-                       if(_topObjectId == 0){\r
-                               _topObjectId = rootInfo._i;\r
-                       }\r
-                       args.RootElement = rootInfo;\r
-                       if(rootInfo._type == typeof(SoapMessage)) RPCHandler(args);\r
-                       else ElementRead(sender, args);\r
-\r
-               }\r
-               \r
-               private void RPCHandler(ElementReadEventArgs e) {\r
-                       ElementInfo rpcInfo = e.RootElement;\r
-                       SoapMessage soapMessage = (SoapMessage) rpcInfo._value;\r
-                       \r
-                       \r
-                       // register the SoapMessage\r
-                       _manager.RegisterObject(soapMessage, 1);\r
-                       \r
-                       int count = e.FieldsInfo.Count;\r
-                       soapMessage.ParamNames = new string[count];\r
-                       soapMessage.ParamTypes = new Type[count];\r
-                       soapMessage.ParamValues = new object[count];\r
-                       \r
-                       long paramValuesId = GetNextId();\r
-                       _manager.RegisterObject(soapMessage.ParamValues, paramValuesId);\r
-                       soapMessage.ParamNames = FixupArrayItems(paramValuesId, e.FieldsInfo);\r
-                       \r
-                       \r
-                       \r
-               }\r
-               \r
-               public void ElementRead(ISoapReader sender, ElementReadEventArgs e) {\r
-                       ElementInfo rootInfo = e.RootElement;\r
-                       \r
-                       object objRoot = FillObject(rootInfo._type, rootInfo._value, rootInfo._arrayDims);\r
-                       SerializationInfo serializationInfo = null;\r
-                       if(_surrogateSelector != null) {\r
-                               ISurrogateSelector selector;\r
-                               ISerializationSurrogate surrogate = _surrogateSelector.GetSurrogate(rootInfo._type, _context, out selector);\r
-                               if(surrogate != null) {\r
-                                       serializationInfo = new SerializationInfo(rootInfo._type, new FormatterConverter());\r
-                               }\r
-                       }\r
-                       if(rootInfo._type.GetInterface("System.Runtime.Serialization.ISerializable") != null) serializationInfo = new SerializationInfo(rootInfo._type, new FormatterConverter());\r
-                       _manager.RegisterObject(objRoot, rootInfo._i, serializationInfo);\r
-                       \r
-                       if(objRoot.GetType().IsArray){\r
-                               FixupArrayItems(rootInfo._i, e.FieldsInfo);\r
-                       }else {\r
-                               FixupFields(rootInfo._i, objRoot, rootInfo._type, e.FieldsInfo, serializationInfo);\r
-                       }\r
-               }\r
-               \r
-               private object FillObject(Type objType, object objValue) {\r
-                       return FillObject(objType, objValue, null);\r
-               }\r
-               \r
-               // a helper function to create the right object and fill\r
-               // it with the value\r
-               private object FillObject(Type objType, object objValue, int[] arrayDims) {\r
-                       object returnObject;\r
-                       if(objType == null){ \r
-                               return objValue;\r
-                       }else if(objValue != null){\r
-                               returnObject = (new FormatterConverter()).Convert(objValue, objType);\r
-                       }else if(objType.IsArray){\r
-                               returnObject = Array.CreateInstance(objType.GetElementType(), arrayDims);\r
-                       }\r
-                       else if(objType == typeof(string)) {\r
-                               returnObject = "";\r
-                       }\r
-                       else returnObject = FormatterServices.GetUninitializedObject(objType);\r
-                       \r
-                       return returnObject;\r
-               }\r
-                               \r
-               private void FixupFields(long objectToBeFixedId, object objectToBeFixed, Type objectToBeFixedType, ICollection fieldsInfo, SerializationInfo serializationInfo) {\r
-                       object objValue;\r
-                       foreach(ElementInfo fieldInfo in fieldsInfo) {\r
-                               switch (fieldInfo._elementType) {\r
-                                       case ElementType.Href:\r
-                                               FieldInfo memberInfo = (objectToBeFixedType != null)?objectToBeFixedType.GetField(fieldInfo._name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic):null;\r
-                                               // check is the object referenced has already been registered\r
-                                               if((objValue = _manager.GetObject(fieldInfo._i)) != null) {\r
-                                                       if(serializationInfo != null) {\r
-                                                               serializationInfo.AddValue(fieldInfo._name, objValue, objValue.GetType());\r
-                                                       }\r
-                                                       else memberInfo.SetValue(objectToBeFixed, objValue, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, null);\r
-                                               }\r
-                                               else\r
-                                                       RecordFixup(objectToBeFixedId, fieldInfo._name,  fieldInfo._i, memberInfo, serializationInfo);\r
-                                               break;\r
-                                       case ElementType.Id:\r
-                                               objValue = (fieldInfo._value != null)?fieldInfo._value:String.Empty;\r
-                                               memberInfo = objectToBeFixedType.GetField(fieldInfo._name, bindingFlags);\r
-                                               if(serializationInfo == null) {\r
-                                                       memberInfo.SetValue(objectToBeFixed, objValue, bindingFlags, null, null);\r
-                                               }\r
-                                               else\r
-                                                       RecordFixup(objectToBeFixedId, fieldInfo._name, fieldInfo._i, null, serializationInfo);\r
-                                               _manager.RegisterObject(objValue, fieldInfo._i, null, objectToBeFixedId, memberInfo);\r
-                                               break;\r
-                                       case ElementType.Nothing:\r
-                                               if(serializationInfo != null) {\r
-                                                       // we don't know the type of the field\r
-                                                       // The converter should do the job during the deserialzation\r
-                                                       serializationInfo.AddValue(fieldInfo._name, fieldInfo._value, typeof(string));\r
-                                               }\r
-                                               else {\r
-                                                       memberInfo = objectToBeFixed.GetType().GetField(fieldInfo._name, bindingFlags);\r
-                                                       objValue = FillObject((fieldInfo._type != null)?fieldInfo._type:memberInfo.FieldType, fieldInfo._value);\r
-                                                       memberInfo.SetValue(objectToBeFixed, objValue, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, null);\r
-                                               }\r
-                                               break;\r
-                                       case ElementType.Null:\r
-                                               if(serializationInfo != null) {\r
-                                                       serializationInfo.AddValue(fieldInfo._name, null, typeof(System.Object));\r
-                                               }\r
-                                               break;\r
-                               }\r
-                       }\r
-                       \r
-               }\r
-               \r
-               private void RecordFixup(long objectToBeFixedId, string memberName, long objId, MemberInfo memberInfo, SerializationInfo serializationInfo) {\r
-                       if(serializationInfo != null) {\r
-                               _manager.RecordDelayedFixup(objectToBeFixedId, memberName, objId);\r
-                       }\r
-                       else {\r
-                               _manager.RecordFixup(objectToBeFixedId, memberInfo, objId);\r
-                               \r
-                       }\r
-               }\r
-               \r
-               private String[] FixupArrayItems(long arrayToBeFixedId, ICollection arrayItemsInfo) {\r
-                       ArrayList arrayNames = new ArrayList(arrayItemsInfo.Count);\r
-                       System.Array array = (System.Array) _manager.GetObject(arrayToBeFixedId);\r
-//                     if(array.Length == 0) return null;\r
-                       int[] indices = new int[array.Rank];\r
-                       for(int dim=array.Rank-1; dim>=0; dim--){\r
-                               indices[dim] = array.GetLowerBound(dim);\r
-                       }\r
-                       object objValue;\r
-                       Type arrayElementType = array.GetType().GetElementType();\r
-                       Type specificElementType;\r
-                       IEnumerator iEnum = arrayItemsInfo.GetEnumerator();\r
-                       while(iEnum.MoveNext()) {\r
-                               ElementInfo arrayItemInfo = (ElementInfo) iEnum.Current;\r
-                               arrayNames.Add(arrayItemInfo._name);\r
-                               specificElementType = (arrayItemInfo._type != null) ? arrayItemInfo._type : arrayElementType;\r
-                               switch(arrayItemInfo._elementType) {\r
-                                       case ElementType.Href:\r
-                                               if((objValue = _manager.GetObject(arrayItemInfo._i)) != null) {\r
-                                                       if(array.Rank == 1) array.SetValue(objValue, indices[0]);\r
-                                                       else array.SetValue(objValue, indices);\r
-                                               }\r
-                                               else\r
-                                                       RecordArrayElementFixup(arrayToBeFixedId, indices, arrayItemInfo._i);                                           \r
-                                               break;\r
-                                       case ElementType.Id:\r
-                                               objValue = FillObject(specificElementType, arrayItemInfo._value);\r
-                                               RecordArrayElementFixup(arrayToBeFixedId, indices, arrayItemInfo._i);\r
-                                               _manager.RegisterObject(objValue, arrayItemInfo._i, null, arrayToBeFixedId, null, indices);\r
-                                               break;\r
-                                       case ElementType.Nothing:\r
-                                               //should be a value type\r
-                                               objValue = FillObject(specificElementType, arrayItemInfo._value);\r
-                                               if(specificElementType.IsValueType && !specificElementType.IsPrimitive) {\r
-                                                       long id;\r
-                                                       objValue = FillValueTypeObject(iEnum, objValue, 0, out id);\r
-                                                       RecordArrayElementFixup(arrayToBeFixedId, indices, id);\r
-                                               }else {\r
-                                                       if(array.Rank == 1) array.SetValue(objValue, indices[0]);\r
-                                                       else array.SetValue(objValue, indices);\r
-                                               }\r
-                                               break;\r
-                                       case ElementType.Null:\r
-                                               break;\r
-                               }\r
-                               bool end = FillIndices(array, ref indices);\r
-                       }\r
-                       string[] aNames = (string[]) arrayNames.ToArray(typeof(string));\r
-                       return aNames;\r
-               }\r
-               \r
-               private bool FillIndices(System.Array array, ref int[] indices) {\r
-                       indices = (int[])indices.Clone();\r
-                       int rank = array.Rank;\r
-                       for(int dim = rank-1; dim>=0; dim--) {\r
-                               indices[dim]++;\r
-                               if(indices[dim] > array.GetUpperBound(dim)){\r
-                                       if(dim > 0){\r
-                                               indices[dim] = array.GetLowerBound(dim);\r
-                                               continue;\r
-                                       }\r
-                                       return false;\r
-                               }\r
-                               break;\r
-                       }\r
-                       return true;\r
-               }\r
-               \r
-               private object FillValueTypeObject(IEnumerator e, object valueTypeObject, long id, out long returnId){\r
-                       MemberInfo[] fieldInfo = FormatterServices.GetSerializableMembers(valueTypeObject.GetType(), _context);\r
-                       Queue fieldsInfo = new Queue(fieldInfo.Length);\r
-                       returnId = (id != 0)?id:GetNextId();\r
-                       ElementInfo rootElement = new ElementInfo(valueTypeObject.GetType(), null, null, ElementType.Id, returnId, null);\r
-                       \r
-               //      e.MoveNext();\r
-                       for(int i = 0; i < fieldInfo.Length; i++) {\r
-                               e.MoveNext();\r
-                               fieldsInfo.Enqueue(e.Current);\r
-                       }\r
-                       ElementReadEventArgs args = new ElementReadEventArgs(rootElement, fieldsInfo);\r
-                       \r
-                       ElementRead(null, args);\r
-                       \r
-                       return  _manager.GetObject(returnId);\r
-               }\r
-               \r
-               private void RecordArrayElementFixup(long arrayToBeFixed, int[] indices, long objId) {\r
-                       int[] index = (int[]) indices.Clone();\r
-                       if(indices.Length == 1) {\r
-                               _manager.RecordArrayElementFixup(arrayToBeFixed, index[0], objId);\r
-                       }\r
-                       else\r
-                               _manager.RecordArrayElementFixup(arrayToBeFixed, index, objId);\r
-                               \r
-               }\r
-       }\r
-}\r
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectWriter.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/ObjectWriter.cs
deleted file mode 100644 (file)
index 5e9adeb..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// created on 07/04/2003 at 17:46\r
-//\r
-//     System.Runtime.Serialization.Formatters.Soap.ObjectWriter\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Reflection;\r
-using System.Runtime.Serialization;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       \r
-       internal sealed class ObjectWriter {\r
-               private ISoapWriter _soapWriter;\r
-               private object _objGraph;\r
-               private ISurrogateSelector _selector;\r
-               private StreamingContext _context;\r
-               private SerializationInfo _serializationInfo;\r
-               \r
-               internal ObjectWriter(ISoapWriter soapWriter, ISurrogateSelector selector, StreamingContext context) {\r
-                       _soapWriter = soapWriter;\r
-                       _selector = selector;\r
-                       _context = context;\r
-               }\r
-               \r
-               internal void Serialize(object objGraph) {\r
-                       if(objGraph == null)\r
-                               throw new ArgumentNullException("objGraph");\r
-                       _objGraph = objGraph;\r
-                       _soapWriter.DoneWithElementEvent += new DoneWithElementEventHandler(GetFieldsElement);\r
-                       _soapWriter.DoneWithArray += new DoneWithElementEventHandler(GetArrayItems);\r
-                       _soapWriter.GetRootInfo += new DoneWithElementEventHandler(GetRootInfo);\r
-                       \r
-                       _soapWriter.TopObject = objGraph;\r
-                       _soapWriter.Run();\r
-                       \r
-               }\r
-               \r
-               internal void GetRootInfo(ISoapWriter sender, DoneWithElementEventArgs e) {\r
-                       object objCurrent = (e != null)?e.Current:null;\r
-                       Type currentType = objCurrent.GetType();\r
-                       _serializationInfo = new SerializationInfo(currentType, new FormatterConverter());\r
-                       if(_selector != null) {\r
-                               ISurrogateSelector selector;\r
-                               ISerializationSurrogate surrogate = _selector.GetSurrogate(currentType, _context, out selector);\r
-                               \r
-                               if(surrogate != null) {\r
-                                       surrogate.GetObjectData(objCurrent, _serializationInfo, _context);\r
-                               }\r
-                       }\r
-                       ISerializable ser = objCurrent as ISerializable;\r
-                       if(ser != null && _serializationInfo.MemberCount == 0){\r
-                               ser.GetObjectData(_serializationInfo, _context);\r
-                       }\r
-                       if(_serializationInfo.MemberCount == 0) {\r
-                               MemberInfo[] fieldInfoArray = FormatterServices.GetSerializableMembers(currentType, _context);//currentType.GetFields(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.FlattenHierarchy);\r
-                               object[] values = FormatterServices.GetObjectData(objCurrent, fieldInfoArray);\r
-                               for(int i = 0; i <      fieldInfoArray.Length; i++){\r
-                                       FieldInfo fieldInfo = fieldInfoArray[i] as FieldInfo;\r
-                                       if(fieldInfo != null){\r
-                                               object fieldValue = fieldInfo.GetValue(objCurrent);\r
-                                               Type fieldType;\r
-                                               fieldType = fieldInfo.FieldType;\r
-                                               _serializationInfo.AddValue(fieldInfo.Name, fieldValue, fieldType);\r
-                                       }\r
-                               }\r
-                       }else {\r
-                               currentType = Type.GetType(_serializationInfo.FullTypeName);\r
-                       }\r
-                       Type objType = Type.GetType(_serializationInfo.FullTypeName);\r
-                       \r
-                       // FIXME: we should store the type name returned by FullTypeName, no need to\r
-                       // get the type again!! (Lluis)\r
-                       \r
-                       //if objType == null\r
-                       // try to load the proper assembly\r
-                       if(objType == null)     objType = FormatterServices.GetTypeFromAssembly(currentType.Assembly, _serializationInfo.FullTypeName);\r
-                       sender.WriteRoot(objCurrent,  objType,(!(objCurrent is string) && _serializationInfo.MemberCount > 0) || objCurrent is Array);\r
-               }\r
-               \r
-               internal void GetFieldsElement(ISoapWriter sender, DoneWithElementEventArgs e) {\r
-                       sender.WriteFields(_serializationInfo);\r
-               }\r
-               \r
-               internal void GetArrayItems(ISoapWriter sender, DoneWithElementEventArgs e) {\r
-                       Array array = (Array)e.Current;\r
-                       Type arrayElementType = array.GetType().GetElementType();\r
-                       sender.CurrentArrayType.Push(arrayElementType);\r
-                       int count = 0;\r
-                       int lastNotNullItem = 0;\r
-                       foreach(object i in array){\r
-                               count++;\r
-                               if(i != null) lastNotNullItem = count;\r
-//                             if(item != null) sender.WriteField(item.GetType(), "item", item, e.IsAnyTypeArray);\r
-                       }\r
-                       IEnumerator iEnum = array.GetEnumerator();\r
-                       iEnum.Reset();\r
-                       for(int i = 0; i < lastNotNullItem; i++) {\r
-                               iEnum.MoveNext();\r
-                               object item = iEnum.Current;\r
-                               if(item != null) sender.WriteArrayItem(item.GetType(), item);\r
-                               else sender.WriteArrayItem(arrayElementType, null);\r
-                       }\r
-                       \r
-                       sender.CurrentArrayType.Pop();\r
-                       \r
-                       \r
-               }\r
-               \r
-               public ISurrogateSelector SurrogateSelector {\r
-                       get {\r
-                               return _selector;\r
-                       }\r
-                       set {\r
-                               _selector = value;\r
-                       }\r
-               }\r
-               \r
-       }\r
-}\r
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapCommon.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapCommon.cs
deleted file mode 100644 (file)
index e1efeed..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// created on 16/04/2003 at 17:27\r
-//\r
-//     Contains classes, structs, delegates, enums used\r
-//  by the other classes\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-using System;\r
-using System.Collections;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       internal delegate void SoapElementReadEventHandler(ISoapParser sender, SoapElementReadEventArgs e);\r
-       \r
-       internal class SoapElementReadEventArgs: EventArgs {\r
-               private Queue _elementQueue;\r
-               \r
-               public SoapElementReadEventArgs(Queue elementQueue) {\r
-                       _elementQueue = elementQueue;\r
-               }\r
-               \r
-               public Queue ElementQueue {\r
-                       get { return _elementQueue;}\r
-               }\r
-       }\r
-       \r
-       \r
-       internal enum ElementType {\r
-               Id, Href, Null, Nothing\r
-       }\r
-       internal struct ElementInfo {\r
-               public Type _type;\r
-               public object _value;\r
-               public ElementType _elementType;\r
-               public long _i;\r
-               public string _name;\r
-               public int[] _arrayDims;\r
-               \r
-               public ElementInfo (Type objType, string name, object objValue, ElementType elementType, long i, int[] arrayDims) {\r
-                       _name = name;\r
-                       _type = objType;\r
-                       _value = objValue;\r
-                       _elementType = elementType;\r
-                       _i = i;\r
-                       _arrayDims = arrayDims;\r
-               }\r
-       }\r
-       internal delegate void ElementReadEventHandler(ISoapReader sender, ElementReadEventArgs e);\r
-       \r
-       internal class ElementReadEventArgs: EventArgs {\r
-               private ElementInfo _rootElement;\r
-               private Queue _fieldsInfo;\r
-               \r
-               public ElementReadEventArgs(ElementInfo rootElement, Queue fieldsInfo) {\r
-                       _rootElement = rootElement;\r
-                       _fieldsInfo = fieldsInfo;\r
-               }\r
-               \r
-               public ElementInfo RootElement {\r
-                       get { return _rootElement;}\r
-                       set { _rootElement = value;}\r
-               }\r
-               \r
-               public Queue FieldsInfo {\r
-                       get { return _fieldsInfo; }\r
-               }\r
-       }\r
-       \r
-       internal struct SoapAttributeStruct {\r
-               public string prefix;\r
-               public string attributeName;\r
-               public string attributeValue;\r
-               public string nameSpace;\r
-               \r
-               public SoapAttributeStruct(string prefix, string attributeName, string attributeValue) {\r
-                       this.prefix = prefix;\r
-                       this.attributeName = attributeName;\r
-                       this.attributeValue = attributeValue;\r
-                       this.nameSpace = null;\r
-               }\r
-\r
-               public SoapAttributeStruct(string prefix, string nameSpace, string attributeName, string attributeValue) {\r
-                       this.prefix = prefix;\r
-                       this.attributeName = attributeName;\r
-                       this.attributeValue = attributeValue;\r
-                       this.nameSpace = nameSpace;\r
-               }\r
-       }\r
-       \r
-       internal class SoapSerializationEntry {\r
-               public string prefix;\r
-               public string elementName;\r
-               public string elementNamespace;\r
-               public ICollection elementAttributes;\r
-               public object elementValue = null;\r
-               public bool getIntoFields = false;\r
-               public bool SpecifyEncoding = false;\r
-               public long i = 0;\r
-               public ElementType elementType = ElementType.Nothing;\r
-               public bool IsArray = false;\r
-               public bool CanBeValue = false;\r
-               public bool WriteFullEndElement = false;\r
-       }\r
-       \r
-       internal delegate void DoneWithElementEventHandler(ISoapWriter sender, DoneWithElementEventArgs e);\r
-       \r
-       internal class DoneWithElementEventArgs: EventArgs {\r
-               private object _objCurrent; \r
-\r
-               public DoneWithElementEventArgs(object objCurrent) {\r
-                       _objCurrent = objCurrent;\r
-               }\r
-               \r
-               public object Current {\r
-                       get { return _objCurrent;}\r
-               }\r
-               \r
-               \r
-       }\r
-       \r
-\r
-}\r
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapFormatter.cmbx b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapFormatter.cmbx
deleted file mode 100644 (file)
index 4aac37b..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<Combine fileversion="1.0" name="SoapFormatter" description="">\r
-  <StartMode startupentry="SoapFormatter" single="True">\r
-    <Execute entry="SoapFormatter" type="None" />\r
-  </StartMode>\r
-  <Entries>\r
-    <Entry filename=".\SoapFormatter.prjx" />\r
-  </Entries>\r
-  <Configurations active="Debug">\r
-    <Configuration name="Release">\r
-      <Entry name="SoapFormatter" configurationname="Debug" build="False" />\r
-    </Configuration>\r
-    <Configuration name="Debug">\r
-      <Entry name="SoapFormatter" configurationname="Debug" build="False" />\r
-    </Configuration>\r
-  </Configurations>\r
-</Combine>
\ No newline at end of file
index 7614870dd4f6d111d36984e48d15a7507391b5f6..7065b35c5f66246bbc0bf72d1102555c423413a3 100755 (executable)
@@ -23,23 +23,24 @@ namespace System.Runtime.Serialization.Formatters.Soap {
        }\r
        \r
        public class SoapFormatter: IRemotingFormatter, IFormatter {\r
-               private ObjectWriter _objWriter;\r
                private SoapWriter _soapWriter;\r
                private SerializationBinder _binder;\r
                private StreamingContext _context;\r
                private ISurrogateSelector _selector;\r
                private FormatterAssemblyStyle _assemblyFormat = FormatterAssemblyStyle.Full;\r
-               private ISoapMessage _topObject;\r
+               private FormatterTypeStyle _typeFormat = FormatterTypeStyle.TypesWhenNeeded;\r
+               private ISoapMessage _topObject = null;\r
                \r
 #if NET_1_1\r
                TypeFilterLevel _filterLevel = TypeFilterLevel.Low;\r
 #endif\r
 \r
                public SoapFormatter() {\r
-                       \r
+                       _selector = null;\r
+                       _context = new StreamingContext(StreamingContextStates.All);\r
                }\r
                \r
-               public SoapFormatter(ISurrogateSelector selector, StreamingContext context):this() {\r
+               public SoapFormatter(ISurrogateSelector selector, StreamingContext context) {\r
                        _selector = selector;\r
                        _context = context;\r
                }\r
@@ -54,21 +55,11 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                \r
                public object Deserialize(Stream serializationStream, HeaderHandler handler) {\r
                        object objReturn = null;\r
-                       SoapParser parser = new SoapParser(serializationStream);\r
-                       SoapReader soapReader = new SoapReader(parser);\r
-                       soapReader.Binder = _binder;\r
-                       \r
-                       if(_topObject != null) soapReader.TopObject = _topObject;\r
-                       ObjectReader reader = new ObjectReader(_selector, _context, soapReader);\r
-                       // Use the english numeral and date format during the serialization\r
-                       // and the deserialization.\r
-                       // The original CultureInfo is restored when the operation\r
-                       // is done\r
+                       SoapReader soapReader = new SoapReader(_binder, _selector, _context);\r
                        CultureInfo savedCi = CultureInfo.CurrentCulture;\r
                        try {\r
                                Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");\r
-                               parser.Run();\r
-                               objReturn = reader.TopObject;\r
+                               objReturn = soapReader.Deserialize(serializationStream, _topObject);\r
                        }\r
                        finally {\r
                                Thread.CurrentThread.CurrentCulture = savedCi;\r
@@ -87,18 +78,16 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                                throw new ArgumentNullException("serializationStream");\r
                        if(!serializationStream.CanWrite)\r
                                throw new SerializationException("Can't write in the serialization stream");\r
-                       _soapWriter = new SoapWriter(serializationStream);\r
-                       _objWriter = new ObjectWriter((ISoapWriter) _soapWriter, _selector,  new StreamingContext(StreamingContextStates.File));\r
-                       _soapWriter.Writer = _objWriter;\r
-\r
-                       // Use the english numeral and date format during the serialization\r
-                       // and the deserialization.\r
-                       // The original CultureInfo is restored when the operation\r
-                       // is done\r
+                       if(graph == null)\r
+                               throw new ArgumentNullException("graph");\r
+                       _soapWriter = new SoapWriter(serializationStream, _selector, _context, _topObject);\r
                        CultureInfo savedCi = CultureInfo.CurrentCulture;\r
                        try {\r
                                Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");\r
-                               _objWriter.Serialize(graph);\r
+                               _soapWriter.Serialize(\r
+                                       graph,\r
+                                       _typeFormat,\r
+                                       _assemblyFormat);\r
                        }\r
                        finally {\r
                                Thread.CurrentThread.CurrentCulture = savedCi;\r
@@ -155,7 +144,6 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                }\r
 #endif\r
                \r
-               [MonoTODO ("Interpret this")]\r
                public FormatterAssemblyStyle AssemblyFormat\r
                {\r
                        get {\r
@@ -166,5 +154,17 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                        }\r
                }\r
 \r
+               public FormatterTypeStyle TypeFormat\r
+               {\r
+                       get \r
+                       {\r
+                               return _typeFormat;\r
+                       }\r
+                       set \r
+                       {\r
+                               _typeFormat = value;\r
+                       }\r
+               }\r
+\r
        }\r
 }\r
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapFormatter.prjx b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapFormatter.prjx
deleted file mode 100644 (file)
index 48fddca..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<Project name="SoapFormatter" description="Creates an empty C# class library" newfilesearch="None" enableviewstate="True" version="1.1" projecttype="C#">\r
-  <Contents>\r
-    <File name=".\AssemblyInfo.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\SoapWriter.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\ISoapParser.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\ISoapReader.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\ISoapWriter.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\ObjectReader.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\ObjectWriter.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\SoapCommon.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\SoapFormatter.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\SoapParser.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\SoapReader.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\SoapTypeMapper.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\SoapTypeMapping.cs" subtype="Code" buildaction="Compile" dependson="" data="" />\r
-    <File name=".\ObjectManager.cs" subtype="Code" buildaction="Nothing" dependson="" data="" />\r
-  </Contents>\r
-  <References />\r
-  <DeploymentInformation target="" script="" strategy="File" />\r
-  <Configuration runwithwarnings="True" name="Debug">\r
-    <CodeGeneration runtime="MsNet" compiler="Csc" warninglevel="0" includedebuginformation="True" optimize="True" unsafecodeallowed="True" generateoverflowchecks="True" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" />\r
-    <Execution commandlineparameters="" consolepause="False" />\r
-    <Output directory="..\..\..\..\..\..\..\..\Jim\SharpDevelop Projects\MySinks" assembly="Soap" />\r
-  </Configuration>\r
-  <Configurations active="Debug">\r
-    <Configuration runwithwarnings="True" name="Debug">\r
-      <CodeGeneration runtime="MsNet" compiler="Csc" warninglevel="0" includedebuginformation="True" optimize="True" unsafecodeallowed="True" generateoverflowchecks="True" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" />\r
-      <Execution commandlineparameters="" consolepause="False" />\r
-      <Output directory="..\..\..\..\..\..\..\..\Jim\SharpDevelop Projects\MySinks" assembly="Soap" />\r
-    </Configuration>\r
-    <Configuration runwithwarnings="True" name="Release">\r
-      <CodeGeneration runtime="MsNet" compiler="Csc" warninglevel="0" includedebuginformation="False" optimize="True" unsafecodeallowed="True" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" />\r
-      <Execution commandlineparameters="" consolepause="False" />\r
-      <Output directory=".\" assembly="SoapFormatter" />\r
-    </Configuration>\r
-  </Configurations>\r
-</Project>
\ No newline at end of file
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapParser.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapParser.cs
deleted file mode 100644 (file)
index 3da5954..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-// created on 22/04/2003 at 19:55\r
-//\r
-//     System.Runtime.Serialization.Formatters.Soap.SoapParser\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-\r
-using System.Collections;\r
-using System.Xml;\r
-using System.IO;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       \r
-       internal class SoapParser: ISoapParser {\r
-               private XmlTextReader _xmlReader;\r
-               public SoapParser(Stream inStream) {\r
-                       _xmlReader = new XmlTextReader(inStream);\r
-                       _xmlReader.WhitespaceHandling = WhitespaceHandling.None;\r
-               }\r
-               \r
-               public event SoapElementReadEventHandler SoapElementReadEvent;\r
-               \r
-               public void Run() {\r
-                       SoapSerializationEntry entry = null;\r
-                       ArrayList attributeList;\r
-                       Queue elementQueue = new Queue();\r
-                       // Read the envelope tag\r
-                       _xmlReader.Read();\r
-                       _xmlReader.MoveToContent();\r
-                       // Read the Body tag\r
-                       _xmlReader.Read();\r
-                       _xmlReader.MoveToContent();\r
-                       try{\r
-                               while(_xmlReader.Read() && _xmlReader.MoveToContent() != XmlNodeType.None){\r
-                                       switch(_xmlReader.NodeType) {\r
-                                               case XmlNodeType.Element:\r
-                                                       int elementDepth = _xmlReader.Depth;\r
-                                                       bool isEmptyElement = _xmlReader.IsEmptyElement;\r
-                                                       if(entry != null) elementQueue.Enqueue(entry);\r
-                                                       entry = new SoapSerializationEntry();\r
-                                                       entry.elementName = XmlConvert.DecodeName(_xmlReader.LocalName);\r
-                                                       entry.elementNamespace = _xmlReader.NamespaceURI;\r
-                                                       entry.prefix = _xmlReader.Prefix;\r
-                                                       attributeList = new ArrayList();\r
-                                                       while(_xmlReader.MoveToNextAttribute()) {\r
-                                                               // if the element is an array, we have to get the type\r
-                                                               // of the array\r
-                                                               if(_xmlReader.Name == "SOAP-ENC:arrayType" || _xmlReader.Name == "xsi:type") {\r
-                                                                       string name = _xmlReader.Value;\r
-                                                                       string[] tokens = name.Split(new System.Char[] {':'});\r
-                                                                       string xmlNamespace = _xmlReader.LookupNamespace(tokens[0]);\r
-                                                                       attributeList.Add(new SoapAttributeStruct(xmlNamespace, _xmlReader.Name, tokens[1]));\r
-                                                               }\r
-                                                               else {\r
-                                                                       attributeList.Add(new SoapAttributeStruct(_xmlReader.Prefix, _xmlReader.Name, _xmlReader.Value));\r
-                                                               }\r
-                                                       }\r
-                                                       entry.elementAttributes = attributeList;\r
-                                                       if(isEmptyElement && elementDepth == 2 && SoapElementReadEvent != null) {\r
-                                                               elementQueue.Enqueue(entry);\r
-                                                               entry = null;\r
-                                                               SoapElementReadEvent(this, new SoapElementReadEventArgs(elementQueue));                                                         \r
-                                                       }\r
-                                                       break;\r
-                                               case XmlNodeType.EndElement:\r
-                                                       if(_xmlReader.Depth == 2 && SoapElementReadEvent != null){\r
-                                                               elementQueue.Enqueue(entry);\r
-                                                               entry = null;\r
-                                                               SoapElementReadEvent(this, new SoapElementReadEventArgs(elementQueue));\r
-                                                       }\r
-                                                       if(_xmlReader.Depth == 0 || _xmlReader.Name == "SOAP-ENV:Envelope") return;\r
-                                                       break;\r
-                                               case XmlNodeType.Text:\r
-                                                       if (entry == null) throw new SerializationException ("Invalid SOAP message");\r
-                                                       entry.elementValue = _xmlReader.Value;\r
-                                                       break;\r
-                                               case XmlNodeType.Attribute:\r
-                                                       break;\r
-                                       }\r
-                               }\r
-                       }\r
-                       finally {\r
-                               //if(_xmlReader != null) _xmlReader.Close();\r
-                       }\r
-               }\r
-               \r
-               public Stream InStream {\r
-                       set { _xmlReader = new XmlTextReader(value);}\r
-               }\r
-       }\r
-}\r
index 6277450f0cbc0ba4edaa34557c157fc544e22ade..6584da8ae300e7ee2eca625f6516bd0cd638c002 100755 (executable)
 //\r
 \r
 using System;\r
+using System.IO;\r
+using System.Xml;\r
 using System.Reflection;\r
 using System.Collections;\r
+using System.Runtime.Remoting;\r
 using System.Runtime.Serialization;\r
 \r
 namespace System.Runtime.Serialization.Formatters.Soap {\r
-       internal sealed class SoapReader: ISoapReader {\r
-               public event ElementReadEventHandler ElementReadEvent;\r
-               private ISoapMessage _soapMessage;\r
-               private ISoapParser _parser;\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
+\r
+               #endregion\r
 \r
-               public SerializationBinder Binder {\r
-                       get { return _binder;}\r
-                       set { _binder = value;}\r
+               #region Properties\r
+\r
+               private long NextAvailableId\r
+               {\r
+                       get \r
+                       {\r
+                               _nextAvailableId--;\r
+                               return _nextAvailableId;\r
+                       }\r
                }\r
+\r
+               #endregion\r
+\r
+               #region Constructors\r
                \r
-               public ISoapMessage TopObject {\r
-                       get { return _soapMessage; }\r
-                       set { \r
-                               _soapMessage = value;\r
+               public SoapReader(SerializationBinder binder, ISurrogateSelector selector, StreamingContext context) \r
+               {\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
+               {\r
+                       xmlReader = new XmlTextReader(inStream);\r
+                       xmlReader.WhitespaceHandling = WhitespaceHandling.None;\r
+                       mapper = new SoapTypeMapper(_binder);\r
+\r
+                       try\r
+                       {\r
+                               // SOAP-ENV:Envelope\r
+                               xmlReader.MoveToContent();\r
+                               xmlReader.Read();\r
+                               // SOAP-ENV:Body\r
+                               xmlReader.Read();\r
+\r
+                               // The root object\r
+                               if(soapMessage != null)\r
+                               {\r
+                                       if(DeserializeMessage(soapMessage)) \r
+                                       {\r
+                                               RegisterObject(1, soapMessage, null, 0, null, null);\r
+                                       }\r
+                               }\r
                                \r
-                               // the first element of the SOAP stream\r
-                               // should be a SOAP RPC\r
-                               _parser.SoapElementReadEvent -= new SoapElementReadEventHandler(SoapElementRead);\r
-                               _parser.SoapElementReadEvent += new SoapElementReadEventHandler(SoapRPCElementRead);\r
+                               if(xmlReader.NodeType != XmlNodeType.EndElement)\r
+                               {\r
+                                       do\r
+                                       {\r
+                                               Deserialize();\r
+\r
+                                       }\r
+                                       while(xmlReader.NodeType != XmlNodeType.EndElement); \r
+                               }\r
                        }\r
+                       finally \r
+                       {\r
+                               if(xmlReader != null) xmlReader.Close();\r
+                       }\r
+\r
+                       return TopObject;\r
                }\r
                \r
-               public SoapReader(ISoapParser parser) {\r
-                       // register the SoapElementReadEvent handler\r
-                       _parser = parser;\r
-                       _parser.SoapElementReadEvent += new SoapElementReadEventHandler(SoapElementRead);\r
-               }\r
-               \r
-               public void SoapRPCElementRead(ISoapParser sender, SoapElementReadEventArgs e) {\r
-                       _parser.SoapElementReadEvent += new SoapElementReadEventHandler(SoapElementRead);\r
-                       _parser.SoapElementReadEvent -= new SoapElementReadEventHandler(SoapRPCElementRead);\r
-                       \r
-                       Queue elementQueue = e.ElementQueue;\r
-                       Queue elementInfoQueue = new Queue();\r
-                       SoapSerializationEntry root = (SoapSerializationEntry) elementQueue.Dequeue();\r
-                       \r
-                       // fill the SoapMessage members\r
-                       // MethodName\r
-                       //elementInfoQueue.Enqueue(new ElementInfo(typeof(string), "MethodName", rpcInfo.elementName, ElementType.Nothing, 0, 0);\r
-                       _soapMessage.MethodName = root.elementName;\r
-                       \r
-                       // XmlNamespace\r
-                       //elementInfoQueue.Enqueue(new ElementInfo(typeof(string), "XmlNamespace", rpcInfo.elementNamespace, ElementType.Nothing, 0, 0);\r
-                       _soapMessage.XmlNameSpace = root.elementNamespace;\r
-                       \r
-                       // the root element is a SoapMessage\r
-                       ElementInfo rpcInfo = new ElementInfo(typeof(SoapMessage), String.Empty, _soapMessage, ElementType.Id, 1, null);\r
-                       \r
-                       //todo: headers\r
-                       \r
-                       // add the function parameters to the queue\r
-                       SoapSerializationEntry field;\r
-                       ElementInfo fieldElementInfo;\r
-                       while(elementQueue.Count > 0){\r
-                               field = (SoapSerializationEntry) elementQueue.Dequeue();\r
-                               fieldElementInfo = GetElementInfo(field);\r
-                               elementInfoQueue.Enqueue(fieldElementInfo);\r
+               #endregion\r
+\r
+               #region Private Methods\r
+\r
+               private object TopObject \r
+               {\r
+                       get \r
+                       {\r
+                               objMgr.DoFixups();\r
+                               objMgr.RaiseDeserializationEvent();\r
+                               return objMgr.GetObject(1);\r
                        }\r
+               }\r
 \r
-                       // raise the ElementReadEvent\r
-                       ElementReadEvent(this,new ElementReadEventArgs(rpcInfo, elementInfoQueue));\r
-                       \r
-                       \r
+               private bool IsNull()\r
+               {\r
+                       string tmp = xmlReader["xsi:null"];\r
+                       return (tmp == null || tmp == string.Empty)?false:true;\r
                }\r
-               \r
-               // called when SoapElementReadEvent is raized by the SoapParser object\r
-               public void SoapElementRead(ISoapParser sender, SoapElementReadEventArgs e) {\r
-                       Queue elementQueue = e.ElementQueue;\r
-                       Queue elementInfoQueue = new Queue();\r
-                       SoapSerializationEntry root = (SoapSerializationEntry) elementQueue.Dequeue();\r
+\r
+               private long GetId()\r
+               {\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
+               private long GetHref()\r
+               {\r
+                       long href = 0;\r
                        \r
-                       ElementInfo rootInfo = GetElementInfo(root);\r
-                       SoapSerializationEntry field;\r
-                       ElementInfo fieldElementInfo;\r
-                       while(elementQueue.Count > 0){\r
-                               field = (SoapSerializationEntry) elementQueue.Dequeue();\r
-                               fieldElementInfo = GetElementInfo(field);\r
-                               elementInfoQueue.Enqueue(fieldElementInfo);\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
+               private Type GetComponentType()\r
+               {\r
+                       Type type = null;\r
+                       if(GetId() != 0) return typeof(string);\r
+                       string strValue = xmlReader["xsi:type"];\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
+               }\r
+\r
+               private bool DeserializeMessage(ISoapMessage message) \r
+               {\r
+                       string typeNamespace, assemblyName;\r
+\r
+                       if(xmlReader.Name == SoapTypeMapper.SoapEnvelopePrefix + ":Fault")\r
+                       {\r
+                               Deserialize();\r
+                               return false;\r
+                       }\r
+\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
+                       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
+                               indices[0] = i;\r
+                               objParam = DeserializeComponent(\r
+                                       null,\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
 \r
-                       // raise the ElementReadEvent\r
-                       ElementReadEvent(this,new ElementReadEventArgs(rootInfo, elementInfoQueue));\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
+\r
                \r
-               // Converts the text information from the SoapParser into\r
-               // information that with by used by the ObjectReader to reconstruct\r
-               // the object.\r
-               private ElementInfo GetElementInfo(SoapSerializationEntry entry) {\r
-                       SoapTypeMapping mapping = new SoapTypeMapping(entry.elementName, entry.elementNamespace);\r
-                       Type elementType = SoapTypeMapper.GetType(mapping);\r
+               private object DeserializeArray(long id)\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
+                       for (int i=0; i < numberOfDims; i++)\r
+                       {\r
+                               lengths[i] = Convert.ToInt32(arrayDims[i]);\r
+                       }\r
+\r
+                       int[] indices = new int[numberOfDims];\r
 \r
-                       if(elementType != null && _binder != null) {\r
-                               elementType = _binder.BindToType(elementType.Assembly.FullName, elementType.FullName);\r
-                               if(elementType == null) throw new SerializationException();\r
+                       // Create the array\r
+                       Type arrayType = mapper[new Element(arrayInfo[0], arrayInfo[1], xmlReader.LookupNamespace(arrayInfo[0]))];\r
+                       Array array = Array.CreateInstance(\r
+                               arrayType,\r
+                               lengths);\r
+\r
+                       for(int i = 0; i < numberOfDims; i++) \r
+                       {\r
+                               indices[i] = array.GetLowerBound(i);\r
                        }\r
-                       \r
-                       \r
-                       long id = 0;\r
-                       ElementType elementId = ElementType.Nothing;\r
-                       ICollection attrLst = entry.elementAttributes;\r
-                       int[] arrayRank = null;\r
-                       foreach(SoapAttributeStruct attr in attrLst){\r
-                               if(attr.attributeName == "id"){\r
-                                       string attrId = ((string)attr.attributeValue).Remove(0,4);\r
-                                       id = (new FormatterConverter()).ToInt64(attrId);\r
-                                       elementId = ElementType.Id;\r
-                               } else if(attr.attributeName == "href") {\r
-                                       string attrId = ((string)attr.attributeValue).Remove(0,5);\r
-                                       id = (new FormatterConverter()).ToInt64(attrId);\r
-                                       elementId = ElementType.Href;\r
-                               } else if(attr.attributeName == "xsi:null" && attr.attributeValue == "1") {\r
-                                       elementId = ElementType.Null;\r
-                               } else if(attr.attributeName == "SOAP-ENC:arrayType") {\r
-                                       string[] tokens = attr.attributeValue.Split(new System.Char[] {'[',',',']'});\r
-                                       mapping = new SoapTypeMapping(tokens[0], attr.prefix);\r
-                                       elementType = SoapTypeMapper.GetType(mapping);\r
-                                       arrayRank = new int[tokens.Length - 2];\r
-                                       for(int i=0; i<tokens.Length-2; i++) {\r
-                                               arrayRank[i] = Convert.ToInt32(tokens[i+1]);\r
-                                       }\r
-                                       Type tempType = Type.GetType(elementType.ToString()+"[]");\r
-                                       \r
-                                       if(tempType == null) {\r
-                                               AssemblyName assName = elementType.Assembly.GetName();\r
-                                               Assembly ass = Assembly.Load(assName);\r
-                                               tempType = ass.GetType(elementType.ToString()+"[]", true);\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
+                               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(dim > 0)\r
+                                               {\r
+                                                       indices[dim] = array.GetLowerBound(dim);\r
+                                                       continue;\r
+                                               }\r
+                                               \r
                                        }\r
-                                       \r
-                                       elementType = tempType;\r
-                               } else if(attr.attributeName == "xsi:type") {\r
-                                       mapping = new SoapTypeMapping(attr.attributeValue, attr.prefix);\r
-                                       elementType = SoapTypeMapper.GetType(mapping);\r
-                                       \r
-                                       \r
+                                       break;\r
                                }\r
                        }\r
-                       \r
 \r
-                       ElementInfo elementInfo =  new ElementInfo(elementType, entry.elementName, entry.elementValue, elementId, id, arrayRank);\r
-                       return elementInfo;\r
+                       RegisterObject(id, array, null, 0, null, null);\r
+                       xmlReader.ReadEndElement();\r
+                       return array;\r
+\r
+               }\r
+\r
+\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
+\r
+                       // Get the Id\r
+                       long id = GetId();\r
+                       id = (id == 0)?1:id;\r
+\r
+                       if(type == typeof(Array))\r
+                       {\r
+                               objReturn = DeserializeArray(id);\r
+                       }\r
+                       else\r
+                       {\r
+                               objReturn = DeserializeObject(type, id, 0, null, null);\r
+\r
+                       }\r
+\r
+                       return objReturn;\r
+               }\r
+\r
+\r
+               private object DeserializeObject(\r
+                       Type type, \r
+                       long id, \r
+                       long parentId, \r
+                       MemberInfo parentMemberInfo,\r
+                       int[] indices)\r
+               {\r
+                       SerializationInfo info = null;\r
+                       bool NeedsSerializationInfo = false;\r
+                       bool hasFixup;\r
+\r
+                       if(SoapTypeMapper.CanBeValue(type)) \r
+                       {\r
+                               string elementString = xmlReader.ReadElementString();\r
+                               object obj;\r
+                               if(type.IsEnum)\r
+                                       obj = Enum.Parse(type, elementString);\r
+                               else\r
+                                       obj = Convert.ChangeType(elementString, type);\r
+                               if(id > 0) \r
+                                       RegisterObject(id, obj, info, parentId, parentMemberInfo, indices);\r
+\r
+                               return obj;\r
+                       }\r
+                       object objReturn = \r
+                               FormatterServices.GetUninitializedObject(type);\r
+                       if(objReturn is ISerializable)\r
+                               NeedsSerializationInfo = true;\r
+\r
+                       if(_surrogateSelector != null && NeedsSerializationInfo == false)\r
+                       {\r
+                               ISurrogateSelector selector;\r
+                               ISerializationSurrogate surrogate = _surrogateSelector.GetSurrogate(\r
+                                       type,\r
+                                       _context,\r
+                                       out selector);\r
+                               NeedsSerializationInfo |= (surrogate != null);\r
+                       }\r
+\r
+                       if(NeedsSerializationInfo)\r
+                       {\r
+                               objReturn = \r
+                                       DeserializeISerializableObject(objReturn, id, out info, out hasFixup);\r
+                       }\r
+                       else\r
+                       {\r
+                               objReturn = \r
+                                       DeserializeSimpleObject(objReturn, id, out hasFixup);\r
+                               if(!hasFixup && objReturn is IObjectReference)\r
+                                       objReturn = ((IObjectReference)objReturn).GetRealObject(_context);\r
+                       }\r
+\r
+                       RegisterObject(id, objReturn, info, parentId, parentMemberInfo, indices);\r
+                       xmlReader.ReadEndElement();\r
+                       return objReturn;\r
+               }\r
+\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
+                       MemberInfo[] memberInfos = \r
+                               FormatterServices.GetSerializableMembers(currentType, _context);\r
+                       Hashtable indices = (Hashtable) _fieldIndices[currentType];\r
+                       if(indices == null) \r
+                       {\r
+                               indices = new Hashtable();\r
+                               for(int i = 0; i < memberInfos.Length; i++) \r
+                               {\r
+                                       indices.Add(memberInfos[i].Name, i);\r
+                               }\r
+                               _fieldIndices[currentType] = indices;\r
+                       }\r
+\r
+                       int objDepth = xmlReader.Depth;\r
+                       object[] data = new object[memberInfos.Length];\r
+                       xmlReader.Read();\r
+                       for(int i = 0; i < memberInfos.Length; i++)\r
+                       {\r
+                               object fieldObject;\r
+                               long fieldId, fieldHref;\r
+                               int index = (int) indices[xmlReader.LocalName];\r
+                               FieldInfo fieldInfo = (memberInfos[index]) as FieldInfo;\r
+                               if(fieldInfo == null) continue;\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
+                                       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
+                       }\r
+\r
+                       FormatterServices.PopulateObjectMembers(obj, memberInfos, data);\r
+                       return obj;\r
+               }\r
+\r
+\r
+               private object DeserializeISerializableObject(\r
+                       object obj, \r
+                       long id, \r
+                       out SerializationInfo info,\r
+                       out bool hasFixup\r
+                       )\r
+               {\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
+                               Type fieldType = GetComponentType();\r
+                               string fieldName = 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
+                                       RecordFixup(id, fieldHref, obj, info, fieldName, null, null);\r
+                                       hasFixup = true;\r
+                                       continue;\r
+                               }\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
+\r
+                       return obj;\r
+               }\r
+\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
+                       object objReturn;\r
+                       componentId = 0;\r
+                       componentHref = 0;\r
+\r
+                       if(IsNull())\r
+                       {\r
+                               xmlReader.Read();\r
+                               return null;\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
+               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
+                       if(info != null)\r
+                       {\r
+                               objMgr.RecordDelayedFixup(parentObjectId, fieldName, childObjectId);\r
+                       }\r
+                       else if (parentObject is Array) \r
+                       {\r
+                               if (indices.Length == 1)\r
+                                       objMgr.RecordArrayElementFixup (parentObjectId, indices[0], childObjectId);\r
+                               else\r
+                                       objMgr.RecordArrayElementFixup (parentObjectId, (int[])indices.Clone(), childObjectId);\r
+                       }\r
+                       else \r
+                       {\r
+                               objMgr.RecordFixup (parentObjectId, memberInfo, childObjectId);\r
+                       }\r
                }\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
+                       if (parentObjectId == 0) indices = null;\r
+\r
+\r
+                       if (!objectInstance.GetType().IsValueType || parentObjectId == 0)\r
+                               objMgr.RegisterObject (objectInstance, objectId, info, 0, null, null);\r
+                       else\r
+                       {\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
+               }\r
+\r
+\r
+               \r
+               #endregion\r
        }\r
 }\r
index 5ff113839d2fec496800efa3eef8f7ab0cac7ab5..fe1d7bf684b140ea059453aef48d88f8a8c36fef 100644 (file)
-// created on 09/04/2003 at 18:58\r
-//\r
-//     System.Runtime.Serialization.Formatters.Soap.SoapTypeMapper\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-using System;\r
-using System.Reflection;\r
-using System.Collections;\r
-using System.Runtime.Remoting;\r
-using System.Xml.Serialization;\r
-using System.Xml.Schema;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       \r
-       internal class SoapTypeMapper {\r
-               private static Hashtable _mappingTable = new Hashtable();\r
-               private static Hashtable _invertMappingTable = new Hashtable();\r
-               \r
-               static SoapTypeMapper() {\r
-                       InitMappingTable();\r
-                       \r
-               }\r
-               \r
-               // returns the SoapTypeMapping corresponding to the System.Type\r
-               public static SoapTypeMapping GetSoapType(Type type) {\r
-                       object rtnMapping;\r
-\r
-                       if (type.IsByRef) type = type.GetElementType ();\r
-\r
-                       \r
-                       if(type.IsArray){\r
-                                       rtnMapping = _mappingTable[typeof(System.Array)];\r
-                       }\r
-                       else {\r
-                               rtnMapping = (object) _mappingTable[type];\r
-                               \r
-                               if(rtnMapping == null){\r
-                                       string sTypeNamespace;\r
-                                       AssemblyName assName = type.Assembly.GetName();\r
-                                       if(assName.Name.StartsWith("mscorlib")) sTypeNamespace = "http://schemas.microsoft.com/clr/ns/"+type.Namespace;\r
-                                       else sTypeNamespace = SoapServices.CodeXmlNamespaceForClrTypeNamespace(type.Namespace, type.Assembly.FullName);\r
-                                       string sType = type.FullName;\r
-                                       string sTypeName = type.FullName;\r
-                                       if(type.Namespace != null && type.Namespace.Length > 0) sTypeName = sTypeName.Remove(0, type.Namespace.Length+1);\r
-                                       SoapTypeMapping newType =  new SoapTypeMapping(type, sTypeName, sTypeNamespace, false, type.IsPrimitive, type.IsValueType, true);\r
-                                       \r
-                                       _mappingTable.Add(type, newType);\r
-                                       _invertMappingTable.Add(newType, type);\r
-                                       \r
-                                       return newType;\r
-                               }\r
-                                       \r
-                       }\r
-                       \r
-                       return (SoapTypeMapping)rtnMapping;\r
-               }\r
-               \r
-               // returns the Type corresponding to the SoapTypeMapping\r
-               public static Type GetType(SoapTypeMapping mapping) {\r
-                       object rtnObject;\r
-                       rtnObject = _invertMappingTable[mapping];\r
-                       \r
-                       if(rtnObject == null && mapping.TypeNamespace.Length != 0) {\r
-                               string typeNamespace;\r
-                               string assemblyName;\r
-                               SoapServices.DecodeXmlNamespaceForClrTypeNamespace(mapping.TypeNamespace, out typeNamespace, out assemblyName);\r
-                               rtnObject = Type.GetType(typeNamespace+"."+mapping.TypeName);\r
-                               \r
-                               if(rtnObject == null) {\r
-                                       Assembly ass =Assembly.Load(assemblyName);\r
-                                       if(ass != null) {\r
-                                               rtnObject = ass.GetType(typeNamespace+"."+mapping.TypeName, true);\r
-                                       }\r
-                               }\r
-                       }\r
-                       \r
-                       return (Type)rtnObject;\r
-               }\r
-\r
-               private static void RegisterSchemaType (Type type, string typeName, bool canBeValue, bool isPrimitive,bool isValueType,bool needId)\r
-               {\r
-                       SoapTypeMapping mapping =  new SoapTypeMapping (type, typeName, canBeValue, isPrimitive, isValueType, needId);\r
-                       _mappingTable.Add(type, mapping);\r
-                       _invertMappingTable.Add(mapping, type);\r
-               }\r
-               \r
-               // initialize the mapping tables\r
-               private static void InitMappingTable() {\r
-                       SoapTypeMapping mapping;\r
-                       \r
-                       // the primitive type "System.String"\r
-                       mapping =  new SoapTypeMapping(typeof(string), "string", true, false, false, true);\r
-                       _mappingTable.Add(typeof(string),mapping);\r
-                       _invertMappingTable.Add(mapping, typeof(string));\r
-                       mapping =  new SoapTypeMapping(typeof(string), "string", XmlSchema.Namespace, true, false, false, true);\r
-                       _invertMappingTable.Add(mapping, typeof(string));\r
-\r
-                       RegisterSchemaType (typeof(short), "short", true, true, true, false);\r
-                       RegisterSchemaType (typeof(ushort), "unsignedShort", true, true, true, false);\r
-                       RegisterSchemaType (typeof(int), "int", true, true, true, false);\r
-                       RegisterSchemaType (typeof(uint), "unsignedInt", true, true, true, false);\r
-                       RegisterSchemaType (typeof(long), "long", true, true, true, false);\r
-                       RegisterSchemaType (typeof(ulong), "unsignedLong", true, true, true, false);\r
-                       RegisterSchemaType (typeof(decimal), "decimal", true, true, true, false);\r
-                       RegisterSchemaType (typeof(sbyte), "byte", true, true, true, false);\r
-                       RegisterSchemaType (typeof(byte), "unsignedByte", true, true, true, false);\r
-                       RegisterSchemaType (typeof(DateTime), "dateTime", true, true, true, false);\r
-                       RegisterSchemaType (typeof(TimeSpan), "duration", true, true, true, false);\r
-                       RegisterSchemaType (typeof(double), "double", true, true, true, false);\r
-                       RegisterSchemaType (typeof(Char), "char", true, true, true, false);\r
-                       RegisterSchemaType (typeof(bool), "boolean", true, true, true, false);\r
-                       RegisterSchemaType (typeof(System.Single), "float", true, true, true, false);\r
-                       RegisterSchemaType (typeof(System.Array), "Array", false, false, false, true);\r
-                       \r
-                       mapping = new SoapTypeMapping(typeof(object), "anyType", "http://www.w3.org/2001/XMLSchema", false, false, false, true);\r
-                       _mappingTable.Add(typeof(object), mapping);\r
-                       _invertMappingTable.Add(mapping, typeof(object));\r
-                       \r
-                       mapping = new SoapTypeMapping(typeof(System.Runtime.Serialization.Formatters.SoapFault), "Fault", "http://schemas.xmlsoap.org/soap/envelope/", false, false, false, true);\r
-                       _mappingTable.Add(typeof(System.Runtime.Serialization.Formatters.SoapFault), mapping);\r
-                       _invertMappingTable.Add(mapping, typeof(System.Runtime.Serialization.Formatters.SoapFault));\r
-                       \r
-                       \r
-               }\r
-       }\r
-}\r
+// created on 09/04/2003 at 18:58
+//
+//     System.Runtime.Serialization.Formatters.Soap.SoapTypeMapper
+//
+//     Authors:
+//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)
+//
+
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Runtime.Remoting;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Runtime.Serialization.Formatters;
+using System.Xml.Schema;
+
+namespace System.Runtime.Serialization.Formatters.Soap {
+
+       internal class Element
+       {
+               private string _prefix;
+               private string _localName;
+               private string _namespaceURI;
+
+               public Element(string prefix, string localName, string namespaceURI) 
+               {
+                       _prefix = prefix;
+                       _localName = localName;
+                       _namespaceURI = namespaceURI;
+               }
+
+               public Element(string localName, string namespaceURI): this(null, localName, namespaceURI)
+               {
+               }
+
+               public string Prefix
+               {
+                       get
+                       {
+                               return _prefix;
+                       }
+               }
+
+               public string LocalName
+               {
+                       get
+                       {
+                               return _localName;
+                       }
+               }
+
+               public string NamespaceURI 
+               {
+                       get 
+                       {
+                               return _namespaceURI;
+                       }
+               }
+
+               public override bool Equals(object obj) 
+               {
+                       Element element = obj as Element;
+                       return (_localName == XmlConvert.DecodeName(element._localName) &&
+                               _namespaceURI == XmlConvert.DecodeName(element._namespaceURI))?true:false;
+               }
+
+               public override int GetHashCode()
+               {
+                       return (String.Format("{0} {1}", 
+                               XmlConvert.DecodeName(_localName),
+                               XmlConvert.DecodeName(_namespaceURI))).GetHashCode();
+               }
+
+               public override string ToString() 
+               {
+                       return string.Format("Element.Prefix = {0}, Element.LocalName = {1}, Element.NamespaceURI = {2}", this.Prefix, this.LocalName, this.NamespaceURI);
+               }
+       }
+
+       internal class SoapTypeMapper {
+               private static Hashtable xmlNodeToTypeTable = new Hashtable();
+               private static Hashtable typeToXmlNodeTable = new Hashtable();
+               public static readonly string SoapEncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";
+               public static readonly string SoapEncodingPrefix = "SOAP-ENC";
+               public static readonly string SoapEnvelopeNamespace = "http://schemas.xmlsoap.org/soap/envelope/";
+               public static readonly string SoapEnvelopePrefix = "SOAP-ENV";
+               internal static readonly string SoapEnvelope;
+               private XmlTextWriter _xmlWriter;
+               private long _prefixNumber;
+               private Hashtable namespaceToPrefixTable = new Hashtable();
+               private SerializationBinder _binder;
+               private static ArrayList _canBeValueTypeList;
+               private FormatterAssemblyStyle _assemblyFormat = FormatterAssemblyStyle.Full;
+               private Element elementString;
+
+
+               // Constructor used by SoapReader
+               public SoapTypeMapper(SerializationBinder binder) 
+               {
+                       _binder = binder;
+               }
+
+               // Constructor used by SoapWriter
+               public SoapTypeMapper(
+                       XmlTextWriter xmlWriter, 
+                       FormatterAssemblyStyle assemblyFormat,
+                       FormatterTypeStyle typeFormat) 
+               {
+                       _xmlWriter = xmlWriter;
+                       _assemblyFormat = assemblyFormat;
+                       _prefixNumber = 1;
+                       Element element;
+                       Type elementType;
+                       elementType = typeof(string);
+                       if(typeFormat == FormatterTypeStyle.XsdString)\r
+                       {
+                               elementString = new Element("string", XmlSchema.Namespace);
+                       }
+                       else
+                       {
+                               elementString = new Element("string", SoapEncodingNamespace);
+                       }
+//                     typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+               }
+               
+               static SoapTypeMapper() {
+//                     SoapEnvelope = String.Format(
+//                             "<{0}:Envelope xmlns:{0}='{1}' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='{2}' xmlns:{3}='{4}' xmlns:clr='{5}' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>",
+//                             SoapEnvelopePrefix,
+//                             SoapEnvelopeNamespace,
+//                             XmlSchema.Namespace,
+//                             SoapEncodingPrefix,
+//                             SoapEncodingNamespace,
+//                             SoapServices.XmlNsForClrType);
+                       _canBeValueTypeList = new ArrayList();
+                       _canBeValueTypeList.Add(typeof(DateTime).ToString());
+                       _canBeValueTypeList.Add(typeof(TimeSpan).ToString());
+                       _canBeValueTypeList.Add(typeof(string).ToString());
+                       _canBeValueTypeList.Add(typeof(decimal).ToString());
+                       _canBeValueTypeList.Sort();
+                       InitMappingTables();
+                       
+               }
+
+               public Type this[Element element]
+               {
+                       get 
+                       {
+                               Type type = null;
+
+                               string localName = XmlConvert.DecodeName(element.LocalName);
+                               string namespaceURI = XmlConvert.DecodeName(element.NamespaceURI);
+                               string typeNamespace, assemblyName;
+                               SoapServices.DecodeXmlNamespaceForClrTypeNamespace(
+                                       element.NamespaceURI, 
+                                       out typeNamespace, 
+                                       out assemblyName);
+                               string typeName = typeNamespace + Type.Delimiter + localName;
+
+                               if(assemblyName != null && assemblyName != string.Empty && _binder != null) 
+                               {
+                                       type = _binder.BindToType(assemblyName, typeName);
+                               }
+                               if(type == null) 
+                               {
+                                       string assemblyQualifiedName = (string)xmlNodeToTypeTable[element];
+                                       if(assemblyQualifiedName != null)
+                                               type = Type.GetType(assemblyQualifiedName);
+                                       else
+                                       { 
+
+                                               type = Type.GetType(element.LocalName);
+                                               if(type == null) 
+                                               { 
+
+                                                       type = Type.GetType(typeName);
+                                                       if(type == null) 
+                                                       {
+
+                                                               if(assemblyName == null || assemblyName == String.Empty)
+                                                                       throw new SerializationException(
+                                                                               String.Format("Parse Error, no assembly associated with XML key {1} {2}", 
+                                                                               localName, 
+                                                                               namespaceURI));
+                                                               type = FormatterServices.GetTypeFromAssembly(
+                                                                       Assembly.Load(assemblyName), 
+                                                                       typeName);
+                                                       }
+                                               }
+                                       }
+                                       if(type == null)
+                                               throw new SerializationException();
+                               }
+                               return type;
+                       }
+               }
+
+
+               public Element this[string typeFullName, string assemblyName]
+               {
+                       get 
+                       {
+                               Element element;
+                               string typeNamespace = string.Empty;
+                               string typeName = typeFullName;
+                               if(_assemblyFormat == FormatterAssemblyStyle.Simple)\r
+                               {
+                                       string[] items = assemblyName.Split(',');
+                                       assemblyName = items[0];
+                               }
+                               string assemblyQualifiedName = typeFullName + ", " + assemblyName;
+                               element = (Element) typeToXmlNodeTable[assemblyQualifiedName];
+                               if(element == null)
+                               {
+                                       int typeNameIndex = typeFullName.LastIndexOf('.');
+                                       if(typeNameIndex != -1) 
+                                       {
+                                               typeNamespace = typeFullName.Substring(0, typeNameIndex);
+                                               typeName = typeFullName.Substring(typeNamespace.Length + 1);
+                                       }
+                                       string namespaceURI = 
+                                               SoapServices.CodeXmlNamespaceForClrTypeNamespace(
+                                               typeNamespace, 
+                                               (!assemblyName.StartsWith("mscorlib"))?assemblyName:String.Empty);
+                                       string prefix = (string) namespaceToPrefixTable[namespaceURI];
+                                       if(prefix == null || prefix == string.Empty)
+                                       {
+                                               prefix = "a" + (_prefixNumber++).ToString();
+                                               namespaceToPrefixTable[namespaceURI] = prefix;
+
+                                       }
+                                       element = new Element(
+                                               prefix, 
+                                               XmlConvert.EncodeName(typeName), 
+                                               namespaceURI);
+                               }
+                               return element;
+                       }
+               }
+
+               public Element this[Type type]
+               {
+                       get 
+                       {
+                               Element element = (Element) typeToXmlNodeTable[type.AssemblyQualifiedName];
+                               if(element == null)
+                               {
+                                       element = this[type.FullName, type.Assembly.FullName];
+//                                     if(_assemblyFormat == FormatterAssemblyStyle.Full)
+//                                             element = this[type.FullName, type.Assembly.FullName];
+//                                     else
+//                                             element = this[type.FullName, type.Assembly.GetName().Name];
+
+                               }
+                               else
+                               {
+                                       element = new Element((element.Prefix == null)?_xmlWriter.LookupPrefix(element.NamespaceURI):element.Prefix, element.LocalName, element.NamespaceURI);
+                               }
+                               if(element == null)
+                                       throw new SerializationException("Oooops");
+                               return element;
+                       }
+               }
+
+               public static bool CanBeValue(Type type)
+               {
+                       if(type.IsPrimitive) return true;
+                       if(type.IsEnum) return true;
+                       if(_canBeValueTypeList.BinarySearch(type.ToString()) >= 0) 
+                       {
+                               return true;
+                       }
+                       return false;
+               }
+
+               private static void InitMappingTables() 
+               {
+                       Element element;
+                       Type elementType;
+                       element = new Element("Array", SoapEncodingNamespace);
+                       elementType = typeof(System.Array);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("string", XmlSchema.Namespace);
+                       elementType = typeof(string);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+//                     typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("string", SoapEncodingNamespace);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+
+                       element = new Element("long", XmlSchema.Namespace);
+                       elementType = typeof(long);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("int", XmlSchema.Namespace);
+                       elementType = typeof(int);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("float", XmlSchema.Namespace);
+                       elementType = typeof(float);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("decimal", XmlSchema.Namespace);
+                       elementType = typeof(decimal);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("short", XmlSchema.Namespace);
+                       elementType = typeof(short);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("anyType", XmlSchema.Namespace);
+                       elementType = typeof(object);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("dateTime", XmlSchema.Namespace);
+                       elementType = typeof(DateTime);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("duration", XmlSchema.Namespace);
+                       elementType = typeof(TimeSpan);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+                       element = new Element("Fault", SoapEnvelopeNamespace);
+                       elementType = typeof(System.Runtime.Serialization.Formatters.SoapFault);
+                       xmlNodeToTypeTable.Add(element, elementType.AssemblyQualifiedName);
+                       typeToXmlNodeTable.Add(elementType.AssemblyQualifiedName, element);
+
+
+               }
+
+
+       }
+}
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapTypeMapping.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapTypeMapping.cs
deleted file mode 100644 (file)
index 769d93e..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-// created on 09/04/2003 at 19:01\r
-//\r
-//     System.Runtime.Serialization.Formatters.Soap.SoapTypeMapping\r
-//\r
-//     Authors:\r
-//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
-//\r
-\r
-using System;\r
-\r
-namespace System.Runtime.Serialization.Formatters.Soap {\r
-       \r
-       \r
-       internal class SoapTypeMapping \r
-       {\r
-               public static readonly string SoapEncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";\r
-               private string _typeNamespace;\r
-               private string _typeName;\r
-               private Type _type;\r
-               private bool _isPrimitive;\r
-               private bool _canBeValue;\r
-               private bool _isValueType;\r
-               private bool _needId;\r
-               private int _id;\r
-               private int _href;\r
-               private bool _isNull;\r
-               private bool _isArray;\r
-               private bool _specifyEncoding;\r
-               \r
-               public bool IsArray {\r
-                       get {\r
-                               return _isArray;\r
-                       }\r
-               }\r
-               \r
-               \r
-               public bool IsNull {\r
-                       get {\r
-                               return _isNull;\r
-                       }\r
-                       set {\r
-                               _isNull = value;\r
-                       }\r
-               }\r
-               \r
-               \r
-               public int Id {\r
-                       get {\r
-                               return _id;\r
-                       }\r
-                       set {\r
-                               _id = value;\r
-                       }\r
-               }\r
-               public int Href {\r
-                       get {\r
-                               return _href;\r
-                       }\r
-                       set {\r
-                               _href = value;\r
-                       }\r
-               }\r
-               \r
-               public bool NeedId {\r
-                       get {\r
-                               return _needId;\r
-                       }\r
-               }\r
-               \r
-               \r
-               \r
-               internal SoapTypeMapping (Type type,\r
-                                         string typeName,\r
-                                         bool canBeValue,\r
-                                         bool isPrimitive,\r
-                                         bool isValueType,\r
-                                         bool needId){\r
-                       _typeName = typeName;\r
-                       _type = type;\r
-                       _isPrimitive = isPrimitive;\r
-                       _isValueType = isValueType;\r
-                       _canBeValue = canBeValue;\r
-                       _needId = needId;\r
-                       _typeNamespace = SoapEncodingNamespace;\r
-                   _id = 0;\r
-                   _href = 0;\r
-                   _isNull = false;\r
-                   _isArray = type.IsArray;\r
-                   _specifyEncoding = false;\r
-               }\r
-               \r
-               internal SoapTypeMapping (Type type, \r
-                                         string typeName, \r
-                                         string typeNamespace, \r
-                                         bool canBeValue, \r
-                                         bool isPrimitive, \r
-                                         bool isValueType,\r
-                                         bool needId): this(type, typeName, canBeValue, isPrimitive, isValueType, needId){\r
-                       _typeNamespace = typeNamespace;\r
-               }\r
-               \r
-               internal SoapTypeMapping (string typeName, string typeNamespace) {\r
-                       _typeName = typeName;\r
-                       _typeNamespace = typeNamespace;\r
-               }\r
-               \r
-               public override int GetHashCode() {\r
-                       int hashCode = _typeName.GetHashCode() + _typeNamespace.GetHashCode();\r
-                       return hashCode;\r
-               }\r
-               \r
-               public override bool Equals(object obj) {\r
-                       if( ((SoapTypeMapping)obj)._typeName == _typeName && ((SoapTypeMapping)obj)._typeNamespace == _typeNamespace)\r
-                               return true;\r
-                       else\r
-                               return false;\r
-                       \r
-               }\r
-               \r
-               public string TypeNamespace {\r
-                       get { return _typeNamespace;}\r
-               }\r
-               \r
-               public string TypeName {\r
-                       get { return _typeName;}\r
-               }\r
-               \r
-               public Type Type {\r
-                       get { return _type; }\r
-               }\r
-               \r
-               public bool IsPrimitive {\r
-                       get { return _isPrimitive;}\r
-               }\r
-               \r
-               public bool IsValueType {\r
-                       get { return _isValueType;}\r
-               }\r
-               \r
-               public bool CanBeValue {\r
-                       get { return _canBeValue;}\r
-               }\r
-               \r
-               public bool SpecifyEncoding {\r
-                       get {\r
-                               return _specifyEncoding;\r
-                       }\r
-               }\r
-               \r
-       }\r
-}\r
index 9a0da53ff5a67e9d1b0dc4ccad7da791f8bd37b6..0664da48be01ccd0ce6c1f03b2330e3bdb2942df 100755 (executable)
@@ -17,11 +17,12 @@ using System.Xml;
 using System.Xml.Schema;\r
 using System.Xml.Serialization;\r
 using System.Globalization;\r
+using System.Text;\r
 \r
 namespace System.Runtime.Serialization.Formatters.Soap {\r
        \r
-       internal class SoapWriter: ISoapWriter {\r
-               public struct EnqueuedObject {\r
+       internal class SoapWriter: IComparer {\r
+               private struct EnqueuedObject {\r
                        public long _id;\r
                        public object _object;\r
                        \r
@@ -29,325 +30,526 @@ namespace System.Runtime.Serialization.Formatters.Soap {
                                _id = id;\r
                                _object = currentObject;\r
                        }\r
+\r
+                       public long Id \r
+                       {\r
+                               get \r
+                               {\r
+                                       return _id;\r
+                               }\r
+                       }\r
+\r
+                       public object Object \r
+                       {\r
+                               get \r
+                               {\r
+                                       return _object;\r
+                               }\r
+                       }\r
                }\r
                \r
-               private IFormatProvider _format;\r
+               #region Fields\r
+\r
                private XmlTextWriter _xmlWriter;\r
-               private ObjectWriter _objWriter;\r
                private Queue _objectQueue = new Queue();\r
-               private long _objectCounter = 0;\r
                private Hashtable _prefixTable = new Hashtable();\r
-               private Stack _currentArrayType = new Stack();\r
-               \r
-               ObjectIDGenerator _idGenerator = new ObjectIDGenerator ();\r
-               \r
-               private long _currentObjectId;\r
-               \r
-               private event DoneWithElementEventHandler Done;\r
-               public event DoneWithElementEventHandler DoneWithElementEvent;\r
-               public event DoneWithElementEventHandler DoneWithArray;\r
-               public event DoneWithElementEventHandler GetRootInfo;\r
+               private Hashtable _objectToIdTable = new Hashtable();\r
+               private ISurrogateSelector _surrogateSelector;\r
+               private SoapTypeMapper _mapper;\r
+               private StreamingContext _context;\r
+               private ISoapMessage _soapMessage = null;\r
+               private ObjectIDGenerator idGen = new ObjectIDGenerator();\r
+               private FormatterAssemblyStyle _assemblyFormat = FormatterAssemblyStyle.Full;\r
+               private FormatterTypeStyle _typeFormat = FormatterTypeStyle.TypesWhenNeeded;\r
+\r
+               #endregion\r
                \r
-               internal SoapWriter(Stream outStream) {\r
-                       // todo: manage the encoding\r
+               ~SoapWriter() \r
+               {\r
+               }\r
+\r
+               #region Constructors\r
+\r
+               internal SoapWriter(\r
+                       Stream outStream, \r
+                       ISurrogateSelector selector, \r
+                       StreamingContext context,\r
+                       ISoapMessage soapMessage)\r
+               {\r
                        _xmlWriter = new XmlTextWriter(outStream, null);\r
                        _xmlWriter.Formatting = Formatting.Indented;\r
-                       _xmlWriter.Indentation = 2;\r
-//                     _xmlWriter.WriteComment("My serialization function");\r
-                       _format = new CultureInfo("en-US");\r
+                       _surrogateSelector = selector;\r
+                       _context = context;\r
+                       _soapMessage = soapMessage;\r
+\r
                }\r
-               \r
-               ~SoapWriter() {\r
+\r
+               static SoapWriter() \r
+               {\r
+\r
                }\r
-               \r
-               private SoapSerializationEntry FillEntry(Type defaultObjectType, object objValue) {\r
-                       SoapTypeMapping mapping = GetTagInfo((objValue != null && defaultObjectType == typeof(object))?objValue.GetType():defaultObjectType);\r
-                       \r
-                       SoapSerializationEntry soapEntry = new SoapSerializationEntry();\r
-                       \r
-                       GetPrefix(mapping.TypeNamespace, out soapEntry.prefix);\r
-                       soapEntry.elementName = mapping.TypeName;\r
-                       soapEntry.elementNamespace = mapping.TypeNamespace;\r
-                       soapEntry.CanBeValue = mapping.CanBeValue;\r
-                       \r
-                       soapEntry.getIntoFields = false;\r
-                       if(mapping.CanBeValue || mapping.IsArray) soapEntry.WriteFullEndElement = true;\r
-                       if(defaultObjectType == typeof(object) || _currentArrayType.Count > 0 && _currentArrayType.Peek() == typeof(System.Object)) \r
-                               soapEntry.SpecifyEncoding = true;\r
-                       \r
-                       if(objValue == null){\r
-                               soapEntry.elementType = ElementType.Null;\r
-                               mapping.IsNull = true;\r
-                       } \r
-                       else \r
+\r
+               #endregion\r
+\r
+               #region Internal Properties\r
+\r
+               internal FormatterAssemblyStyle AssemblyFormat\r
+               {\r
+                       get \r
                        {\r
-                               if(mapping.IsValueType)\r
-                                       return soapEntry;\r
-                       \r
-                               bool firstTime;\r
-                               long id = _idGenerator.GetId (objValue, out firstTime);\r
-                               \r
-                               if(!firstTime) {\r
-                                       soapEntry.elementType = ElementType.Href;\r
-                                       soapEntry.i = id;\r
-                                       soapEntry.WriteFullEndElement = false;\r
-                                       soapEntry.SpecifyEncoding = false;\r
-                               }\r
-                               else if(!mapping.CanBeValue){\r
-                                       soapEntry.i = id;\r
-                                       soapEntry.elementType = ElementType.Href;\r
-                                       soapEntry.WriteFullEndElement = false;\r
-                                       _objectQueue.Enqueue(new EnqueuedObject(objValue, id));\r
-                                       soapEntry.SpecifyEncoding = false;\r
-                               } \r
-                               else if(mapping.NeedId){ \r
-                                       soapEntry.i = id;\r
-                                       soapEntry.elementType = ElementType.Id;\r
-                               }\r
+                               return _assemblyFormat;\r
                        }\r
-                       \r
-                       return soapEntry;\r
-               }\r
-               \r
-               private ICollection FormatteAttributes (object value, SoapSerializationEntry entry) {\r
-                       \r
-                       string prefix;\r
-                       bool needNamespace;\r
-                       ArrayList attributeList = new ArrayList();\r
-                       \r
-                       // If the type of the element needs to be specified, do it there\r
-                       if(entry.SpecifyEncoding) {\r
-                               needNamespace = GetPrefix(entry.elementNamespace, out prefix);\r
-                               attributeList.Add(new SoapAttributeStruct("xsi", XmlSchema.InstanceNamespace, "type", prefix+":"+ entry.elementName));\r
-                               if(needNamespace) attributeList.Add(new SoapAttributeStruct("xmlns", prefix, entry.elementNamespace));\r
+                       set \r
+                       {\r
+                               _assemblyFormat = value;\r
                        }\r
-                       \r
-                       switch(entry.elementType) {\r
-                               case ElementType.Null:\r
-                                       attributeList.Add(new SoapAttributeStruct("xsi", XmlSchema.InstanceNamespace, "null", "1"));\r
-                                       return attributeList;\r
-                                       //break;\r
-                               case ElementType.Id:\r
-                                       attributeList.Add(new SoapAttributeStruct(null, "id", "ref-"+entry.i.ToString()));\r
-                                       break;\r
-                               case ElementType.Href:\r
-                                       attributeList.Add(new SoapAttributeStruct(null, "href", "#ref-"+entry.i.ToString()));\r
-                                       return attributeList;\r
-                                       //break;\r
+               }\r
+\r
+               internal FormatterTypeStyle TypeFormat \r
+               {\r
+                       get \r
+                       {\r
+                               return _typeFormat;\r
                        }\r
-                       \r
-                       // Add attributes about the type of the array items\r
-                       if(entry.IsArray) {\r
-                               Array array = (Array) value;\r
-                               Type elementType = array.GetType().GetElementType();\r
-                               SoapTypeMapping elementMapping = GetTagInfo(elementType);\r
-                               string rank = "[";\r
-                               for(int i=0; i < array.Rank; i++){\r
-                                       rank += array.GetLength(i)+",";\r
-                               }\r
-                               rank = rank.Substring(0,rank.Length - 1);\r
-                               rank += "]";\r
-                               needNamespace = GetPrefix(elementMapping.TypeNamespace, out prefix);\r
-                               attributeList.Add(new SoapAttributeStruct("SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "arrayType", prefix+":"+elementMapping.TypeName+rank));\r
-                               if(needNamespace) attributeList.Add(new SoapAttributeStruct("xmlns", prefix, elementMapping.TypeNamespace));\r
-                               \r
+                       set \r
+                       {\r
+                               _typeFormat = value;\r
                        }\r
-                       return attributeList;\r
-               }\r
-               \r
-               private string GetNextObjectPrefix() {\r
-                       return "a"+(++_objectCounter);\r
                }\r
-               \r
-               private bool GetPrefix(string xmlNamespace, out string prefix) {\r
-                       prefix = _xmlWriter.LookupPrefix(xmlNamespace);\r
-                   if(prefix == null){ \r
-                       prefix = (string)_prefixTable[xmlNamespace];\r
-                       if(prefix == null){\r
-                                       prefix = GetNextObjectPrefix();\r
-                               _prefixTable[xmlNamespace] = prefix;\r
-                       }\r
-                       return true;\r
-                       }\r
-                       else\r
-                               return false;\r
+\r
+               #endregion\r
+\r
+               private void Id(long id) \r
+               {\r
+                       _xmlWriter.WriteAttributeString(null, "id", null, "ref-" + id.ToString());\r
                }\r
-               \r
-               private SoapTypeMapping GetTagInfo(Type tagType) {\r
-                       SoapTypeMapping mapping = SoapTypeMapper.GetSoapType(tagType);\r
-                       mapping.Href = 0;\r
-                       mapping.Id = 0;\r
-                       mapping.IsNull = false;\r
-                       \r
-                       return mapping;\r
-                       \r
+\r
+               private void Href(long href) \r
+               {\r
+                       _xmlWriter.WriteAttributeString(null, "href", null, "#ref-" + href.ToString());\r
                }\r
-               \r
-               public void WriteArrayItem(Type itemType, object itemValue) {\r
-                       SoapSerializationEntry soapEntry;\r
-                       \r
-                       soapEntry = FillEntry(itemType, itemValue);\r
-                       \r
-                       soapEntry.elementAttributes = FormatteAttributes (itemValue, soapEntry);\r
-                       \r
-                       soapEntry.elementName = "item";\r
-                       soapEntry.prefix = null;\r
-                       soapEntry.elementNamespace = null;\r
-                       if(soapEntry.elementType != ElementType.Href && soapEntry.CanBeValue) soapEntry.elementValue = itemValue.ToString();\r
-                       else if(itemType.IsValueType){\r
-                               // the array item is a struct\r
-                               // so we have to serialize it now\r
-                               soapEntry.getIntoFields = true;\r
-                               soapEntry.elementValue = itemValue;\r
-                               Done = GetRootInfo;\r
-                       } \r
-                       \r
-                       WriteElement(soapEntry);\r
+\r
+\r
+               private void Null() \r
+               {\r
+                       _xmlWriter.WriteAttributeString("xsi", "null", XmlSchema.InstanceNamespace, "1");\r
                }\r
-               \r
-               public void WriteFields(SerializationInfo info) {\r
-                       ICollection attributeList;\r
-                       SoapSerializationEntry soapEntry;\r
-                       \r
-                       foreach(SerializationEntry entry in info){\r
-                               soapEntry = FillEntry(entry.ObjectType, entry.Value);\r
-                               \r
-                               attributeList = FormatteAttributes (entry.Value, soapEntry);\r
-                               soapEntry.elementValue = (soapEntry.elementType != ElementType.Href && soapEntry.CanBeValue)?entry.Value:null;\r
-                               \r
-                               soapEntry.elementAttributes = attributeList;\r
-                               soapEntry.elementName = entry.Name;\r
-                               \r
-                               soapEntry.elementNamespace = null;\r
-                               soapEntry.prefix = null;\r
-                               \r
-                               WriteElement(soapEntry);\r
-                               \r
-                               \r
+\r
+               private bool IsEncodingNeeded(\r
+                       object componentObject,\r
+                       Type componentType)\r
+               {\r
+                       if(componentObject == null)\r
+                               return false;\r
+                       if(_typeFormat == FormatterTypeStyle.TypesAlways)\r
+                               return true;\r
+                       if(componentType == null) \r
+                       {\r
+                               componentType = componentObject.GetType();\r
+                               if(componentType.IsPrimitive || componentType == typeof(string))\r
+                                       return false;\r
+                               else\r
+                                       return true;\r
+\r
+                       }\r
+                       else \r
+                       {\r
+                               if(componentType == typeof(object) || componentType != componentObject.GetType())\r
+                                       return true;\r
+                               else\r
+                                       return false;\r
                        }\r
-                       \r
                }\r
 \r
-               private void WriteElement(SoapSerializationEntry entry) {\r
-                       _xmlWriter.WriteStartElement(entry.prefix, XmlConvert.EncodeNmToken(entry.elementName), entry.elementNamespace);\r
-                       \r
-                       if (entry.elementAttributes != null) foreach(SoapAttributeStruct attr in entry.elementAttributes){\r
-                               _xmlWriter.WriteAttributeString(attr.prefix, attr.attributeName, attr.nameSpace, attr.attributeValue);\r
+\r
+               internal void Serialize(\r
+                       object objGraph,\r
+                       FormatterTypeStyle typeFormat,\r
+                       FormatterAssemblyStyle assemblyFormat)\r
+               {\r
+                       _typeFormat = typeFormat;\r
+                       _assemblyFormat = assemblyFormat;\r
+                       // Create the XmlDocument with the \r
+                       // Envelope and Body elements\r
+                       _mapper = new SoapTypeMapper(_xmlWriter, assemblyFormat, typeFormat);\r
+\r
+                       // The root element\r
+                       _xmlWriter.WriteStartElement(\r
+                               SoapTypeMapper.SoapEnvelopePrefix, \r
+                               "Envelope",\r
+                               SoapTypeMapper.SoapEnvelopeNamespace);\r
+\r
+                       // adding namespaces\r
+                       _xmlWriter.WriteAttributeString(\r
+                               "xmlns",\r
+                               "xsi",\r
+                               "http://www.w3.org/2000/xmlns/",\r
+                               "http://www.w3.org/2001/XMLSchema-instance");\r
+\r
+                       _xmlWriter.WriteAttributeString(\r
+                               "xmlns",\r
+                               "xsd",\r
+                               "http://www.w3.org/2000/xmlns/",\r
+                               XmlSchema.Namespace);\r
+\r
+                       _xmlWriter.WriteAttributeString(\r
+                               "xmlns",\r
+                               SoapTypeMapper.SoapEncodingPrefix,\r
+                               "http://www.w3.org/2000/xmlns/",\r
+                               SoapTypeMapper.SoapEncodingNamespace);\r
+\r
+                       _xmlWriter.WriteAttributeString(\r
+                               "xmlns",\r
+                               SoapTypeMapper.SoapEnvelopePrefix,\r
+                               "http://www.w3.org/2000/xmlns/",\r
+                               SoapTypeMapper.SoapEnvelopeNamespace);\r
+\r
+                       _xmlWriter.WriteAttributeString(\r
+                               "xmlns",\r
+                               "clr",\r
+                               "http://www.w3.org/2000/xmlns/",\r
+                               SoapServices.XmlNsForClrType);\r
+\r
+                       _xmlWriter.WriteAttributeString(\r
+                               SoapTypeMapper.SoapEnvelopePrefix,\r
+                               "encodingStyle",\r
+                               SoapTypeMapper.SoapEnvelopeNamespace,\r
+                               "http://schemas.xmlsoap.org/soap/encoding/");\r
+\r
+                       // The body element\r
+                       _xmlWriter.WriteStartElement(\r
+                               SoapTypeMapper.SoapEnvelopePrefix,\r
+                               "Body",\r
+                               SoapTypeMapper.SoapEnvelopeNamespace);\r
+\r
+\r
+                       bool firstTime = false;\r
+\r
+                       if(objGraph is ISoapMessage)\r
+                       {\r
+                               SerializeMessage(objGraph as ISoapMessage);\r
+                               \r
                        }\r
-                       if(entry.CanBeValue && entry.elementValue != null && !entry.getIntoFields){\r
-                               _xmlWriter.WriteString(String.Format(_format, "{0}", entry.elementValue));\r
+                       else\r
+                               _objectQueue.Enqueue(new EnqueuedObject( objGraph, idGen.GetId(objGraph, out firstTime)));\r
+\r
+                       while(_objectQueue.Count > 0) \r
+                       {\r
+                               EnqueuedObject currentEnqueuedObject;\r
+                               currentEnqueuedObject = (EnqueuedObject) _objectQueue.Dequeue();\r
+                               object currentObject =  currentEnqueuedObject.Object;\r
+                               Type currentType = currentObject.GetType();\r
+\r
+                               if(!currentType.IsValueType) _objectToIdTable[currentObject] = currentEnqueuedObject.Id;\r
+\r
+                               if(currentType.IsArray) \r
+                               {\r
+                                               SerializeArray((Array) currentObject, currentEnqueuedObject.Id);\r
+                               }\r
+                               else\r
+                               {\r
+                                       SerializeObject(currentObject, currentEnqueuedObject.Id);\r
+                               }\r
+\r
                        }\r
-                       if( entry.getIntoFields && Done != null) Done(this, new DoneWithElementEventArgs(entry.elementValue));                  \r
-                       if(entry.WriteFullEndElement) {\r
-                               _xmlWriter.WriteFullEndElement();\r
-                       }else \r
-                               _xmlWriter.WriteEndElement();\r
-                       \r
+\r
+                       _xmlWriter.WriteFullEndElement(); // the body element\r
+                       _xmlWriter.WriteFullEndElement(); // the envelope element\r
+                       _xmlWriter.Flush();\r
                }\r
-               \r
-               \r
-               public void WriteRoot(object rootValue, Type rootType, bool getIntoFields) { //EnqueuedObject rootObject) {\r
-                       Done = DoneWithElementEvent;\r
-                       SoapSerializationEntry entry = FillEntry(rootType, rootValue); //new SoapSerializationEntry();\r
-                       if(rootType.IsArray) {\r
 \r
-                               Done = DoneWithArray;\r
-                               entry.IsArray = true;\r
+               private void SerializeMessage(ISoapMessage message) \r
+               {\r
+                       bool firstTime;\r
+                       _xmlWriter.WriteStartElement("i2", message.MethodName, message.XmlNameSpace);\r
+                       Id(idGen.GetId(message, out firstTime));\r
+\r
+                       string[] paramNames = message.ParamNames;\r
+                       Type[] paramTypes = message.ParamTypes;\r
+                       object[] paramValues = message.ParamValues;\r
+                       int length = (paramNames != null)?paramNames.Length:0;\r
+\r
+                       for(int i = 0; i < length; i++) \r
+                       {\r
+                               _xmlWriter.WriteStartElement(paramNames[i]);\r
+//                             bool specifyEncoding = false;\r
+//                             if(paramValues[i].GetType() != paramTypes[i]) specifyEncoding = true;\r
+                               SerializeComponent(paramValues[i], IsEncodingNeeded(paramValues[i], paramTypes[i]));\r
+                               _xmlWriter.WriteEndElement();\r
                        }\r
-                       \r
-                       entry.i = _currentObjectId;\r
-                       entry.elementType = ElementType.Id;\r
-                       ICollection attributeList = FormatteAttributes (rootValue, entry);\r
-                       entry.elementAttributes = attributeList;\r
-                       \r
-                       entry.elementValue = rootValue;\r
-                       entry.getIntoFields = getIntoFields;\r
-                       entry.WriteFullEndElement = true;\r
-                       \r
-                       if(_currentArrayType.Count > 0 )\r
-                               Done(this, new DoneWithElementEventArgs(entry.elementValue));\r
-                       else\r
-                               WriteElement(entry);\r
-                       \r
+\r
+\r
+                       _xmlWriter.WriteFullEndElement();\r
                }\r
-               \r
-               \r
-               public void Run() {\r
-                       WriteEnvelope();\r
-                       _xmlWriter.Flush();\r
+\r
+               private void SerializeObject(object currentObject, long currentObjectId) \r
+               {\r
+                       bool needsSerializationInfo = false;\r
+                       ISurrogateSelector selector;\r
+                       ISerializationSurrogate surrogate = null;\r
+                       if(_surrogateSelector != null)\r
+                       {\r
+                                surrogate = _surrogateSelector.GetSurrogate(\r
+                                       currentObject.GetType(),\r
+                                       _context,\r
+                                       out selector);\r
+                       }\r
+                       if(currentObject is ISerializable || surrogate != null) needsSerializationInfo = true;\r
+                       if(needsSerializationInfo) \r
+                       {\r
+                               SerializeISerializableObject(currentObject, currentObjectId, surrogate);\r
+                       }\r
+                       else \r
+                       {\r
+                               if(!currentObject.GetType().IsSerializable)\r
+                                       throw new SerializationException(String.Format("Type {0} in assembly {1} is not marked as serializable.", currentObject.GetType(), currentObject.GetType().Assembly.FullName));\r
+                               SerializeSimpleObject(currentObject, currentObjectId);\r
+                       }\r
                }\r
-               \r
-               public ObjectWriter Writer {\r
-                       get{ return _objWriter;}\r
-                       set{ _objWriter = value;}\r
+\r
+               // implement IComparer\r
+               public int Compare(object x, object y) \r
+               {\r
+                       MemberInfo a = x as MemberInfo;\r
+                       MemberInfo b = y as MemberInfo;\r
+\r
+                       return String.Compare(a.Name, b.Name);\r
                }\r
-               \r
-               public object TopObject {\r
-                       set {\r
-                               bool ft;\r
-                               _currentObjectId = _idGenerator.GetId (value, out ft);\r
-                               _objectQueue.Enqueue(new EnqueuedObject(value, _currentObjectId));\r
+\r
+               private void SerializeSimpleObject(\r
+                       object currentObject, \r
+                       long currentObjectId) \r
+               {\r
+                       Type currentType = currentObject.GetType();\r
+                       \r
+                       // Value type have to be serialized "on the fly" so\r
+                       // SerializeComponent calls SerializeObject when\r
+                       // a field of another object is a struct. A node with the field\r
+                       // name has already be written so WriteStartElement must not be called\r
+                       // again. Fields that are structs are passed to SerializeObject\r
+                       // with a id = 0\r
+                       if(currentObjectId > 0)\r
+                       {\r
+                               Element element = _mapper[currentType];\r
+                               _xmlWriter.WriteStartElement(element.Prefix, element.LocalName, element.NamespaceURI);\r
+                               Id(currentObjectId);\r
+                       }\r
+                       if(currentType == typeof(string))\r
+                       {\r
+                               _xmlWriter.WriteString(currentObject.ToString());\r
+                       }\r
+                       else\r
+                       {\r
+                               MemberInfo[] memberInfos = \r
+                                       FormatterServices.GetSerializableMembers(currentType, _context);\r
+                               object[] objectData =\r
+                                       FormatterServices.GetObjectData(currentObject, memberInfos);\r
+//                             Array.Sort(memberInfos, objectData, this);\r
+                               for(int i = 0; i < memberInfos.Length; i++) \r
+                               {\r
+                                       FieldInfo fieldInfo = memberInfos[i] as FieldInfo;\r
+//                                     bool specifyEncoding = false;\r
+//                                     if(objectData[i] != null)\r
+//                                              specifyEncoding = (objectData[i].GetType() != fieldInfo.FieldType);\r
+                                       _xmlWriter.WriteStartElement(fieldInfo.Name);\r
+                                       SerializeComponent(\r
+                                               objectData[i], \r
+                                               IsEncodingNeeded(objectData[i], fieldInfo.FieldType));\r
+                                       _xmlWriter.WriteEndElement();\r
+                               }\r
                        }\r
+                       if(currentObjectId > 0)\r
+                               _xmlWriter.WriteFullEndElement();\r
+\r
                }\r
-               \r
-               private void WriteEnvelope() {\r
-                       ArrayList lstAttr = new ArrayList();\r
-                       _xmlWriter.WriteStartElement("SOAP-ENV", "Envelope",  "http://schemas.xmlsoap.org/soap/envelope/");\r
-                       \r
-                       _xmlWriter.WriteAttributeString("xmlns", "xsi", null, XmlSchema.InstanceNamespace);\r
-                       _xmlWriter.WriteAttributeString("xmlns", "xsd", null, XmlSchema.Namespace );\r
-                       _xmlWriter.WriteAttributeString("xmlns", "SOAP-ENC", null, "http://schemas.xmlsoap.org/soap/encoding/");\r
-                       _xmlWriter.WriteAttributeString("xmlns", "SOAP-ENV", null, "http://schemas.xmlsoap.org/soap/envelope/");\r
-                       _xmlWriter.WriteAttributeString("xmlns", "clr", null, "http://schemas.microsoft.com/soap/encoding/clr/1.0" );\r
-                       _xmlWriter.WriteAttributeString("SOAP-ENV", "encodingStyle", "http://schemas.xmlsoap.org/soap/envelope/", "http://schemas.xmlsoap.org/soap/encoding/");\r
-                       \r
-                       WriteBody();\r
-                       \r
-                       _xmlWriter.WriteEndElement();\r
-                       _xmlWriter.Flush();\r
+\r
+               private void SerializeISerializableObject(\r
+                       object currentObject,\r
+                       long currentObjectId,\r
+                       ISerializationSurrogate surrogate)\r
+               {\r
+                       Type currentType = currentObject.GetType();\r
+                       SerializationInfo info = new SerializationInfo(currentType, new FormatterConverter());\r
+\r
+\r
+                       ISerializable objISerializable = currentObject as ISerializable;\r
+                       if(surrogate != null) surrogate.GetObjectData(currentObject, info, _context);\r
+                       else\r
+                       {\r
+                               objISerializable.GetObjectData(info, _context);\r
+                       }\r
+\r
+                       // Same as above\r
+                       if(currentObjectId > 0L)\r
+                       {\r
+                               Element element = _mapper[info.FullTypeName, info.AssemblyName];\r
+                               _xmlWriter.WriteStartElement(element.Prefix, element.LocalName, element.NamespaceURI);\r
+                               Id(currentObjectId);\r
+                       }\r
+\r
+                       foreach(SerializationEntry entry in info)\r
+                       {\r
+                               _xmlWriter.WriteStartElement(entry.Name);\r
+                               SerializeComponent(entry.Value, IsEncodingNeeded(entry.Value, null));\r
+                               _xmlWriter.WriteEndElement();\r
+                       }\r
+                       if(currentObjectId > 0)\r
+                               _xmlWriter.WriteFullEndElement();\r
+\r
                }\r
-               \r
-               private void WriteBody() {\r
-                       _xmlWriter.WriteStartElement("SOAP-ENV", "Body",  "http://schemas.xmlsoap.org/soap/envelope/");\r
+\r
+               private void SerializeArray(Array currentArray, long currentArrayId) \r
+               {\r
+                       Element element = _mapper[typeof(System.Array)];\r
                        \r
-                       EnqueuedObject enqueuedObject;\r
-                       while(_objectQueue.Count > 0){\r
-                               enqueuedObject = (EnqueuedObject) _objectQueue.Dequeue();\r
-                               _currentObjectId = enqueuedObject._id;\r
-                               if(enqueuedObject._object is ISoapMessage)\r
-                                       WriteSoapRPC((ISoapMessage) enqueuedObject._object);\r
-                               else\r
-                                       GetRootInfo(this, new DoneWithElementEventArgs(enqueuedObject._object)); //WriteRoot(enqueuedObject);\r
+\r
+                       // Set the arrayType attribute\r
+                       Type arrayType = currentArray.GetType().GetElementType();\r
+                       Element xmlArrayType = _mapper[arrayType];\r
+                       _xmlWriter.WriteStartElement(element.Prefix, element.LocalName, element.NamespaceURI);\r
+                       if(currentArrayId > 1) Id(currentArrayId);\r
+\r
+                       if(_xmlWriter.LookupPrefix(xmlArrayType.NamespaceURI) == null)\r
+                       {\r
+                               _xmlWriter.WriteAttributeString(\r
+                                       "xmlns",\r
+                                       xmlArrayType.Prefix,\r
+                                       "http://www.w3.org/2000/xmlns/",\r
+                                       xmlArrayType.NamespaceURI);\r
                        }\r
-                       \r
-                       _xmlWriter.WriteEndElement();\r
+\r
+                       StringBuilder str = new StringBuilder();\r
+                       str.AppendFormat("{0}:{1}[",xmlArrayType.Prefix, xmlArrayType.LocalName);\r
+                       for(int i = 0; i < currentArray.Rank; i++)\r
+                       {\r
+                               str.AppendFormat("{0},", currentArray.GetUpperBound(i) + 1);\r
+                       }\r
+                       str.Replace(',', ']', str.Length - 1, 1);\r
+                       _xmlWriter.WriteAttributeString(\r
+                               SoapTypeMapper.SoapEncodingPrefix,\r
+                               "arrayType",\r
+                               SoapTypeMapper.SoapEncodingNamespace,\r
+                               str.ToString());\r
+                               \r
+\r
+                       // Get the array items\r
+                       int lastNonNullItem = 0;\r
+                       int currentIndex = 0;\r
+//                     bool specifyEncoding = false;\r
+                       foreach(object item in currentArray) \r
+                       {\r
+                               if(item != null)\r
+                               {\r
+                                       for(int j = lastNonNullItem; j < currentIndex; j++)\r
+                                       {\r
+                                               _xmlWriter.WriteStartElement("item");\r
+                                               Null();\r
+                                               _xmlWriter.WriteEndElement();\r
+                                       }; \r
+                                       lastNonNullItem = currentIndex + 1;\r
+//                                     specifyEncoding |= (arrayType != item.GetType());\r
+                                       _xmlWriter.WriteStartElement("item");\r
+                                       SerializeComponent(item, IsEncodingNeeded(item, arrayType));\r
+                                       _xmlWriter.WriteEndElement();\r
+                               }\r
+                               currentIndex++;\r
+                       }\r
+                       _xmlWriter.WriteFullEndElement();\r
                        \r
                }\r
-               \r
-               private void WriteSoapRPC(ISoapMessage soapMsg) {\r
-                       \r
-                       _xmlWriter.WriteStartElement("i2", soapMsg.MethodName, soapMsg.XmlNameSpace);\r
-                       _xmlWriter.WriteAttributeString("id", null, "ref-"+_currentObjectId);\r
-                       SerializationInfo info = new SerializationInfo(soapMsg.GetType(), new FormatterConverter());\r
-                       \r
-                       \r
-                       if(soapMsg.ParamNames != null) {\r
-                               for(int i=0; i<soapMsg.ParamNames.Length; i++){\r
-                                       string name = soapMsg.ParamNames[i];\r
-                                       object objValue = soapMsg.ParamValues[i];\r
-                                       Type type = soapMsg.ParamTypes[i];\r
-                                       info.AddValue(name, objValue, type);\r
+\r
+               private void SerializeComponent(\r
+                       object obj,\r
+                       bool specifyEncoding)\r
+               {\r
+                       if(_typeFormat == FormatterTypeStyle.TypesAlways)\r
+                               specifyEncoding = true;\r
+\r
+                       // A null component\r
+                       if(obj == null)\r
+                       {\r
+                               Null();\r
+                               return;\r
+                       }\r
+                       Type objType = obj.GetType();\r
+                       bool canBeValue = SoapTypeMapper.CanBeValue(objType);\r
+                       bool firstTime;\r
+                       long id = 0;\r
+\r
+                       // An object already serialized\r
+                       if((id = idGen.HasId(obj, out firstTime)) != 0L) \r
+                       {\r
+                               Href((long)idGen.GetId(obj, out firstTime));\r
+                               return;\r
+                       }\r
+\r
+\r
+\r
+                       // A string\r
+                       if(objType == typeof(string)) \r
+                       {\r
+                               if(_typeFormat != FormatterTypeStyle.XsdString)\r
+                               {\r
+                                       id = idGen.GetId(obj, out firstTime);\r
+                                       Id(id);\r
                                }\r
-                               WriteFields(info);\r
+//                             specifyEncoding = false;\r
                        }\r
-                       \r
-                       \r
-                       _xmlWriter.WriteEndElement();\r
-                       \r
+\r
+                       // This component has to be \r
+                       // serialized later\r
+                       if(!canBeValue && !objType.IsValueType)\r
+                       {\r
+                               long href = idGen.GetId(obj, out firstTime);\r
+                               Href(href);\r
+                               _objectQueue.Enqueue(new EnqueuedObject(obj, href));\r
+                               return;\r
+                       }\r
+\r
+                       if(specifyEncoding)\r
+                       {\r
+                               EncodeType(objType);\r
+                       }\r
+\r
+                       // A struct\r
+                       if(!canBeValue && objType.IsValueType)\r
+                       {\r
+                               SerializeObject(obj, 0);\r
+                               return;\r
+                       }\r
+\r
+                       if(obj is double)\r
+                               _xmlWriter.WriteString(((double)obj).ToString("R"));\r
+                       else if(obj is DateTime)\r
+                               _xmlWriter.WriteString(((DateTime)obj).ToString("s")\r
+                                       + ((DateTime)obj).ToString(".fffffffzzz"));\r
+                       else\r
+                               _xmlWriter.WriteString(obj.ToString());\r
                }\r
-               \r
-               public Stack CurrentArrayType {\r
-                       get { return _currentArrayType;}\r
+\r
+               private void EncodeType(Type type) \r
+               {\r
+                       if(type == null) \r
+                               throw new SerializationException("Oooops");\r
+\r
+                       Element xmlType = _mapper[type];\r
+\r
+                       _xmlWriter.WriteAttributeString(\r
+                               "xsi",\r
+                               "type",\r
+                               "http://www.w3.org/2001/XMLSchema-instance",\r
+                               xmlType.Prefix + ":" + xmlType.LocalName);\r
+                       string prefix = _xmlWriter.LookupPrefix(xmlType.NamespaceURI);\r
+                       if(prefix == null || prefix == string.Empty) \r
+                       {\r
+                               _xmlWriter.WriteAttributeString(\r
+                                       "xmlns",\r
+                                       xmlType.Prefix,\r
+                                       "http://www.w3.org/2000/xmlns/",\r
+                                       xmlType.NamespaceURI);\r
+\r
+                       }\r
+\r
                }\r
        }\r
 }\r
diff --git a/mcs/class/System.Runtime.Serialization.Formatters.Soap/Test/SerializationTest.cs b/mcs/class/System.Runtime.Serialization.Formatters.Soap/Test/SerializationTest.cs
new file mode 100644 (file)
index 0000000..4ad3a1d
--- /dev/null
@@ -0,0 +1,771 @@
+//\r
+// System.Runtime.Serialization.SerializationTest.cs\r
+//\r
+// Author: Lluis Sanchez Gual  (lluis@ximian.com)\r
+//\r
+// (C) Ximian, Inc.\r
+//\r
+\r
+using System;\r
+using System.Diagnostics;\r
+using System.IO;\r
+using System.Runtime.Serialization;\r
+using System.Runtime.Serialization.Formatters.Soap;\r
+using System.Reflection;\r
+using System.Runtime.Remoting;\r
+using System.Runtime.Remoting.Channels;\r
+using System.Runtime.Remoting.Proxies;\r
+using System.Runtime.Remoting.Messaging;\r
+using System.Collections;\r
+using NUnit.Framework;\r
+\r
+namespace MonoTests.System.Runtime.Serialization.Formatters.Soap\r
+{\r
+       [TestFixture]\r
+       public class SerializationTest\r
+       {\r
+               MemoryStream ms;\r
+\r
+               [Test]\r
+               public void TestSerialization ()\r
+               {\r
+                       MethodTester mt = new MethodTester();\r
+                       RemotingServices.Marshal (mt, "myuri");\r
+\r
+                       WriteData();\r
+                       ReadData();\r
+\r
+                       RemotingServices.Disconnect (mt);\r
+               }\r
+\r
+               public static void Main() \r
+               {\r
+                       SerializationTest test = new SerializationTest();\r
+                       test.TestSerialization();\r
+               }\r
+\r
+               void WriteData ()\r
+               {\r
+                       StreamingContext context = new StreamingContext (StreamingContextStates.Other);\r
+                       SurrogateSelector sel = new SurrogateSelector();\r
+                       sel.AddSurrogate (typeof (Point), context, new PointSurrogate());\r
+\r
+                       List list = CreateTestData();\r
+                       BinderTester_A bta = CreateBinderTestData();\r
+\r
+                       ms = new MemoryStream();\r
+                       SoapFormatter f = new SoapFormatter (sel, new StreamingContext(StreamingContextStates.Other));\r
+                       f.Serialize (ms, list);\r
+//                     ProcessMessages (ms, null);\r
+//                     f.Serialize (ms, bta);\r
+                       ms.Flush ();\r
+                       ms.Position = 0;\r
+                       StreamReader reader = new StreamReader(ms);\r
+                       Console.WriteLine(reader.ReadToEnd());\r
+                       ms.Position = 0;\r
+               }\r
+\r
+               void ReadData()\r
+               {\r
+                       StreamingContext context = new StreamingContext (StreamingContextStates.Other);\r
+                       SurrogateSelector sel = new SurrogateSelector();\r
+                       sel.AddSurrogate (typeof (Point), context, new PointSurrogate());\r
+\r
+                       SoapFormatter f = new SoapFormatter (sel, context);\r
+\r
+                       object list = f.Deserialize (ms);\r
+\r
+                       object[][] originalMsgData = null;\r
+                       IMessage[] calls = null;\r
+                       IMessage[] resps = null;\r
+\r
+//                     originalMsgData = ProcessMessages (null, null);\r
+\r
+//                     calls = new IMessage[originalMsgData.Length];\r
+//                     resps = new IMessage[originalMsgData.Length];\r
+\r
+\r
+//                     for (int n=0; n<originalMsgData.Length; n++)\r
+//                     {\r
+//                             calls[n] = (IMessage) f.Deserialize (ms);\r
+//                             resps[n] = (IMessage) f.DeserializeMethodResponse (ms, null, (IMethodCallMessage)calls[n]);\r
+//                     }\r
+//\r
+//                     f.Binder = new TestBinder ();\r
+//                     object btbob = f.Deserialize (ms);\r
+\r
+                       ms.Close();\r
+\r
+                       ((List)list).CheckEquals(CreateTestData());\r
+//\r
+//                     BinderTester_A bta = CreateBinderTestData();\r
+//                     Assertion.AssertEquals ("BinderTest.class", btbob.GetType(), typeof (BinderTester_B));\r
+//                     BinderTester_B btb = btbob as BinderTester_B;\r
+//                     if (btb != null)\r
+//                     {\r
+//                             Assertion.AssertEquals ("BinderTest.x", btb.x, bta.x);\r
+//                             Assertion.AssertEquals ("BinderTest.y", btb.y, bta.y);\r
+//                     }\r
+//                     \r
+//                     CheckMessages ("MethodCall", originalMsgData, ProcessMessages (null, calls));\r
+//                     CheckMessages ("MethodResponse", originalMsgData, ProcessMessages (null, resps));\r
+               }\r
+\r
+               BinderTester_A CreateBinderTestData ()\r
+               {\r
+                       BinderTester_A bta = new BinderTester_A();\r
+                       bta.x = 11;\r
+                       bta.y = "binder tester";\r
+                       return bta;\r
+               }\r
+\r
+               List CreateTestData()\r
+               {\r
+                       List list = new List();\r
+                       list.name = "my list";\r
+                       list.values = new SomeValues();\r
+                       list.values.Init();\r
+\r
+                       ListItem item1 = new ListItem();\r
+                       ListItem item2 = new ListItem();\r
+                       ListItem item3 = new ListItem();\r
+\r
+                       item1.label = "value label 1";\r
+                       item1.next = item2;\r
+                       item1.value.color = 111;\r
+                       item1.value.point = new Point();\r
+                       item1.value.point.x = 11;\r
+                       item1.value.point.y = 22;\r
+\r
+                       item2.label = "value label 2";\r
+                       item2.next = item3;\r
+                       item2.value.color = 222;\r
+\r
+                       item2.value.point = new Point();\r
+                       item2.value.point.x = 33;\r
+                       item2.value.point.y = 44;\r
+\r
+                       item3.label = "value label 3";\r
+                       item3.value.color = 333;\r
+                       item3.value.point = new Point();\r
+                       item3.value.point.x = 55;\r
+                       item3.value.point.y = 66;\r
+\r
+                       list.children = new ListItem[3];\r
+\r
+                       list.children[0] = item1;\r
+                       list.children[1] = item2;\r
+                       list.children[2] = item3;\r
+\r
+                       return list;\r
+               }\r
+\r
+\r
+               object[][] ProcessMessages (Stream stream, IMessage[] messages)\r
+               {\r
+                       object[][] results = new object[9][];\r
+\r
+                       AuxProxy prx = new AuxProxy (stream, "myuri");\r
+                       MethodTester mt = (MethodTester)prx.GetTransparentProxy();\r
+                       object res;\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[0]);\r
+                       res = mt.OverloadedMethod();\r
+                       results[0] = new object[] {res};\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[1]);\r
+                       res = mt.OverloadedMethod(22);\r
+                       results[1] = new object[] {res};\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[2]);\r
+                       int[] par1 = new int[] {1,2,3};\r
+                       res = mt.OverloadedMethod(par1);\r
+                       results[2] = new object[] { res, par1 };\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[3]);\r
+                       mt.NoReturn();\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[4]);\r
+                       res = mt.Simple ("hello",44);\r
+                       results[4] = new object[] { res };\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[5]);\r
+                       res = mt.Simple2 ('F');\r
+                       results[5] = new object[] { res };\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[6]);\r
+                       char[] par2 = new char[] { 'G' };\r
+                       res = mt.Simple3 (par2);\r
+                       results[6] = new object[] { res, par2 };\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[7]);\r
+                       res = mt.Simple3 (null);\r
+                       results[7] = new object[] { res };\r
+\r
+                       if (messages != null) prx.SetTestMessage (messages[8]);\r
+\r
+                       SimpleClass b = new SimpleClass ('H');\r
+                       res = mt.SomeMethod (123456, b);\r
+                       results[8] = new object[] { res, b };\r
+\r
+                       return results;\r
+               }\r
+\r
+               void CheckMessages (string label, object[][] original, object[][] serialized)\r
+               {\r
+                       for (int n=0; n<original.Length; n++)\r
+                               EqualsArray (label + " " + n, original[n], serialized[n]);\r
+               }\r
+\r
+               public static void AssertEquals(string message, Object expected, Object actual)\r
+               {\r
+                       if (expected != null && expected.GetType().IsArray)\r
+                               EqualsArray (message, (Array)expected, (Array)actual);\r
+                       else\r
+                               Assertion.AssertEquals (message, expected, actual);\r
+               }\r
+\r
+               public static void EqualsArray (string message, object oar1, object oar2)\r
+               {\r
+                       if (oar1 == null || oar2 == null || !(oar1 is Array) || !(oar2 is Array))\r
+                       {\r
+                               SerializationTest.AssertEquals (message, oar1, oar2);\r
+                               return;\r
+                       }\r
+\r
+                       Array ar1 = (Array) oar1;\r
+                       Array ar2 = (Array) oar2;\r
+\r
+                       SerializationTest.AssertEquals(message + ".Length", ar1.Length,ar2.Length);\r
+\r
+                       for (int n=0; n<ar1.Length; n++)\r
+                       {\r
+                               object av1 = ar1.GetValue(n);\r
+                               object av2 = ar2.GetValue(n);\r
+                               SerializationTest.AssertEquals (message + "[" + n + "]", av1, av2);\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+\r
+       class PointSurrogate: ISerializationSurrogate\r
+       {\r
+               public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)\r
+               {\r
+                       Point p = (Point)obj;\r
+                       info.AddValue ("xv",p.x);\r
+                       info.AddValue ("yv",p.y);\r
+               }\r
+\r
+               public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)\r
+               {\r
+                       typeof (Point).GetField ("x").SetValue (obj, info.GetInt32 ("xv"));\r
+                       typeof (Point).GetField ("y").SetValue (obj, info.GetInt32 ("yv"));\r
+                       return obj;\r
+               }\r
+       }\r
+\r
+       [Serializable]\r
+       public class List\r
+       {\r
+               public string name = null;\r
+               public ListItem[] children = null; \r
+               public SomeValues values;\r
+\r
+               public void CheckEquals(List val)\r
+               {\r
+                       SerializationTest.AssertEquals ("List.children.Length", children.Length, val.children.Length);\r
+\r
+                       for (int n=0; n<children.Length; n++)\r
+                               children[n].CheckEquals (val.children[n]);\r
+\r
+                       SerializationTest.AssertEquals ("List.name", name, val.name);\r
+                       values.CheckEquals (val.values);\r
+               }\r
+       }\r
+\r
+       [Serializable]\r
+       public class ListItem: ISerializable\r
+       {\r
+               public ListItem()\r
+               {\r
+               }\r
+\r
+               ListItem (SerializationInfo info, StreamingContext ctx)\r
+               {\r
+                       next = (ListItem)info.GetValue ("next", typeof (ListItem));\r
+                       value = (ListValue)info.GetValue ("value", typeof (ListValue));\r
+                       label = info.GetString ("label");\r
+               }\r
+\r
+               public void GetObjectData (SerializationInfo info, StreamingContext ctx)\r
+               {\r
+                       info.AddValue ("next", next);\r
+                       info.AddValue ("value", value);\r
+                       info.AddValue ("label", label);\r
+               }\r
+\r
+               public void CheckEquals(ListItem val)\r
+               {\r
+                       SerializationTest.AssertEquals ("ListItem.next", next, val.next);\r
+                       SerializationTest.AssertEquals ("ListItem.label", label, val.label);\r
+                       value.CheckEquals (val.value);\r
+               }\r
+               \r
+               public override bool Equals(object obj)\r
+               {\r
+                       ListItem val = (ListItem)obj;\r
+                       if ((next == null || val.next == null) && (next != val.next)) return false;\r
+                       if (next == null) return true;\r
+                       if (!next.Equals(val.next)) return false;\r
+                       return value.Equals (val.value) && label == val.label;\r
+               }\r
+\r
+               public override int GetHashCode ()\r
+               {\r
+                       return base.GetHashCode ();\r
+               }\r
+\r
+               public ListItem next;\r
+               public ListValue value;\r
+               public string label;\r
+       }\r
+\r
+       [Serializable]\r
+       public struct ListValue\r
+       {\r
+               public int color;\r
+               public Point point;\r
+               \r
+               public override bool Equals(object obj)\r
+               {\r
+                       ListValue val = (ListValue)obj;\r
+                       return (color == val.color && point.Equals(val.point));\r
+               }\r
+\r
+               public void CheckEquals(ListValue val)\r
+               {\r
+                       SerializationTest.AssertEquals ("ListValue.color", color, val.color);\r
+                       point.CheckEquals (val.point);\r
+               }\r
+\r
+               public override int GetHashCode ()\r
+               {\r
+                       return base.GetHashCode ();\r
+               }\r
+       }\r
+\r
+//     [Serializable]\r
+       public struct Point\r
+       {\r
+               public int x;\r
+               public int y;\r
+\r
+               public override bool Equals(object obj)\r
+               {\r
+                       Point p = (Point)obj;\r
+                       return (x == p.x && y == p.y);\r
+               }\r
+\r
+               public void CheckEquals(Point p)\r
+               {\r
+                       SerializationTest.AssertEquals ("Point.x", x, p.x);\r
+                       SerializationTest.AssertEquals ("Point.y", y, p.y);\r
+               }\r
+\r
+               public override int GetHashCode ()\r
+               {\r
+                       return base.GetHashCode ();\r
+               }\r
+       }\r
+\r
+       [Serializable]\r
+       public class SimpleClass\r
+       {\r
+               public SimpleClass (char v) { val = v; }\r
+\r
+               public override bool Equals(object obj)\r
+               {\r
+                       if (obj == null) return false;\r
+                       return val == ((SimpleClass)obj).val;\r
+               }\r
+\r
+               public override int GetHashCode()\r
+               {\r
+                       return val.GetHashCode();\r
+               }\r
+\r
+               public int SampleCall (string str, SomeValues sv, ref int acum)\r
+               {\r
+                       acum += (int)val;\r
+                       return (int)val;\r
+               }\r
+\r
+               public char val;\r
+       }\r
+\r
+       enum IntEnum { aaa, bbb, ccc }\r
+       enum ByteEnum: byte { aaa=221, bbb=3, ccc=44 }\r
+\r
+       delegate int SampleDelegate (string str, SomeValues sv, ref int acum);\r
+\r
+       [Serializable]\r
+       public class SomeValues\r
+       {\r
+               Type _type;\r
+               Type _type2;\r
+               DBNull _dbnull;\r
+               Assembly _assembly;\r
+               IntEnum _intEnum;\r
+               ByteEnum _byteEnum;\r
+\r
+               bool _bool;\r
+               bool _bool2;\r
+               byte _byte;\r
+               char _char;\r
+               DateTime _dateTime;\r
+               decimal _decimal;\r
+               double _double;\r
+               short _short;\r
+               int _int;\r
+               long _long;\r
+               sbyte _sbyte;\r
+               float _float;\r
+               ushort _ushort;\r
+               uint _uint;\r
+               ulong _ulong;\r
+\r
+               object[] _objects;\r
+               string[] _strings;\r
+               int[] _ints;\r
+               public int[,,] _intsMulti;\r
+               int[][] _intsJagged;\r
+               SimpleClass[] _simples;\r
+               SimpleClass[,] _simplesMulti;\r
+               SimpleClass[][] _simplesJagged;\r
+               double[] _doubles;\r
+               object[] _almostEmpty;\r
+\r
+               object[] _emptyObjectArray;\r
+               Type[] _emptyTypeArray;\r
+               SimpleClass[] _emptySimpleArray;\r
+               int[] _emptyIntArray;\r
+               string[] _emptyStringArray;\r
+\r
+\r
+               SampleDelegate _sampleDelegate;\r
+               SampleDelegate _sampleDelegate2;\r
+               SampleDelegate _sampleDelegate3;\r
+               SampleDelegate _sampleDelegateStatic;\r
+               SampleDelegate _sampleDelegateCombined;\r
+\r
+               SimpleClass _shared1;\r
+               SimpleClass _shared2;\r
+               SimpleClass _shared3;\r
+\r
+               public void Init()\r
+               {\r
+                       _type = typeof (string);\r
+                       _type2 = typeof (SomeValues);\r
+                       _dbnull = DBNull.Value;\r
+                       _assembly = typeof (SomeValues).Assembly;\r
+                       _intEnum = IntEnum.bbb;\r
+                       _byteEnum = ByteEnum.ccc;\r
+                       _bool = true;\r
+                       _bool2 = false;\r
+                       _byte = 254;\r
+                       _char = 'A';\r
+                       _dateTime = new DateTime (1972,7,13,1,20,59);\r
+                       _decimal = (decimal)101010.10101;\r
+                       _double = 123456.6789;\r
+                       _short = -19191;\r
+                       _int = -28282828;\r
+                       _long = 37373737373;\r
+                       _sbyte = -123;\r
+                       _float = (float)654321.321;\r
+                       _ushort = 61616;\r
+                       _uint = 464646464;\r
+                       _ulong = 55555555;\r
+\r
+                       Point p = new Point();\r
+                       p.x = 56; p.y = 67;\r
+                       object boxedPoint = p;\r
+\r
+                       long i = 22;\r
+                       object boxedLong = i;\r
+\r
+                       _objects = new object[] { "string", (int)1234, null , /*boxedPoint, boxedPoint,*/ boxedLong, boxedLong};\r
+                       _strings = new string[] { "an", "array", "of", "strings","I","repeat","an", "array", "of", "strings" };\r
+                       _ints = new int[] { 4,5,6,7,8 };\r
+                       _intsMulti = new int[2,3,4] { { {1,2,3,4},{5,6,7,8},{9,10,11,12}}, { {13,14,15,16},{17,18,19,20},{21,22,23,24} } };\r
+                       _intsJagged = new int[2][] { new int[3] {1,2,3}, new int[2] {4,5} };\r
+                       _simples = new SimpleClass[] { new SimpleClass('a'),new SimpleClass('b'),new SimpleClass('c') };\r
+                       _simplesMulti = new SimpleClass[2,3] {{new SimpleClass('d'),new SimpleClass('e'),new SimpleClass('f')}, {new SimpleClass('g'),new SimpleClass('j'),new SimpleClass('h')}};\r
+                       _simplesJagged = new SimpleClass[2][] { new SimpleClass[1] { new SimpleClass('i') }, new SimpleClass[2] {null, new SimpleClass('k')}};\r
+                       _almostEmpty = new object[2000];\r
+                       _almostEmpty[1000] = 4;\r
+\r
+                       _emptyObjectArray = new object[0];\r
+                       _emptyTypeArray = new Type[0];\r
+                       _emptySimpleArray = new SimpleClass[0];\r
+                       _emptyIntArray = new int[0];\r
+                       _emptyStringArray = new string[0];\r
+\r
+                       // FIXME: Once double.ToString("G17") is implemented\r
+                       // we'll be able to serialize double.MaxValue and double.MinValue.\r
+                       // Currently, it throws a System.OverflowException.\r
+                       //_doubles = new double[] { 1010101.101010, 292929.29292, 3838383.38383, 4747474.474, 56565.5656565, 0, Double.NaN, Double.MaxValue, Double.MinValue, Double.NegativeInfinity, Double.PositiveInfinity };\r
+                       _doubles = new double[] { 1010101.101010, 292929.29292, 3838383.38383, 4747474.474, 56565.5656565, 0, Double.NaN, Double.NegativeInfinity, Double.PositiveInfinity };\r
+\r
+                       _sampleDelegate = new SampleDelegate(SampleCall);\r
+                       _sampleDelegate2 = new SampleDelegate(_simples[0].SampleCall);\r
+                       _sampleDelegate3 = new SampleDelegate(new SimpleClass('x').SampleCall);\r
+                       _sampleDelegateStatic = new SampleDelegate(SampleStaticCall);\r
+                       _sampleDelegateCombined = (SampleDelegate)Delegate.Combine (new Delegate[] {_sampleDelegate, _sampleDelegate2, _sampleDelegate3, _sampleDelegateStatic });\r
+\r
+                       // This is to test that references are correctly solved\r
+                       _shared1 = new SimpleClass('A');\r
+                       _shared2 = new SimpleClass('A');\r
+                       _shared3 = _shared1;\r
+               }\r
+\r
+               public int SampleCall (string str, SomeValues sv, ref int acum)\r
+               {\r
+                       acum += _int;\r
+                       return _int;\r
+               }\r
+\r
+               public static int SampleStaticCall (string str, SomeValues sv, ref int acum)\r
+               {\r
+                       acum += 99;\r
+                       return 99;\r
+               }\r
+\r
+               public void CheckEquals(SomeValues obj)\r
+               {\r
+                       SerializationTest.AssertEquals ("SomeValues._type", _type, obj._type);\r
+                       SerializationTest.AssertEquals ("SomeValues._type2", _type2, obj._type2);\r
+                       SerializationTest.AssertEquals ("SomeValues._dbnull", _dbnull, obj._dbnull);\r
+                       SerializationTest.AssertEquals ("SomeValues._assembly", _assembly, obj._assembly);\r
+\r
+                       SerializationTest.AssertEquals ("SomeValues._intEnum", _intEnum, obj._intEnum);\r
+                       SerializationTest.AssertEquals ("SomeValues._byteEnum", _byteEnum, obj._byteEnum);\r
+                       SerializationTest.AssertEquals ("SomeValues._bool", _bool, obj._bool);\r
+                       SerializationTest.AssertEquals ("SomeValues._bool2", _bool2, obj._bool2);\r
+                       SerializationTest.AssertEquals ("SomeValues._byte", _byte, obj._byte);\r
+                       SerializationTest.AssertEquals ("SomeValues._char", _char, obj._char);\r
+                       SerializationTest.AssertEquals ("SomeValues._dateTime", _dateTime, obj._dateTime);\r
+                       SerializationTest.AssertEquals ("SomeValues._decimal", _decimal, obj._decimal);\r
+                       SerializationTest.AssertEquals ("SomeValues._int", _int, obj._int);\r
+                       SerializationTest.AssertEquals ("SomeValues._long", _long, obj._long);\r
+                       SerializationTest.AssertEquals ("SomeValues._sbyte", _sbyte, obj._sbyte);\r
+                       SerializationTest.AssertEquals ("SomeValues._float", _float, obj._float);\r
+                       SerializationTest.AssertEquals ("SomeValues._ushort", _ushort, obj._ushort);\r
+                       SerializationTest.AssertEquals ("SomeValues._uint", _uint, obj._uint);\r
+                       SerializationTest.AssertEquals ("SomeValues._ulong", _ulong, obj._ulong);\r
+\r
+                       SerializationTest.EqualsArray ("SomeValues._objects", _objects, obj._objects);\r
+                       SerializationTest.EqualsArray ("SomeValues._strings", _strings, obj._strings);\r
+                       SerializationTest.EqualsArray ("SomeValues._doubles", _doubles, obj._doubles);\r
+                       SerializationTest.EqualsArray ("SomeValues._ints", _ints, obj._ints);\r
+                       SerializationTest.EqualsArray ("SomeValues._simples", _simples, obj._simples);\r
+                       SerializationTest.EqualsArray ("SomeValues._almostEmpty", _almostEmpty, obj._almostEmpty);\r
+\r
+                       SerializationTest.EqualsArray ("SomeValues._emptyObjectArray", _emptyObjectArray, obj._emptyObjectArray);\r
+                       SerializationTest.EqualsArray ("SomeValues._emptyTypeArray", _emptyTypeArray, obj._emptyTypeArray);\r
+                       SerializationTest.EqualsArray ("SomeValues._emptySimpleArray", _emptySimpleArray, obj._emptySimpleArray);\r
+                       SerializationTest.EqualsArray ("SomeValues._emptyIntArray", _emptyIntArray, obj._emptyIntArray);\r
+                       SerializationTest.EqualsArray ("SomeValues._emptyStringArray", _emptyStringArray, obj._emptyStringArray);\r
+\r
+                       for (int i=0; i<2; i++)\r
+                               for (int j=0; j<3; j++)\r
+                                       for (int k=0; k<4; k++)\r
+                                               SerializationTest.AssertEquals("SomeValues._intsMulti[" + i + "," + j + "," + k + "]", _intsMulti[i,j,k], obj._intsMulti[i,j,k]);\r
+\r
+                       for (int i=0; i<_intsJagged.Length; i++)\r
+                               for (int j=0; j<_intsJagged[i].Length; j++)\r
+                                       SerializationTest.AssertEquals ("SomeValues._intsJagged[" + i + "][" + j + "]", _intsJagged[i][j], obj._intsJagged[i][j]);\r
+\r
+                       for (int i=0; i<2; i++)\r
+                               for (int j=0; j<3; j++)\r
+                                       SerializationTest.AssertEquals ("SomeValues._simplesMulti[" + i + "," + j + "]", _simplesMulti[i,j], obj._simplesMulti[i,j]);\r
+\r
+                       for (int i=0; i<_simplesJagged.Length; i++)\r
+                               SerializationTest.EqualsArray ("SomeValues._simplesJagged", _simplesJagged[i], obj._simplesJagged[i]);\r
+\r
+                       int acum = 0;\r
+                       SerializationTest.AssertEquals ("SomeValues._sampleDelegate", _sampleDelegate ("hi", this, ref acum), _int);\r
+                       SerializationTest.AssertEquals ("SomeValues._sampleDelegate_bis", _sampleDelegate ("hi", this, ref acum), obj._sampleDelegate ("hi", this, ref acum));\r
+\r
+                       SerializationTest.AssertEquals ("SomeValues._sampleDelegate2", _sampleDelegate2 ("hi", this, ref acum), (int)_simples[0].val);\r
+                       SerializationTest.AssertEquals ("SomeValues._sampleDelegate2_bis", _sampleDelegate2 ("hi", this, ref acum), obj._sampleDelegate2 ("hi", this, ref acum));\r
+\r
+                       SerializationTest.AssertEquals ("SomeValues._sampleDelegate3", _sampleDelegate3 ("hi", this, ref acum), (int)'x');\r
+                       SerializationTest.AssertEquals ("SomeValues._sampleDelegate3_bis", _sampleDelegate3 ("hi", this, ref acum), obj._sampleDelegate3 ("hi", this, ref acum));\r
+\r
+                       SerializationTest.AssertEquals ("SomeValues._sampleDelegateStatic", _sampleDelegateStatic ("hi", this, ref acum), 99);\r
+                       SerializationTest.AssertEquals ("SomeValues._sampleDelegateStatic_bis", _sampleDelegateStatic ("hi", this, ref acum), obj._sampleDelegateStatic ("hi", this, ref acum));\r
+\r
+                       int acum1 = 0;\r
+                       int acum2 = 0;\r
+                       _sampleDelegateCombined ("hi", this, ref acum1);\r
+                       obj._sampleDelegateCombined ("hi", this, ref acum2);\r
+\r
+                       SerializationTest.AssertEquals ("_sampleDelegateCombined", acum1, _int + (int)_simples[0].val + (int)'x' + 99);\r
+                       SerializationTest.AssertEquals ("_sampleDelegateCombined_bis", acum1, acum2);\r
+\r
+                       SerializationTest.AssertEquals ("SomeValues._shared1", _shared1, _shared2);\r
+                       SerializationTest.AssertEquals ("SomeValues._shared1_bis", _shared1, _shared3);\r
+\r
+                       _shared1.val = 'B';\r
+                       SerializationTest.AssertEquals ("SomeValues._shared2", _shared2.val, 'A');\r
+                       SerializationTest.AssertEquals ("SomeValues._shared3", _shared3.val, 'B');\r
+               }\r
+       }\r
+\r
+       class MethodTester : MarshalByRefObject\r
+       {\r
+               public int OverloadedMethod ()\r
+               {\r
+                       return 123456789;\r
+               }\r
+\r
+               public int OverloadedMethod (int a)\r
+               {\r
+                       return a+2;\r
+               }\r
+\r
+               public int OverloadedMethod (int[] a)\r
+               {\r
+                       return a.Length;\r
+               }\r
+\r
+               public void NoReturn ()\r
+               {}\r
+\r
+               public string Simple (string a, int b)\r
+               {\r
+                       return a + b;\r
+               }\r
+\r
+               public SimpleClass Simple2 (char c)\r
+               {\r
+                       return new SimpleClass(c);\r
+               }\r
+\r
+               public SimpleClass Simple3 (char[] c)\r
+               {\r
+                       if (c != null) return new SimpleClass(c[0]);\r
+                       else return null;\r
+               }\r
+\r
+               public int SomeMethod (int a, SimpleClass b)\r
+               {\r
+                       object[] d;\r
+                       string c = "hi";\r
+                       int r = a + c.Length;\r
+                       c = "bye";\r
+                       d = new object[3];\r
+                       d[1] = b;\r
+                       return r;\r
+               }\r
+       }\r
+\r
+       class AuxProxy: RealProxy\r
+       {\r
+               public static bool useHeaders = false;\r
+               Stream _stream;\r
+               string _uri;\r
+               IMethodMessage _testMsg;\r
+\r
+               public AuxProxy(Stream stream, string uri): base(typeof(MethodTester))\r
+               {\r
+                       _stream = stream;\r
+                       _uri = uri;\r
+               }\r
+\r
+               public void SetTestMessage (IMessage msg)\r
+               {\r
+                       _testMsg = (IMethodMessage)msg;\r
+                       _testMsg.Properties["__Uri"] = _uri;\r
+               }\r
+\r
+               public override IMessage Invoke(IMessage msg)\r
+               {\r
+                       IMethodCallMessage call = (IMethodCallMessage)msg;\r
+                       if (call.MethodName.StartsWith ("Initialize")) return new ReturnMessage(null,null,0,null,(IMethodCallMessage)msg);\r
+\r
+                       call.Properties["__Uri"] = _uri;\r
+\r
+                       if (_stream != null)\r
+                       {\r
+                               SerializeCall (call);\r
+                               IMessage response = ChannelServices.SyncDispatchMessage (call);\r
+                               SerializeResponse (response);\r
+                               return response;\r
+                       }\r
+                       else if (_testMsg != null)\r
+                       {\r
+                               if (_testMsg is IMethodCallMessage)\r
+                                       return ChannelServices.SyncDispatchMessage (_testMsg);\r
+                               else\r
+                                       return _testMsg;\r
+                       }\r
+                       else\r
+                               return ChannelServices.SyncDispatchMessage (call);\r
+               }\r
+\r
+               void SerializeCall (IMessage call)\r
+               {\r
+                       RemotingSurrogateSelector rss = new RemotingSurrogateSelector();\r
+                       IRemotingFormatter fmt = new SoapFormatter (rss, new StreamingContext(StreamingContextStates.Remoting));\r
+                       fmt.Serialize (_stream, call, GetHeaders());\r
+               }\r
+\r
+               void SerializeResponse (IMessage resp)\r
+               {\r
+                       RemotingSurrogateSelector rss = new RemotingSurrogateSelector();\r
+                       IRemotingFormatter fmt = new SoapFormatter (rss, new StreamingContext(StreamingContextStates.Remoting));\r
+                       fmt.Serialize (_stream, resp, GetHeaders());\r
+               }\r
+\r
+               Header[] GetHeaders()\r
+               {\r
+                       Header[] hs = null;\r
+                       if (useHeaders)\r
+                       {\r
+                               hs = new Header[1];\r
+                               hs[0] = new Header("unom",new SimpleClass('R'));\r
+                       }\r
+                       return hs;\r
+               }\r
+       }\r
+\r
+       public class TestBinder : SerializationBinder\r
+       {\r
+               public override Type BindToType (string assemblyName, string typeName)\r
+               {\r
+                       if (typeName.IndexOf("BinderTester_A") != -1)\r
+                               typeName = typeName.Replace ("BinderTester_A", "BinderTester_B");\r
+\r
+                       return Assembly.Load (assemblyName).GetType (typeName);\r
+               }\r
+       }\r
+\r
+       [Serializable]\r
+       public class BinderTester_A\r
+       {\r
+               public int x;\r
+               public string y;\r
+       }\r
+\r
+       [Serializable]\r
+       public class BinderTester_B\r
+       {\r
+               public string y;\r
+               public int x;\r
+       }\r
+\r
+\r
+}\r