private void ProcessAttributes(ParseRecord pr, ParseRecord objectPr) { InternalST.Soap( this, "ProcessAttributes Entry ",pr.Trace()," headerState ",((Enum)headerState).ToString()); String keyPosition = null; String keyOffset = null; String keyMustUnderstand = null; pr.PRisProcessAttributes = true; String SoapKeyUrl = "http://schemas.xmlsoap.org/soap/encoding/"; int SoapKeyUrlLength = SoapKeyUrl.Length; String UrtKeyUrl = "http://schemas.microsoft.com/clr/id"; int UrtKeyUrlLength = UrtKeyUrl.Length; String SoapEnvKeyUrl = "http://schemas.xmlsoap.org/soap/envelope/"; int SoapEnvKeyUrlLength = SoapEnvKeyUrl.Length; String XSIKey2001 = "http://www.w3.org/2001/XMLSchema-instance"; int XSIKey2001Length = XSIKey2001.Length; String XSIKey2000 = "http://www.w3.org/2000/10/XMLSchema-instance"; int XSIKey2000Length = XSIKey2000.Length; String XSIKey1999 = "http://www.w3.org/1999/XMLSchema-instance"; int XSIKey1999Length = XSIKey1999.Length; String XSDKey1999 = "http://www.w3.org/1999/XMLSchema"; int XSDKey1999Length = XSDKey1999.Length; String XSDKey2000 = "http://www.w3.org/2000/10/XMLSchema"; int XSDKey2000Length = XSDKey2000.Length; String XSDKey2001 = "http://www.w3.org/2001/XMLSchema"; int XSDKey2001Length = XSDKey2001.Length; String clrNS = "http://schemas.microsoft.com/soap/encoding/clr/1.0"; int clrNSLength = clrNS.Length; for (int i = 0; i<attributeValues.Count(); i++) { AttributeValueEntry attributeValueEntry = (AttributeValueEntry)attributeValues.GetItem(i); String prefix = attributeValueEntry.prefix; String key = attributeValueEntry.key; if ((key == null) || (key.Length == 0)) key = pr.PRnameXmlKey; //case where there is a default key String value = attributeValueEntry.value; bool prefixMatchesXmlns = false; String urn = attributeValueEntry.urn; InternalST.Soap( this, "ProcessAttributes attribute prefix ",prefix," key ",key," value ",value," urn ", urn); int keyLength = key.Length; int valueLength = value.Length; // table need for QName xsd types if (key == null || keyLength == 0) keyToNamespaceTable[prefix] = value; else keyToNamespaceTable[prefix+":"+key] = value; if (keyLength == 2 && String.Compare(key, "id", true, CultureInfo.InvariantCulture) == 0) pr.PRobjectId = objectReader.GetId(value); else if (keyLength == 8 && String.Compare(key, "position", true, CultureInfo.InvariantCulture) == 0) keyPosition = value; else if (keyLength == 6 && String.Compare(key, "offset", true, CultureInfo.InvariantCulture) == 0) keyOffset = value; else if (keyLength == 14 && String.Compare(key, "MustUnderstand", true, CultureInfo.InvariantCulture) == 0) keyMustUnderstand = value; else if (keyLength == 4 && String.Compare(key, "null", true, CultureInfo.InvariantCulture) == 0) { pr.PRmemberValueEnum = InternalMemberValueE.Null; pr.PRvalue = null; } else if (keyLength == 4 && String.Compare(key, "root", true, CultureInfo.InvariantCulture) == 0) { if (value.Equals("1")) pr.PRisHeaderRoot = true; } else if (keyLength == 4 && String.Compare(key, "href", true, CultureInfo.InvariantCulture) == 0) pr.PRidRef = objectReader.GetId(value); else if (keyLength == 4 && String.Compare(key, "type", true, CultureInfo.InvariantCulture) == 0) { String currentPRtypeXmlKey = pr.PRtypeXmlKey; String currentPRkeyDt = pr.PRkeyDt; Type currentPRdtType = pr.PRdtType; String typeValue = value; int index = value.IndexOf(":"); if (index > 0) { pr.PRtypeXmlKey = value.Substring(0, index); typeValue = value.Substring(++index); } else { pr.PRtypeXmlKey = prefix; } if (String.Compare(typeValue, "anyType", true, CultureInfo.InvariantCulture) == 0 || String.Compare(typeValue, "ur-type", true, CultureInfo.InvariantCulture) == 0) { pr.PRkeyDt = "System.Object"; pr.PRdtType = SoapUtil.typeofObject; pr.PRtypeXmlKey = urtKey; } if (pr.PRtypeXmlKey == soapKey && typeValue == "Array") //Don't need to process xsi:type="SOAP-ENC:Array" { // Array values already found,use these value rather then the xsi:type values pr.PRtypeXmlKey = currentPRtypeXmlKey; pr.PRkeyDt = currentPRkeyDt; pr.PRdtType = currentPRdtType; InternalST.Soap( this,"ProcessAttributes, xsi:type='SOAP-ENC:Array' pr.PRtypeXmlKey ", pr.PRtypeXmlKey," pr.PRkeyDt "+pr.PRkeyDt); } else { pr.PRkeyDt = typeValue; InternalST.Soap( this,"ProcessAttributes, not xsi:type='SOAP-ENC:Array' pr.PRtypeXmlKey ", pr.PRtypeXmlKey," pr.PRkeyDt "+pr.PRkeyDt); } } else if (keyLength == 9 && String.Compare(key, "arraytype", true, CultureInfo.InvariantCulture) == 0) { String typeValue = value; int index = value.IndexOf(":"); if (index > 0) { pr.PRtypeXmlKey = value.Substring(0, index); pr.PRkeyDt = typeValue = value.Substring(++index); } if (typeValue.StartsWith("ur_type[")) { pr.PRkeyDt = "System.Object"+typeValue.Substring(6); pr.PRtypeXmlKey = urtKey; } } else if (SoapServices.IsClrTypeNamespace(value)) { if (!assemKeyToAssemblyTable.ContainsKey(key)) { String typeNamespace = null; String assemblyName = null; SoapServices.DecodeXmlNamespaceForClrTypeNamespace(value, out typeNamespace, out assemblyName); if (assemblyName == null) { assemKeyToAssemblyTable[key] = new SoapAssemblyInfo(SoapUtil.urtAssemblyString, SoapUtil.urtAssembly); assemKeyToNameSpaceTable[key] = typeNamespace; } else { assemKeyToAssemblyTable[key] = new SoapAssemblyInfo(assemblyName); if (typeNamespace != null) assemKeyToNameSpaceTable[key] = typeNamespace; } } } else if ((prefixMatchesXmlns = prefix.Equals("xmlns")) && (valueLength == SoapKeyUrlLength && String.Compare(value, SoapKeyUrl, true, CultureInfo.InvariantCulture) == 0)) { soapKey = key; } else if (prefixMatchesXmlns && (valueLength == UrtKeyUrlLength && String.Compare(value, UrtKeyUrl, true, CultureInfo.InvariantCulture) == 0)) { urtKey = key; assemKeyToAssemblyTable[urtKey] = new SoapAssemblyInfo(SoapUtil.urtAssemblyString, SoapUtil.urtAssembly); } else if (prefixMatchesXmlns && (valueLength == SoapEnvKeyUrlLength && String.Compare(value, SoapEnvKeyUrl, true) == 0)) { soapEnvKey = key; } else if (key == "encodingStyle") { /* String[] split = value.Split(' '); foreach (String s in split) { if (s == "http://schemas.microsoft.com/soap/encoding/clr/1.0") { objectReader.SetVersion(1,0); break; } } */ } else if (prefixMatchesXmlns && ((valueLength == XSIKey2001Length && String.Compare(value, XSIKey2001,true, CultureInfo.InvariantCulture) == 0) || (valueLength == XSIKey1999Length && String.Compare(value, XSIKey1999,true, CultureInfo.InvariantCulture) == 0) || (valueLength == XSIKey2000Length && String.Compare(value, XSIKey2000,true, CultureInfo.InvariantCulture) == 0))) { xsiKey = key; } else if (prefixMatchesXmlns && ((valueLength == XSDKey2001Length && String.Compare(value, XSDKey2001 , true, CultureInfo.InvariantCulture) == 0)) || (valueLength == XSDKey1999Length && String.Compare(value, XSDKey1999, true, CultureInfo.InvariantCulture) == 0) || (valueLength == XSDKey2000Length && String.Compare(value, XSDKey2000, true, CultureInfo.InvariantCulture) == 0)) { xsdKey = key; } else if (prefixMatchesXmlns && (valueLength == clrNSLength && String.Compare(value, clrNS, true, CultureInfo.InvariantCulture) == 0)) { objectReader.SetVersion(1,0); } else { //String lowerCaseValue = value.ToLower(CultureInfo.InvariantCulture); if (prefixMatchesXmlns) { // Assume it is an interop namespace assemKeyToInteropAssemblyTable[key] = value; InternalST.Soap( this,"ProcessAttributes, InteropType key "+key+" value ",value); } else if (String.Compare(prefix, soapKey, true, CultureInfo.InvariantCulture) == 0) { InternalST.Soap( this,"ProcessAttributes, Not processed key ",prefix,":",key," = ",value); } else { // See if it is a XmlAttribute InternalST.Soap( this,"ProcessAttributes, XmlAttribute prefix ",prefix," key ",key," value ",value," urn ",urn, " hashtable ",assemKeyToInteropAssemblyTable[prefix]); if ((assemKeyToInteropAssemblyTable.ContainsKey(prefix)) && ((String)assemKeyToInteropAssemblyTable[prefix]).Equals(urn)) { ProcessXmlAttribute(prefix, key, value, objectPr); } else { InternalST.Soap( this,"ProcessAttributes, Not processed prefix ",prefix," key ",key," value ",value," urn ",urn); } } } } attributeValues.Clear(); // reset the header state // If no headers then headerState is None // // if parent is a header section then these are top level objects // within the header section. If the object has a root set // then it is a header record, if not then it is a toplevel object // in the header section which is not a header record. // // if the parent is not a header section and is a header root // then this is a nested object within a header record. All // subsequent object will be nested until another header // root is encountered // // The first header record is considered a root record if (headerState != HeaderStateEnum.None) { if (objectPr.PRparseTypeEnum == InternalParseTypeE.Headers) { if (pr.PRisHeaderRoot || (headerState == HeaderStateEnum.FirstHeaderRecord)) { headerState = HeaderStateEnum.HeaderRecord; } else { headerState = HeaderStateEnum.TopLevelObject; currentState = InternalParseStateE.Object; pr.PRobjectTypeEnum = InternalObjectTypeE.Object; pr.PRparseTypeEnum = InternalParseTypeE.Object; pr.PRparseStateEnum = InternalParseStateE.Object; pr.PRmemberTypeEnum = InternalMemberTypeE.Empty; pr.PRmemberValueEnum = InternalMemberValueE.Empty; } } else if (objectPr.PRisHeaderRoot) headerState = HeaderStateEnum.NestedObject; } InternalST.Soap( this,"ProcessAttributes, headerState ",((Enum)headerState).ToString()); if (!isTopFound && (objectPr != null ) && (objectPr.PRparseTypeEnum == InternalParseTypeE.Body)) { pr.PRobjectPositionEnum = InternalObjectPositionE.Top; isTopFound = true; } else if (pr.PRobjectPositionEnum != InternalObjectPositionE.Top) pr.PRobjectPositionEnum = InternalObjectPositionE.Child; // Don't process type for envelop, topSoapElement unless it has a key of soapEnvKey (SOAP-ENV). Fault // is the only top record which currently falls into this category. if (!((pr.PRparseTypeEnum == InternalParseTypeE.Envelope)|| (pr.PRparseTypeEnum == InternalParseTypeE.Body) || (pr.PRparseTypeEnum == InternalParseTypeE.Headers) || (pr.PRobjectPositionEnum == InternalObjectPositionE.Top && objectReader.IsFakeTopObject && !pr.PRnameXmlKey.Equals(soapEnvKey)))) { InternalST.Soap( this, "ProcessAttributes before Process Type ",((Enum)pr.PRparseTypeEnum).ToString()); ProcessType(pr, objectPr); } if (keyPosition != null) { int outRank; String outDimSignature; InternalArrayTypeE outArrayTypeEnum; pr.PRpositionA = ParseArrayDimensions(keyPosition, out outRank, out outDimSignature, out outArrayTypeEnum); } if (keyOffset != null) { int outRank; String outDimSignature; InternalArrayTypeE outArrayTypeEnum; pr.PRlowerBoundA = ParseArrayDimensions(keyOffset, out outRank, out outDimSignature, out outArrayTypeEnum); } if (keyMustUnderstand != null) if (keyMustUnderstand.Equals("1")) pr.PRisMustUnderstand = true; else if (keyMustUnderstand.Equals("0")) pr.PRisMustUnderstand = false; else throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_MustUnderstand"),keyMustUnderstand)); if (pr.PRparseTypeEnum == InternalParseTypeE.Member) { // Process Member InternalST.Soap( this, "ProcessAttributes Member "); stack.Dump(); if (objectPr.PRparseTypeEnum == InternalParseTypeE.Headers) pr.PRmemberTypeEnum = InternalMemberTypeE.Header; else if (objectPr.PRobjectTypeEnum == InternalObjectTypeE.Array) pr.PRmemberTypeEnum = InternalMemberTypeE.Item; else pr.PRmemberTypeEnum = InternalMemberTypeE.Field; } }
// End of object encountered in stream private void ParseObjectEnd(ParseRecord pr) { InternalST.Soap( this, "ParseObjectEnd Entry ",pr.Trace()); ParseRecord objectPr = (ParseRecord)stack.Peek(); if (objectPr == null) objectPr = pr; //BCLDebug.Assert(objectPr != null, "[System.Runtime.Serialization.Formatters.ParseObjectEnd]objectPr != null"); InternalST.Soap( this, "ParseObjectEnd objectPr ",objectPr.Trace()); if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top) { InternalST.Soap( this, "ParseObjectEnd Top Object dtType ",objectPr.PRdtType); if (objectPr.PRdtType == Converter.typeofString) { InternalST.Soap( this, "ParseObjectEnd Top String"); if (objectPr.PRvalue == null) objectPr.PRvalue = String.Empty; // Not a null object, but an empty string objectPr.PRnewObj = objectPr.PRvalue; CheckSecurity(objectPr); isTopObjectResolved = true; topObject = objectPr.PRnewObj; return; } else if (objectPr.PRdtType != null && objectPr.PRvalue != null && !IsWhiteSpace(objectPr.PRvalue) && (objectPr.PRdtType.IsPrimitive || objectPr.PRdtType == Converter.typeofTimeSpan)) { // When an xsd type is transmitted as a top level string <xsd:int>111</xsd:int> 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(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 item encountered in stream private void ParseArrayMember(ParseRecord pr) { InternalST.Soap( this, "ParseArrayMember Entry"); ParseRecord objectPr = (ParseRecord)stack.Peek(); // Set up for inserting value into correct array position if (objectPr.PRarrayTypeEnum == InternalArrayTypeE.Rectangular) { if (objectPr.PRmemberIndex > 0) NextRectangleMap(objectPr); // Rectangle array, calculate position in array if (objectPr.PRisLowerBound) { for (int i=0; i<objectPr.PRrank; i++) { if (objectPr.PRpositionA == null) objectPr.PRindexMap[i] = objectPr.PRrectangularMap[i] + objectPr.PRlowerBoundA[i]; else objectPr.PRindexMap[i] = objectPr.PRpositionA[i]; } } } else { if (!objectPr.PRisLowerBound) { if (objectPr.PRpositionA == null) objectPr.PRindexMap[0] = objectPr.PRmemberIndex; // Zero based array else objectPr.PRindexMap[0] = objectPr.PRpositionA[0]; // item position specified in SOAP stream } else objectPr.PRindexMap[0] = objectPr.PRlowerBoundA[0]+objectPr.PRmemberIndex; // Lower Bound based array } IndexTraceMessage("ParseArrayMember isLowerBound "+objectPr.PRisLowerBound+" indexMap ", objectPr.PRindexMap); // Set Array element according to type of element if (pr.PRmemberValueEnum == InternalMemberValueE.Reference) { // Object Reference // See if object has already been instantiated Object refObj = m_objectManager.GetObject(pr.PRidRef); if (refObj == null) { // Object not instantiated // Array fixup manager IndexTraceMessage("ParseArrayMember Record Fixup "+objectPr.PRnewObj.GetType(), objectPr.PRindexMap); int[] fixupIndex = new int[objectPr.PRrank]; Array.Copy(objectPr.PRindexMap, 0, fixupIndex, 0, objectPr.PRrank); InternalST.Soap( this, "ParseArrayMember RecordArrayElementFixup objectId ",objectPr.PRobjectId," idRef ",pr.PRidRef); m_objectManager.RecordArrayElementFixup(objectPr.PRobjectId, fixupIndex, pr.PRidRef); } else { IndexTraceMessage("ParseArrayMember SetValue ObjectReference "+objectPr.PRnewObj.GetType()+" "+refObj, objectPr.PRindexMap); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = refObj; else ((Array)objectPr.PRnewObj).SetValue(refObj, objectPr.PRindexMap); // Object has been instantiated } } else if (pr.PRmemberValueEnum == InternalMemberValueE.Nested) { //Set up dtType for ParseObject InternalST.Soap( this, "ParseArrayMember Nested "); if (pr.PRdtType == null) { pr.PRdtType = objectPr.PRarrayElementType; } ParseObject(pr); InternalST.Soap( "ParseArrayMember Push object "+pr.PRname); stack.Push(pr); if ((objectPr.PRarrayElementType.IsValueType) && (pr.PRarrayElementTypeCode == InternalPrimitiveTypeE.Invalid)) { InternalST.Soap( "ParseArrayMember ValueType ObjectPr ",objectPr.PRnewObj," index ",objectPr.PRmemberIndex); pr.PRisValueTypeFixup = true; //Valuefixup valueFixupStack.Push(new ValueFixup((Array)objectPr.PRnewObj, objectPr.PRindexMap)); //valuefixup RegisterObject(pr.PRnewObj, pr, objectPr); } else { InternalST.Soap( "ParseArrayMember SetValue Nested, memberIndex ",objectPr.PRmemberIndex); IndexTraceMessage("ParseArrayMember SetValue Nested ContainerObject "+objectPr.PRnewObj.GetType()+" "+objectPr.PRnewObj+" item Object "+pr.PRnewObj+" index ", objectPr.PRindexMap); stack.Dump(); InternalST.Soap( "ParseArrayMember SetValue Nested ContainerObject objectPr ",objectPr.Trace()); InternalST.Soap( "ParseArrayMember SetValue Nested ContainerObject pr ",pr.Trace()); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = pr.PRnewObj; else ((Array)objectPr.PRnewObj).SetValue(pr.PRnewObj, objectPr.PRindexMap); } } else if (pr.PRmemberValueEnum == InternalMemberValueE.InlineValue) { if (objectPr.PRarrayElementType == Converter.typeofString) { // String ParseString(pr, objectPr); IndexTraceMessage("ParseArrayMember SetValue String "+objectPr.PRnewObj.GetType()+" "+pr.PRvalue, objectPr.PRindexMap); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = (Object)pr.PRvalue; else ((Array)objectPr.PRnewObj).SetValue((Object)pr.PRvalue, objectPr.PRindexMap); } else if (objectPr.PRisEnum) { // Soap sends Enums as strings Object var = Enum.Parse(objectPr.PRarrayElementType, pr.PRvalue); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = (Enum)var; else ((Array)objectPr.PRnewObj).SetValue((Enum)var, objectPr.PRindexMap); InternalST.Soap( this, "ParseArrayMember Enum 1"); } else if (objectPr.PRisArrayVariant) { // Array of type object if (pr.PRdtType == null && pr.PRkeyDt == null) throw new SerializationException(SoapUtil.GetResourceString("Serialization_ArrayTypeObject")); Object var = null; if (pr.PRdtType == Converter.typeofString) { ParseString(pr, objectPr); var = pr.PRvalue; } else if (pr.PRdtType.IsEnum) { // Soap sends Enums as strings var = Enum.Parse(pr.PRdtType, pr.PRvalue); InternalST.Soap( this, "ParseArrayMember Enum 2"); } else if (pr.PRdtTypeCode == InternalPrimitiveTypeE.Invalid) { // Not nested and invalid, so it is an empty object var = FormatterServices.GetUninitializedObject(pr.PRdtType); } else { if (pr.PRvarValue != null) var = pr.PRvarValue; else var = Converter.FromString(pr.PRvalue, pr.PRdtTypeCode); } IndexTraceMessage("ParseArrayMember SetValue variant or Object "+objectPr.PRnewObj.GetType()+" var "+var+" indexMap ", objectPr.PRindexMap); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = var; else ((Array)objectPr.PRnewObj).SetValue(var, objectPr.PRindexMap); // Primitive type } else { // Primitive type if (objectPr.PRprimitiveArray != null) { // Fast path for Soap primitive arrays. Binary was handled in the BinaryParser objectPr.PRprimitiveArray.SetValue(pr.PRvalue, objectPr.PRindexMap[0]); } else { Object var = null; if (pr.PRvarValue != null) var = pr.PRvarValue; else var = Converter.FromString(pr.PRvalue, objectPr.PRarrayElementTypeCode); if (objectPr.PRarrayElementTypeCode == InternalPrimitiveTypeE.QName) { InternalST.Soap( this, "ParseArrayMember Primitive QName"); SoapQName soapQName = (SoapQName)var; if (soapQName.Key.Length == 0) soapQName.Namespace = (String)soapHandler.keyToNamespaceTable["xmlns"]; else soapQName.Namespace = (String)soapHandler.keyToNamespaceTable["xmlns"+":"+soapQName.Key]; } InternalST.Soap( this, "ParseArrayMember SetValue Primitive pr.PRvalue "+var," elementTypeCode ",((Enum)objectPr.PRdtTypeCode).ToString()); IndexTraceMessage("ParseArrayMember SetValue Primitive "+objectPr.PRnewObj.GetType()+" var: "+var+" varType "+var.GetType(), objectPr.PRindexMap); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = var; else ((Array)objectPr.PRnewObj).SetValue(var, objectPr.PRindexMap); // Primitive type InternalST.Soap( this, "ParseArrayMember SetValue Primitive after"); } } } else if (pr.PRmemberValueEnum == InternalMemberValueE.Null) { InternalST.Soap( "ParseArrayMember Null item ",pr.PRmemberIndex); } else ParseError(pr, objectPr); InternalST.Soap( "ParseArrayMember increment memberIndex ",objectPr.PRmemberIndex," ",objectPr.Trace()); objectPr.PRmemberIndex++; InternalST.Soap( "ParseArrayMember Exit"); }
// Object member encountered in stream private void ParseMember(ParseRecord pr) { InternalST.Soap( this, "ParseMember Entry "); ParseRecord objectPr = (ParseRecord)stack.Peek(); String objName = null; if (objectPr != null) objName = objectPr.PRname; InternalST.Soap( this, "ParseMember ",objectPr.PRobjectId," ",pr.PRname); InternalST.Soap( this, "ParseMember objectPr ",objectPr.Trace()); InternalST.Soap( this, "ParseMember pr ",pr.Trace()); if (objectPr.PRdtType == Converter.typeofSoapFault && pr.PRname.ToLower(CultureInfo.InvariantCulture) == "faultstring") faultString = pr.PRvalue; // Save fault string in case rest of SoapFault cannot be parsed if ((objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top) && !isTopObjectResolved) { InternalST.Soap( this, "ParseMember Top not resolved"); if (pr.PRdtType == Converter.typeofString) { ParseString(pr, objectPr); } topStack.Push(pr.Copy()); return; } switch(pr.PRmemberTypeEnum) { case InternalMemberTypeE.Item: ParseArrayMember(pr); return; case InternalMemberTypeE.Field: break; } if (objectPr.PRobjectInfo != null) objectPr.PRobjectInfo.AddMemberSeen(); bool bParams = (IsFakeTopObject && objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top && objectPr.PRobjectInfo != null && objectPr.PRdtType != Converter.typeofSoapFault); if ((pr.PRdtType == null) && objectPr.PRobjectInfo.isTyped) { InternalST.Soap( this, "ParseMember pr.PRdtType null and not isSi"); if (bParams) { // Get type of parameters InternalST.Soap( this, "ParseMember pr.PRdtType Get Param Type position "+paramPosition+" name "+pr.PRname); pr.PRdtType = objectPr.PRobjectInfo.GetType(paramPosition++); InternalST.Soap( this, "ParseMember pr.PRdtType Get Param Type Type "+pr.PRdtType); } else pr.PRdtType = objectPr.PRobjectInfo.GetType(pr.PRname); if (pr.PRdtType == null) throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_TypeResolved"), objectPr.PRnewObj+" "+pr.PRname)); pr.PRdtTypeCode = Converter.ToCode(pr.PRdtType); } else { if (bParams) { paramPosition++; } } if (pr.PRmemberValueEnum == InternalMemberValueE.Null) { // Value is Null InternalST.Soap( this, "ParseMember null member: ",pr.PRname); InternalST.Soap( this, "AddValue 1"); objectPr.PRobjectInfo.AddValue(pr.PRname, null); } else if (pr.PRmemberValueEnum == InternalMemberValueE.Nested) { InternalST.Soap( this, "ParseMember Nested Type member: ",pr.PRname," objectPr.PRnewObj ",objectPr.PRnewObj); ParseObject(pr); InternalST.Soap( "ParseMember Push object "+pr.PRname); stack.Push(pr); InternalST.Soap( this, "AddValue 2 ",pr.PRnewObj," is value type ",pr.PRnewObj.GetType().IsValueType); if ((pr.PRobjectInfo != null) && (pr.PRobjectInfo.objectType.IsValueType)) { InternalST.Soap( "ParseMember ValueType ObjectPr ",objectPr.PRnewObj," memberName ",pr.PRname," nested object ",pr.PRnewObj); if (IsFakeTopObject) objectPr.PRobjectInfo.AddParamName(pr.PRname); pr.PRisValueTypeFixup = true; //Valuefixup valueFixupStack.Push(new ValueFixup(objectPr.PRnewObj, pr.PRname, objectPr.PRobjectInfo));//valuefixup } else { InternalST.Soap( this, "AddValue 2A "); objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRnewObj); } } else if (pr.PRmemberValueEnum == InternalMemberValueE.Reference) { InternalST.Soap( this, "ParseMember Reference Type member: ",pr.PRname); // See if object has already been instantiated Object refObj = m_objectManager.GetObject(pr.PRidRef); if (refObj == null) { InternalST.Soap( this, "ParseMember RecordFixup: ",pr.PRname); InternalST.Soap( this, "AddValue 3"); objectPr.PRobjectInfo.AddValue(pr.PRname, null); objectPr.PRobjectInfo.RecordFixup(objectPr.PRobjectId, pr.PRname, pr.PRidRef); // Object not instantiated } else { InternalST.Soap( this, "ParseMember Referenced Object Known ",pr.PRname," ",refObj); InternalST.Soap( this, "AddValue 5"); objectPr.PRobjectInfo.AddValue(pr.PRname, refObj); } } else if (pr.PRmemberValueEnum == InternalMemberValueE.InlineValue) { // Primitive type or String InternalST.Soap( this, "ParseMember primitive or String member: ",pr.PRname); if (pr.PRdtType == Converter.typeofString) { ParseString(pr, objectPr); InternalST.Soap( this, "AddValue 6"); objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvalue); } else if (pr.PRdtTypeCode == InternalPrimitiveTypeE.Invalid) { // The member field was an object put the value is Inline either bin.Base64 or invalid if (pr.PRarrayTypeEnum == InternalArrayTypeE.Base64) { InternalST.Soap( this, "AddValue 7"); objectPr.PRobjectInfo.AddValue(pr.PRname, Convert.FromBase64String(FilterBin64(pr.PRvalue))); } else if (pr.PRdtType == Converter.typeofObject && pr.PRvalue != null) { if (objectPr != null && objectPr.PRdtType == Converter.typeofHeader) { // assume the type is a string for a header pr.PRdtType = Converter.typeofString; ParseString(pr, objectPr); InternalST.Soap( this, "AddValue 6"); objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvalue); } else throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_TypeMissing"), pr.PRname)); } else { InternalST.Soap( this, "Object Class with no memberInfo data Member "+pr.PRname+" type "+pr.PRdtType); if (pr.PRdtType != null && pr.PRdtType.IsEnum) { // Soap sends Enums as strings Object obj = Enum.Parse(pr.PRdtType, pr.PRvalue); InternalST.Soap( this, "AddValue 8"); objectPr.PRobjectInfo.AddValue(pr.PRname, obj); } else if (pr.PRdtType != null && pr.PRdtType == Converter.typeofTypeArray) { // Soap sends MethodSignature as an array of types InternalST.Soap( this, "AddValue 8A"); objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvarValue); } else { if ((!pr.PRisRegistered) && (pr.PRobjectId > 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); }