Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / 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; i0)) { 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; i 111 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; i 111 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
- DynamicUpdateCommand.cs
- X509CertificateCollection.cs
- ScriptResourceInfo.cs
- SqlCacheDependencyDatabaseCollection.cs
- Base64Encoder.cs
- PriorityBinding.cs
- OleDbParameterCollection.cs
- XMLSchema.cs
- EdmToObjectNamespaceMap.cs
- KeySpline.cs
- ResolvedKeyFrameEntry.cs
- ReachPageContentSerializerAsync.cs
- PropertyManager.cs
- RawStylusInputReport.cs
- DataContractSerializerOperationGenerator.cs
- HyperlinkAutomationPeer.cs
- PrivacyNoticeBindingElementImporter.cs
- TextServicesCompartment.cs
- Compiler.cs
- TabControlCancelEvent.cs
- CalendarDateRange.cs
- TextBoxBase.cs
- ProtocolsConfigurationEntry.cs
- HtmlValidatorAdapter.cs
- _RequestCacheProtocol.cs
- VisualStyleElement.cs
- TimelineCollection.cs
- DetailsViewCommandEventArgs.cs
- SqlDataSourceCustomCommandPanel.cs
- TraceLog.cs
- MemberPath.cs
- PagedDataSource.cs
- RotateTransform.cs
- IntersectQueryOperator.cs
- PropertyKey.cs
- RoleGroupCollectionEditor.cs
- ConfigurationPropertyAttribute.cs
- AddInDeploymentState.cs
- WeakKeyDictionary.cs
- NotifyCollectionChangedEventArgs.cs
- DesignerActionUIStateChangeEventArgs.cs
- ScriptRegistrationManager.cs
- BitmapFrameEncode.cs
- Scene3D.cs
- SafeArrayRankMismatchException.cs
- FormViewPagerRow.cs
- KoreanLunisolarCalendar.cs
- ListBoxDesigner.cs
- TextEffect.cs
- CultureMapper.cs
- CompressEmulationStream.cs
- LoginDesignerUtil.cs
- SmiSettersStream.cs
- ConstraintConverter.cs
- StorageRoot.cs
- SqlDataSourceCommandEventArgs.cs
- WindowsListViewItemCheckBox.cs
- XmlProcessingInstruction.cs
- QilTypeChecker.cs
- InnerItemCollectionView.cs
- XPathChildIterator.cs
- ReferenceSchema.cs
- RunClient.cs
- BindingsCollection.cs
- MsmqIntegrationChannelListener.cs
- ChildrenQuery.cs
- ScriptingRoleServiceSection.cs
- RectAnimationClockResource.cs
- WarningException.cs
- XmlSchemaComplexContentRestriction.cs
- ArraySegment.cs
- UnitySerializationHolder.cs
- SplitterEvent.cs
- Profiler.cs
- NotImplementedException.cs
- SafeIUnknown.cs
- GetPageCompletedEventArgs.cs
- LicenseManager.cs
- SoapSchemaImporter.cs
- SqlErrorCollection.cs
- HostingEnvironment.cs
- HGlobalSafeHandle.cs
- ToolStripContainerDesigner.cs
- EntityDataSource.cs
- DuplexClientBase.cs
- Configuration.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- DateTimeConverter2.cs
- StructuredTypeEmitter.cs
- EmptyReadOnlyDictionaryInternal.cs
- MarkerProperties.cs
- KerberosSecurityTokenProvider.cs
- ProxyAssemblyNotLoadedException.cs
- TextUtf8RawTextWriter.cs
- LicenseProviderAttribute.cs
- PixelShader.cs
- TableStyle.cs
- RSAPKCS1KeyExchangeFormatter.cs
- TextSerializer.cs
- EnterpriseServicesHelper.cs