Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / ManagedLibraries / SoapSerializer / SoapObjectReader.cs / 1 / SoapObjectReader.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
//============================================================
//
// Class: ObjectReader
//
// Author: Peter de Jong ([....])
//
// Purpose: DeSerializes XML in SOAP Format into an an object graph
//
// Date: June 10, 1999
//
//===========================================================
namespace System.Runtime.Serialization.Formatters.Soap {
using System;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
using System.Diagnostics;
using System.Globalization;
internal sealed class ObjectReader
{
// System.Serializer information
internal ObjectIDGenerator m_idGenerator;
internal Stream m_stream;
internal ISurrogateSelector m_surrogates;
internal StreamingContext m_context;
internal ObjectManager m_objectManager;
internal InternalFE formatterEnums;
internal SerializationBinder m_binder;
internal SoapHandler soapHandler; //Set from SoapHandler
// Fake Top object and headers
internal long topId = 0;
internal SerStack topStack; // Stack for placing ProcessRecords if the top record cannot be serialized on the first pass.
internal bool isTopObjectSecondPass = false;
internal bool isTopObjectResolved = true;
internal bool isHeaderHandlerCalled = false;
internal Exception deserializationSecurityException = null;
internal Object handlerObject = null;
internal Object topObject;
internal long soapFaultId;
internal Header[] headers;
internal Header[] newheaders;
internal bool IsFakeTopObject = false;
internal HeaderHandler handler;
internal SerObjectInfoInit serObjectInfoInit = null;
internal IFormatterConverter m_formatterConverter = null;
// Stack of Object ParseRecords
internal SerStack stack = new SerStack("ObjectReader Object Stack");
// ValueType Fixup Stack
internal SerStack valueFixupStack = new SerStack("ValueType Fixup Stack");
// Generate Object Id's
internal Hashtable objectIdTable = new Hashtable(25); // holds the keyId value from the XML input and associated internal Id
internal long objectIds = 0;
internal int paramPosition = 0; //Position of parameter if soap top fake record.
internal int majorVersion = 0;
internal int minorVersion = 0;
internal String faultString = null;
// GetType - eliminate redundant Type.GetType()
//internal Hashtable typeTable = new Hashtable(10);
internal static SecurityPermission serializationPermission = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
private static FileIOPermission sfileIOPermission = new FileIOPermission(PermissionState.Unrestricted);
internal ObjectReader(Stream stream, ISurrogateSelector selector, StreamingContext context, InternalFE formatterEnums, SerializationBinder binder)
{
InternalST.Soap( this, "Constructor ISurrogateSelector ",((selector == null)?"null selector ":"selector present"));
if (stream==null)
{
throw new ArgumentNullException("stream", SoapUtil.GetResourceString("ArgumentNull_Stream"));
}
m_stream=stream;
m_surrogates = selector;
m_context = context;
m_binder = binder;
this.formatterEnums = formatterEnums;
InternalST.Soap( this, "Constructor formatterEnums.FEtopObject ",formatterEnums.FEtopObject);
if (formatterEnums.FEtopObject != null)
IsFakeTopObject = true;
else
IsFakeTopObject = false;
m_formatterConverter = new FormatterConverter();
}
private ObjectManager GetObjectManager() {
new SecurityPermission(SecurityPermissionFlag.SerializationFormatter).Assert();
return new ObjectManager(m_surrogates, m_context);
}
// 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(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("ArgumentNull_WithParamName"), serParser));
deserializationSecurityException = null;
try {
serializationPermission.Demand();
} catch(Exception e ) {
deserializationSecurityException = e;
}
catch {
deserializationSecurityException = new Exception(SoapUtil.GetResourceString("Serialization_NonClsCompliantException"));
}
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 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(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_SoapFault"),faultString));
}
throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TypeElement"),pr.PRname));
}
CheckSerializable(pr.PRdtType);
if (IsRemoting && formatterEnums.FEsecurityLevel != TypeFilterLevel.Full)
pr.PRnewObj = FormatterServices.GetSafeUninitializedObject(pr.PRdtType);
else
pr.PRnewObj = FormatterServices.GetUninitializedObject(pr.PRdtType);
CheckSecurity(pr);
// Run the OnDeserializing methods
m_objectManager.RaiseOnDeserializingEvent(pr.PRnewObj);
}
if (pr.PRnewObj == null)
throw new SerializationException(String.Format(CultureInfo.CurrentCulture, 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 bool IsWhiteSpace(String value)
{
for (int i=0; i111
objectPr.PRnewObj = Converter.FromString(objectPr.PRvalue, Converter.ToCode(objectPr.PRdtType));
CheckSecurity(objectPr);
isTopObjectResolved = true;
topObject = objectPr.PRnewObj;
return;
}
else if ((!isTopObjectResolved) && (objectPr.PRdtType != Converter.typeofSoapFault))
{
InternalST.Soap( this, "ParseObjectEnd Top but not String");
// Need to keep top record on object stack until finished building top stack
topStack.Push(pr.Copy());
// Note this is PRparseRecordId and not objectId
if (objectPr.PRparseRecordId == pr.PRparseRecordId)
{
// This handles the case of top stack containing nested objects and
// referenced objects. If nested objects the objects are not placed
// on stack, only topstack. If referenced objects they are placed on
// stack and need to be popped.
stack.Pop();
}
return;
}
}
stack.Pop();
ParseRecord parentPr = (ParseRecord)stack.Peek();
if (objectPr.PRobjectTypeEnum == InternalObjectTypeE.Array)
{
if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top)
{
InternalST.Soap( this, "ParseObjectEnd Top Object (Array) Resolved");
isTopObjectResolved = true;
topObject = objectPr.PRnewObj;
}
InternalST.Soap( this, "ParseArray RegisterObject ",objectPr.PRobjectId," ",objectPr.PRnewObj.GetType());
RegisterObject(objectPr.PRnewObj, objectPr, parentPr);
return;
}
if (objectPr.PRobjectInfo != null)
{
objectPr.PRobjectInfo.PopulateObjectMembers();
}
if (objectPr.PRnewObj == null)
{
if (objectPr.PRdtType == Converter.typeofString)
{
InternalST.Soap( this, "ParseObjectEnd String ");
if (objectPr.PRvalue == null)
objectPr.PRvalue = String.Empty; // Not a null object, but an empty string
objectPr.PRnewObj = objectPr.PRvalue;
CheckSecurity(objectPr);
}
else
throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_ObjectMissing"),pr.PRname));
}
// Registration is after object is populated
if (!objectPr.PRisRegistered && objectPr.PRobjectId > 0)
{
InternalST.Soap( this, "ParseObjectEnd Register Object ",objectPr.PRobjectId," ",objectPr.PRnewObj.GetType());
RegisterObject(objectPr.PRnewObj, objectPr, parentPr);
}
if (objectPr.PRisValueTypeFixup)
{
InternalST.Soap( this, "ParseObjectEnd ValueTypeFixup ",objectPr.PRnewObj.GetType());
ValueFixup fixup = (ValueFixup)valueFixupStack.Pop(); //Value fixup
fixup.Fixup(objectPr, parentPr); // Value fixup
}
if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top)
{
InternalST.Soap( this, "ParseObjectEnd Top Object Resolved ",objectPr.PRnewObj.GetType());
isTopObjectResolved = true;
topObject = objectPr.PRnewObj;
}
if (objectPr.PRnewObj is SoapFault)
soapFaultId = objectPr.PRobjectId;
if (objectPr.PRobjectInfo != null)
{
if (objectPr.PRobjectInfo.bfake && !objectPr.PRobjectInfo.bSoapFault)
objectPr.PRobjectInfo.AddValue("__fault", null); // need this because SerializationObjectInfo throws an exception if a name being referenced is missing
objectPr.PRobjectInfo.ObjectEnd();
}
InternalST.Soap( this, "ParseObjectEnd Exit ",objectPr.PRnewObj," id: ",objectPr.PRobjectId);
}
// Array object encountered in stream
private void ParseArray(ParseRecord pr)
{
InternalST.Soap( this, "ParseArray Entry");
pr.Dump();
long genId = pr.PRobjectId;
if (genId < 1)
pr.PRobjectId = GetId("GenId-"+objectIds);
if ((pr.PRarrayElementType != null) && (pr.PRarrayElementType.IsEnum))
pr.PRisEnum = true;
if (pr.PRarrayTypeEnum == InternalArrayTypeE.Base64)
{
if (pr.PRvalue == null)
{
pr.PRnewObj = new Byte[0];
CheckSecurity(pr);
}
else
{
// Used for arrays of Base64 and also for a parameter of Base64
InternalST.Soap( this, "ParseArray bin.base64 ",pr.PRvalue.Length," ",pr.PRvalue);
if (pr.PRdtType == Converter.typeofSoapBase64Binary)
{
// Parameter - Case where the return type is a SoapENC:base64 but the parameter type is xsd:base64Binary
pr.PRnewObj = SoapBase64Binary.Parse(pr.PRvalue);
CheckSecurity(pr);
}
else
{
// ByteArray
if (pr.PRvalue.Length > 0)
{
pr.PRnewObj = Convert.FromBase64String(FilterBin64(pr.PRvalue));
CheckSecurity(pr);
}
else
{
pr.PRnewObj = new Byte[0];
CheckSecurity(pr);
}
}
}
if (stack.Peek() == pr)
{
InternalST.Soap( this, "ParseArray, bin.base64 has been stacked");
stack.Pop();
}
if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
{
InternalST.Soap( this, "ParseArray, bin.base64 Top Object");
topObject = pr.PRnewObj;
isTopObjectResolved = true;
}
ParseRecord parentPr = (ParseRecord)stack.Peek();
// Base64 can be registered at this point because it is populated
InternalST.Soap( this, "ParseArray RegisterObject ",pr.PRobjectId," ",pr.PRnewObj.GetType());
RegisterObject(pr.PRnewObj, pr, parentPr);
}
else if ((pr.PRnewObj != null) && Converter.IsWriteAsByteArray(pr.PRarrayElementTypeCode))
{
// Primtive typed Array has already been read
if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
{
topObject = pr.PRnewObj;
isTopObjectResolved = true;
}
ParseRecord parentPr = (ParseRecord)stack.Peek();
// Primitive typed array can be registered at this point because it is populated
InternalST.Soap( this, "ParseArray RegisterObject ",pr.PRobjectId," ",pr.PRnewObj.GetType());
RegisterObject(pr.PRnewObj, pr, parentPr);
}
else if ((pr.PRarrayTypeEnum == InternalArrayTypeE.Jagged) || (pr.PRarrayTypeEnum == InternalArrayTypeE.Single))
{
// Multidimensional jagged array or single array
InternalST.Soap( this, "ParseArray Before Jagged,Simple create ",pr.PRarrayElementType," ",(pr.PRrank >0?pr.PRlengthA[0].ToString():"0"));
if ((pr.PRlowerBoundA == null) || (pr.PRlowerBoundA[0] == 0))
{
pr.PRnewObj = Array.CreateInstance(pr.PRarrayElementType, (pr.PRrank>0?pr.PRlengthA[0]:0));
pr.PRisLowerBound = false;
}
else
{
pr.PRnewObj = Array.CreateInstance(pr.PRarrayElementType, pr.PRlengthA, pr.PRlowerBoundA);
pr.PRisLowerBound = true;
}
if (pr.PRarrayTypeEnum == InternalArrayTypeE.Single)
{
if (!pr.PRisLowerBound && (Converter.IsWriteAsByteArray(pr.PRarrayElementTypeCode)))
{
pr.PRprimitiveArray = new PrimitiveArray(pr.PRarrayElementTypeCode, (Array)pr.PRnewObj);
}
else if (!pr.PRarrayElementType.IsValueType && pr.PRlowerBoundA== null)
{
pr.PRobjectA = (Object[])pr.PRnewObj;
}
}
CheckSecurity(pr);
InternalST.Soap( this, "ParseArray Jagged,Simple Array ",pr.PRnewObj.GetType());
// For binary, headers comes in as an array of header objects
if (pr.PRobjectPositionEnum == InternalObjectPositionE.Headers)
{
InternalST.Soap( this, "ParseArray header array");
headers = (Header[])pr.PRnewObj;
}
pr.PRindexMap = new int[1];
}
else if (pr.PRarrayTypeEnum == InternalArrayTypeE.Rectangular)
{
// Rectangle array
pr.PRisLowerBound = false;
if (pr.PRlowerBoundA != null)
{
for (int i=0; i-1; irank--)
{
// Find the current or lower dimension which can be incremented.
if (pr.PRrectangularMap[irank] < pr.PRlengthA[irank]-1)
{
// The current dimension is at maximum. Increase the next lower dimension by 1
pr.PRrectangularMap[irank]++;
if (irank < pr.PRrank-1)
{
// The current dimension and higher dimensions are zeroed.
for (int i = irank+1; i 0)
NextRectangleMap(objectPr); // Rectangle array, calculate position in array
for (int i=0; i 0))
{
if (pr.PRvalue == null)
pr.PRvalue = ""; //can't register null value, this must be a string so set to empty string.
InternalST.Soap( this, "ParseMember RegisterObject ",pr.PRvalue," ",pr.PRobjectId);
RegisterObject(pr.PRvalue, pr, objectPr);
}
// Object Class with no memberInfo data
// <
if (pr.PRdtType == Converter.typeofSystemVoid)
{
InternalST.Soap( this, "AddValue 9");
objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRdtType);
}
else if (objectPr.PRobjectInfo.isSi)
{
// ISerializable are added as strings, the conversion to type is done by the
// ISerializable object
InternalST.Soap( this, "AddValue 10");
objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvalue);
}
}
}
}
else
{
Object var = null;
if (pr.PRvarValue != null)
var = pr.PRvarValue;
else
var = Converter.FromString(pr.PRvalue, pr.PRdtTypeCode);
// Not a string, convert the value
InternalST.Soap( this, "ParseMember Converting primitive and storing");
stack.Dump();
InternalST.Soap( this, "ParseMember pr "+pr.Trace());
InternalST.Soap( this, "ParseMember objectPr ",objectPr.Trace());
InternalST.Soap( this, "AddValue 11");
if (pr.PRdtTypeCode == InternalPrimitiveTypeE.QName && var != null)
{
SoapQName soapQName = (SoapQName)var;
if (soapQName.Key != null)
{
if (soapQName.Key.Length == 0)
soapQName.Namespace = (String)soapHandler.keyToNamespaceTable["xmlns"];
else
soapQName.Namespace = (String)soapHandler.keyToNamespaceTable["xmlns"+":"+soapQName.Key];
}
}
objectPr.PRobjectInfo.AddValue(pr.PRname, var);
}
}
else
ParseError(pr, objectPr);
}
// Object member end encountered in stream
private void ParseMemberEnd(ParseRecord pr)
{
InternalST.Soap( this, "ParseMemberEnd");
switch(pr.PRmemberTypeEnum)
{
case InternalMemberTypeE.Item:
ParseArrayMemberEnd(pr);
return;
case InternalMemberTypeE.Field:
if (pr.PRmemberValueEnum == InternalMemberValueE.Nested)
ParseObjectEnd(pr);
break;
default:
if (pr.PRmemberValueEnum == InternalMemberValueE.Nested)
ParseObjectEnd(pr);
else
ParseError(pr, (ParseRecord)stack.Peek());
break;
}
}
// Processes a string object by getting an internal ID for it and registering it with the objectManager
private void ParseString(ParseRecord pr, ParseRecord parentPr)
{
InternalST.Soap( this, "ParseString Entry ",pr.PRobjectId," ",pr.PRvalue," ",pr.PRisRegistered);
// If there is a string and it wasn't marked as a null object, then it is an empty string
if (pr.PRvalue == null)
pr.PRvalue = "";
// Process String class
if ((!pr.PRisRegistered) && (pr.PRobjectId > 0))
{
InternalST.Soap( this, "ParseString RegisterObject ",pr.PRvalue," ",pr.PRobjectId);
// String is treated as an object if it has an id
//m_objectManager.RegisterObject(pr.PRvalue, pr.PRobjectId);
RegisterObject(pr.PRvalue, pr, parentPr);
}
}
private void RegisterObject(Object obj, ParseRecord pr, ParseRecord objectPr)
{
if (!pr.PRisRegistered)
{
pr.PRisRegistered = true;
SerializationInfo si = null;
long parentId = 0;
MemberInfo memberInfo = null;
int[] indexMap = null;
if (objectPr != null)
{
indexMap = objectPr.PRindexMap;
parentId = objectPr.PRobjectId;
if (objectPr.PRobjectInfo != null)
{
if (!objectPr.PRobjectInfo.isSi)
{
// ParentId is only used if there is a memberInfo
InternalST.Soap( this, "RegisterObject GetMemberInfo parent ",objectPr.PRobjectInfo.objectType," name looking for ", pr.PRname," field obj "+obj);
memberInfo = objectPr.PRobjectInfo.GetMemberInfo(pr.PRname);
}
}
}
if (pr.PRobjectInfo != null)
{
// SerializationInfo is always needed for ISerialization
si = pr.PRobjectInfo.si;
}
InternalST.Soap( this, "RegisterObject 0bj ",obj," objectId ",pr.PRobjectId," si ", si," parentId ",parentId," memberInfo ",memberInfo, " indexMap "+indexMap);
m_objectManager.RegisterObject(obj, pr.PRobjectId, si, parentId, memberInfo, indexMap);
}
}
internal void SetVersion(int major, int minor)
{
// Don't do version checking if property is set to Simple
if (formatterEnums.FEassemblyFormat != FormatterAssemblyStyle.Simple)
{
this.majorVersion = major;
this.minorVersion = minor;
}
}
// Assigns an internal ID associated with the xml id attribute
String inKeyId = null;
long outKeyId = 0;
internal long GetId(String keyId)
{
if (keyId == null)
throw new ArgumentNullException("keyId", String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("ArgumentNull_WithParamName"), "keyId"));
if (keyId != inKeyId)
{
inKeyId = keyId;
String idString = null;
InternalST.Soap( this, "GetId Entry ",keyId);
if (keyId[0] == '#')
idString = keyId.Substring(1);
else
idString = keyId;
Object idObj = objectIdTable[idString];
if (idObj == null)
{
outKeyId = ++objectIds;
objectIdTable[idString] = outKeyId;
InternalST.Soap( this, "GetId Exit new ID ",outKeyId);
}
else
{
InternalST.Soap( this, "GetId Exit oldId ",(Int64)idObj);
outKeyId = (Int64)idObj;
}
}
InternalST.Soap( this, "GetId in id ",keyId, " out id ", outKeyId);
return outKeyId;
}
// Trace which includes a single dimensional int array
[Conditional("SER_LOGGING")]
private void IndexTraceMessage(String message, int[] index)
{
StringBuilder sb = new StringBuilder(10);
sb.Append("[");
for (int i=0; i
// Author: Peter de Jong ([....])
//
// Purpose: DeSerializes XML in SOAP Format into an an object graph
//
// Date: June 10, 1999
//
//===========================================================
namespace System.Runtime.Serialization.Formatters.Soap {
using System;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
using System.Diagnostics;
using System.Globalization;
internal sealed class ObjectReader
{
// System.Serializer information
internal ObjectIDGenerator m_idGenerator;
internal Stream m_stream;
internal ISurrogateSelector m_surrogates;
internal StreamingContext m_context;
internal ObjectManager m_objectManager;
internal InternalFE formatterEnums;
internal SerializationBinder m_binder;
internal SoapHandler soapHandler; //Set from SoapHandler
// Fake Top object and headers
internal long topId = 0;
internal SerStack topStack; // Stack for placing ProcessRecords if the top record cannot be serialized on the first pass.
internal bool isTopObjectSecondPass = false;
internal bool isTopObjectResolved = true;
internal bool isHeaderHandlerCalled = false;
internal Exception deserializationSecurityException = null;
internal Object handlerObject = null;
internal Object topObject;
internal long soapFaultId;
internal Header[] headers;
internal Header[] newheaders;
internal bool IsFakeTopObject = false;
internal HeaderHandler handler;
internal SerObjectInfoInit serObjectInfoInit = null;
internal IFormatterConverter m_formatterConverter = null;
// Stack of Object ParseRecords
internal SerStack stack = new SerStack("ObjectReader Object Stack");
// ValueType Fixup Stack
internal SerStack valueFixupStack = new SerStack("ValueType Fixup Stack");
// Generate Object Id's
internal Hashtable objectIdTable = new Hashtable(25); // holds the keyId value from the XML input and associated internal Id
internal long objectIds = 0;
internal int paramPosition = 0; //Position of parameter if soap top fake record.
internal int majorVersion = 0;
internal int minorVersion = 0;
internal String faultString = null;
// GetType - eliminate redundant Type.GetType()
//internal Hashtable typeTable = new Hashtable(10);
internal static SecurityPermission serializationPermission = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
private static FileIOPermission sfileIOPermission = new FileIOPermission(PermissionState.Unrestricted);
internal ObjectReader(Stream stream, ISurrogateSelector selector, StreamingContext context, InternalFE formatterEnums, SerializationBinder binder)
{
InternalST.Soap( this, "Constructor ISurrogateSelector ",((selector == null)?"null selector ":"selector present"));
if (stream==null)
{
throw new ArgumentNullException("stream", SoapUtil.GetResourceString("ArgumentNull_Stream"));
}
m_stream=stream;
m_surrogates = selector;
m_context = context;
m_binder = binder;
this.formatterEnums = formatterEnums;
InternalST.Soap( this, "Constructor formatterEnums.FEtopObject ",formatterEnums.FEtopObject);
if (formatterEnums.FEtopObject != null)
IsFakeTopObject = true;
else
IsFakeTopObject = false;
m_formatterConverter = new FormatterConverter();
}
private ObjectManager GetObjectManager() {
new SecurityPermission(SecurityPermissionFlag.SerializationFormatter).Assert();
return new ObjectManager(m_surrogates, m_context);
}
// 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(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("ArgumentNull_WithParamName"), serParser));
deserializationSecurityException = null;
try {
serializationPermission.Demand();
} catch(Exception e ) {
deserializationSecurityException = e;
}
catch {
deserializationSecurityException = new Exception(SoapUtil.GetResourceString("Serialization_NonClsCompliantException"));
}
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 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(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_SoapFault"),faultString));
}
throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TypeElement"),pr.PRname));
}
CheckSerializable(pr.PRdtType);
if (IsRemoting && formatterEnums.FEsecurityLevel != TypeFilterLevel.Full)
pr.PRnewObj = FormatterServices.GetSafeUninitializedObject(pr.PRdtType);
else
pr.PRnewObj = FormatterServices.GetUninitializedObject(pr.PRdtType);
CheckSecurity(pr);
// Run the OnDeserializing methods
m_objectManager.RaiseOnDeserializingEvent(pr.PRnewObj);
}
if (pr.PRnewObj == null)
throw new SerializationException(String.Format(CultureInfo.CurrentCulture, 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 bool IsWhiteSpace(String value)
{
for (int i=0; i111
objectPr.PRnewObj = Converter.FromString(objectPr.PRvalue, Converter.ToCode(objectPr.PRdtType));
CheckSecurity(objectPr);
isTopObjectResolved = true;
topObject = objectPr.PRnewObj;
return;
}
else if ((!isTopObjectResolved) && (objectPr.PRdtType != Converter.typeofSoapFault))
{
InternalST.Soap( this, "ParseObjectEnd Top but not String");
// Need to keep top record on object stack until finished building top stack
topStack.Push(pr.Copy());
// Note this is PRparseRecordId and not objectId
if (objectPr.PRparseRecordId == pr.PRparseRecordId)
{
// This handles the case of top stack containing nested objects and
// referenced objects. If nested objects the objects are not placed
// on stack, only topstack. If referenced objects they are placed on
// stack and need to be popped.
stack.Pop();
}
return;
}
}
stack.Pop();
ParseRecord parentPr = (ParseRecord)stack.Peek();
if (objectPr.PRobjectTypeEnum == InternalObjectTypeE.Array)
{
if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top)
{
InternalST.Soap( this, "ParseObjectEnd Top Object (Array) Resolved");
isTopObjectResolved = true;
topObject = objectPr.PRnewObj;
}
InternalST.Soap( this, "ParseArray RegisterObject ",objectPr.PRobjectId," ",objectPr.PRnewObj.GetType());
RegisterObject(objectPr.PRnewObj, objectPr, parentPr);
return;
}
if (objectPr.PRobjectInfo != null)
{
objectPr.PRobjectInfo.PopulateObjectMembers();
}
if (objectPr.PRnewObj == null)
{
if (objectPr.PRdtType == Converter.typeofString)
{
InternalST.Soap( this, "ParseObjectEnd String ");
if (objectPr.PRvalue == null)
objectPr.PRvalue = String.Empty; // Not a null object, but an empty string
objectPr.PRnewObj = objectPr.PRvalue;
CheckSecurity(objectPr);
}
else
throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_ObjectMissing"),pr.PRname));
}
// Registration is after object is populated
if (!objectPr.PRisRegistered && objectPr.PRobjectId > 0)
{
InternalST.Soap( this, "ParseObjectEnd Register Object ",objectPr.PRobjectId," ",objectPr.PRnewObj.GetType());
RegisterObject(objectPr.PRnewObj, objectPr, parentPr);
}
if (objectPr.PRisValueTypeFixup)
{
InternalST.Soap( this, "ParseObjectEnd ValueTypeFixup ",objectPr.PRnewObj.GetType());
ValueFixup fixup = (ValueFixup)valueFixupStack.Pop(); //Value fixup
fixup.Fixup(objectPr, parentPr); // Value fixup
}
if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top)
{
InternalST.Soap( this, "ParseObjectEnd Top Object Resolved ",objectPr.PRnewObj.GetType());
isTopObjectResolved = true;
topObject = objectPr.PRnewObj;
}
if (objectPr.PRnewObj is SoapFault)
soapFaultId = objectPr.PRobjectId;
if (objectPr.PRobjectInfo != null)
{
if (objectPr.PRobjectInfo.bfake && !objectPr.PRobjectInfo.bSoapFault)
objectPr.PRobjectInfo.AddValue("__fault", null); // need this because SerializationObjectInfo throws an exception if a name being referenced is missing
objectPr.PRobjectInfo.ObjectEnd();
}
InternalST.Soap( this, "ParseObjectEnd Exit ",objectPr.PRnewObj," id: ",objectPr.PRobjectId);
}
// Array object encountered in stream
private void ParseArray(ParseRecord pr)
{
InternalST.Soap( this, "ParseArray Entry");
pr.Dump();
long genId = pr.PRobjectId;
if (genId < 1)
pr.PRobjectId = GetId("GenId-"+objectIds);
if ((pr.PRarrayElementType != null) && (pr.PRarrayElementType.IsEnum))
pr.PRisEnum = true;
if (pr.PRarrayTypeEnum == InternalArrayTypeE.Base64)
{
if (pr.PRvalue == null)
{
pr.PRnewObj = new Byte[0];
CheckSecurity(pr);
}
else
{
// Used for arrays of Base64 and also for a parameter of Base64
InternalST.Soap( this, "ParseArray bin.base64 ",pr.PRvalue.Length," ",pr.PRvalue);
if (pr.PRdtType == Converter.typeofSoapBase64Binary)
{
// Parameter - Case where the return type is a SoapENC:base64 but the parameter type is xsd:base64Binary
pr.PRnewObj = SoapBase64Binary.Parse(pr.PRvalue);
CheckSecurity(pr);
}
else
{
// ByteArray
if (pr.PRvalue.Length > 0)
{
pr.PRnewObj = Convert.FromBase64String(FilterBin64(pr.PRvalue));
CheckSecurity(pr);
}
else
{
pr.PRnewObj = new Byte[0];
CheckSecurity(pr);
}
}
}
if (stack.Peek() == pr)
{
InternalST.Soap( this, "ParseArray, bin.base64 has been stacked");
stack.Pop();
}
if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
{
InternalST.Soap( this, "ParseArray, bin.base64 Top Object");
topObject = pr.PRnewObj;
isTopObjectResolved = true;
}
ParseRecord parentPr = (ParseRecord)stack.Peek();
// Base64 can be registered at this point because it is populated
InternalST.Soap( this, "ParseArray RegisterObject ",pr.PRobjectId," ",pr.PRnewObj.GetType());
RegisterObject(pr.PRnewObj, pr, parentPr);
}
else if ((pr.PRnewObj != null) && Converter.IsWriteAsByteArray(pr.PRarrayElementTypeCode))
{
// Primtive typed Array has already been read
if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
{
topObject = pr.PRnewObj;
isTopObjectResolved = true;
}
ParseRecord parentPr = (ParseRecord)stack.Peek();
// Primitive typed array can be registered at this point because it is populated
InternalST.Soap( this, "ParseArray RegisterObject ",pr.PRobjectId," ",pr.PRnewObj.GetType());
RegisterObject(pr.PRnewObj, pr, parentPr);
}
else if ((pr.PRarrayTypeEnum == InternalArrayTypeE.Jagged) || (pr.PRarrayTypeEnum == InternalArrayTypeE.Single))
{
// Multidimensional jagged array or single array
InternalST.Soap( this, "ParseArray Before Jagged,Simple create ",pr.PRarrayElementType," ",(pr.PRrank >0?pr.PRlengthA[0].ToString():"0"));
if ((pr.PRlowerBoundA == null) || (pr.PRlowerBoundA[0] == 0))
{
pr.PRnewObj = Array.CreateInstance(pr.PRarrayElementType, (pr.PRrank>0?pr.PRlengthA[0]:0));
pr.PRisLowerBound = false;
}
else
{
pr.PRnewObj = Array.CreateInstance(pr.PRarrayElementType, pr.PRlengthA, pr.PRlowerBoundA);
pr.PRisLowerBound = true;
}
if (pr.PRarrayTypeEnum == InternalArrayTypeE.Single)
{
if (!pr.PRisLowerBound && (Converter.IsWriteAsByteArray(pr.PRarrayElementTypeCode)))
{
pr.PRprimitiveArray = new PrimitiveArray(pr.PRarrayElementTypeCode, (Array)pr.PRnewObj);
}
else if (!pr.PRarrayElementType.IsValueType && pr.PRlowerBoundA== null)
{
pr.PRobjectA = (Object[])pr.PRnewObj;
}
}
CheckSecurity(pr);
InternalST.Soap( this, "ParseArray Jagged,Simple Array ",pr.PRnewObj.GetType());
// For binary, headers comes in as an array of header objects
if (pr.PRobjectPositionEnum == InternalObjectPositionE.Headers)
{
InternalST.Soap( this, "ParseArray header array");
headers = (Header[])pr.PRnewObj;
}
pr.PRindexMap = new int[1];
}
else if (pr.PRarrayTypeEnum == InternalArrayTypeE.Rectangular)
{
// Rectangle array
pr.PRisLowerBound = false;
if (pr.PRlowerBoundA != null)
{
for (int i=0; i-1; irank--)
{
// Find the current or lower dimension which can be incremented.
if (pr.PRrectangularMap[irank] < pr.PRlengthA[irank]-1)
{
// The current dimension is at maximum. Increase the next lower dimension by 1
pr.PRrectangularMap[irank]++;
if (irank < pr.PRrank-1)
{
// The current dimension and higher dimensions are zeroed.
for (int i = irank+1; i 0)
NextRectangleMap(objectPr); // Rectangle array, calculate position in array
for (int i=0; i 0))
{
if (pr.PRvalue == null)
pr.PRvalue = ""; //can't register null value, this must be a string so set to empty string.
InternalST.Soap( this, "ParseMember RegisterObject ",pr.PRvalue," ",pr.PRobjectId);
RegisterObject(pr.PRvalue, pr, objectPr);
}
// Object Class with no memberInfo data
// <
if (pr.PRdtType == Converter.typeofSystemVoid)
{
InternalST.Soap( this, "AddValue 9");
objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRdtType);
}
else if (objectPr.PRobjectInfo.isSi)
{
// ISerializable are added as strings, the conversion to type is done by the
// ISerializable object
InternalST.Soap( this, "AddValue 10");
objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvalue);
}
}
}
}
else
{
Object var = null;
if (pr.PRvarValue != null)
var = pr.PRvarValue;
else
var = Converter.FromString(pr.PRvalue, pr.PRdtTypeCode);
// Not a string, convert the value
InternalST.Soap( this, "ParseMember Converting primitive and storing");
stack.Dump();
InternalST.Soap( this, "ParseMember pr "+pr.Trace());
InternalST.Soap( this, "ParseMember objectPr ",objectPr.Trace());
InternalST.Soap( this, "AddValue 11");
if (pr.PRdtTypeCode == InternalPrimitiveTypeE.QName && var != null)
{
SoapQName soapQName = (SoapQName)var;
if (soapQName.Key != null)
{
if (soapQName.Key.Length == 0)
soapQName.Namespace = (String)soapHandler.keyToNamespaceTable["xmlns"];
else
soapQName.Namespace = (String)soapHandler.keyToNamespaceTable["xmlns"+":"+soapQName.Key];
}
}
objectPr.PRobjectInfo.AddValue(pr.PRname, var);
}
}
else
ParseError(pr, objectPr);
}
// Object member end encountered in stream
private void ParseMemberEnd(ParseRecord pr)
{
InternalST.Soap( this, "ParseMemberEnd");
switch(pr.PRmemberTypeEnum)
{
case InternalMemberTypeE.Item:
ParseArrayMemberEnd(pr);
return;
case InternalMemberTypeE.Field:
if (pr.PRmemberValueEnum == InternalMemberValueE.Nested)
ParseObjectEnd(pr);
break;
default:
if (pr.PRmemberValueEnum == InternalMemberValueE.Nested)
ParseObjectEnd(pr);
else
ParseError(pr, (ParseRecord)stack.Peek());
break;
}
}
// Processes a string object by getting an internal ID for it and registering it with the objectManager
private void ParseString(ParseRecord pr, ParseRecord parentPr)
{
InternalST.Soap( this, "ParseString Entry ",pr.PRobjectId," ",pr.PRvalue," ",pr.PRisRegistered);
// If there is a string and it wasn't marked as a null object, then it is an empty string
if (pr.PRvalue == null)
pr.PRvalue = "";
// Process String class
if ((!pr.PRisRegistered) && (pr.PRobjectId > 0))
{
InternalST.Soap( this, "ParseString RegisterObject ",pr.PRvalue," ",pr.PRobjectId);
// String is treated as an object if it has an id
//m_objectManager.RegisterObject(pr.PRvalue, pr.PRobjectId);
RegisterObject(pr.PRvalue, pr, parentPr);
}
}
private void RegisterObject(Object obj, ParseRecord pr, ParseRecord objectPr)
{
if (!pr.PRisRegistered)
{
pr.PRisRegistered = true;
SerializationInfo si = null;
long parentId = 0;
MemberInfo memberInfo = null;
int[] indexMap = null;
if (objectPr != null)
{
indexMap = objectPr.PRindexMap;
parentId = objectPr.PRobjectId;
if (objectPr.PRobjectInfo != null)
{
if (!objectPr.PRobjectInfo.isSi)
{
// ParentId is only used if there is a memberInfo
InternalST.Soap( this, "RegisterObject GetMemberInfo parent ",objectPr.PRobjectInfo.objectType," name looking for ", pr.PRname," field obj "+obj);
memberInfo = objectPr.PRobjectInfo.GetMemberInfo(pr.PRname);
}
}
}
if (pr.PRobjectInfo != null)
{
// SerializationInfo is always needed for ISerialization
si = pr.PRobjectInfo.si;
}
InternalST.Soap( this, "RegisterObject 0bj ",obj," objectId ",pr.PRobjectId," si ", si," parentId ",parentId," memberInfo ",memberInfo, " indexMap "+indexMap);
m_objectManager.RegisterObject(obj, pr.PRobjectId, si, parentId, memberInfo, indexMap);
}
}
internal void SetVersion(int major, int minor)
{
// Don't do version checking if property is set to Simple
if (formatterEnums.FEassemblyFormat != FormatterAssemblyStyle.Simple)
{
this.majorVersion = major;
this.minorVersion = minor;
}
}
// Assigns an internal ID associated with the xml id attribute
String inKeyId = null;
long outKeyId = 0;
internal long GetId(String keyId)
{
if (keyId == null)
throw new ArgumentNullException("keyId", String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("ArgumentNull_WithParamName"), "keyId"));
if (keyId != inKeyId)
{
inKeyId = keyId;
String idString = null;
InternalST.Soap( this, "GetId Entry ",keyId);
if (keyId[0] == '#')
idString = keyId.Substring(1);
else
idString = keyId;
Object idObj = objectIdTable[idString];
if (idObj == null)
{
outKeyId = ++objectIds;
objectIdTable[idString] = outKeyId;
InternalST.Soap( this, "GetId Exit new ID ",outKeyId);
}
else
{
InternalST.Soap( this, "GetId Exit oldId ",(Int64)idObj);
outKeyId = (Int64)idObj;
}
}
InternalST.Soap( this, "GetId in id ",keyId, " out id ", outKeyId);
return outKeyId;
}
// Trace which includes a single dimensional int array
[Conditional("SER_LOGGING")]
private void IndexTraceMessage(String message, int[] index)
{
StringBuilder sb = new StringBuilder(10);
sb.Append("[");
for (int i=0; i
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TextRunCache.cs
- Parser.cs
- RtfControlWordInfo.cs
- DPTypeDescriptorContext.cs
- PropertyEmitter.cs
- ThrowHelper.cs
- TextServicesHost.cs
- ConcatQueryOperator.cs
- TrackBar.cs
- FragmentQueryKB.cs
- PageAdapter.cs
- WebBrowser.cs
- GridSplitterAutomationPeer.cs
- XmlSchemaCompilationSettings.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- XmlCodeExporter.cs
- GAC.cs
- DbUpdateCommandTree.cs
- WebPartEventArgs.cs
- QueryResults.cs
- OwnerDrawPropertyBag.cs
- MonitoringDescriptionAttribute.cs
- WindowsMenu.cs
- ContextDataSourceView.cs
- SecurityDescriptor.cs
- loginstatus.cs
- DefinitionUpdate.cs
- TextRangeEdit.cs
- MasterPageParser.cs
- RowVisual.cs
- CapiHashAlgorithm.cs
- ToolStripItem.cs
- ProxyWebPartManagerDesigner.cs
- TraceContextRecord.cs
- PKCS1MaskGenerationMethod.cs
- ContractNamespaceAttribute.cs
- InheritablePropertyChangeInfo.cs
- ToolZone.cs
- CommandManager.cs
- SqlWebEventProvider.cs
- TextEffectCollection.cs
- RequiredAttributeAttribute.cs
- RequestTimeoutManager.cs
- Transform3D.cs
- Freezable.cs
- ListViewCancelEventArgs.cs
- ReferenceConverter.cs
- SettingsPropertyValue.cs
- SapiGrammar.cs
- StringKeyFrameCollection.cs
- CssStyleCollection.cs
- BevelBitmapEffect.cs
- InsufficientMemoryException.cs
- BlurEffect.cs
- TimelineClockCollection.cs
- MarkupExtensionSerializer.cs
- NativeRecognizer.cs
- QuestionEventArgs.cs
- DrawingContextWalker.cs
- CodeMethodInvokeExpression.cs
- MenuItem.cs
- WebSysDisplayNameAttribute.cs
- ComboBoxHelper.cs
- WindowsRichEditRange.cs
- VirtualPathProvider.cs
- _HeaderInfo.cs
- TrackBar.cs
- ToolboxDataAttribute.cs
- _ListenerAsyncResult.cs
- StrokeRenderer.cs
- DataGridViewCellToolTipTextNeededEventArgs.cs
- Graphics.cs
- DataServiceRequest.cs
- UIElementPropertyUndoUnit.cs
- CharEntityEncoderFallback.cs
- Int16Storage.cs
- PlatformNotSupportedException.cs
- MessagePropertyDescription.cs
- CapabilitiesState.cs
- RuleConditionDialog.Designer.cs
- ColumnMapProcessor.cs
- Compiler.cs
- RenderTargetBitmap.cs
- TransactionScope.cs
- SoapDocumentServiceAttribute.cs
- XsdBuilder.cs
- DataGridViewComboBoxCell.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- GACIdentityPermission.cs
- ServiceHttpHandlerFactory.cs
- MatrixStack.cs
- ExeConfigurationFileMap.cs
- ReferencedAssembly.cs
- Missing.cs
- LicenseProviderAttribute.cs
- XmlDocumentViewSchema.cs
- BoolLiteral.cs
- GeneralTransform3DGroup.cs
- HotSpot.cs
- DuplicateDetector.cs