We need you! We're working hard on the next version of Developer Fusion - Let us know what you think we should be up to!

The Labs \ Source Viewer \ SSCLI \ System.Runtime.Serialization.Formatters.Soap \ SerObjectInfoInit

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. //============================================================
  16. //
  17. // Class: SerObjectInfo
  18. // Purpose: Holds information about an objects Members
  19. //
  20. // Date: September 29, 1999
  21. //
  22. //============================================================
  23. namespace System.Runtime.Serialization.Formatters.Soap
  24. {
  25.     using System.Runtime.Remoting;
  26.     using System.Runtime.Remoting.Metadata;
  27.     using System.Runtime.Serialization;
  28.     using System;
  29.     using System.Collections;
  30.     using System.Reflection;
  31.     using System.Diagnostics;
  32.     using System.Globalization;
  33.    
  34.     // This class contains information about an object. It is used so that
  35.     // the rest of the Formatter routines can use a common interface for
  36.     // a normal object, an ISerializable object, and a surrogate object
  37.     //
  38.     // The methods in this class are for the internal use of the Formatters.
  39.     // There use will be restricted when signing is supported for assemblies
  40.     internal sealed class WriteObjectInfo
  41.     {
  42.         internal int objectInfoId;
  43.        
  44.         internal object obj;
  45.         internal Type objectType;
  46.        
  47.         internal bool isSi = false;
  48.         internal bool isNamed = false;
  49.         internal bool isTyped = false;
  50.        
  51.         internal SerializationInfo si = null;
  52.        
  53.         internal SerObjectInfoCache cache = null;
  54.        
  55.         internal object[] memberData = null;
  56.         internal ISerializationSurrogate serializationSurrogate = null;
  57.         internal ISurrogateSelector surrogateSelector;
  58.         internal IFormatterConverter converter;
  59.        
  60.         internal StreamingContext context;
  61.        
  62.         internal SerObjectInfoInit serObjectInfoInit = null;
  63.        
  64.         // Writing and Parsing information
  65.         internal long objectId;
  66.         internal long assemId;
  67.        
  68.         private int lastPosition = 0;
  69.         private SoapAttributeInfo parentMemberAttributeInfo;
  70.         internal bool isArray = false;
  71.         internal SoapAttributeInfo typeAttributeInfo;
  72.         internal WriteObjectInfo arrayElemObjectInfo;
  73.        
  74.        
  75.         internal WriteObjectInfo()
  76.         {
  77.         }
  78.        
  79.         internal void ObjectEnd()
  80.         {
  81.             InternalST.Soap(this, objectInfoId, " objectType ", objectType, " ObjectEnd");
  82.             PutObjectInfo(serObjectInfoInit, this);
  83.         }
  84.        
  85.         private void InternalInit()
  86.         {
  87.             InternalST.Soap(this, objectInfoId, " InternalInit");
  88.             obj = null;
  89.             objectType = null;
  90.             isSi = false;
  91.             isNamed = false;
  92.             isTyped = false;
  93.             si = null;
  94.             cache = null;
  95.             memberData = null;
  96.             isArray = false;
  97.            
  98.             // Writing and Parsing information
  99.             objectId = 0;
  100.             assemId = 0;
  101.            
  102.             // Added for Soap
  103.             lastPosition = 0;
  104.             typeAttributeInfo = null;
  105.             parentMemberAttributeInfo = null;
  106.             arrayElemObjectInfo = null;
  107.         }
  108.        
  109.         static internal WriteObjectInfo Serialize(object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo, ObjectWriter objectWriter)
  110.         {
  111.             WriteObjectInfo soi = GetObjectInfo(serObjectInfoInit);
  112.            
  113.             soi.InitSerialize(obj, surrogateSelector, context, serObjectInfoInit, converter, attributeInfo, objectWriter);
  114.             return soi;
  115.         }
  116.        
  117.         // Write constructor
  118.         internal void InitSerialize(object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo, ObjectWriter objectWriter)
  119.         {
  120.             InternalST.Soap(this, objectInfoId, " Constructor 1 ", obj);
  121.             this.context = context;
  122.             this.obj = obj;
  123.             this.serObjectInfoInit = serObjectInfoInit;
  124.             this.parentMemberAttributeInfo = attributeInfo;
  125.             this.surrogateSelector = surrogateSelector;
  126.             this.converter = converter;
  127.             ISurrogateSelector surrogateSelectorTemp;
  128.            
  129.             if (RemotingServices.IsTransparentProxy(obj))
  130.                 objectType = Converter.typeofMarshalByRefObject;
  131.             else
  132.                 objectType = obj.GetType();
  133.            
  134.             if (objectType.IsArray) {
  135.                 arrayElemObjectInfo = Serialize(objectType.GetElementType(), surrogateSelector, context, serObjectInfoInit, converter, null);
  136.                 typeAttributeInfo = GetTypeAttributeInfo();
  137.                 isArray = true;
  138.                 InitNoMembers();
  139.                 return;
  140.             }
  141.            
  142.             InternalST.Soap(this, objectInfoId, " Constructor 1 trace 2");
  143.            
  144.             typeAttributeInfo = GetTypeAttributeInfo();
  145.            
  146.             objectWriter.ObjectManager.RegisterObject(obj);
  147.             if (surrogateSelector != null && (serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp)) != null) {
  148.                 InternalST.Soap(this, objectInfoId, " Constructor 1 trace 3");
  149.                 si = new SerializationInfo(objectType, converter);
  150.                 if (!objectType.IsPrimitive)
  151.                     serializationSurrogate.GetObjectData(obj, si, context);
  152.                 InitSiWrite(objectWriter);
  153.             }
  154.             else if (obj is ISerializable) {
  155.                 if (!objectType.IsSerializable) {
  156.                     throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_NonSerType"), objectType.FullName, objectType.Module.Assembly.FullName));
  157.                 }
  158.                 si = new SerializationInfo(objectType, converter);
  159.                 ((ISerializable)obj).GetObjectData(si, context);
  160.                 InternalST.Soap(this, objectInfoId, " Constructor 1 trace 4 ISerializable " + objectType);
  161.                 InitSiWrite(objectWriter);
  162.             }
  163.             else {
  164.                 InternalST.Soap(this, objectInfoId, " Constructor 1 trace 5");
  165.                 InitMemberInfo();
  166.             }
  167.         }
  168.        
  169.         [Conditional("SER_LOGGING")]
  170.         private void DumpMemberInfo()
  171.         {
  172.             for (int i = 0; i < cache.memberInfos.Length; i++) {
  173.                 InternalST.Soap(this, objectInfoId, " Constructor 1 memberInfos data ", cache.memberInfos[i].Name, " ", memberData[i]);
  174.                
  175.             }
  176.         }
  177.        
  178.         static internal WriteObjectInfo Serialize(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo)
  179.         {
  180.             WriteObjectInfo soi = GetObjectInfo(serObjectInfoInit);
  181.             soi.InitSerialize(objectType, surrogateSelector, context, serObjectInfoInit, converter, attributeInfo);
  182.             return soi;
  183.         }
  184.        
  185.         // Write Constructor used for array types or null members
  186.         internal void InitSerialize(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo)
  187.         {
  188.            
  189.             InternalST.Soap(this, objectInfoId, " Constructor 2 ", objectType);
  190.            
  191.             this.objectType = objectType;
  192.             this.context = context;
  193.             this.serObjectInfoInit = serObjectInfoInit;
  194.             this.parentMemberAttributeInfo = attributeInfo;
  195.             this.surrogateSelector = surrogateSelector;
  196.             this.converter = converter;
  197.            
  198.             if (objectType.IsArray) {
  199.                 arrayElemObjectInfo = Serialize(objectType.GetElementType(), surrogateSelector, context, serObjectInfoInit, converter, null);
  200.                 typeAttributeInfo = GetTypeAttributeInfo();
  201.                 InitNoMembers();
  202.                 return;
  203.             }
  204.            
  205.             typeAttributeInfo = GetTypeAttributeInfo();
  206.            
  207.             ISurrogateSelector surrogateSelectorTemp = null;
  208.            
  209.             if (surrogateSelector != null)
  210.                 serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp);
  211.            
  212.             if (serializationSurrogate != null) {
  213.                 isSi = true;
  214.             }
  215.             else if (objectType == Converter.typeofObject) {
  216.             }
  217.             else if (Converter.typeofISerializable.IsAssignableFrom(objectType))
  218.                 isSi = true;
  219.            
  220.             if (isSi) {
  221.                 si = new SerializationInfo(objectType, converter);
  222.                 cache = new SerObjectInfoCache();
  223.                 cache.fullTypeName = si.FullTypeName;
  224.                 cache.assemblyString = si.AssemblyName;
  225.             }
  226.             else {
  227.                 InitMemberInfo();
  228.             }
  229.            
  230.             InternalST.Soap(this, objectInfoId, " ", objectType, " InitSerialize Exit ", isSi);
  231.         }
  232.        
  233.         private void InitSiWrite(ObjectWriter objectWriter)
  234.         {
  235.             InternalST.Soap(this, objectInfoId, " InitSiWrite Entry ");
  236.             // FormatterWrapper instructs the Formatters to use the
  237.             // __WrappedObject has the real object. This is a way
  238.             // to get Surrogates to return a real object.
  239.             if (si.FullTypeName.Equals("FormatterWrapper")) {
  240.                 obj = si.GetValue("__WrappedObject", Converter.typeofObject);
  241.                 InitSerialize(obj, surrogateSelector, context, serObjectInfoInit, converter, null, objectWriter);
  242.             }
  243.             else {
  244.                
  245.                 SerializationInfoEnumerator siEnum = null;
  246.                 isSi = true;
  247.                 siEnum = si.GetEnumerator();
  248.                 int infoLength = 0;
  249.                
  250.                 infoLength = si.MemberCount;
  251.                
  252.                 int count = infoLength;
  253.                
  254.                 // For ISerializable cache cannot be saved because each object instance can have different values
  255.                 // BinaryWriter only puts the map on the wire if the ISerializable map cannot be reused.
  256.                 cache = new SerObjectInfoCache();
  257.                 cache.memberNames = new string[count];
  258.                 cache.memberTypes = new Type[count];
  259.                 memberData = new object[count];
  260.                
  261.                 cache.fullTypeName = si.FullTypeName;
  262.                 cache.assemblyString = si.AssemblyName;
  263.                 siEnum = si.GetEnumerator();
  264.                 for (int i = 0; siEnum.MoveNext(); i++) {
  265.                     cache.memberNames[i] = siEnum.Name;
  266.                     cache.memberTypes[i] = siEnum.ObjectType;
  267.                     memberData[i] = siEnum.Value;
  268.                     InternalST.Soap(this, objectInfoId + " ", objectType, " InitSiWrite ", cache.memberNames[i], " Type ", cache.memberTypes[i], " data ", memberData[i]);
  269.                 }
  270.                
  271.                 isNamed = true;
  272.                 isTyped = false;
  273.             }
  274.             InternalST.Soap(this, objectInfoId, " InitSiWrite Exit ");
  275.         }
  276.        
  277.         private void InitNoMembers()
  278.         {
  279.             cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
  280.             if (cache == null) {
  281.                 InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  282.                 cache = new SerObjectInfoCache();
  283.                 cache.fullTypeName = objectType.FullName;
  284.                 cache.assemblyString = objectType.Module.Assembly.FullName;
  285.                 serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
  286.             }
  287.         }
  288.        
  289.         private void InitMemberInfo()
  290.         {
  291.             InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo Entry");
  292.            
  293.             cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
  294.             if (cache == null) {
  295.                 InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  296.                 cache = new SerObjectInfoCache();
  297.                 int count = 0;
  298.                 // byref will only occur for MethodSignature
  299.                 if (!objectType.IsByRef) {
  300.                     cache.memberInfos = FormatterServices.GetSerializableMembers(objectType, context);
  301.                     count = cache.memberInfos.Length;
  302.                 }
  303.                 cache.memberNames = new string[count];
  304.                 cache.memberTypes = new Type[count];
  305.                 cache.memberAttributeInfos = new SoapAttributeInfo[count];
  306.                
  307.                 // Calculate new arrays
  308.                 for (int i = 0; i < count; i++) {
  309.                     cache.memberNames[i] = cache.memberInfos[i].Name;
  310.                     cache.memberTypes[i] = GetMemberType(cache.memberInfos[i]);
  311.                     cache.memberAttributeInfos[i] = Attr.GetMemberAttributeInfo(cache.memberInfos[i], cache.memberNames[i], cache.memberTypes[i]);
  312.                     InternalST.Soap(this, objectInfoId, " InitMemberInfo name ", cache.memberNames[i], ", type ", cache.memberTypes[i], ", memberInfoType ", cache.memberInfos[i].GetType());
  313.                 }
  314.                 cache.fullTypeName = objectType.FullName;
  315.                 cache.assemblyString = objectType.Module.Assembly.FullName;
  316.                 serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
  317.             }
  318.            
  319.             if (obj != null) {
  320.                 memberData = FormatterServices.GetObjectData(obj, cache.memberInfos);
  321.                 DumpMemberInfo();
  322.             }
  323.            
  324.             isTyped = true;
  325.             isNamed = true;
  326.             InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo Exit");
  327.         }
  328.        
  329.        
  330.         // Return type name for the object.
  331.        
  332.         internal string GetTypeFullName()
  333.         {
  334.             InternalST.Soap(this, objectInfoId, " ", objectType, " GetTypeFullName isSi ", isSi, " " + cache.fullTypeName);
  335.             return cache.fullTypeName;
  336.         }
  337.        
  338.         internal string GetAssemblyString()
  339.         {
  340.             string assemblyString = null;
  341.             InternalST.Soap(this, objectInfoId, " ", objectType, " GetAssemblyString Entry isSi ", isSi);
  342.            
  343.             if (arrayElemObjectInfo != null)
  344.                 assemblyString = arrayElemObjectInfo.GetAssemblyString();
  345.             else if (IsAttributeNameSpace())
  346.                 assemblyString = typeAttributeInfo.m_nameSpace;
  347.             else
  348.                 assemblyString = cache.assemblyString;
  349.            
  350.             InternalST.Soap(this, objectInfoId, " ", objectType, " GetAssemblyString Exit ", assemblyString);
  351.             return assemblyString;
  352.         }
  353.        
  354.        
  355.         // Retrieves the member type from the MemberInfo
  356.        
  357.         internal Type GetMemberType(MemberInfo objMember)
  358.         {
  359.             Type objectType = null;
  360.            
  361.             if (objMember is FieldInfo) {
  362.                 objectType = ((FieldInfo)objMember).FieldType;
  363.                 InternalST.Soap(this, objectInfoId, " ", "GetMemberType FieldInfo ", objectType);
  364.             }
  365.             else if (objMember is PropertyInfo) {
  366.                 objectType = ((PropertyInfo)objMember).PropertyType;
  367.                 InternalST.Soap(this, objectInfoId, " ", "GetMemberType PropertyInfo ", objectType);
  368.             }
  369.             else {
  370.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_SerMemberInfo"), objMember.GetType()));
  371.             }
  372.            
  373.             return objectType;
  374.         }
  375.        
  376.         // Return the information about the object's members
  377.        
  378.         internal void GetMemberInfo(out string[] outMemberNames, out Type[] outMemberTypes, out object[] outMemberData, out SoapAttributeInfo[] outAttributeInfo)
  379.         {
  380.             outMemberNames = cache.memberNames;
  381.             outMemberTypes = cache.memberTypes;
  382.             outMemberData = memberData;
  383.             outAttributeInfo = cache.memberAttributeInfos;
  384.            
  385.             if (isSi) {
  386.                 if (!isNamed)
  387.                     throw new SerializationException(SoapUtil.GetResourceString("Serialization_ISerializableMemberInfo"));
  388.             }
  389.         }
  390.        
  391.         private static WriteObjectInfo GetObjectInfo(SerObjectInfoInit serObjectInfoInit)
  392.         {
  393.             WriteObjectInfo objectInfo = null;
  394.            
  395.             if (!serObjectInfoInit.oiPool.IsEmpty()) {
  396.                 objectInfo = (WriteObjectInfo)serObjectInfoInit.oiPool.Pop();
  397.                 objectInfo.InternalInit();
  398.                 //InternalST.Soap( "GetObjectInfo",objectInfo.objectInfoId," GetObjectInfo from pool");
  399.             }
  400.             else {
  401.                 objectInfo = new WriteObjectInfo();
  402.                 objectInfo.objectInfoId = serObjectInfoInit.objectInfoIdCount++;
  403.                 //InternalST.Soap( "GetObjectInfo",objectInfo.objectInfoId," GetObjectInfo new not from pool");
  404.             }
  405.            
  406.             return objectInfo;
  407.         }
  408.        
  409.         private int Position(string name)
  410.         {
  411.             InternalST.Soap(this, objectInfoId, " Position ", lastPosition, " ", name);
  412.             if (cache.memberNames[lastPosition].Equals(name)) {
  413.                 return lastPosition;
  414.             }
  415.             else if ((++lastPosition < cache.memberNames.Length) && (cache.memberNames[lastPosition].Equals(name))) {
  416.                 return lastPosition;
  417.             }
  418.             else {
  419.                 // Search for name
  420.                 InternalST.Soap(this, objectInfoId, " Position miss search for name " + name);
  421.                 for (int i = 0; i < cache.memberNames.Length; i++) {
  422.                     if (cache.memberNames[i].Equals(name)) {
  423.                         lastPosition = i;
  424.                         return lastPosition;
  425.                     }
  426.                 }
  427.                
  428.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_Position"), objectType + " " + name));
  429.             }
  430.         }
  431.        
  432.         private static void PutObjectInfo(SerObjectInfoInit serObjectInfoInit, WriteObjectInfo objectInfo)
  433.         {
  434.             serObjectInfoInit.oiPool.Push(objectInfo);
  435.             //InternalST.Soap( "PutObjectInfo",objectInfo.objectInfoId," PutObjectInfo to pool");
  436.         }
  437.        
  438.         internal bool IsInteropNameSpace()
  439.         {
  440.             if (arrayElemObjectInfo != null)
  441.                 return arrayElemObjectInfo.IsInteropNameSpace();
  442.            
  443.             if (IsAttributeNameSpace() || IsCallElement())
  444.                 return true;
  445.             else
  446.                 return false;
  447.         }
  448.        
  449.         internal bool IsCallElement()
  450.         {
  451.             // This should only return true when this object is being
  452.             // serialized first.
  453.            
  454.             if ((objectType != Converter.typeofObject) && (Converter.typeofIMethodCallMessage.IsAssignableFrom(objectType) && !Converter.typeofIConstructionCallMessage.IsAssignableFrom(objectType)) || (objectType == Converter.typeofReturnMessage) || (objectType == Converter.typeofInternalSoapMessage)) {
  455.                 return true;
  456.             }
  457.             else {
  458.                 return false;
  459.             }
  460.         }
  461.        
  462.         internal bool IsCustomXmlAttribute()
  463.         {
  464.             if (arrayElemObjectInfo != null)
  465.                 return arrayElemObjectInfo.IsCustomXmlAttribute();
  466.            
  467.             if ((typeAttributeInfo != null) && ((typeAttributeInfo.m_attributeType & SoapAttributeType.XmlAttribute) != 0))
  468.                 return true;
  469.             else
  470.                 return false;
  471.         }
  472.        
  473.         internal bool IsCustomXmlElement()
  474.         {
  475.             if (arrayElemObjectInfo != null)
  476.                 return arrayElemObjectInfo.IsCustomXmlElement();
  477.            
  478.             if ((typeAttributeInfo != null) && ((typeAttributeInfo.m_attributeType & SoapAttributeType.XmlElement) != 0))
  479.                 return true;
  480.             else
  481.                 return false;
  482.         }
  483.        
  484.         internal bool IsAttributeNameSpace()
  485.         {
  486.             if (arrayElemObjectInfo != null)
  487.                 return arrayElemObjectInfo.IsAttributeNameSpace();
  488.            
  489.             if ((typeAttributeInfo != null) && (typeAttributeInfo.m_nameSpace != null))
  490.                 return true;
  491.             else
  492.                 return false;
  493.         }
  494.        
  495.         // Check for Interop type (SchemaType)
  496.         private SoapAttributeInfo GetTypeAttributeInfo()
  497.         {
  498.             if (arrayElemObjectInfo != null)
  499.                 return arrayElemObjectInfo.GetTypeAttributeInfo();
  500.            
  501.             SoapAttributeInfo attributeInfo = null;
  502.             if (parentMemberAttributeInfo != null)
  503.                 attributeInfo = parentMemberAttributeInfo;
  504.             else
  505.                 attributeInfo = new SoapAttributeInfo();
  506.            
  507.             Attr.ProcessTypeAttribute(objectType, attributeInfo);
  508.            
  509.             attributeInfo.Dump("type " + objectType);
  510.             return attributeInfo;
  511.         }
  512.        
  513.        
  514.         // Specifies whether the embedded attribute is set for a member.
  515.        
  516.         internal bool IsEmbeddedAttribute(string name)
  517.         {
  518.             InternalST.Soap(this, objectInfoId, " ", objectType, " IsEmbedded Entry ", name);
  519.            
  520.             if (arrayElemObjectInfo != null)
  521.                 return arrayElemObjectInfo.IsEmbeddedAttribute(name);
  522.            
  523.             bool isEmbedded = false;
  524.             if (cache.memberAttributeInfos != null && cache.memberAttributeInfos.Length > 0) {
  525.                 SoapAttributeInfo attributeInfo = cache.memberAttributeInfos[Position(name)];
  526.                 isEmbedded = attributeInfo.IsEmbedded();
  527.             }
  528.             InternalST.Soap(this, objectInfoId, " ", objectType, " IsEmbedded Exit ", isEmbedded);
  529.             return isEmbedded;
  530.         }
  531.     }
  532.    
  533.    
  534.     internal sealed class ReadObjectInfo
  535.     {
  536.         internal int objectInfoId;
  537.        
  538.         internal object obj;
  539.         internal Type objectType;
  540.        
  541.        
  542.         internal ObjectManager objectManager;
  543.        
  544.         internal int count;
  545.        
  546.         internal bool isSi = false;
  547.         internal bool isNamed = false;
  548.         internal bool isTyped = false;
  549.        
  550.         internal SerializationInfo si = null;
  551.        
  552.         internal SerObjectInfoCache cache = null;
  553.        
  554.         internal string[] wireMemberNames = null;
  555.         internal Type[] wireMemberTypes = null;
  556.         internal object[] memberData = null;
  557.         internal string[] memberNames = null;
  558.        
  559.         private int lastPosition = 0;
  560.        
  561.         internal ISurrogateSelector surrogateSelector = null;
  562.         internal ISerializationSurrogate serializationSurrogate = null;
  563.        
  564.         internal StreamingContext context;
  565.        
  566.        
  567.         // Si Read
  568.         internal ArrayList memberTypesList;
  569.        
  570.         internal SerObjectInfoInit serObjectInfoInit = null;
  571.        
  572.         internal IFormatterConverter formatterConverter;
  573.        
  574.         // fake object for soap top record when remoting or IRemotingFormatter interface
  575.         internal bool bfake = false;
  576.         internal bool bSoapFault = false;
  577.         internal ArrayList paramNameList;
  578.         // Contain parameter names in correct order
  579.         private int majorVersion = 0;
  580.         private int minorVersion = 0;
  581.         internal SoapAttributeInfo typeAttributeInfo;
  582.         private ReadObjectInfo arrayElemObjectInfo;
  583.         private int numberMembersSeen = 0;
  584.        
  585.         internal ReadObjectInfo()
  586.         {
  587.         }
  588.        
  589.         internal void ObjectEnd()
  590.         {
  591.             InternalST.Soap(this, objectInfoId, " objectType ", objectType, " ObjectEnd");
  592.             PutObjectInfo(serObjectInfoInit, this);
  593.         }
  594.        
  595.         private void InternalInit()
  596.         {
  597.             InternalST.Soap(this, objectInfoId, " objectType ", objectType, " InternalInit");
  598.             obj = null;
  599.             objectType = null;
  600.             count = 0;
  601.             isSi = false;
  602.             isNamed = false;
  603.             isTyped = false;
  604.             si = null;
  605.             wireMemberNames = null;
  606.             wireMemberTypes = null;
  607.             cache = null;
  608.             lastPosition = 0;
  609.             numberMembersSeen = 0;
  610.            
  611.             bfake = false;
  612.             bSoapFault = false;
  613.             majorVersion = 0;
  614.             minorVersion = 0;
  615.             typeAttributeInfo = null;
  616.             arrayElemObjectInfo = null;
  617.            
  618.            
  619.            
  620.             // Si Read
  621.             if (memberTypesList != null) {
  622.                 memberTypesList.Clear();
  623.             }
  624.            
  625.         }
  626.        
  627.         static internal ReadObjectInfo Create(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, string assemblyName)
  628.         {
  629.             ReadObjectInfo soi = GetObjectInfo(serObjectInfoInit);
  630.             soi.Init(objectType, surrogateSelector, context, objectManager, serObjectInfoInit, converter, assemblyName);
  631.             return soi;
  632.         }
  633.        
  634.        
  635.         // Read Constructor
  636.         internal void Init(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, string assemblyName)
  637.         {
  638.            
  639.             InternalST.Soap(this, objectInfoId, " Constructor 3 ", objectType);
  640.            
  641.             this.objectType = objectType;
  642.             this.objectManager = objectManager;
  643.             this.context = context;
  644.             this.serObjectInfoInit = serObjectInfoInit;
  645.             this.formatterConverter = converter;
  646.            
  647.             InitReadConstructor(objectType, surrogateSelector, context, assemblyName);
  648.         }
  649.        
  650.         static internal ReadObjectInfo Create(Type objectType, string[] memberNames, Type[] memberTypes, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, string assemblyName)
  651.         {
  652.             ReadObjectInfo soi = GetObjectInfo(serObjectInfoInit);
  653.             soi.Init(objectType, memberNames, memberTypes, surrogateSelector, context, objectManager, serObjectInfoInit, converter, assemblyName);
  654.             return soi;
  655.         }
  656.        
  657.         // Read Constructor
  658.         internal void Init(Type objectType, string[] memberNames, Type[] memberTypes, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, string assemblyName)
  659.         {
  660.             InternalST.Soap(this, objectInfoId, " Constructor 5 ", objectType);
  661.             this.objectType = objectType;
  662.             this.objectManager = objectManager;
  663.             this.wireMemberNames = memberNames;
  664.             this.wireMemberTypes = memberTypes;
  665.             this.context = context;
  666.             this.serObjectInfoInit = serObjectInfoInit;
  667.             this.formatterConverter = converter;
  668.             if (memberNames != null)
  669.                 isNamed = true;
  670.             if (memberTypes != null)
  671.                 isTyped = true;
  672.            
  673.             InitReadConstructor(objectType, surrogateSelector, context, assemblyName);
  674.         }
  675.        
  676.         private void InitReadConstructor(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, string assemblyName)
  677.         {
  678.             InternalST.Soap(this, objectInfoId, " ", objectType, " InitReadConstructor Entry ", objectType);
  679.            
  680.             if (objectType.IsArray) {
  681.                 arrayElemObjectInfo = Create(objectType.GetElementType(), surrogateSelector, context, objectManager, serObjectInfoInit, formatterConverter, assemblyName);
  682.                 typeAttributeInfo = GetTypeAttributeInfo();
  683.                 InitNoMembers();
  684.                 return;
  685.             }
  686.            
  687.             ISurrogateSelector surrogateSelectorTemp = null;
  688.            
  689.             if (surrogateSelector != null)
  690.                 serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp);
  691.            
  692.             if (serializationSurrogate != null) {
  693.                 isSi = true;
  694.             }
  695.             else if (objectType == Converter.typeofObject) {
  696.             }
  697.             else if (Converter.typeofISerializable.IsAssignableFrom(objectType))
  698.                 isSi = true;
  699.            
  700.             if (isSi) {
  701.                 si = new SerializationInfo(objectType, formatterConverter);
  702.                 InitSiRead(assemblyName);
  703.             }
  704.             else {
  705.                 InitMemberInfo();
  706.             }
  707.             InternalST.Soap(this, objectInfoId, " ", objectType, " InitReadConstructor Exit ", isSi);
  708.         }
  709.        
  710.         private void InitSiRead(string assemblyName)
  711.         {
  712.             InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  713.             if (assemblyName != null) {
  714.                 // Need to set to assembly name from the wire. This assembly name could contain version information
  715.                 // not in the default assembly name which was returned from fusion
  716.                 si.AssemblyName = assemblyName;
  717.             }
  718.             cache = new SerObjectInfoCache();
  719.             cache.fullTypeName = si.FullTypeName;
  720.             cache.assemblyString = si.AssemblyName;
  721.            
  722.             // Input from IFieldInfo
  723.             cache.memberNames = wireMemberNames;
  724.             cache.memberTypes = wireMemberTypes;
  725.            
  726.             if (memberTypesList != null) {
  727.                 memberTypesList = new ArrayList(20);
  728.             }
  729.            
  730.            
  731.             if (wireMemberNames != null && wireMemberTypes != null)
  732.                 isTyped = true;
  733.         }
  734.        
  735.         private void InitNoMembers()
  736.         {
  737.             cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
  738.             if (cache == null) {
  739.                 InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  740.                 cache = new SerObjectInfoCache();
  741.                 cache.fullTypeName = objectType.FullName;
  742.                 cache.assemblyString = objectType.Module.Assembly.FullName;
  743.                 serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
  744.             }
  745.         }
  746.        
  747.         private void InitMemberInfo()
  748.         {
  749.             InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo Entry");
  750.            
  751.             cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
  752.             if (cache == null) {
  753.                 InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  754.                 cache = new SerObjectInfoCache();
  755.                 cache.memberInfos = FormatterServices.GetSerializableMembers(objectType, context);
  756.                 count = cache.memberInfos.Length;
  757.                 cache.memberNames = new string[count];
  758.                 cache.memberTypes = new Type[count];
  759.                 cache.memberAttributeInfos = new SoapAttributeInfo[count];
  760.                
  761.                 // Calculate new arrays
  762.                 for (int i = 0; i < count; i++) {
  763.                     cache.memberNames[i] = cache.memberInfos[i].Name;
  764.                     cache.memberTypes[i] = GetMemberType(cache.memberInfos[i]);
  765.                     cache.memberAttributeInfos[i] = Attr.GetMemberAttributeInfo(cache.memberInfos[i], cache.memberNames[i], cache.memberTypes[i]);
  766.                     InternalST.Soap(this, objectInfoId, " InitMemberInfo name ", cache.memberNames[i], ", type ", cache.memberTypes[i], ", memberInfoType ", cache.memberInfos[i].GetType());
  767.                 }
  768.                 cache.fullTypeName = objectType.FullName;
  769.                 cache.assemblyString = objectType.Module.Assembly.FullName;
  770.                 serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
  771.             }
  772.             memberData = new object[cache.memberNames.Length];
  773.             memberNames = new string[cache.memberNames.Length];
  774.            
  775.             isTyped = true;
  776.             isNamed = true;
  777.             InternalST.Soap(this, objectInfoId, " ", objectType, " InitMemberInfo Exit");
  778.         }
  779.        
  780.         // Get the memberInfo for a memberName
  781.         internal MemberInfo GetMemberInfo(string name)
  782.         {
  783.             InternalST.Soap(this, objectInfoId, " ", objectType, " GetMemberInfo Entry ", name);
  784.             if (isSi)
  785.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_MemberInfo"), objectType + " " + name));
  786.             if (cache.memberInfos == null)
  787.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_NoMemberInfo"), objectType + " " + name));
  788.             return cache.memberInfos[Position(name)];
  789.         }
  790.        
  791.         internal Type GetMemberType(MemberInfo objMember)
  792.         {
  793.             Type objectType = null;
  794.            
  795.             if (objMember is FieldInfo) {
  796.                 objectType = ((FieldInfo)objMember).FieldType;
  797.                 InternalST.Soap(this, objectInfoId, " ", "GetMemberType FieldInfo ", objectType);
  798.             }
  799.             else if (objMember is PropertyInfo) {
  800.                 objectType = ((PropertyInfo)objMember).PropertyType;
  801.                 InternalST.Soap(this, objectInfoId, " ", "GetMemberType PropertyInfo ", objectType);
  802.             }
  803.             else {
  804.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_SerMemberInfo"), objMember.GetType()));
  805.             }
  806.            
  807.             return objectType;
  808.         }
  809.        
  810.         // Get the ObjectType for a memberName
  811.         internal Type GetType(string name)
  812.         {
  813.             InternalST.Soap(this, objectInfoId, " ", objectType, " GetType Entry ", name);
  814.             Type type = null;
  815.             if (isTyped)
  816.                 type = cache.memberTypes[Position(name)];
  817.             else
  818.                 type = (Type)memberTypesList[Position(name)];
  819. <