+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:
+++ /dev/null
-<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
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
+++ /dev/null
-// 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
+++ /dev/null
-// 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
+++ /dev/null
-// 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
+++ /dev/null
-// 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
+++ /dev/null
-// 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
+++ /dev/null
-// 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
+++ /dev/null
-<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
}\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
\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
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
}\r
#endif\r
\r
- [MonoTODO ("Interpret this")]\r
public FormatterAssemblyStyle AssemblyFormat\r
{\r
get {\r
}\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
+++ /dev/null
-<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
+++ /dev/null
-// 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
//\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
-// 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);
+
+
+ }
+
+
+ }
+}
+++ /dev/null
-// 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
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
_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
AssemblyInfo.cs
SoapFormatterTest.cs
+SerializationTest.cs
--- /dev/null
+//\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