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 \ ObjectReader

  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: ObjectReader
  18. // Purpose: DeSerializes XML in SOAP Format into an an object graph
  19. //
  20. // Date: June 10, 1999
  21. //
  22. //============================================================
  23. namespace System.Runtime.Serialization.Formatters.Soap
  24. {
  25.    
  26.     using System;
  27.     using System.IO;
  28.     using System.Reflection;
  29.     using System.Collections;
  30.     using System.Text;
  31.     using System.Runtime.Remoting;
  32.     using System.Runtime.Remoting.Metadata.W3cXsd2001;
  33.     using System.Runtime.Remoting.Messaging;
  34.     using System.Runtime.Serialization;
  35.     using System.Security;
  36.     using System.Security.Permissions;
  37.     using System.Diagnostics;
  38.     using System.Globalization;
  39.    
  40.     internal sealed class ObjectReader
  41.     {
  42.        
  43.         // System.Serializer information
  44.         internal ObjectIDGenerator m_idGenerator;
  45.         internal Stream m_stream;
  46.         internal ISurrogateSelector m_surrogates;
  47.         internal StreamingContext m_context;
  48.         internal ObjectManager m_objectManager;
  49.         internal InternalFE formatterEnums;
  50.         internal SerializationBinder m_binder;
  51.        
  52.         internal SoapHandler soapHandler;
  53.         //Set from SoapHandler
  54.         // Fake Top object and headers
  55.         internal long topId = 0;
  56.         internal SerStack topStack;
  57.         // Stack for placing ProcessRecords if the top record cannot be serialized on the first pass.
  58.         internal bool isTopObjectSecondPass = false;
  59.         internal bool isTopObjectResolved = true;
  60.         internal bool isHeaderHandlerCalled = false;
  61.         internal Exception deserializationSecurityException = null;
  62.         internal object handlerObject = null;
  63.         internal object topObject;
  64.         internal long soapFaultId;
  65.         internal Header[] headers;
  66.         internal Header[] newheaders;
  67.         internal bool IsFakeTopObject = false;
  68.         internal HeaderHandler handler;
  69.         internal SerObjectInfoInit serObjectInfoInit = null;
  70.         internal IFormatterConverter m_formatterConverter = null;
  71.        
  72.         // Stack of Object ParseRecords
  73.         internal SerStack stack = new SerStack("ObjectReader Object Stack");
  74.        
  75.         // ValueType Fixup Stack
  76.         internal SerStack valueFixupStack = new SerStack("ValueType Fixup Stack");
  77.        
  78.         // Generate Object Id's
  79.         internal Hashtable objectIdTable = new Hashtable(25);
  80.         // holds the keyId value from the XML input and associated internal Id
  81.         internal long objectIds = 0;
  82.        
  83.         internal int paramPosition = 0;
  84.         //Position of parameter if soap top fake record.
  85.         internal int majorVersion = 0;
  86.         internal int minorVersion = 0;
  87.        
  88.         internal string faultString = null;
  89.        
  90.         // GetType - eliminate redundant Type.GetType()
  91.         //internal Hashtable typeTable = new Hashtable(10);
  92.        
  93.         static internal SecurityPermission serializationPermission = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
  94.         private static FileIOPermission sfileIOPermission = new FileIOPermission(PermissionState.Unrestricted);
  95.        
  96.        
  97.         internal ObjectReader(Stream stream, ISurrogateSelector selector, StreamingContext context, InternalFE formatterEnums, SerializationBinder binder)
  98.         {
  99.             InternalST.Soap(this, "Constructor ISurrogateSelector ", ((selector == null) ? "null selector " : "selector present"));
  100.            
  101.             if (stream == null) {
  102.                 throw new ArgumentNullException("stream", SoapUtil.GetResourceString("ArgumentNull_Stream"));
  103.             }
  104.            
  105.             m_stream = stream;
  106.             m_surrogates = selector;
  107.             m_context = context;
  108.             m_binder = binder;
  109.             this.formatterEnums = formatterEnums;
  110.            
  111.             InternalST.Soap(this, "Constructor formatterEnums.FEtopObject ", formatterEnums.FEtopObject);
  112.             if (formatterEnums.FEtopObject != null)
  113.                 IsFakeTopObject = true;
  114.             else
  115.                 IsFakeTopObject = false;
  116.            
  117.             m_formatterConverter = new FormatterConverter();
  118.         }
  119.        
  120.        
  121.         private ObjectManager GetObjectManager()
  122.         {
  123.             new SecurityPermission(SecurityPermissionFlag.SerializationFormatter).Assert();
  124.             return new ObjectManager(m_surrogates, m_context);
  125.         }
  126.        
  127.        
  128.        
  129.        
  130.         // Deserialize the stream into an object graph.
  131.         internal object Deserialize(HeaderHandler handler, ISerParser serParser)
  132.         {
  133.            
  134.             InternalST.Soap(this, "Deserialize Entry handler", handler);
  135.            
  136.             if (serParser == null)
  137.                 throw new ArgumentNullException("serParser", String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("ArgumentNull_WithParamName"), serParser));
  138.            
  139.            
  140.             deserializationSecurityException = null;
  141.             try {
  142.                 serializationPermission.Demand();
  143.             }
  144.             catch (Exception e) {
  145.                 deserializationSecurityException = e;
  146.             }
  147.             catch {
  148.                 deserializationSecurityException = new Exception(SoapUtil.GetResourceString("Serialization_NonClsCompliantException"));
  149.             }
  150.            
  151.             this.handler = handler;
  152.             isTopObjectSecondPass = false;
  153.             isHeaderHandlerCalled = false;
  154.            
  155.             if (handler != null)
  156.                 IsFakeTopObject = true;
  157.            
  158.             m_idGenerator = new ObjectIDGenerator();
  159.            
  160.            
  161.             m_objectManager = GetObjectManager();
  162.            
  163.             serObjectInfoInit = new SerObjectInfoInit();
  164.             objectIdTable.Clear();
  165.             objectIds = 0;
  166.            
  167.             // Will call back to ParseObject, ParseHeader for each object found
  168.             serParser.Run();
  169.            
  170.             if (handler != null) {
  171.                 InternalST.Soap(this, "Deserialize Fixup Before Delegate Invoke");
  172.                 m_objectManager.DoFixups();
  173.                 // Fixup for headers
  174.                 // Header handler isn't invoked until method name is known from body fake record
  175.                 // Except for SoapFault, in which case it is invoked below
  176.                 if (handlerObject == null) {
  177.                     InternalST.Soap(this, "Deserialize Before SoapFault Delegate Invoke ");
  178.                     handlerObject = handler(newheaders);
  179.                     InternalST.Soap(this, "Deserialize after SoapFault Delegate Invoke");
  180.                 }
  181.                
  182.                
  183.                 // SoapFault creation Create a fake Pr for the handlerObject to use.
  184.                 // Create a member for the fake pr with name __fault;
  185.                 if ((soapFaultId > 0) && (handlerObject != null)) {
  186.                     InternalST.Soap(this, "Deserialize SoapFault ");
  187.                     topStack = new SerStack("Top ParseRecords");
  188.                     ParseRecord pr = new ParseRecord();
  189.                     pr.PRparseTypeEnum = InternalParseTypeE.Object;
  190.                     pr.PRobjectPositionEnum = InternalObjectPositionE.Top;
  191.                     pr.PRparseStateEnum = InternalParseStateE.Object;
  192.                     pr.PRname = "Response";
  193.                     topStack.Push(pr);
  194.                     pr = new ParseRecord();
  195.                     pr.PRparseTypeEnum = InternalParseTypeE.Member;
  196.                     pr.PRobjectPositionEnum = InternalObjectPositionE.Child;
  197.                     pr.PRmemberTypeEnum = InternalMemberTypeE.Field;
  198.                     pr.PRmemberValueEnum = InternalMemberValueE.Reference;
  199.                     pr.PRparseStateEnum = InternalParseStateE.Member;
  200.                     pr.PRname = "__fault";
  201.                     pr.PRidRef = soapFaultId;
  202.                     topStack.Push(pr);
  203.                     pr = new ParseRecord();
  204.                     pr.PRparseTypeEnum = InternalParseTypeE.ObjectEnd;
  205.                     pr.PRobjectPositionEnum = InternalObjectPositionE.Top;
  206.                     pr.PRparseStateEnum = InternalParseStateE.Object;
  207.                     pr.PRname = "Response";
  208.                     topStack.Push(pr);
  209.                     isTopObjectResolved = false;
  210.                 }
  211.             }
  212.            
  213.            
  214.             // Resolve fake top object if necessary
  215.             if (!isTopObjectResolved) {
  216.                 //resolve top object
  217.                 InternalST.Soap(this, "Deserialize TopObject Second Pass");
  218.                 isTopObjectSecondPass = true;
  219.                 topStack.Reverse();
  220.                 // The top of the stack now contains the fake record
  221.                 // When it is Parsed, the handler object will be substituted
  222.                 // for it in ParseObject.
  223.                 int topStackLength = topStack.Count();
  224.                 ParseRecord pr = null;
  225.                 for (int i = 0; i < topStackLength; i++) {
  226.                     pr = (ParseRecord)topStack.Pop();
  227.                     Parse(pr);
  228.                 }
  229.             }
  230.            
  231.            
  232.             InternalST.Soap(this, "Deserialize Finished Parsing DoFixups");
  233.            
  234.             m_objectManager.DoFixups();
  235.            
  236.             if (topObject == null)
  237.                 throw new SerializationException(SoapUtil.GetResourceString("Serialization_TopObject"));
  238.            
  239.             //if topObject has a surrogate then the actual object may be changed during special fixup
  240.             //So refresh it using topID.
  241.             if (HasSurrogate(topObject.GetType()) && topId != 0)
  242.                 //Not yet resolved
  243.                 topObject = m_objectManager.GetObject(topId);
  244.            
  245.             if (topObject is IObjectReference) {
  246.                 topObject = ((IObjectReference)topObject).GetRealObject(m_context);
  247.             }
  248.            
  249.             InternalST.Soap(this, "Deserialize Exit ", topObject);
  250.            
  251.             m_objectManager.RaiseDeserializationEvent();
  252.            
  253.            
  254.            
  255.             if ((formatterEnums.FEtopObject != null) && (topObject is InternalSoapMessage)) {
  256.                 // Convert InternalSoapMessage to SoapMessage
  257.                 InternalST.Soap(this, "Deserialize SoapMessage Entry ");
  258.                
  259.                 InternalSoapMessage ismc = (InternalSoapMessage)topObject;
  260.                 ISoapMessage smc = (ISoapMessage)formatterEnums.FEtopObject;
  261.                 smc.MethodName = ismc.methodName;
  262.                 smc.XmlNameSpace = ismc.xmlNameSpace;
  263.                 smc.ParamNames = ismc.paramNames;
  264.                 smc.ParamValues = ismc.paramValues;
  265.                 smc.Headers = headers;
  266.                 topObject = smc;
  267.                 isTopObjectResolved = true;
  268.                 InternalST.Soap(this, "Deserialize SoapMessage Exit topObject ", topObject, " method name ", smc.MethodName);
  269.             }
  270.            
  271.             return topObject;
  272.         }
  273.        
  274.         private bool HasSurrogate(Type t)
  275.         {
  276.             if (m_surrogates == null)
  277.                 return false;
  278.             ISurrogateSelector notUsed;
  279.             return m_surrogates.GetSurrogate(t, m_context, out notUsed) != null;
  280.         }
  281.        
  282.         private void CheckSerializable(Type t)
  283.         {
  284.             if (!t.IsSerializable && !HasSurrogate(t))
  285.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_NonSerType"), t.FullName, t.Module.Assembly.FullName));
  286.         }
  287.        
  288.         internal ReadObjectInfo CreateReadObjectInfo(Type objectType, string assemblyName)
  289.         {
  290.             ReadObjectInfo objectInfo = ReadObjectInfo.Create(objectType, m_surrogates, m_context, m_objectManager, serObjectInfoInit, m_formatterConverter, assemblyName);
  291.             objectInfo.SetVersion(majorVersion, minorVersion);
  292.             return objectInfo;
  293.         }
  294.        
  295.         internal ReadObjectInfo CreateReadObjectInfo(Type objectType, string[] memberNames, Type[] memberTypes, string assemblyName)
  296.         {
  297.             ReadObjectInfo objectInfo = ReadObjectInfo.Create(objectType, memberNames, memberTypes, m_surrogates, m_context, m_objectManager, serObjectInfoInit, m_formatterConverter, assemblyName);
  298.             objectInfo.SetVersion(majorVersion, minorVersion);
  299.             return objectInfo;
  300.         }
  301.        
  302.        
  303.         // Main Parse routine, called by the XML Parse Handlers in XMLParser and also called internally to
  304.         // parse the fake top object.
  305.         internal void Parse(ParseRecord pr)
  306.         {
  307.             InternalST.Soap(this, "Parse Entry");
  308.             stack.Dump();
  309.             pr.Dump();
  310.            
  311.             switch (pr.PRparseTypeEnum) {
  312.                 case InternalParseTypeE.SerializedStreamHeader:
  313.                     ParseSerializedStreamHeader(pr);
  314.                     break;
  315.                 case InternalParseTypeE.SerializedStreamHeaderEnd:
  316.                     ParseSerializedStreamHeaderEnd(pr);
  317.                     break;
  318.                 case InternalParseTypeE.Object:
  319.                     ParseObject(pr);
  320.                     break;
  321.                 case InternalParseTypeE.ObjectEnd:
  322.                     ParseObjectEnd(pr);
  323.                     break;
  324.                 case InternalParseTypeE.Member:
  325.                     ParseMember(pr);
  326.                     break;
  327.                 case InternalParseTypeE.MemberEnd:
  328.                     ParseMemberEnd(pr);
  329.                     break;
  330.                 case InternalParseTypeE.Body:
  331.                 case InternalParseTypeE.BodyEnd:
  332.                 case InternalParseTypeE.Envelope:
  333.                 case InternalParseTypeE.EnvelopeEnd:
  334.                     break;
  335.                 case InternalParseTypeE.Empty:
  336.                 default:
  337.                     throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_XMLElement"), pr.PRname));
  338.                     break;
  339.                
  340.             }
  341.         }
  342.        
  343.         // Styled ParseError output
  344.         private void ParseError(ParseRecord processing, ParseRecord onStack)
  345.         {
  346.             InternalST.Soap(this, " ParseError ", processing, " ", onStack);
  347.             throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_ParseError"), onStack.PRname + " " + ((Enum)onStack.PRparseTypeEnum).ToString() + " " + processing.PRname + " " + ((Enum)processing.PRparseTypeEnum).ToString()));
  348.         }
  349.        
  350.         // Parse the SerializedStreamHeader element. This is the first element in the stream if present
  351.         private void ParseSerializedStreamHeader(ParseRecord pr)
  352.         {
  353.             InternalST.Soap(this, "SerializedHeader ", pr);
  354.             stack.Push(pr);
  355.         }
  356.        
  357.         // Parse the SerializedStreamHeader end element. This is the last element in the stream if present
  358.         private void ParseSerializedStreamHeaderEnd(ParseRecord pr)
  359.         {
  360.             InternalST.Soap(this, "SerializedHeaderEnd ", pr);
  361.             stack.Pop();
  362.         }
  363.        
  364.        
  365.        
  366.         private bool IsRemoting {
  367. //return (m_context.State & (StreamingContextStates.Persistence|StreamingContextStates.File|StreamingContextStates.Clone)) == 0;
  368.             get { return IsFakeTopObject; }
  369.         }
  370.        
  371.         private void CheckSecurity(ParseRecord pr)
  372.         {
  373.             InternalST.SoapAssert(pr != null, "[BinaryObjectReader.CheckSecurity]pr!=null");
  374.             Type t = pr.PRdtType;
  375.            
  376.             if (t != null) {
  377.                 if (IsRemoting) {
  378.                     if (typeof(MarshalByRefObject).IsAssignableFrom(t))
  379.                         throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_MBRAsMBV"), t.FullName));
  380.                     FormatterServices.CheckTypeSecurity(t, formatterEnums.FEsecurityLevel);
  381.                 }
  382.             }
  383.            
  384.             //If we passed the security check, they can do whatever they'd like,
  385.             //so we'll just short-circuit this.
  386.             if (deserializationSecurityException == null) {
  387.                 return;
  388.             }
  389.            
  390.             // BaseTypes and Array of basetypes allowed
  391.            
  392.             if (t != null) {
  393.                 if (t.IsPrimitive || t == Converter.typeofString)
  394.                     return;
  395.                
  396.                 if (typeof(Enum).IsAssignableFrom(t))
  397.                     return;
  398.                
  399.                 if (t.IsArray) {
  400.                     Type type = t.GetElementType();
  401.                     if (type.IsPrimitive || type == Converter.typeofString)
  402.                         return;
  403.                 }
  404.             }
  405.            
  406.             throw deserializationSecurityException;
  407.         }
  408.        
  409.         // New object encountered in stream
  410.         private void ParseObject(ParseRecord pr)
  411.         {
  412.             InternalST.Soap(this, "ParseObject Entry ");
  413.            
  414.             if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
  415.                 topId = pr.PRobjectId;
  416.            
  417.             if (pr.PRparseTypeEnum == InternalParseTypeE.Object) {
  418.                 InternalST.Soap(this, "ParseObject Push " + pr.PRname);
  419.                 stack.Push(pr);
  420.                 // Nested objects member names are already on stack
  421.             }
  422.            
  423.             if (pr.PRobjectTypeEnum == InternalObjectTypeE.Array) {
  424.                 ParseArray(pr);
  425.                 InternalST.Soap(this, "ParseObject Exit, ParseArray ");
  426.                 return;
  427.             }
  428.            
  429.             if ((pr.PRdtType == null) && !IsFakeTopObject)
  430.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"), pr.PRname));
  431.            
  432.            
  433.             if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top && IsFakeTopObject && pr.PRdtType != Converter.typeofSoapFault) {
  434.                
  435.                 // Soap fake top object
  436.                 if (handler != null) {
  437.                     // Handler object will supply real top object
  438.                     InternalST.Soap(this, "ParseObject FakeTopObject with handlerObject ");
  439.                    
  440.                     // Now know the method name, can call header handler
  441.                     //Create header for method name
  442.                     if (!isHeaderHandlerCalled) {
  443.                         newheaders = null;
  444.                         isHeaderHandlerCalled = true;
  445.                         if (headers == null) {
  446.                             newheaders = new Header[1];
  447.                         }
  448.                         else {
  449.                             newheaders = new Header[headers.Length + 1];
  450.                             Array.Copy(headers, 0, newheaders, 1, headers.Length);
  451.                         }
  452.                        
  453.                         Header methodNameHeader = new Header("__methodName", pr.PRname, false, pr.PRnameXmlKey);
  454.                         newheaders[0] = methodNameHeader;
  455.                         InternalST.Soap(this, "Deserialize Before Delegate Invoke ");
  456.                         handlerObject = handler(newheaders);
  457.                        
  458.                         InternalST.Soap(this, "Deserialize after Delegate Invoke");
  459.                         InternalST.Soap(this, "Deserialize delgate object ", ((handlerObject == null) ? "null" : handlerObject));
  460.                     }
  461.                    
  462.                     if (isHeaderHandlerCalled) {
  463.                         // Handler object has supplied the real object for the fake object
  464.                         // which is on top of the stack
  465.                         pr.PRnewObj = handlerObject;
  466.                         pr.PRdtType = handlerObject.GetType();
  467.                         CheckSecurity(pr);
  468.                         if (pr.PRnewObj is IFieldInfo) {
  469.                             IFieldInfo fi = (IFieldInfo)pr.PRnewObj;
  470.                             if ((fi.FieldTypes != null) && (fi.FieldTypes.Length > 0)) {
  471.                                 pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, fi.FieldNames, fi.FieldTypes, pr.PRassemblyName);
  472.                             }
  473.                         }
  474.                     }
  475.                     else {
  476.                         // Handler object has not yet been asked for the real object
  477.                         // Stack the parse record until the second pass
  478.                         isTopObjectResolved = false;
  479.                         topStack = new SerStack("Top ParseRecords");
  480.                         InternalST.Soap(this, "ParseObject Handler Push " + pr.PRname);
  481.                         topStack.Push(pr.Copy());
  482.                         return;
  483.                     }
  484.                 }
  485.                 else if (formatterEnums.FEtopObject != null) {
  486.                     // SoapMessage will be used as the real object
  487.                     InternalST.Soap(this, "ParseObject FakeTopObject with SoapMessage ");
  488.                     if (isTopObjectSecondPass) {
  489.                         // This creates a the SoapMessage object as the real object, at this point it is an unitialized object.
  490.                         pr.PRnewObj = new InternalSoapMessage();
  491.                         pr.PRdtType = typeof(InternalSoapMessage);
  492.                         CheckSecurity(pr);
  493.                         if (formatterEnums.FEtopObject != null) {
  494.                             ISoapMessage soapMessage = (ISoapMessage)formatterEnums.FEtopObject;
  495.                             pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, soapMessage.ParamNames, soapMessage.ParamTypes, pr.PRassemblyName);
  496.                         }
  497.                     }
  498.                     else {
  499.                         // Stack the parse record until the second pass
  500.                         isTopObjectResolved = false;
  501.                         topStack = new SerStack("Top ParseRecords");
  502.                         topStack.Push(pr.Copy());
  503.                         return;
  504.                     }
  505.                 }
  506.             }
  507.             else if (pr.PRdtType == Converter.typeofString) {
  508.                 // String as a top level object
  509.                 if (pr.PRvalue != null) {
  510.                     pr.PRnewObj = pr.PRvalue;
  511.                     if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top) {
  512.                         InternalST.Soap(this, "ParseObject String as top level, Top Object Resolved");
  513.                         isTopObjectResolved = true;
  514.                         topObject = pr.PRnewObj;
  515.                         //stack.Pop();
  516.                         return;
  517.                     }
  518.                     else {
  519.                         InternalST.Soap(this, "ParseObject String as an object");
  520.                         stack.Pop();
  521.                         RegisterObject(pr.PRnewObj, pr, (ParseRecord)stack.Peek());
  522.                         return;
  523.                     }
  524.                 }
  525.                 else {
  526.                     // xml Doesn't have the value until later
  527.                     return;
  528.                 }
  529.             }
  530.             else {
  531.                 if (pr.PRdtType == null) {
  532.                     ParseRecord objectPr = (ParseRecord)stack.Peek();
  533.                     if (objectPr.PRdtType == Converter.typeofSoapFault) {
  534.                         InternalST.Soap(this, "ParseObject unknown SoapFault detail");
  535.                         throw new ServerException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_SoapFault"), faultString));
  536.                     }
  537.                    
  538.                     throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TypeElement"), pr.PRname));
  539.                 }
  540.                 CheckSerializable(pr.PRdtType);
  541.                 if (IsRemoting && formatterEnums.FEsecurityLevel != TypeFilterLevel.Full)
  542.                     pr.PRnewObj = FormatterServices.GetSafeUninitializedObject(pr.PRdtType);
  543.                 else
  544.                     pr.PRnewObj = FormatterServices.GetUninitializedObject(pr.PRdtType);
  545.                
  546.                 CheckSecurity(pr);
  547.                 // Run the OnDeserializing methods
  548.                 m_objectManager.RaiseOnDeserializingEvent(pr.PRnewObj);
  549.                
  550.             }
  551.            
  552.             if (pr.PRnewObj == null)
  553.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"), pr.PRdtType));
  554.            
  555.             long genId = pr.PRobjectId;
  556.             if (genId < 1)
  557.                 pr.PRobjectId = GetId("GenId-" + objectIds);
  558.            
  559.            
  560.             if (IsFakeTopObject && pr.PRobjectPositionEnum == InternalObjectPositionE.Top) {
  561.                 InternalST.Soap(this, "ParseObject fake Top object resolved ", pr.PRnewObj);
  562.                 isTopObjectResolved = true;
  563.                 topObject = pr.PRnewObj;
  564.             }
  565.            
  566.             if (pr.PRobjectInfo == null)
  567.                 pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, pr.PRassemblyName);
  568.             pr.PRobjectInfo.obj = pr.PRnewObj;
  569.            
  570.             if (IsFakeTopObject && pr.PRobjectPositionEnum == InternalObjectPositionE.Top) {
  571.                 InternalST.Soap(this, "ParseObject AddValue to fake object ", pr.PRobjectInfo.obj);
  572.                 // Add the methodName to top object, either InternalSoapMessage or object returned by handler
  573.                 pr.PRobjectInfo.AddValue("__methodName", pr.PRname);
  574.                 pr.PRobjectInfo.AddValue("__keyToNamespaceTable", soapHandler.keyToNamespaceTable);
  575.                 pr.PRobjectInfo.AddValue("__paramNameList", pr.PRobjectInfo.SetFakeObject());
  576.                 if (formatterEnums.FEtopObject != null)
  577.                     pr.PRobjectInfo.AddValue("__xmlNameSpace", pr.PRxmlNameSpace);
  578.             }
  579.            
  580.             InternalST.Soap(this, "ParseObject Exit ");
  581.         }
  582.        
  583.        
  584.         private bool IsWhiteSpace(string value)
  585.         {
  586.             for (int i = 0; i < value.Length; i++) {
  587.                 if (value[i] == ' ' || value[i] == '\n' || value[i] == '\r')
  588.                     continue;
  589.                 else
  590.                     return false;
  591.             }
  592.             return true;
  593.         }
  594.        
  595.         // End of object encountered in stream
  596.        
  597.         private void ParseObjectEnd(ParseRecord pr)
  598.         {
  599.             InternalST.Soap(this, "ParseObjectEnd Entry ", pr.Trace());
  600.             ParseRecord objectPr = (ParseRecord)stack.Peek();
  601.             if (objectPr == null)
  602.                 objectPr = pr;
  603.            
  604.            
  605.             //BCLDebug.Assert(objectPr != null, "[System.Runtime.Serialization.Formatters.ParseObjectEnd]objectPr != null");
  606.            
  607.             InternalST.Soap(this, "ParseObjectEnd objectPr ", objectPr.Trace());
  608.            
  609.             if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top) {
  610.                 InternalST.Soap(this, "ParseObjectEnd Top Object dtType ", objectPr.PRdtType);
  611.                 if (objectPr.PRdtType == Converter.typeofString) {
  612.                     InternalST.Soap(this, "ParseObjectEnd Top String");
  613.                     if (objectPr.PRvalue == null)
  614.                         objectPr.PRvalue = String.Empty;
  615.                     // Not a null object, but an empty string
  616.                     objectPr.PRnewObj = objectPr.PRvalue;
  617.                     CheckSecurity(objectPr);
  618.                     isTopObjectResolved = true;
  619.                     topObject = objectPr.PRnewObj;
  620.                     return;
  621.                 }
  622.                 else if (objectPr.PRdtType != null && objectPr.PRvalue != null && !IsWhiteSpace(objectPr.PRvalue) && (objectPr.PRdtType.IsPrimitive || objectPr.PRdtType == Converter.typeofTimeSpan)) {
  623.                     // When an xsd type is transmitted as a top level string <xsd:int>111</xsd:int>
  624.                     objectPr.PRnewObj = Converter.FromString(objectPr.PRvalue, Converter.ToCode(objectPr.PRdtType));
  625.                     CheckSecurity(objectPr);
  626.                     isTopObjectResolved = true;
  627.                     topObject = objectPr.PRnewObj;
  628.                     return;
  629.                    
  630.                 }
  631.                 else if ((!isTopObjectResolved) && (objectPr.PRdtType != Converter.typeofSoapFault)) {
  632.                     InternalST.Soap(this, "ParseObjectEnd Top but not String");
  633.                     // Need to keep top record on object stack until finished building top stack
  634.                     topStack.Push(pr.Copy());
  635.                     // Note this is PRparseRecordId and not objectId
  636.                     if (objectPr.PRparseRecordId == pr.PRparseRecordId) {
  637.                         // This handles the case of top stack containing nested objects and
  638.                         // referenced objects. If nested objects the objects are not placed
  639.                         // on stack, only topstack. If referenced objects they are placed on
  640.                         // stack and need to be popped.
  641.                         stack.Pop();
  642.                     }
  643.                     return;
  644.                 }
  645.             }
  646.            
  647.             stack.Pop();
  648.            
  649.             ParseRecord parentPr = (ParseRecord)stack.Peek();
  650.            
  651.             if (objectPr.PRobjectTypeEnum == InternalObjectTypeE.Array) {
  652.                 if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top) {
  653.                     InternalST.Soap(this, "ParseObjectEnd Top Object (Array) Resolved");
  654.                     isTopObjectResolved = true;
  655.                     topObject = objectPr.PRnewObj;
  656.                 }
  657.                
  658.                 InternalST.Soap(this, "ParseArray RegisterObject ", objectPr.PRobjectId, " ", objectPr.PRnewObj.GetType());
  659.                 RegisterObject(objectPr.PRnewObj, objectPr, parentPr);
  660.                
  661.                 return;
  662.             }
  663.            
  664.             if (objectPr.PRobjectInfo != null) {
  665.                 objectPr.PRobjectInfo.PopulateObjectMembers();
  666.             }
  667.            
  668.             if (objectPr.PRnewObj == null) {
  669.                 if (objectPr.PRdtType == Converter.typeofString) {
  670.                     InternalST.Soap(this, "ParseObjectEnd String ");
  671.                     if (objectPr.PRvalue == null)
  672.                         objectPr.PRvalue = String.Empty;
  673.                     // Not a null object, but an empty string
  674.                     objectPr.PRnewObj = objectPr.PRvalue;
  675.                     CheckSecurity(objectPr);
  676.                 }
  677.                 else
  678.                     throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_ObjectMissing"), pr.PRname));
  679.             }
  680.            
  681.             // Registration is after object is populated
  682.             if (!objectPr.PRisRegistered && objectPr.PRobjectId > 0) {
  683.                 InternalST.Soap(this, "ParseObjectEnd Register Object ", objectPr.PRobjectId, " ", objectPr.PRnewObj.GetType());
  684.                 RegisterObject(objectPr.PRnewObj, objectPr, parentPr);
  685.             }
  686.            
  687.             if (objectPr.PRisValueTypeFixup) {
  688.                 InternalST.Soap(this, "ParseObjectEnd ValueTypeFixup ", objectPr.PRnewObj.GetType());
  689.                 ValueFixup fixup = (ValueFixup)valueFixupStack.Pop();
  690.                 //Value fixup
  691.                 fixup.Fixup(objectPr, parentPr);
  692.                 // Value fixup
  693.             }
  694.            
  695.             if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top) {
  696.                 InternalST.Soap(this, "ParseObjectEnd Top Object Resolved ", objectPr.PRnewObj.GetType());
  697.                 isTopObjectResolved = true;
  698.                 topObject = objectPr.PRnewObj;
  699.             }
  700.            
  701.             if (objectPr.PRnewObj is SoapFault)
  702.                 soapFaultId = objectPr.PRobjectId;
  703.            
  704.             if (objectPr.PRobjectInfo != null) {
  705.                 if (objectPr.PRobjectInfo.bfake && !objectPr.PRobjectInfo.bSoapFault)
  706.                     objectPr.PRobjectInfo.AddValue("__fault", null);
  707.                 // need this because SerializationObjectInfo throws an exception if a name being referenced is missing
  708.                 objectPr.PRobjectInfo.ObjectEnd();
  709.             }
  710.            
  711.             InternalST.Soap(this, "ParseObjectEnd Exit ", objectPr.PRnewObj, " id: ", objectPr.PRobjectId);
  712.         }
  713.        
  714.        
  715.        
  716.         // Array object encountered in stream
  717.         private void ParseArray(