internal object Deserialize(HeaderHandler handler, ISerParser serParser)
 {
     if (serParser == null)
     {
         throw new ArgumentNullException("serParser", string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("ArgumentNull_WithParamName"), new object[] { serParser }));
     }
     this.deserializationSecurityException = null;
     try
     {
         serializationPermission.Demand();
     }
     catch (Exception exception)
     {
         this.deserializationSecurityException = exception;
     }
     this.handler = handler;
     this.isTopObjectSecondPass = false;
     this.isHeaderHandlerCalled = false;
     if (handler != null)
     {
         this.IsFakeTopObject = true;
     }
     this.m_idGenerator = new ObjectIDGenerator();
     this.m_objectManager = this.GetObjectManager();
     this.serObjectInfoInit = new SerObjectInfoInit();
     this.objectIdTable.Clear();
     this.objectIds = 0L;
     serParser.Run();
     if (handler != null)
     {
         this.m_objectManager.DoFixups();
         if (this.handlerObject == null)
         {
             this.handlerObject = handler(this.newheaders);
         }
         if ((this.soapFaultId > 0L) && (this.handlerObject != null))
         {
             this.topStack = new SerStack("Top ParseRecords");
             ParseRecord record = new ParseRecord {
                 PRparseTypeEnum = InternalParseTypeE.Object,
                 PRobjectPositionEnum = InternalObjectPositionE.Top,
                 PRparseStateEnum = InternalParseStateE.Object,
                 PRname = "Response"
             };
             this.topStack.Push(record);
             record = new ParseRecord {
                 PRparseTypeEnum = InternalParseTypeE.Member,
                 PRobjectPositionEnum = InternalObjectPositionE.Child,
                 PRmemberTypeEnum = InternalMemberTypeE.Field,
                 PRmemberValueEnum = InternalMemberValueE.Reference,
                 PRparseStateEnum = InternalParseStateE.Member,
                 PRname = "__fault",
                 PRidRef = this.soapFaultId
             };
             this.topStack.Push(record);
             record = new ParseRecord {
                 PRparseTypeEnum = InternalParseTypeE.ObjectEnd,
                 PRobjectPositionEnum = InternalObjectPositionE.Top,
                 PRparseStateEnum = InternalParseStateE.Object,
                 PRname = "Response"
             };
             this.topStack.Push(record);
             this.isTopObjectResolved = false;
         }
     }
     if (!this.isTopObjectResolved)
     {
         this.isTopObjectSecondPass = true;
         this.topStack.Reverse();
         int num = this.topStack.Count();
         ParseRecord pr = null;
         for (int i = 0; i < num; i++)
         {
             pr = (ParseRecord) this.topStack.Pop();
             this.Parse(pr);
         }
     }
     this.m_objectManager.DoFixups();
     if (this.topObject == null)
     {
         throw new SerializationException(SoapUtil.GetResourceString("Serialization_TopObject"));
     }
     if (this.HasSurrogate(this.topObject.GetType()) && (this.topId != 0L))
     {
         this.topObject = this.m_objectManager.GetObject(this.topId);
     }
     if (this.topObject is IObjectReference)
     {
         this.topObject = ((IObjectReference) this.topObject).GetRealObject(this.m_context);
     }
     this.m_objectManager.RaiseDeserializationEvent();
     if ((this.formatterEnums.FEtopObject != null) && (this.topObject is InternalSoapMessage))
     {
         InternalSoapMessage topObject = (InternalSoapMessage) this.topObject;
         ISoapMessage fEtopObject = this.formatterEnums.FEtopObject;
         fEtopObject.MethodName = topObject.methodName;
         fEtopObject.XmlNameSpace = topObject.xmlNameSpace;
         fEtopObject.ParamNames = topObject.paramNames;
         fEtopObject.ParamValues = topObject.paramValues;
         fEtopObject.Headers = this.headers;
         this.topObject = fEtopObject;
         this.isTopObjectResolved = true;
     }
     return this.topObject;
 }
Example #2
0
        // New object encountered in stream
        private void ParseObject(ParseRecord pr)
        {
            InternalST.Soap( this, "ParseObject Entry ");

            if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
                topId = pr.PRobjectId;

            if (pr.PRparseTypeEnum == InternalParseTypeE.Object)
            {
                InternalST.Soap( this, "ParseObject Push "+pr.PRname);
                stack.Push(pr); // Nested objects member names are already on stack
            }

            if (pr.PRobjectTypeEnum == InternalObjectTypeE.Array)
            {
                ParseArray(pr);
                InternalST.Soap( this, "ParseObject Exit, ParseArray ");
                return;
            }

            if ((pr.PRdtType == null) && !IsFakeTopObject)
                throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"),pr.PRname));


            if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top && IsFakeTopObject && pr.PRdtType != Converter.typeofSoapFault)
            {

                // Soap fake top object
                if (handler != null) 
                {
                    // Handler object will supply real top object
                    InternalST.Soap( this, "ParseObject FakeTopObject with handlerObject ");    

                    // Now know the method name, can call header handler 
                    //Create header for method name
                    if (!isHeaderHandlerCalled)
                    {
                        newheaders = null;
                        isHeaderHandlerCalled = true;
                        if (headers == null)
                        {
                            newheaders = new Header[1];
                        }
                        else
                        {
                            newheaders = new Header[headers.Length+1];
                            Array.Copy(headers, 0, newheaders, 1, headers.Length);
                        }

                        Header methodNameHeader = new Header("__methodName", pr.PRname, false, pr.PRnameXmlKey);
                        newheaders[0] = methodNameHeader;
                        InternalST.Soap( this, "Deserialize Before Delegate Invoke ");
                        handlerObject = handler(newheaders);

                        InternalST.Soap( this, "Deserialize after Delegate Invoke");
                        InternalST.Soap( this, "Deserialize delgate object ",((handlerObject == null)?"null":handlerObject));                   
                    }

                    if (isHeaderHandlerCalled)
                    {
                        // Handler object has supplied the real object for the fake object
                        // which is on top of the stack
                        pr.PRnewObj = handlerObject;
                        pr.PRdtType = handlerObject.GetType();
                        CheckSecurity(pr);
                        if (pr.PRnewObj is IFieldInfo)
                        {
                            IFieldInfo fi = (IFieldInfo)pr.PRnewObj;
                            if ((fi.FieldTypes != null) && (fi.FieldTypes.Length > 0))
                            {
                                pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, fi.FieldNames, fi.FieldTypes, pr.PRassemblyName);
                            }
                        }                       
                    }
                    else
                    {
                        // Handler object has not yet been asked for the real object
                        // Stack the parse record until the second pass
                        isTopObjectResolved = false;
                        topStack = new SerStack("Top ParseRecords");
                        InternalST.Soap( this, "ParseObject Handler Push "+pr.PRname);
                        topStack.Push(pr.Copy());
                        return;
                    }
                }
                else if (formatterEnums.FEtopObject != null)
                {
                    // SoapMessage will be used as the real object
                    InternalST.Soap( this, "ParseObject FakeTopObject with SoapMessage ");                                  
                    if (isTopObjectSecondPass)
                    {
                        // This creates a the SoapMessage object as the real object, at this point it is an unitialized object.
                        pr.PRnewObj = new InternalSoapMessage();
                        pr.PRdtType = typeof(InternalSoapMessage);
                        CheckSecurity(pr);
                        if (formatterEnums.FEtopObject != null)
                        {
                            ISoapMessage soapMessage = (ISoapMessage)formatterEnums.FEtopObject;
                            pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, soapMessage.ParamNames, soapMessage.ParamTypes, pr.PRassemblyName);
                        }
                    }
                    else
                    {
                        // Stack the parse record until the second pass
                        isTopObjectResolved = false;
                        topStack = new SerStack("Top ParseRecords");
                        topStack.Push(pr.Copy());
                        return;
                    }
                }
            }
            else if (pr.PRdtType == Converter.typeofString)
            {
                // String as a top level object
                if (pr.PRvalue != null)
                {
                    pr.PRnewObj = pr.PRvalue;
                    if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
                    {
                        InternalST.Soap( this, "ParseObject String as top level, Top Object Resolved");
                        isTopObjectResolved = true;
                        topObject = pr.PRnewObj;
                        //stack.Pop();
                        return;
                    }
                    else
                    {
                        InternalST.Soap( this, "ParseObject  String as an object");
                        stack.Pop();                        
                        RegisterObject(pr.PRnewObj, pr, (ParseRecord)stack.Peek());                         
                        return;
                    }
                }
                else
                {
                    // xml Doesn't have the value until later
                    return;
                }
            }
            else 
            {
                if (pr.PRdtType == null)
                {
                    ParseRecord objectPr = (ParseRecord)stack.Peek();
                    if (objectPr.PRdtType == Converter.typeofSoapFault)
                    {
                        InternalST.Soap( this, "ParseObject unknown SoapFault detail");
                        throw new ServerException(String.Format(SoapUtil.GetResourceString("Serialization_SoapFault"),faultString));                
                    }

                    throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_TypeElement"),pr.PRname));             
                }

                pr.PRnewObj = FormatterServices.GetUninitializedObject(pr.PRdtType);    
                CheckSecurity(pr);
            }

            if (pr.PRnewObj == null)
                throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"),pr.PRdtType));              

            long genId = pr.PRobjectId;
            if (genId < 1)
                pr.PRobjectId = GetId("GenId-"+objectIds);


            if (IsFakeTopObject && pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
            {
                InternalST.Soap( this, "ParseObject fake Top object resolved ",pr.PRnewObj);
                isTopObjectResolved = true;
                topObject = pr.PRnewObj;
            }

            if (pr.PRobjectInfo == null)
                pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, pr.PRassemblyName);
            pr.PRobjectInfo.obj = pr.PRnewObj;

            if (IsFakeTopObject && pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
            {
                InternalST.Soap( this, "ParseObject AddValue to fake object ",pr.PRobjectInfo.obj);
                // Add the methodName to top object, either InternalSoapMessage or object returned by handler
                pr.PRobjectInfo.AddValue("__methodName", pr.PRname);
                pr.PRobjectInfo.AddValue("__keyToNamespaceTable", soapHandler.keyToNamespaceTable);
                pr.PRobjectInfo.AddValue("__paramNameList", pr.PRobjectInfo.SetFakeObject());
                if (formatterEnums.FEtopObject != null)
                    pr.PRobjectInfo.AddValue("__xmlNameSpace", pr.PRxmlNameSpace);
            }

            InternalST.Soap( this, "ParseObject Exit ");        
        }
 private void ParseObject(ParseRecord pr)
 {
     if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
     {
         this.topId = pr.PRobjectId;
     }
     if (pr.PRparseTypeEnum == InternalParseTypeE.Object)
     {
         this.stack.Push(pr);
     }
     if (pr.PRobjectTypeEnum == InternalObjectTypeE.Array)
     {
         this.ParseArray(pr);
     }
     else
     {
         if ((pr.PRdtType == null) && !this.IsFakeTopObject)
         {
             throw new SerializationException(string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"), new object[] { pr.PRname }));
         }
         if (((pr.PRobjectPositionEnum == InternalObjectPositionE.Top) && this.IsFakeTopObject) && (pr.PRdtType != Converter.typeofSoapFault))
         {
             if (this.handler == null)
             {
                 if (this.formatterEnums.FEtopObject != null)
                 {
                     if (!this.isTopObjectSecondPass)
                     {
                         this.isTopObjectResolved = false;
                         this.topStack = new SerStack("Top ParseRecords");
                         this.topStack.Push(pr.Copy());
                         return;
                     }
                     pr.PRnewObj = new InternalSoapMessage();
                     pr.PRdtType = typeof(InternalSoapMessage);
                     this.CheckSecurity(pr);
                     if (this.formatterEnums.FEtopObject != null)
                     {
                         ISoapMessage fEtopObject = this.formatterEnums.FEtopObject;
                         pr.PRobjectInfo = this.CreateReadObjectInfo(pr.PRdtType, fEtopObject.ParamNames, fEtopObject.ParamTypes, pr.PRassemblyName);
                     }
                 }
             }
             else
             {
                 if (!this.isHeaderHandlerCalled)
                 {
                     this.newheaders = null;
                     this.isHeaderHandlerCalled = true;
                     if (this.headers == null)
                     {
                         this.newheaders = new Header[1];
                     }
                     else
                     {
                         this.newheaders = new Header[this.headers.Length + 1];
                         Array.Copy(this.headers, 0, this.newheaders, 1, this.headers.Length);
                     }
                     Header header = new Header("__methodName", pr.PRname, false, pr.PRnameXmlKey);
                     this.newheaders[0] = header;
                     this.handlerObject = this.handler(this.newheaders);
                 }
                 if (!this.isHeaderHandlerCalled)
                 {
                     this.isTopObjectResolved = false;
                     this.topStack = new SerStack("Top ParseRecords");
                     this.topStack.Push(pr.Copy());
                     return;
                 }
                 pr.PRnewObj = this.handlerObject;
                 pr.PRdtType = this.handlerObject.GetType();
                 this.CheckSecurity(pr);
                 if (pr.PRnewObj is IFieldInfo)
                 {
                     IFieldInfo pRnewObj = (IFieldInfo) pr.PRnewObj;
                     if ((pRnewObj.FieldTypes != null) && (pRnewObj.FieldTypes.Length > 0))
                     {
                         pr.PRobjectInfo = this.CreateReadObjectInfo(pr.PRdtType, pRnewObj.FieldNames, pRnewObj.FieldTypes, pr.PRassemblyName);
                     }
                 }
             }
         }
         else
         {
             if (pr.PRdtType == Converter.typeofString)
             {
                 if (pr.PRvalue != null)
                 {
                     pr.PRnewObj = pr.PRvalue;
                     if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
                     {
                         this.isTopObjectResolved = true;
                         this.topObject = pr.PRnewObj;
                         return;
                     }
                     this.stack.Pop();
                     this.RegisterObject(pr.PRnewObj, pr, (ParseRecord) this.stack.Peek());
                 }
                 return;
             }
             if (pr.PRdtType == null)
             {
                 ParseRecord record = (ParseRecord) this.stack.Peek();
                 if (record.PRdtType == Converter.typeofSoapFault)
                 {
                     throw new ServerException(string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_SoapFault"), new object[] { this.faultString }));
                 }
                 throw new SerializationException(string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TypeElement"), new object[] { pr.PRname }));
             }
             this.CheckSerializable(pr.PRdtType);
             if (this.IsRemoting && (this.formatterEnums.FEsecurityLevel != TypeFilterLevel.Full))
             {
                 pr.PRnewObj = FormatterServices.GetSafeUninitializedObject(pr.PRdtType);
             }
             else
             {
                 pr.PRnewObj = FormatterServices.GetUninitializedObject(pr.PRdtType);
             }
             this.CheckSecurity(pr);
             this.m_objectManager.RaiseOnDeserializingEvent(pr.PRnewObj);
         }
         if (pr.PRnewObj == null)
         {
             throw new SerializationException(string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"), new object[] { pr.PRdtType }));
         }
         if (pr.PRobjectId < 1L)
         {
             pr.PRobjectId = this.GetId("GenId-" + this.objectIds);
         }
         if (this.IsFakeTopObject && (pr.PRobjectPositionEnum == InternalObjectPositionE.Top))
         {
             this.isTopObjectResolved = true;
             this.topObject = pr.PRnewObj;
         }
         if (pr.PRobjectInfo == null)
         {
             pr.PRobjectInfo = this.CreateReadObjectInfo(pr.PRdtType, pr.PRassemblyName);
         }
         pr.PRobjectInfo.obj = pr.PRnewObj;
         if (this.IsFakeTopObject && (pr.PRobjectPositionEnum == InternalObjectPositionE.Top))
         {
             pr.PRobjectInfo.AddValue("__methodName", pr.PRname);
             pr.PRobjectInfo.AddValue("__keyToNamespaceTable", this.soapHandler.keyToNamespaceTable);
             pr.PRobjectInfo.AddValue("__paramNameList", pr.PRobjectInfo.SetFakeObject());
             if (this.formatterEnums.FEtopObject != null)
             {
                 pr.PRobjectInfo.AddValue("__xmlNameSpace", pr.PRxmlNameSpace);
             }
         }
     }
 }
Example #4
0
        // Deserialize the stream into an object graph.
        internal Object Deserialize(HeaderHandler handler, ISerParser serParser)
        {

            InternalST.Soap( this, "Deserialize Entry handler", handler);

            if (serParser == null)
                throw new ArgumentNullException("serParser", String.Format(SoapUtil.GetResourceString("ArgumentNull_WithParamName"), serParser));


            deserializationSecurityException = null;
            try {
                serializationPermission.Demand();
            } catch(Exception e ) {
                deserializationSecurityException = e;
            }

            this.handler = handler;
            isTopObjectSecondPass = false;
            isHeaderHandlerCalled = false;

            if (handler != null)
                IsFakeTopObject = true;

            m_idGenerator = new ObjectIDGenerator();


            m_objectManager = GetObjectManager();

            serObjectInfoInit = new SerObjectInfoInit();
            objectIdTable.Clear();
            objectIds = 0;

            // Will call back to ParseObject, ParseHeader for each object found
            serParser.Run();

            if (handler != null)
            {
                InternalST.Soap( this, "Deserialize Fixup Before Delegate Invoke");         
                m_objectManager.DoFixups(); // Fixup for headers

                // Header handler isn't invoked until method name is known from body fake record
                // Except for SoapFault, in which case it is invoked below
                if (handlerObject == null)
                {
                    InternalST.Soap( this, "Deserialize Before SoapFault Delegate Invoke ");
                    handlerObject = handler(newheaders);
                    InternalST.Soap( this, "Deserialize after SoapFault Delegate Invoke");
                }


                // SoapFault creation Create a fake Pr for the handlerObject to use.
                // Create a member for the fake pr with name __fault;
                if ((soapFaultId > 0) && (handlerObject != null))
                {
                    InternalST.Soap( this, "Deserialize SoapFault ");
                    topStack = new SerStack("Top ParseRecords");                
                    ParseRecord pr = new ParseRecord();
                    pr.PRparseTypeEnum = InternalParseTypeE.Object;
                    pr.PRobjectPositionEnum = InternalObjectPositionE.Top;
                    pr.PRparseStateEnum = InternalParseStateE.Object;
                    pr.PRname = "Response";
                    topStack.Push(pr);
                    pr = new ParseRecord();
                    pr.PRparseTypeEnum = InternalParseTypeE.Member;
                    pr.PRobjectPositionEnum = InternalObjectPositionE.Child;
                    pr.PRmemberTypeEnum = InternalMemberTypeE.Field;
                    pr.PRmemberValueEnum = InternalMemberValueE.Reference;
                    pr.PRparseStateEnum = InternalParseStateE.Member;
                    pr.PRname = "__fault";
                    pr.PRidRef = soapFaultId;
                    topStack.Push(pr);
                    pr = new ParseRecord();
                    pr.PRparseTypeEnum = InternalParseTypeE.ObjectEnd;
                    pr.PRobjectPositionEnum = InternalObjectPositionE.Top;
                    pr.PRparseStateEnum = InternalParseStateE.Object;
                    pr.PRname = "Response";
                    topStack.Push(pr);
                    isTopObjectResolved = false;
                }
            }


            // Resolve fake top object if necessary
            if (!isTopObjectResolved)
            {
                //resolve top object
                InternalST.Soap( this, "Deserialize TopObject Second Pass");                
                isTopObjectSecondPass = true;
                topStack.Reverse();
                // The top of the stack now contains the fake record
                // When it is Parsed, the handler object will be substituted
                // for it in ParseObject.
                int topStackLength = topStack.Count();
                ParseRecord pr = null;
                for (int i=0; i<topStackLength; i++)
                {
                    pr = (ParseRecord)topStack.Pop();
                    Parse(pr);
                }
            }


            InternalST.Soap( this, "Deserialize Finished Parsing DoFixups");

            m_objectManager.DoFixups();

            if (topObject == null)
                throw new SerializationException(SoapUtil.GetResourceString("Serialization_TopObject"));

            if (topObject is IObjectReference) {
                topObject = ((IObjectReference)topObject).GetRealObject(m_context);
            }       

            InternalST.Soap( this, "Deserialize Exit ",topObject);

            m_objectManager.RaiseDeserializationEvent();

            if ((formatterEnums.FEtopObject != null) &&
                  (topObject is InternalSoapMessage))


            {
                // Convert InternalSoapMessage to SoapMessage           
                InternalST.Soap( this, "Deserialize SoapMessage Entry ");           

                InternalSoapMessage ismc = (InternalSoapMessage)topObject;
                ISoapMessage smc = (ISoapMessage)formatterEnums.FEtopObject;
                smc.MethodName = ismc.methodName;
                smc.XmlNameSpace = ismc.xmlNameSpace;
                smc.ParamNames = ismc.paramNames;
                smc.ParamValues = ismc.paramValues;
                smc.Headers = headers;
                topObject = smc;
                isTopObjectResolved = true;
                InternalST.Soap( this, "Deserialize SoapMessage Exit topObject ",topObject," method name ",smc.MethodName);                         
            }

            return topObject;
        }