// 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;
}