The Labs \ Source Viewer \ SSCLI \ System.Runtime.Serialization.Formatters.Binary \ ReadObjectInfo

  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. **
  19. **
  20. ** Purpose: Holds information about an objects Members
  21. **
  22. **
  23. ===========================================================*/
  24. namespace System.Runtime.Serialization.Formatters.Binary
  25. {
  26.     using System.Runtime.Remoting;
  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.         internal bool isArray = false;
  51.        
  52.         internal SerializationInfo si = null;
  53.        
  54.         internal SerObjectInfoCache cache = null;
  55.        
  56.         internal object[] memberData = null;
  57.         internal ISerializationSurrogate serializationSurrogate = null;
  58.        
  59.         internal StreamingContext context;
  60.        
  61.         internal SerObjectInfoInit serObjectInfoInit = null;
  62.        
  63.         // Writing and Parsing information
  64.         internal long objectId;
  65.         internal long assemId;
  66.        
  67.         internal WriteObjectInfo()
  68.         {
  69.         }
  70.        
  71.         internal void ObjectEnd()
  72.         {
  73.             SerTrace.Log(this, objectInfoId, " objectType ", objectType, " ObjectEnd");
  74.             PutObjectInfo(serObjectInfoInit, this);
  75.         }
  76.        
  77.         private void InternalInit()
  78.         {
  79.             SerTrace.Log(this, objectInfoId, " objectType ", objectType, " InternalInit");
  80.             obj = null;
  81.             objectType = null;
  82.             isSi = false;
  83.             isNamed = false;
  84.             isTyped = false;
  85.             isArray = false;
  86.             si = null;
  87.             cache = null;
  88.             memberData = null;
  89.            
  90.             // Writing and Parsing information
  91.             objectId = 0;
  92.             assemId = 0;
  93.         }
  94.        
  95.        
  96.         static internal WriteObjectInfo Serialize(object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
  97.         {
  98.             WriteObjectInfo soi = GetObjectInfo(serObjectInfoInit);
  99.            
  100.             soi.InitSerialize(obj, surrogateSelector, context, serObjectInfoInit, converter, objectWriter);
  101.             return soi;
  102.         }
  103.        
  104.         // Write constructor
  105.         internal void InitSerialize(object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
  106.         {
  107.             SerTrace.Log(this, objectInfoId, " Constructor 1 ", obj);
  108.             this.context = context;
  109.             this.obj = obj;
  110.             this.serObjectInfoInit = serObjectInfoInit;
  111.             ISurrogateSelector surrogateSelectorTemp;
  112.            
  113.             if (RemotingServices.IsTransparentProxy(obj))
  114.                 objectType = Converter.typeofMarshalByRefObject;
  115.             else
  116.                 objectType = obj.GetType();
  117.            
  118.             if (objectType.IsArray) {
  119.                 isArray = true;
  120.                 InitNoMembers();
  121.                 return;
  122.             }
  123.            
  124.             SerTrace.Log(this, objectInfoId, " Constructor 1 trace 2");
  125.            
  126.             objectWriter.ObjectManager.RegisterObject(obj);
  127.             if (surrogateSelector != null && (serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp)) != null) {
  128.                 SerTrace.Log(this, objectInfoId, " Constructor 1 trace 3");
  129.                 si = new SerializationInfo(objectType, converter);
  130.                 if (!objectType.IsPrimitive)
  131.                     serializationSurrogate.GetObjectData(obj, si, context);
  132.                 InitSiWrite();
  133.             }
  134.             else if (obj is ISerializable) {
  135.                 if (!objectType.IsSerializable) {
  136.                     throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_NonSerType"), objectType.FullName, objectType.Assembly.FullName));
  137.                 }
  138.                 si = new SerializationInfo(objectType, converter);
  139.                 ((ISerializable)obj).GetObjectData(si, context);
  140.                 SerTrace.Log(this, objectInfoId, " Constructor 1 trace 4 ISerializable " + objectType);
  141.                 InitSiWrite();
  142.             }
  143.             else {
  144.                 SerTrace.Log(this, objectInfoId, " Constructor 1 trace 5");
  145.                 InitMemberInfo();
  146.             }
  147.         }
  148.        
  149.         [Conditional("SER_LOGGING")]
  150.         private void DumpMemberInfo()
  151.         {
  152.             for (int i = 0; i < cache.memberInfos.Length; i++) {
  153.                 SerTrace.Log(this, objectInfoId, " Constructor 1 memberInfos data ", cache.memberInfos[i].Name, " ", memberData[i]);
  154.                
  155.             }
  156.         }
  157.        
  158.         static internal WriteObjectInfo Serialize(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter)
  159.         {
  160.             WriteObjectInfo soi = GetObjectInfo(serObjectInfoInit);
  161.             soi.InitSerialize(objectType, surrogateSelector, context, serObjectInfoInit, converter);
  162.             return soi;
  163.         }
  164.        
  165.         // Write Constructor used for array types or null members
  166.         internal void InitSerialize(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter)
  167.         {
  168.            
  169.             SerTrace.Log(this, objectInfoId, " Constructor 2 ", objectType);
  170.            
  171.             this.objectType = objectType;
  172.             this.context = context;
  173.             this.serObjectInfoInit = serObjectInfoInit;
  174.            
  175.             if (objectType.IsArray) {
  176.                 InitNoMembers();
  177.                 return;
  178.             }
  179.            
  180.             ISurrogateSelector surrogateSelectorTemp = null;
  181.            
  182.             if (surrogateSelector != null)
  183.                 serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp);
  184.            
  185.             if (serializationSurrogate != null) {
  186.                 isSi = true;
  187.             }
  188.             else if (objectType == Converter.typeofObject) {
  189.             }
  190.             else if (Converter.typeofISerializable.IsAssignableFrom(objectType))
  191.                 isSi = true;
  192.            
  193.             if (isSi) {
  194.                 si = new SerializationInfo(objectType, converter);
  195.                 cache = new SerObjectInfoCache();
  196.                 cache.fullTypeName = si.FullTypeName;
  197.                 cache.assemblyString = si.AssemblyName;
  198.             }
  199.             else {
  200.                 InitMemberInfo();
  201.             }
  202.            
  203.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitSerialize Exit ", isSi);
  204.         }
  205.        
  206.        
  207.         private void InitSiWrite()
  208.         {
  209.             SerTrace.Log(this, objectInfoId, " InitSiWrite Entry ");
  210.            
  211.             SerializationInfoEnumerator siEnum = null;
  212.             isSi = true;
  213.             siEnum = si.GetEnumerator();
  214.             int infoLength = 0;
  215.            
  216.             infoLength = si.MemberCount;
  217.            
  218.             int count = infoLength;
  219.            
  220.             // For ISerializable cache cannot be saved because each object instance can have different values
  221.             // BinaryWriter only puts the map on the wire if the ISerializable map cannot be reused.
  222.             cache = new SerObjectInfoCache();
  223.             cache.memberNames = new string[count];
  224.             cache.memberTypes = new Type[count];
  225.             memberData = new object[count];
  226.            
  227.             cache.fullTypeName = si.FullTypeName;
  228.             cache.assemblyString = si.AssemblyName;
  229.             siEnum = si.GetEnumerator();
  230.             for (int i = 0; siEnum.MoveNext(); i++) {
  231.                 cache.memberNames[i] = siEnum.Name;
  232.                 cache.memberTypes[i] = siEnum.ObjectType;
  233.                 memberData[i] = siEnum.Value;
  234.                 SerTrace.Log(this, objectInfoId + " ", objectType, " InitSiWrite ", cache.memberNames[i], " Type ", cache.memberTypes[i], " data ", memberData[i]);
  235.             }
  236.            
  237.             isNamed = true;
  238.             isTyped = false;
  239.            
  240.             SerTrace.Log(this, objectInfoId, " InitSiWrite Exit ");
  241.         }
  242.        
  243.         private void InitNoMembers()
  244.         {
  245.             cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
  246.             if (cache == null) {
  247.                 SerTrace.Log(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  248.                 cache = new SerObjectInfoCache();
  249.                 cache.fullTypeName = objectType.FullName;
  250.                 cache.assemblyString = objectType.Assembly.FullName;
  251.                 serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
  252.             }
  253.         }
  254.        
  255.         private void InitMemberInfo()
  256.         {
  257.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitMemberInfo Entry");
  258.            
  259.            
  260.             cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
  261.             if (cache == null) {
  262.                 SerTrace.Log(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  263.                 cache = new SerObjectInfoCache();
  264.                
  265.                 cache.memberInfos = FormatterServices.GetSerializableMembers(objectType, context);
  266.                 int count = cache.memberInfos.Length;
  267.                 cache.memberNames = new string[count];
  268.                 cache.memberTypes = new Type[count];
  269.                
  270.                 // Calculate new arrays
  271.                 for (int i = 0; i < count; i++) {
  272.                     cache.memberNames[i] = cache.memberInfos[i].Name;
  273.                     cache.memberTypes[i] = GetMemberType(cache.memberInfos[i]);
  274.                     SerTrace.Log(this, objectInfoId, " InitMemberInfo name ", cache.memberNames[i], ", type ", cache.memberTypes[i], ", memberInfoType ", cache.memberInfos[i].GetType());
  275.                 }
  276.                 cache.fullTypeName = objectType.FullName;
  277.                 cache.assemblyString = objectType.Assembly.FullName;
  278.                 serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
  279.             }
  280.            
  281.             if (obj != null) {
  282.                 memberData = FormatterServices.GetObjectData(obj, cache.memberInfos);
  283.                 DumpMemberInfo();
  284.             }
  285.            
  286.             isTyped = true;
  287.             isNamed = true;
  288.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitMemberInfo Exit");
  289.         }
  290.        
  291.        
  292.        
  293.         // Return type name for the object.
  294.        
  295.         internal string GetTypeFullName()
  296.         {
  297.             SerTrace.Log(this, objectInfoId, " ", objectType, " GetTypeFullName isSi ", isSi, " " + cache.fullTypeName);
  298.             return cache.fullTypeName;
  299.         }
  300.        
  301.         internal string GetAssemblyString()
  302.         {
  303.             SerTrace.Log(this, objectInfoId, " ", objectType, " GetAssemblyString Entry isSi ", isSi, " ", cache.assemblyString);
  304.             return cache.assemblyString;
  305.         }
  306.        
  307.        
  308.         // Retrieves the member type from the MemberInfo
  309.        
  310.         internal Type GetMemberType(MemberInfo objMember)
  311.         {
  312.             Type objectType = null;
  313.            
  314.             if (objMember is FieldInfo) {
  315.                 objectType = ((FieldInfo)objMember).FieldType;
  316.                 SerTrace.Log(this, objectInfoId, " ", "GetMemberType FieldInfo ", objectType);
  317.             }
  318.             else if (objMember is PropertyInfo) {
  319.                 objectType = ((PropertyInfo)objMember).PropertyType;
  320.                 SerTrace.Log(this, objectInfoId, " ", "GetMemberType PropertyInfo ", objectType);
  321.             }
  322.             else {
  323.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_SerMemberInfo"), objMember.GetType()));
  324.             }
  325.            
  326.             return objectType;
  327.         }
  328.        
  329.         internal void GetMemberInfo(out string[] outMemberNames, out Type[] outMemberTypes, out object[] outMemberData)
  330.         {
  331.             outMemberNames = cache.memberNames;
  332.             outMemberTypes = cache.memberTypes;
  333.             outMemberData = memberData;
  334.            
  335.             if (isSi) {
  336.                 if (!isNamed)
  337.                     throw new SerializationException(Environment.GetResourceString("Serialization_ISerializableMemberInfo"));
  338.             }
  339.         }
  340.        
  341.         private static WriteObjectInfo GetObjectInfo(SerObjectInfoInit serObjectInfoInit)
  342.         {
  343.             WriteObjectInfo objectInfo = null;
  344.            
  345.             if (!serObjectInfoInit.oiPool.IsEmpty()) {
  346.                 objectInfo = (WriteObjectInfo)serObjectInfoInit.oiPool.Pop();
  347.                 objectInfo.InternalInit();
  348.                 //SerTrace.Log( "GetObjectInfo",objectInfo.objectInfoId," GetObjectInfo from pool");
  349.             }
  350.             else {
  351.                 objectInfo = new WriteObjectInfo();
  352.                 objectInfo.objectInfoId = serObjectInfoInit.objectInfoIdCount++;
  353.                 //SerTrace.Log( "GetObjectInfo",objectInfo.objectInfoId," GetObjectInfo new not from pool");
  354.             }
  355.            
  356.             return objectInfo;
  357.         }
  358.        
  359.         private static void PutObjectInfo(SerObjectInfoInit serObjectInfoInit, WriteObjectInfo objectInfo)
  360.         {
  361.             serObjectInfoInit.oiPool.Push(objectInfo);
  362.             //SerTrace.Log( "PutObjectInfo",objectInfo.objectInfoId," PutObjectInfo to pool");
  363.         }
  364.     }
  365.    
  366.     internal sealed class ReadObjectInfo
  367.     {
  368.         internal int objectInfoId;
  369.         static internal int readObjectInfoCounter = 1;
  370.        
  371.         internal Type objectType;
  372.        
  373.         internal ObjectManager objectManager;
  374.        
  375.         internal int count;
  376.        
  377.         internal bool isSi = false;
  378.         internal bool isNamed = false;
  379.         internal bool isTyped = false;
  380.         internal bool bSimpleAssembly = false;
  381.        
  382.         internal SerObjectInfoCache cache;
  383.        
  384.         internal string[] wireMemberNames;
  385.         internal Type[] wireMemberTypes;
  386.        
  387.         private int lastPosition = 0;
  388.        
  389.         internal ISurrogateSelector surrogateSelector = null;
  390.         internal ISerializationSurrogate serializationSurrogate = null;
  391.        
  392.         internal StreamingContext context;
  393.        
  394.        
  395.         // Si Read
  396.         internal ArrayList memberTypesList;
  397.        
  398.         internal SerObjectInfoInit serObjectInfoInit = null;
  399.        
  400.         internal IFormatterConverter formatterConverter;
  401.        
  402.         internal ReadObjectInfo()
  403.         {
  404.         }
  405.        
  406.         internal void ObjectEnd()
  407.         {
  408.             SerTrace.Log(this, objectInfoId, " objectType ", objectType, " ObjectEnd");
  409.         }
  410.        
  411.         internal void PrepareForReuse()
  412.         {
  413.             lastPosition = 0;
  414.         }
  415.        
  416.         static internal ReadObjectInfo Create(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, bool bSimpleAssembly)
  417.         {
  418.             ReadObjectInfo soi = GetObjectInfo(serObjectInfoInit);
  419.             soi.Init(objectType, surrogateSelector, context, objectManager, serObjectInfoInit, converter, bSimpleAssembly);
  420.             return soi;
  421.         }
  422.        
  423.        
  424.         // Read Constructor
  425.         internal void Init(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, bool bSimpleAssembly)
  426.         {
  427.            
  428.             SerTrace.Log(this, objectInfoId, " Constructor 3 ", objectType);
  429.            
  430.             this.objectType = objectType;
  431.             this.objectManager = objectManager;
  432.             this.context = context;
  433.             this.serObjectInfoInit = serObjectInfoInit;
  434.             this.formatterConverter = converter;
  435.             this.bSimpleAssembly = bSimpleAssembly;
  436.            
  437.             InitReadConstructor(objectType, surrogateSelector, context);
  438.         }
  439.        
  440.         static internal ReadObjectInfo Create(Type objectType, string[] memberNames, Type[] memberTypes, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, bool bSimpleAssembly)
  441.         {
  442.             ReadObjectInfo soi = GetObjectInfo(serObjectInfoInit);
  443.             soi.Init(objectType, memberNames, memberTypes, surrogateSelector, context, objectManager, serObjectInfoInit, converter, bSimpleAssembly);
  444.             return soi;
  445.         }
  446.        
  447.         // Read Constructor
  448.         internal void Init(Type objectType, string[] memberNames, Type[] memberTypes, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, bool bSimpleAssembly)
  449.         {
  450.             SerTrace.Log(this, objectInfoId, " Constructor 5 ", objectType);
  451.             this.objectType = objectType;
  452.             this.objectManager = objectManager;
  453.             this.wireMemberNames = memberNames;
  454.             this.wireMemberTypes = memberTypes;
  455.             this.context = context;
  456.             this.serObjectInfoInit = serObjectInfoInit;
  457.             this.formatterConverter = converter;
  458.             this.bSimpleAssembly = bSimpleAssembly;
  459.             if (memberNames != null)
  460.                 isNamed = true;
  461.             if (memberTypes != null)
  462.                 isTyped = true;
  463.            
  464.             if (objectType != null)
  465.                 InitReadConstructor(objectType, surrogateSelector, context);
  466.         }
  467.        
  468.         private void InitReadConstructor(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context)
  469.         {
  470.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitReadConstructor Entry ", objectType);
  471.            
  472.             if (objectType.IsArray) {
  473.                 InitNoMembers();
  474.                 return;
  475.             }
  476.            
  477.             ISurrogateSelector surrogateSelectorTemp = null;
  478.            
  479.             if (surrogateSelector != null)
  480.                 serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp);
  481.            
  482.             if (serializationSurrogate != null) {
  483.                 isSi = true;
  484.             }
  485.             else if (objectType == Converter.typeofObject) {
  486.             }
  487.             else if (Converter.typeofISerializable.IsAssignableFrom(objectType))
  488.                 isSi = true;
  489.            
  490.             if (isSi) {
  491.                 InitSiRead();
  492.             }
  493.             else {
  494.                 InitMemberInfo();
  495.             }
  496.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitReadConstructor Exit ", isSi);
  497.         }
  498.        
  499.         private void InitSiRead()
  500.         {
  501.             if (memberTypesList != null) {
  502.                 memberTypesList = new ArrayList(20);
  503.             }
  504.         }
  505.        
  506.         private void InitNoMembers()
  507.         {
  508.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  509.             cache = new SerObjectInfoCache();
  510.             cache.fullTypeName = objectType.FullName;
  511.             cache.assemblyString = objectType.Assembly.FullName;
  512.         }
  513.        
  514.         private void InitMemberInfo()
  515.         {
  516.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitMemberInfo Entry");
  517.            
  518.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitMemberInfo new cache");
  519.             cache = new SerObjectInfoCache();
  520.             cache.memberInfos = FormatterServices.GetSerializableMembers(objectType, context);
  521.             count = cache.memberInfos.Length;
  522.             cache.memberNames = new string[count];
  523.             cache.memberTypes = new Type[count];
  524.            
  525.             // Calculate new arrays
  526.             for (int i = 0; i < count; i++) {
  527.                 cache.memberNames[i] = cache.memberInfos[i].Name;
  528.                 cache.memberTypes[i] = GetMemberType(cache.memberInfos[i]);
  529.                 SerTrace.Log(this, objectInfoId, " InitMemberInfo name ", cache.memberNames[i], ", type ", cache.memberTypes[i], ", memberInfoType ", cache.memberInfos[i].GetType());
  530.             }
  531.             cache.fullTypeName = objectType.FullName;
  532.             cache.assemblyString = objectType.Assembly.FullName;
  533.            
  534.             isTyped = true;
  535.             isNamed = true;
  536.             SerTrace.Log(this, objectInfoId, " ", objectType, " InitMemberInfo Exit");
  537.         }
  538.        
  539.         // Get the memberInfo for a memberName
  540.         internal MemberInfo GetMemberInfo(string name)
  541.         {
  542.             SerTrace.Log(this, objectInfoId, " ", objectType, " GetMemberInfo Entry ", name);
  543.             if (cache == null)
  544.                 return null;
  545.             if (isSi)
  546.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_MemberInfo"), objectType + " " + name));
  547.             if (cache.memberInfos == null)
  548.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_NoMemberInfo"), objectType + " " + name));
  549.             int position = Position(name);
  550.             if (position != -1)
  551.                 return cache.memberInfos[Position(name)];
  552.             else
  553.                 return null;
  554.         }
  555.        
  556.         // Get the ObjectType for a memberName
  557.         internal Type GetType(string name)
  558.         {
  559.             SerTrace.Log(this, objectInfoId, " ", objectType, " GetType Entry ", name);
  560.             Type type = null;
  561.             int position = Position(name);
  562.             if (position == -1)
  563.                 return null;
  564.            
  565.             if (isTyped)
  566.                 type = cache.memberTypes[position];
  567.             else
  568.                 type = (Type)memberTypesList[position];
  569.            
  570.             if (type == null)
  571.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_ISerializableTypes"), objectType + " " + name));
  572.            
  573.             SerTrace.Log(this, objectInfoId, " ", objectType, " GetType Exit ", type);
  574.             return type;
  575.         }
  576.        
  577.        
  578.         // Adds the value for a memberName
  579.         internal void AddValue(string name, object value, ref SerializationInfo si, ref object[] memberData)
  580.         {
  581.             SerTrace.Log(this, objectInfoId, " ", objectType, " AddValue ", name, " ", value, " isSi ", isSi
  582.             );
  583.             if (isSi) {
  584.                 si.AddValue(name, value);
  585.             }
  586.             else {
  587.                 // Console.WriteLine("Calling add value for " + name + " with value " + value);
  588.                 int position = Position(name);
  589.                
  590.                 // If a member in the stream is not found, ignore it
  591.                 if (position != -1)
  592.                     memberData[position] = value;
  593.             }
  594.         }
  595.        
  596.         internal void InitDataStore(ref SerializationInfo si, ref object[] memberData)
  597.         {
  598.             if (isSi) {
  599.                 if (si == null)
  600.                     si = new SerializationInfo(objectType, formatterConverter);
  601.             }
  602.             else {
  603.                 if (memberData == null && cache != null)
  604.                     memberData = new object[cache.memberNames.Length];
  605.             }
  606.         }
  607.        
  608.        
  609.         // Records an objectId in a member when the actual object for that member is not yet known
  610.         internal void RecordFixup(long objectId, string name, long idRef)
  611.         {
  612.            
  613.             if (isSi) {
  614.                 SerTrace.Log(this, objectInfoId, " ", objectType, " RecordFixup RecordDelayedFixup objectId ", objectId, " name ", name, " idRef ", idRef,
  615.                 " isSi ", isSi);
  616.                 objectManager.RecordDelayedFixup(objectId, name, idRef);
  617.             }
  618.             else {
  619.                 SerTrace.Log(this, objectInfoId, " ", objectType, " RecordFixup objectId ", objectId, " name ", name, " idRef ", idRef,
  620.                 " isSi ", isSi);
  621.                 int position = Position(name);
  622.                 if (position != -1)
  623.                     objectManager.RecordFixup(objectId, cache.memberInfos[position], idRef);
  624.             }
  625.         }
  626.        
  627.         // Fills in the values for an object
  628.         internal void PopulateObjectMembers(object obj, object[] memberData)
  629.         {
  630.             SerTrace.Log(this, objectInfoId, " ", objectType, " PopulateObjectMembers isSi ", isSi);
  631.             if (!isSi && memberData != null) {
  632.                 DumpPopulate(cache.memberInfos, memberData);
  633.                
  634.                 FormatterServices.PopulateObjectMembers(obj, cache.memberInfos, memberData);
  635.             }
  636.         }
  637.        
  638.         [Conditional("SER_LOGGING")]
  639.         private void DumpPopulate(MemberInfo[] memberInfos, object[] memberData)
  640.         {
  641.             for (int i = 0; i < memberInfos.Length; i++) {
  642.                 SerTrace.Log(this, objectInfoId, " ", objectType, " PopulateObjectMembers ", memberInfos[i].Name, " ", memberData[i]);
  643.                
  644.             }
  645.         }
  646.        
  647.         [Conditional("SER_LOGGING")]
  648.         private void DumpPopulateSi()
  649.         {
  650.             //SerTrace.Log( this,objectInfoId," ", objectType," PopulateObjectMembers SetObjectData, ISerializable obj ");
  651.             //SerializationInfoEnumerator siEnum = si.GetEnumerator();
  652.             //for (int i=0; siEnum.MoveNext(); i++)
  653.             //{
  654.             // SerTrace.Log( this,objectInfoId," ",objectType," Populate Si ",siEnum.Name," ",siEnum.Value);
  655.             //}
  656.         }
  657.        
  658.         // Specifies the position in the memberNames array of this name
  659.        
  660.         private int Position(string name)
  661.         {
  662.             SerTrace.Log(this, objectInfoId, " Position ", lastPosition, " ", name);
  663.             if (cache == null)
  664.                 return -1;
  665.            
  666.             if (cache.memberNames.Length > 0 && cache.memberNames[lastPosition].Equals(name)) {
  667.                 return lastPosition;
  668.             }
  669.             else if ((++lastPosition < cache.memberNames.Length) && (cache.memberNames[lastPosition].Equals(name))) {
  670.                 return lastPosition;
  671.             }
  672.             else {
  673.                 // Search for name
  674.                 SerTrace.Log(this, objectInfoId, " Position miss search for name " + name);
  675.                 for (int i = 0; i < cache.memberNames.Length; i++) {
  676.                     if (cache.memberNames[i].Equals(name)) {
  677.                         lastPosition = i;
  678.                         return lastPosition;
  679.                     }
  680.                 }
  681.                
  682.                 //throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_MissingMember"),name,objectType));
  683.                 lastPosition = 0;
  684.                 return -1;
  685.             }
  686.         }
  687.        
  688.         // Return the member Types in order of memberNames
  689.         internal Type[] GetMemberTypes(string[] inMemberNames, Type objectType)
  690.         {
  691.             if (isSi)
  692.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_ISerializableTypes"), objectType));
  693.            
  694.             //BCLDebug.Assert(cache!=null, "[ReadObjectInfo::GetMemberTypes] cache!=null");
  695.             if (cache == null)
  696.                 return null;
  697.            
  698.             if (cache.memberTypes == null) {
  699.                 cache.memberTypes = new Type[count];
  700.                 for (int i = 0; i < count; i++)
  701.                     cache.memberTypes[i] = GetMemberType(cache.memberInfos[i]);
  702.             }
  703.            
  704.             bool memberMissing = false;
  705.             // If the field length in the stream is < cache a member is missing
  706.             if (inMemberNames.Length < cache.memberInfos.Length)
  707.                 memberMissing = true;
  708.            
  709.             Type[] outMemberTypes = new Type[cache.memberInfos.Length];
  710.            
  711.             bool isFound = false;
  712.            
  713.             for (int i = 0; i < cache.memberInfos.Length; i++) {
  714.                 if (!memberMissing && inMemberNames[i].Equals(cache.memberInfos[i].Name))
  715.                     outMemberTypes[i] = cache.memberTypes[i];
  716.                 else {
  717.                     // MemberNames on wire in different order then memberInfos returned by reflection
  718.                     isFound = false;
  719.                     for (int j = 0; j < inMemberNames.Length; j++) {
  720.                         if (cache.memberInfos[i].Name.Equals(inMemberNames[j])) {
  721.                             outMemberTypes[i] = cache.memberTypes[i];
  722.                             SerTrace.Log(this, objectInfoId, " ", objectType, " GetMemberTypes memberName ", cache.memberTypes[i], " ", i, " memberTypes ", outMemberTypes[j],
  723.                             " ", j);
  724.                             isFound = true;
  725.                             break;
  726.                         }
  727.                     }
  728.                     if (!isFound) {
  729.                         // A field on the type isnt found. See if the field has OptionallySerializable and the type has the deserialization constructor
  730.                         object[] attrs = cache.memberInfos[i].GetCustomAttributes(typeof(OptionalFieldAttribute), false);
  731.                         if ((attrs == null || attrs.Length == 0) && !bSimpleAssembly) {
  732.                             // the member isnt optionally serializable
  733.                             throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_MissingMember"), cache.memberNames[i], objectType, typeof(OptionalFieldAttribute).FullName));
  734.                         }
  735.                     }
  736.                 }
  737.             }
  738.             return outMemberTypes;
  739.         }
  740.        
  741.        
  742.        
  743.        
  744.         // Retrieves the member type from the MemberInfo
  745.         internal Type GetMemberType(MemberInfo objMember)
  746.         {
  747.             Type objectType = null;
  748.            
  749.             if (objMember is FieldInfo) {
  750.                 objectType = ((FieldInfo)objMember).FieldType;
  751.                 SerTrace.Log(this, objectInfoId, " ", "GetMemberType FieldInfo ", objectType);
  752.             }
  753.             else if (objMember is PropertyInfo) {
  754.                 objectType = ((PropertyInfo)objMember).PropertyType;
  755.                 SerTrace.Log(this, objectInfoId, " ", "GetMemberType PropertyInfo ", objectType);
  756.             }
  757.             else {
  758.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_SerMemberInfo"), objMember.GetType()));
  759.             }
  760.            
  761.             return objectType;
  762.         }
  763.        
  764.        
  765.         private static ReadObjectInfo GetObjectInfo(SerObjectInfoInit serObjectInfoInit)
  766.         {
  767.             ReadObjectInfo roi = new ReadObjectInfo();
  768.             roi.objectInfoId = readObjectInfoCounter++;
  769.             return roi;
  770.         }
  771.        
  772.     }
  773.    
  774.    
  775.     internal sealed class SerObjectInfoInit
  776.     {
  777.         internal Hashtable seenBeforeTable = new Hashtable();
  778.         internal int objectInfoIdCount = 1;
  779.         internal SerStack oiPool = new SerStack("SerObjectInfo Pool");
  780.     }
  781.    
  782.     internal sealed class SerObjectInfoCache
  783.     {
  784.         internal string fullTypeName = null;
  785.         internal string assemblyString = null;
  786.         internal MemberInfo[] memberInfos = null;
  787.         internal string[] memberNames = null;
  788.         internal Type[] memberTypes = null;
  789.     }
  790. }

Developer Fusion