The Labs \ Source Viewer \ SSCLI \ System.Runtime.Serialization.Formatters.Soap \ DottedInfo

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. //============================================================
  16. //
  17. // Class: SoapWriter
  18. // Purpose: Emits XML for SOAP Formatter
  19. //
  20. // Date: June 10, 1999
  21. //
  22. //============================================================
  23. namespace System.Runtime.Serialization.Formatters.Soap
  24. {
  25.     using System;
  26.     using System.Runtime.Serialization.Formatters;
  27.     using System.Collections;
  28.     using System.Collections.Generic;
  29.     using System.Reflection;
  30.     using System.IO;
  31.     using System.Globalization;
  32.     using System.Text;
  33.     using System.Diagnostics;
  34.     using System.Runtime.Remoting;
  35.     using System.Runtime.Remoting.Metadata.W3cXsd2001;
  36.    
  37.     // This class provides persistence of a COM+ object graph to a stream using
  38.     // the SOAP XML-based format.
  39.    
  40.     internal sealed class SoapWriter
  41.     {
  42.         // the start of a soap message always looks like one of these
  43.        
  44.         // Encoding style not used because of difficulty in interop
  45.         // "SOAP-ENV:encodingStyle=\"http://schemas.microsoft.com/soap/encoding/clr/1.0 http://schemas.xmlsoap.org/soap/encoding/\"";
  46.        
  47.         private static string _soapStartStr = "<SOAP-ENV:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" " + "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " + "xmlns:clr=\"http://schemas.microsoft.com/soap/encoding/clr/1.0\" " + "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"";
  48.        
  49.         private static string _soapStart1999Str = "<SOAP-ENV:Envelope xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" " + "xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\" " + "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" " + "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " + "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"";
  50.        
  51.         private static string _soapStart2000Str = "<SOAP-ENV:Envelope xmlns:xsi=\"http://www.w3.org/2000/10/XMLSchema-instance\" " + "xmlns:xsd=\"http://www.w3.org/2000/10/XMLSchema\" " + "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" " + "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " + "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"";
  52.        
  53.         private static byte[] _soapStart = Encoding.UTF8.GetBytes(_soapStartStr);
  54.         private static byte[] _soapStart1999 = Encoding.UTF8.GetBytes(_soapStart1999Str);
  55.         private static byte[] _soapStart2000 = Encoding.UTF8.GetBytes(_soapStart2000Str);
  56.         public static Dictionary<char, string> encodingTable = new Dictionary<char, string>();
  57.        
  58.         static SoapWriter()
  59.         {
  60.             // special and
  61.             // RestrictedChar ::= [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]
  62.             //
  63.             encodingTable.Add('&', "&#38;");
  64.             encodingTable.Add('"', "&#34;");
  65.             encodingTable.Add('\'', "&#39;");
  66.             encodingTable.Add('<', "&#60;");
  67.             encodingTable.Add('>', "&#62;");
  68.             encodingTable.Add(Char.MinValue, "&#0;");
  69.             encodingTable.Add('\v', "&#xB;");
  70.             encodingTable.Add('\f', "&#xC;");
  71.            
  72.             for (int i = 1; i < 9; i++)
  73.                 encodingTable.Add(((IConvertible)i).ToChar(NumberFormatInfo.InvariantInfo), "&#x" + i.ToString("X", CultureInfo.InvariantCulture) + ";");
  74.             for (int i = 14; i < 32; i++)
  75.                 encodingTable.Add(((IConvertible)i).ToChar(NumberFormatInfo.InvariantInfo), "&#x" + i.ToString("X", CultureInfo.InvariantCulture) + ";");
  76.             for (int i = 127; i < 133; i++)
  77.                 encodingTable.Add(((IConvertible)i).ToChar(NumberFormatInfo.InvariantInfo), "&#x" + i.ToString("X", CultureInfo.InvariantCulture) + ";");
  78.             for (int i = 134; i < 160; i++)
  79.                 encodingTable.Add(((IConvertible)i).ToChar(NumberFormatInfo.InvariantInfo), "&#x" + i.ToString("X", CultureInfo.InvariantCulture) + ";");
  80.            
  81.         }
  82.        
  83.         private AttributeList attrList = new AttributeList();
  84.         private AttributeList attrValueList = new AttributeList();
  85.        
  86.         const int StringBuilderSize = 1024;
  87.        
  88.        
  89.         // used for emitting into the text stream
  90.         private int lineIndent = 4;
  91.         private int instanceIndent = 1;
  92.        
  93.         // used to escape strings. cache it as a member variable because its used frequently.
  94.         private StringBuilder stringBuffer = new StringBuilder(120);
  95.         private StringBuilder sb = new StringBuilder(120);
  96.        
  97.         private int topId;
  98.         private int headerId;
  99.        
  100.         //Assembly information
  101.         Hashtable assemblyInfos = new Hashtable(10);
  102.         StreamWriter writer;
  103.         Stream stream;
  104.        
  105.         // Support for combining assembly names with namespaces
  106.         Hashtable typeNameToDottedInfoTable = null;
  107.         Hashtable dottedAssemToAssemIdTable = null;
  108.         Hashtable assemblyInfoUsed = new Hashtable(10);
  109.         // for each xml element keeps track of unique types used
  110.         int dottedAssemId = 1;
  111.        
  112.         internal bool isUsedEnc = false;
  113.         XsdVersion xsdVersion = XsdVersion.V2001;
  114.        
  115.         internal struct DottedInfo
  116.         {
  117.             internal string dottedAssemblyName;
  118.             internal string name;
  119.             internal string nameSpace;
  120.             internal int assemId;
  121.         }
  122.        
  123.        
  124.         internal SoapWriter(Stream stream)
  125.         {
  126.             this.stream = stream;
  127.             UTF8Encoding enc = new UTF8Encoding(false, true);
  128.             this.writer = new StreamWriter(stream, enc, StringBuilderSize);
  129.             // Need to combine the type namespace with the assembly name for an element
  130.             typeNameToDottedInfoTable = new Hashtable(20);
  131.             dottedAssemToAssemIdTable = new Hashtable(20);
  132.         }
  133.        
  134.        
  135.         // Emit spaces for indentation
  136.        
  137.         [Conditional("_DEBUG")]
  138.         private void EmitIndent(int count)
  139.         {
  140.             while (--count >= 0) {
  141.                 for (int i = 0; i < lineIndent; i++) {
  142.                     TraceSoap(" ");
  143.                     writer.Write(' ');
  144.                 }
  145.             }
  146.         }
  147.        
  148.         // Emit a line
  149.         [Conditional("_DEBUG")]
  150.         private void EmitLine(int indent, string value)
  151.         {
  152.             InternalST.Soap(this, "EmitLine: ", value);
  153.             EmitIndent(indent);
  154.             writer.Write(value);
  155.             EmitLine();
  156.         }
  157.        
  158.         // Emit a blank line
  159.         private void EmitLine()
  160.         {
  161.             WriteTraceSoap();
  162.             writer.Write("\r\n");
  163.         }
  164.        
  165.         // Add xml escape characters to the string value, if necessary.
  166.        
  167.         private string Escape(string value)
  168.         {
  169.             stringBuffer.Length = 0;
  170.             foreach (char c in value) {
  171.                 if (encodingTable.ContainsKey(c))
  172.                     stringBuffer.Append(encodingTable[c]);
  173.                 else
  174.                     stringBuffer.Append(c);
  175.             }
  176.            
  177.             string returnValue = null;
  178.            
  179.             if (stringBuffer.Length > 0)
  180.                 returnValue = stringBuffer.ToString();
  181.             else
  182.                 returnValue = value;
  183.            
  184.             return returnValue;
  185.         }
  186.        
  187.        
  188.         // Add escape character for a $ and . in an element name
  189.        
  190.        
  191.         NameCache nameCache = new NameCache();
  192.         private string NameEscape(string name)
  193.         {
  194.             string value = (string)nameCache.GetCachedValue(name);
  195.             if (value == null) {
  196.                 value = System.Xml.XmlConvert.EncodeName(name);
  197.                 nameCache.SetCachedValue(value);
  198.             }
  199.             return value;
  200.         }
  201.        
  202.        
  203.         // Initial writer
  204.         internal void Reset()
  205.         {
  206.             writer = null;
  207.             stringBuffer = null;
  208.         }
  209.        
  210.         internal void InternalWrite(string s)
  211.         {
  212.             TraceSoap(s);
  213.             writer.Write(s);
  214.         }
  215.        
  216.         StringBuilder traceBuffer = null;
  217.         [Conditional("_LOGGING")]
  218.         internal void TraceSoap(string s)
  219.         {
  220.             if (traceBuffer == null)
  221.                 traceBuffer = new StringBuilder();
  222.             traceBuffer.Append(s);
  223.         }
  224.        
  225.         [Conditional("_LOGGING")]
  226.         internal void WriteTraceSoap()
  227.         {
  228.             InternalST.InfoSoap(traceBuffer.ToString());
  229.             traceBuffer.Length = 0;
  230.         }
  231.        
  232.         // Write an XML element
  233.         internal void Write(InternalElementTypeE use, string name, AttributeList attrList, string value, bool isNameEscape, bool isValueEscape)
  234.         {
  235.             InternalST.Soap(this, "Write ", ((Enum)use).ToString(), ", name " + name + ", value ", value, " isNameEscape ", isNameEscape, " isValueEscape ", isValueEscape);
  236.            
  237.             string elementName = name;
  238.             if (isNameEscape)
  239.                 elementName = NameEscape(name);
  240.            
  241.             if (use == InternalElementTypeE.ObjectEnd)
  242.                 instanceIndent--;
  243.            
  244.             EmitIndent(instanceIndent);
  245.            
  246.             InternalWrite("<");
  247.             if (use == InternalElementTypeE.ObjectEnd)
  248.                 InternalWrite("/");
  249.             InternalWrite(elementName);
  250.            
  251.             WriteAttributeList(attrList);
  252.            
  253.             switch (use) {
  254.                 case InternalElementTypeE.ObjectBegin:
  255.                     InternalWrite(">");
  256.                     instanceIndent++;
  257.                     break;
  258.                 case InternalElementTypeE.ObjectEnd:
  259.                     InternalWrite(">");
  260.                     break;
  261.                 case InternalElementTypeE.Member:
  262.                     if (value == null)
  263.                         InternalWrite("/>");
  264.                     else {
  265.                         InternalWrite(">");
  266.                         if (isValueEscape)
  267.                             InternalWrite(Escape(value));
  268.                         else
  269.                             InternalWrite(value);
  270.                         InternalWrite("</");
  271.                         InternalWrite(elementName);
  272.                         InternalWrite(">");
  273.                     }
  274.                     break;
  275.                 default:
  276.                     throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_UseCode"), ((Enum)use).ToString()));
  277.                     break;
  278.             }
  279.             EmitLine();
  280.         }
  281.        
  282.        
  283.         void WriteAttributeList(AttributeList attrList)
  284.         {
  285.             for (int i = 0; i < attrList.Count; i++) {
  286.                 string aName;
  287.                 string aValue;
  288.                 attrList.Get(i, out aName, out aValue);
  289.                 InternalWrite(" ");
  290.                 InternalWrite(aName);
  291.                 InternalWrite("=");
  292.                 InternalWrite("\"");
  293.                 //InternalWrite(Escape(aValue));
  294.                 InternalWrite(aValue);
  295.                 InternalWrite("\"");
  296.             }
  297.         }
  298.         // WriteAttributeList
  299.        
  300.         // Begin a new XML stream
  301.         internal void WriteBegin()
  302.         {
  303.             InternalST.InfoSoap("******************** Start Serialized Stream *****************");
  304.         }
  305.        
  306.         // Finish an XML stream
  307.         internal void WriteEnd()
  308.         {
  309.             writer.Flush();
  310.             InternalST.InfoSoap("******************** End Serialized Stream *******************");
  311.             Reset();
  312.         }
  313.        
  314.         internal void WriteXsdVersion(XsdVersion xsdVersion)
  315.         {
  316.             this.xsdVersion = xsdVersion;
  317.         }
  318.        
  319.         // Methods to write XML Serialization Record onto the stream,
  320.         internal void WriteObjectEnd(NameInfo memberNameInfo, NameInfo typeNameInfo)
  321.         {
  322.             //nameInfo.Dump("WriteObjectEnd nameInfo");
  323.            
  324.             attrList.Clear();
  325.             Write(InternalElementTypeE.ObjectEnd, MemberElementName(memberNameInfo, typeNameInfo), attrList, null, true, false);
  326.             assemblyInfoUsed.Clear();
  327.         }
  328.        
  329.         internal void WriteSerializationHeaderEnd()
  330.         {
  331.             attrList.Clear();
  332.             Write(InternalElementTypeE.ObjectEnd, "SOAP-ENV:Body", attrList, null, false, false);
  333.             Write(InternalElementTypeE.ObjectEnd, "SOAP-ENV:Envelope", attrList, null, false, false);
  334.             writer.Flush();
  335.         }
  336.        
  337.         internal void WriteHeaderArrayEnd()
  338.         {
  339.             //attrList.Clear();
  340.             //Write(InternalElementTypeE.ObjectEnd, "SOAP:HeaderRoots",attrList, null);
  341.         }
  342.        
  343.         internal void WriteHeaderSectionEnd()
  344.         {
  345.             attrList.Clear();
  346.             Write(InternalElementTypeE.ObjectEnd, "SOAP-ENV:Header", attrList, null, false, false);
  347.         }
  348.        
  349.        
  350.         internal void WriteSerializationHeader(int topId, int headerId, int minorVersion, int majorVersion)
  351.         {
  352.             InternalST.Soap(this, "WriteSerializationHeader");
  353.             this.topId = topId;
  354.             this.headerId = headerId;
  355.            
  356.             // write start of header directly to stream
  357.             switch (xsdVersion) {
  358.                 case XsdVersion.V1999:
  359.                     InternalST.InfoSoap(_soapStart1999Str, ">");
  360.                     stream.Write(_soapStart1999, 0, _soapStart1999.Length);
  361.                     break;
  362.                 case XsdVersion.V2000:
  363.                     InternalST.InfoSoap(_soapStart2000Str, ">");
  364.                     stream.Write(_soapStart1999, 0, _soapStart2000.Length);
  365.                     break;
  366.                 case XsdVersion.V2001:
  367.                     InternalST.InfoSoap(_soapStartStr, ">");
  368.                     stream.Write(_soapStart, 0, _soapStart.Length);
  369.                     break;
  370.             }
  371.             writer.Write(">\r\n");
  372.         }
  373.         // InternalWriteSerializationHeader
  374.        
  375.         internal void WriteObject(NameInfo nameInfo, NameInfo typeNameInfo, int numMembers, string[] memberNames, Type[] memberTypes, WriteObjectInfo[] objectInfos)
  376.         {
  377.             nameInfo.Dump("WriteObject nameInfo");
  378.             typeNameInfo.Dump("WriteObject typeNameInfo");
  379.            
  380.             int objectId = (int)nameInfo.NIobjectId;
  381.             attrList.Clear();
  382.             if (objectId == topId)
  383.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, null, false, false);
  384.            
  385.             // Only write the objectId in the top record if the header has been written or
  386.             if (objectId > 0)
  387.                 attrList.Put("id", IdToString((int)nameInfo.NIobjectId));
  388.             // Types when Object is embedded member and types needed
  389.             if (((nameInfo.NItransmitTypeOnObject || nameInfo.NItransmitTypeOnMember) && (nameInfo.NIisNestedObject || nameInfo.NIisArrayItem)))
  390.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  391.             if (nameInfo.NIisMustUnderstand) {
  392.                 attrList.Put("SOAP-ENV:mustUnderstand", "1");
  393.                 isUsedEnc = true;
  394.             }
  395.             if (nameInfo.NIisHeader) {
  396.                 attrList.Put("xmlns:" + nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  397.                 attrList.Put("SOAP-ENC:root", "1");
  398.             }
  399.            
  400.             if (attrValueList.Count > 0) {
  401.                 // Combine the values from the XmlAttributes with the object attributes
  402.                 for (int i = 0; i < attrValueList.Count; i++) {
  403.                     string aName;
  404.                     string aValue;
  405.                     attrValueList.Get(i, out aName, out aValue);
  406.                     attrList.Put(aName, aValue);
  407.                 }
  408.                 attrValueList.Clear();
  409.             }
  410.            
  411.             string memberName = MemberElementName(nameInfo, typeNameInfo);
  412.             NamespaceAttribute();
  413.             Write(InternalElementTypeE.ObjectBegin, memberName, attrList, null, true, false);
  414.         }
  415.        
  416.         internal void WriteAttributeValue(NameInfo memberNameInfo, NameInfo typeNameInfo, object value)
  417.         {
  418.             // Called when the XmlAttribute is specified on a member
  419.             InternalST.Soap(this, "WriteAttributeValues ", value);
  420.             string stringValue = null;
  421.             if (value is string)
  422.                 stringValue = (string)value;
  423.             else
  424.                 stringValue = Converter.SoapToString(value, typeNameInfo.NIprimitiveTypeEnum);
  425.             attrValueList.Put(MemberElementName(memberNameInfo, typeNameInfo), stringValue);
  426.         }
  427.        
  428.         internal void WriteObjectString(NameInfo nameInfo, string value)
  429.         {
  430.             InternalST.Soap(this, "WriteObjectString value ", value);
  431.             nameInfo.Dump("WriteObjectString nameInfo");
  432.             attrList.Clear();
  433.             if (nameInfo.NIobjectId == topId)
  434.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, null, false, false);
  435.            
  436.            
  437.             if (nameInfo.NIobjectId > 0) {
  438.                 attrList.Put("id", IdToString((int)nameInfo.NIobjectId));
  439.             }
  440.            
  441.             string stringType = null;
  442.             if (nameInfo.NIobjectId > 0) {
  443.                 stringType = "SOAP-ENC:string";
  444.                 isUsedEnc = true;
  445.             }
  446.             else
  447.                 stringType = "xsd:string";
  448.            
  449.             Write(InternalElementTypeE.Member, stringType, attrList, value, false, Converter.IsEscaped(nameInfo.NIprimitiveTypeEnum));
  450.         }
  451.        
  452.         internal void WriteTopPrimitive(NameInfo nameInfo, object value)
  453.         {
  454.             nameInfo.Dump("WriteMember memberNameInfo");
  455.            
  456.             attrList.Clear();
  457.            
  458.             Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, null, false, false);
  459.            
  460.             if (nameInfo.NIobjectId > 0) {
  461.                 attrList.Put("id", IdToString((int)nameInfo.NIobjectId));
  462.             }
  463.            
  464.             string stringValue = null;
  465.             if (value is string)
  466.                 stringValue = (string)value;
  467.             else
  468.                 stringValue = Converter.SoapToString(value, nameInfo.NIprimitiveTypeEnum);
  469.            
  470.             Write(InternalElementTypeE.Member, "xsd:" + (Converter.ToXmlDataType(nameInfo.NIprimitiveTypeEnum)), attrList, stringValue, true, false);
  471.         }
  472.        
  473.        
  474.        
  475.         internal void WriteObjectByteArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, byte[] byteA)
  476.         {
  477.             memberNameInfo.Dump("WriteObjectByteArray memberNameInfo");
  478.             arrayNameInfo.Dump("WriteObjectByteArray arrayNameInfo");
  479.             arrayElemTypeNameInfo.Dump("WriteObjectByteArray arrayElemTypeNameInfo");
  480.            
  481.             string byteString = Convert.ToBase64String(byteA);
  482.             attrList.Clear();
  483.             if (memberNameInfo.NIobjectId == topId)
  484.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, null, false, false);
  485.             if (arrayNameInfo.NIobjectId > 1)
  486.                 attrList.Put("id", IdToString((int)arrayNameInfo.NIobjectId));
  487.             attrList.Put("xsi:type", "SOAP-ENC:base64");
  488.             isUsedEnc = true;
  489.             string memberName = MemberElementName(memberNameInfo, null);
  490.             NamespaceAttribute();
  491.             Write(InternalElementTypeE.Member, memberName, attrList, byteString, true, false);
  492.         }
  493.        
  494.        
  495.         internal void WriteMember(NameInfo memberNameInfo, NameInfo typeNameInfo, object value)
  496.         {
  497.             memberNameInfo.Dump("WriteMember memberNameInfo");
  498.             typeNameInfo.Dump("WriteMember typeNameInfo");
  499.            
  500.             attrList.Clear();
  501.             if ((typeNameInfo.NItype != null) && (memberNameInfo.NItransmitTypeOnMember || (memberNameInfo.NItransmitTypeOnObject && !memberNameInfo.NIisArrayItem))) {
  502.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  503.             }
  504.            
  505.             string stringValue = null;
  506.             if (value != null) {
  507.                 if (typeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.QName) {
  508.                     SoapQName soapQName = (SoapQName)value;
  509.                     if (soapQName.Key == null || soapQName.Key.Length == 0)
  510.                         attrList.Put("xmlns", "");
  511.                     else
  512.                         attrList.Put("xmlns:" + soapQName.Key, soapQName.Namespace);
  513.                    
  514.                     stringValue = soapQName.ToString();
  515.                 }
  516.                 else {
  517.                    
  518.                     if (value is string)
  519.                         stringValue = (string)value;
  520.                     else
  521.                         stringValue = Converter.SoapToString(value, typeNameInfo.NIprimitiveTypeEnum);
  522.                 }
  523.             }
  524.            
  525.             NameInfo tempNameInfo = null;
  526.            
  527.             // If XmlElement attribute was defined on member, then an alternate member name has been specifed
  528.             if (typeNameInfo.NInameSpaceEnum == InternalNameSpaceE.Interop)
  529.                 tempNameInfo = typeNameInfo;
  530.            
  531.             string memberName = MemberElementName(memberNameInfo, tempNameInfo);
  532.             NamespaceAttribute();
  533.             Write(InternalElementTypeE.Member, memberName, attrList, stringValue, true, Converter.IsEscaped(typeNameInfo.NIprimitiveTypeEnum));
  534.         }
  535.        
  536.        
  537.         //internal void WriteNullMember(String memberName, Type memberType, Boolean isTyped, Type objType)
  538.         internal void WriteNullMember(NameInfo memberNameInfo, NameInfo typeNameInfo)
  539.         {
  540.             memberNameInfo.Dump("WriteNullMember memberNameInfo");
  541.             typeNameInfo.Dump("WriteNullMember typeNameInfo");
  542.            
  543.             attrList.Clear();
  544.             if ((typeNameInfo.NItype != null) && (memberNameInfo.NItransmitTypeOnMember || (memberNameInfo.NItransmitTypeOnObject && !memberNameInfo.NIisArrayItem))) {
  545.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  546.             }
  547.             attrList.Put("xsi:null", "1");
  548.            
  549.             /*
  550. NameInfo tempNameInfo = null;
  551. // If XmlElement attribute was defined on member, then an alternate member name has been specifed
  552. if (typeNameInfo.NInameSpaceEnum == InternalNameSpaceE.Interop)
  553. tempNameInfo = typeNameInfo;
  554.                 */           
  555.            
  556. string memberName = MemberElementName(memberNameInfo, null);
  557.             NamespaceAttribute();
  558.             Write(InternalElementTypeE.Member, memberName, attrList, null, true, false);
  559.         }
  560.        
  561.        
  562.         internal void WriteMemberObjectRef(NameInfo memberNameInfo, NameInfo typeNameInfo, int idRef)
  563.         {
  564.             memberNameInfo.Dump("WriteMemberObjectRef memberNameInfo");
  565.             attrList.Clear();
  566.             attrList.Put("href", RefToString(idRef));
  567.             NameInfo tempNameInfo = null;
  568.            
  569.             // If XmlElement attribute was defined on member, then an alternate member name has been specifed
  570.             if (typeNameInfo.NInameSpaceEnum == InternalNameSpaceE.Interop)
  571.                 tempNameInfo = typeNameInfo;
  572.             string memberName = MemberElementName(memberNameInfo, tempNameInfo);
  573.             NamespaceAttribute();
  574.             Write(InternalElementTypeE.Member, memberName, attrList, null, true, false);
  575.         }
  576.        
  577.         internal void WriteMemberNested(NameInfo memberNameInfo)
  578.         {
  579.            
  580.         }
  581.        
  582.         //internal void WriteMemberString(String memberName, int objectId, String value, Boolean isTyped, Type objType)
  583.         internal void WriteMemberString(NameInfo memberNameInfo, NameInfo typeNameInfo, string value)
  584.         {
  585.             memberNameInfo.Dump("WriteMemberString memberNameInfo");
  586.             typeNameInfo.Dump("WriteMemberString typeNameInfo");
  587.            
  588.             InternalST.Soap(this, "WriteMemberString memberName ", memberNameInfo.NIname, " objectId ", typeNameInfo.NIobjectId, " value ", value);
  589.             int objectId = (int)typeNameInfo.NIobjectId;
  590.             attrList.Clear();
  591.             if (objectId > 0)
  592.                 attrList.Put("id", IdToString((int)typeNameInfo.NIobjectId));
  593.             if ((typeNameInfo.NItype != null) && (memberNameInfo.NItransmitTypeOnMember || (memberNameInfo.NItransmitTypeOnObject && !memberNameInfo.NIisArrayItem))) {
  594.                 if (typeNameInfo.NIobjectId > 0) {
  595.                     attrList.Put("xsi:type", "SOAP-ENC:string");
  596.                     isUsedEnc = true;
  597.                 }
  598.                 else
  599.                     attrList.Put("xsi:type", "xsd:string");
  600.             }
  601.            
  602.             NameInfo tempNameInfo = null;
  603.            
  604.             // If XmlElement attribute was defined on member, then an alternate member name has been specifed
  605.             if (typeNameInfo.NInameSpaceEnum == InternalNameSpaceE.Interop)
  606.                 tempNameInfo = typeNameInfo;
  607.            
  608.             string memberName = MemberElementName(memberNameInfo, tempNameInfo);
  609.             NamespaceAttribute();
  610.             Write(InternalElementTypeE.Member, memberName, attrList, value, true, Converter.IsEscaped(typeNameInfo.NIprimitiveTypeEnum));
  611.         }
  612.        
  613.         internal void WriteSingleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, Array array)
  614.         {
  615.             memberNameInfo.Dump("WriteSingleArray memberNameInfo");
  616.             arrayNameInfo.Dump("WriteSingleArray arrayNameInfo");
  617.             arrayElemTypeNameInfo.Dump("WriteSingleArray arrayElemTypeNameInfo");
  618.            
  619.             attrList.Clear();
  620.             if (memberNameInfo.NIobjectId == topId)
  621.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, null, false, false);
  622.             if (arrayNameInfo.NIobjectId > 1)
  623.                 attrList.Put("id", IdToString((int)arrayNameInfo.NIobjectId));
  624.             arrayElemTypeNameInfo.NIitemName = NameTagResolver(arrayElemTypeNameInfo, true);
  625.             attrList.Put("SOAP-ENC:arrayType", NameTagResolver(arrayNameInfo, true, memberNameInfo.NIname));
  626.             isUsedEnc = true;
  627.             if (lowerBound != 0)
  628.                 attrList.Put("SOAP-ENC:offset", "[" + lowerBound + "]");
  629.             string memberName = MemberElementName(memberNameInfo, null);
  630.             NamespaceAttribute();
  631.             Write(InternalElementTypeE.ObjectBegin, memberName, attrList, null, false, false);
  632.         }
  633.        
  634.         internal void WriteJaggedArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound)
  635.         {
  636.             memberNameInfo.Dump("WriteJaggedArray memberNameInfo");
  637.             arrayNameInfo.Dump("WriteJaggedArray arrayNameInfo");
  638.             arrayElemTypeNameInfo.Dump("WriteJaggedArray arrayElemTypeNameInfo");
  639.            
  640.             attrList.Clear();
  641.             if (memberNameInfo.NIobjectId == topId)
  642.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, null, false, false);
  643.             if (arrayNameInfo.NIobjectId > 1)
  644.                 attrList.Put("id", IdToString((int)arrayNameInfo.NIobjectId));
  645.             arrayElemTypeNameInfo.NIitemName = "SOAP-ENC:Array";
  646.             isUsedEnc = true;
  647.             attrList.Put("SOAP-ENC:arrayType", TypeArrayNameTagResolver(memberNameInfo, arrayNameInfo, true));
  648.             if (lowerBound != 0)
  649.                 attrList.Put("SOAP-ENC:offset", "[" + lowerBound + "]");
  650.             string memberName = MemberElementName(memberNameInfo, null);
  651.             NamespaceAttribute();
  652.             Write(InternalElementTypeE.ObjectBegin, memberName, attrList, null, false, false);
  653.         }
  654.        
  655.        
  656.         private StringBuilder sbOffset = new StringBuilder(10);
  657.        
  658.         internal void WriteRectangleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int rank, int[] lengthA, int[] lowerBoundA)
  659.         {
  660.             memberNameInfo.Dump("WriteRectangleArray memberNameInfo");
  661.             arrayNameInfo.Dump("WriteRectangleArray arrayNameInfo");
  662.             arrayElemTypeNameInfo.Dump("WriteRectangleArray arrayElemTypeNameInfo");
  663.            
  664.             sbOffset.Length = 0;
  665.             sbOffset.Append("[");
  666.             bool isZero = true;
  667.             for (int i = 0; i < rank; i++) {
  668.                 if (lowerBoundA[i] != 0)
  669.                     isZero = false;
  670.                 if (i > 0)
  671.                     sbOffset.Append(",");
  672.                 sbOffset.Append(lowerBoundA[i]);
  673.             }
  674.             sbOffset.Append("]");
  675.            
  676.             attrList.Clear();
  677.             if (memberNameInfo.NIobjectId == topId)
  678.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, null, false, false);
  679.             if (arrayNameInfo.NIobjectId > 1)
  680.                 attrList.Put("id", IdToString((int)arrayNameInfo.NIobjectId));
  681.             arrayElemTypeNameInfo.NIitemName = NameTagResolver(arrayElemTypeNameInfo, true);
  682.             attrList.Put("SOAP-ENC:arrayType", TypeArrayNameTagResolver(memberNameInfo, arrayNameInfo, true));
  683.             isUsedEnc = true;
  684.             if (!isZero)
  685.                 attrList.Put("SOAP-ENC:offset", sbOffset.ToString());
  686.             string memberName = MemberElementName(memberNameInfo, null);
  687.             NamespaceAttribute();
  688.             Write(InternalElementTypeE.ObjectBegin, memberName, attrList, null, false, false);
  689.         }
  690.        
  691.         //internal void WriteItem(Variant value, InternalPrimitiveTypeE code, Boolean isTyped, Type objType)
  692.         internal void WriteItem(NameInfo itemNameInfo, NameInfo typeNameInfo, object value)
  693.         {
  694.             itemNameInfo.Dump("WriteItem itemNameInfo");
  695.             typeNameInfo.Dump("WriteItem typeNameInfo");
  696.            
  697.             attrList.Clear();
  698.             if (itemNameInfo.NItransmitTypeOnMember) {
  699.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  700.             }
  701.            
  702.             string stringValue = null;
  703.            
  704.             if (typeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.QName) {
  705.                 if (value != null) {
  706.                     SoapQName soapQName = (SoapQName)value;
  707.                     if (soapQName.Key == null || soapQName.Key.Length == 0)
  708.                         attrList.Put("xmlns", "");
  709.                     else
  710.                         attrList.Put("xmlns:" + soapQName.Key, soapQName.Namespace);
  711.                    
  712.                     stringValue = soapQName.ToString();
  713.                 }
  714.             }
  715.             else
  716.                 stringValue = Converter.SoapToString(value, typeNameInfo.NIprimitiveTypeEnum);
  717.            
  718.            
  719.             NamespaceAttribute();
  720.             Write(InternalElementTypeE.Member, "item", attrList, stringValue, false, (typeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.Invalid));
  721.         }
  722.        
  723.         internal void WriteNullItem(NameInfo memberNameInfo, NameInfo typeNameInfo)
  724.         {
  725.             memberNameInfo.Dump("WriteNullItem memberNameInfo");
  726.             typeNameInfo.Dump("WriteNullItem typeNameInfo");
  727.            
  728.             string typeName = typeNameInfo.NIname;
  729.             attrList.Clear();
  730.             if (typeNameInfo.NItransmitTypeOnMember && !((typeName.Equals("System.Object")) || (typeName.Equals("Object")) || (typeName.Equals("System.Empty") || (typeName.Equals("ur-type")) || (typeName.Equals("anyType")))))
  731.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  732.            
  733.             attrList.Put("xsi:null", "1");
  734.             NamespaceAttribute();
  735.             Write(InternalElementTypeE.Member, "item", attrList, null, false, false);
  736.         }
  737.        
  738.        
  739.         //internal void WriteItemObjectRef(int idRef)
  740.         internal void WriteItemObjectRef(NameInfo itemNameInfo, int arrayId)
  741.         {
  742.             itemNameInfo.Dump("WriteItemObjectRef itemNameInfo");
  743.             attrList.Clear();
  744.             attrList.Put("href", RefToString(arrayId));
  745.             Write(InternalElementTypeE.Member, "item", attrList, null, false, false);
  746.         }
  747.        
  748.         // Type of string or primitive type which has already been converted to string
  749.         internal void WriteItemString(NameInfo itemNameInfo, NameInfo typeNameInfo, string value)
  750.         {
  751.             itemNameInfo.Dump("WriteItemString itemNameInfo");
  752.             typeNameInfo.Dump("WriteItemString typeNameInfo");
  753.            
  754.             attrList.Clear();
  755.            
  756.             if (typeNameInfo.NIobjectId > 0) {
  757.                 attrList.Put("id", IdToString((int)typeNameInfo.NIobjectId));
  758.             }
  759.             if (itemNameInfo.NItransmitTypeOnMember) {
  760.                 if (typeNameInfo.NItype == SoapUtil.typeofString) {
  761.                     if (typeNameInfo.NIobjectId > 0) {
  762.                         attrList.Put("xsi:type", "SOAP-ENC:string");
  763.                         isUsedEnc = true;
  764.                     }
  765.                     else
  766.                         attrList.Put("xsi:type", "xsd:string");
  767.                 }
  768.                 else
  769.                     attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  770.             }
  771.            
  772.             NamespaceAttribute();
  773.             Write(InternalElementTypeE.Member, "item", attrList, value, false, Converter.IsEscaped(typeNameInfo.NIprimitiveTypeEnum));
  774.         }
  775.        
  776.         internal void WriteHeader(int objectId, int numMembers)
  777.         {
  778.             attrList.Clear();
  779.             Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Header", attrList, null, false, false);
  780.             //Write(InternalElementTypeE.ObjectBegin, "SOAP:HeaderRoots",attrList, null);
  781.         }
  782.        
  783.        
  784.         //internal void WriteHeaderEntry(String name, Boolean isMustUnderstand, InternalPrimitiveTypeE code, Variant value)
  785.         internal void WriteHeaderEntry(NameInfo nameInfo, NameInfo typeNameInfo, object value)
  786.         {
  787.             nameInfo.Dump("WriteHeaderEntry nameInfo");
  788.             if (typeNameInfo != null) {
  789.                 typeNameInfo.Dump("WriteHeaderEntry typeNameInfo");
  790.             }
  791.            
  792.             attrList.Clear();
  793.             if (value == null)
  794.                 attrList.Put("xsi:null", "1");
  795.             else
  796.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  797.             if (nameInfo.NIisMustUnderstand) {
  798.                 attrList.Put("SOAP-ENV:mustUnderstand", "1");
  799.                 isUsedEnc = true;
  800.             }
  801.            
  802.             attrList.Put("xmlns:" + nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  803.             attrList.Put("SOAP-ENC:root", "1");
  804.             string stringValue = null;
  805.            
  806.             if (value != null) {
  807.                 if (typeNameInfo != null && typeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.QName) {
  808.                     SoapQName soapQName = (SoapQName)value;
  809.                     if (soapQName.Key == null || soapQName.Key.Length == 0)
  810.                         attrList.Put("xmlns", "");
  811.                     else
  812.                         attrList.Put("xmlns:" + soapQName.Key, soapQName.Namespace);
  813.                    
  814.                     stringValue = soapQName.ToString();
  815.                 }
  816.                 else
  817.                     stringValue = Converter.SoapToString(value, typeNameInfo.NIprimitiveTypeEnum);
  818.             }
  819.            
  820.             NamespaceAttribute();
  821.             Write(InternalElementTypeE.Member, nameInfo.NIheaderPrefix + ":" + nameInfo.NIname, attrList, stringValue, true, true);
  822.         }
  823.        
  824.         //internal void WriteHeaderObjectRef(String name, Boolean isMustUnderstand, int idRef)
  825.         internal void WriteHeaderObjectRef(NameInfo nameInfo)
  826.         {
  827.             nameInfo.Dump("WriteHeaderObjectRef nameInfo");
  828.            
  829.             attrList.Clear();
  830.             attrList.Put("href", RefToString((int)nameInfo.NIobjectId));
  831.             if (nameInfo.NIisMustUnderstand) {
  832.                 attrList.Put("SOAP-ENV:mustUnderstand", "1");
  833.                 isUsedEnc = true;
  834.             }
  835.             attrList.Put("xmlns:" + nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  836.             attrList.Put("SOAP-ENC:root", "1");
  837.             Write(InternalElementTypeE.Member, nameInfo.NIheaderPrefix + ":" + nameInfo.NIname, attrList, null, true, true);
  838.         }
  839.        
  840.         //internal void WriteHeaderString(String name, Boolean isMustUnderstand, int objectId, String value)
  841.         internal void WriteHeaderString(NameInfo nameInfo, string value)
  842.         {
  843.             nameInfo.Dump("WriteHeaderString nameInfo");
  844.            
  845.             attrList.Clear();
  846.             attrList.Put("xsi:type", "SOAP-ENC:string");
  847.             isUsedEnc = true;
  848.             if (nameInfo.NIisMustUnderstand)
  849.                 attrList.Put("SOAP-ENV:mustUnderstand", "1");
  850.             attrList.Put("xmlns:" + nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  851.             attrList.Put("SOAP-ENC:root", "1");
  852.             Write(InternalElementTypeE.Member, nameInfo.NIheaderPrefix + ":" + nameInfo.NIname, attrList, value, true, true);
  853.         }
  854.        
  855.         internal void WriteHeaderMethodSignature(NameInfo nameInfo, NameInfo[] typeNameInfos)
  856.         {
  857.             nameInfo.Dump("WriteHeaderString nameInfo");
  858.             attrList.Clear();
  859.             attrList.Put("xsi:type", "SOAP-ENC:methodSignature");
  860.             isUsedEnc = true;
  861.             if (nameInfo.NIisMustUnderstand)
  862.                 attrList.Put("SOAP-ENV:mustUnderstand", "1");
  863.             attrList.Put("xmlns:" + nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  864.             attrList.Put("SOAP-ENC:root", "1");
  865.            
  866.             StringBuilder sb = new StringBuilder();
  867.            
  868.             // The signature string is an sequence of prefixed types, where the prefix is the key to the namespace.
  869.             for (int i = 0; i < typeNameInfos.Length; i++) {
  870.                 if (i > 0)
  871.                     sb.Append(' ');
  872.                 sb.Append(NameTagResolver(typeNameInfos[i], true));
  873.             }
  874.            
  875.             NamespaceAttribute();
  876.             Write(InternalElementTypeE.Member, nameInfo.NIheaderPrefix + ":" + nameInfo.NIname, attrList, sb.ToString(), true, true);
  877.         }
  878.        
  879.         internal void WriteAssembly(string typeFullName, Type type, string assemName, int assemId, bool isNew, bool isInteropType)
  880.         {
  881.             InternalST.Soap(this, "WriteAssembly ", typeFullName, " ", type, " ", assemId, " ", assemName, " isNew ",
  882.             isNew, " isInteropType ", isInteropType);
  883.             if (isNew) {
  884.                 InternalST.Soap(this, "WriteAssembly new Assembly ");
  885.                 if (isInteropType) {
  886.                     // Interop type
  887.                     assemblyInfos[InteropAssemIdToString(assemId)] = new AssemblyInfo(assemId, assemName, isInteropType);
  888.                 }
  889.             }
  890.            
  891.             if (!isInteropType) {
  892.                 // assembly name and dotted namespaces are combined
  893.                 ParseAssemblyName(typeFullName, assemName);
  894.             }
  895.         }
  896.        
  897.         private DottedInfo ParseAssemblyName(string typeFullName, string assemName)
  898.         {
  899.             InternalST.Soap(this, "ParseAssemblyName Entry typeFullName ", typeFullName, " assemName ", assemName);
  900.             DottedInfo dottedInfo;
  901.             string nameSpace = null;
  902.             string name = null;
  903.             string dottedAssemblyName = null;
  904.             int assemId;
  905.             if (typeNameToDottedInfoTable.ContainsKey(typeFullName)) {
  906.                 // type name already seen
  907.                 dottedInfo = (DottedInfo)typeNameToDottedInfoTable[typeFullName];
  908.             }
  909.             else {
  910.                 // type name new, find nameSpace and concatenate the assembly name to it.
  911.                 int index = typeFullName.LastIndexOf('.');
  912.                 if (index > 0)
  913.                     nameSpace = typeFullName.Substring(0, index);
  914.                 else
  915.                     nameSpace = "";
  916.                
  917.                
  918.                 dottedAssemblyName = SoapServices.CodeXmlNamespaceForClrTypeNamespace(nameSpace, assemName);
  919.                
  920.                 name = typeFullName.Substring(index + 1);
  921.                
  922.                 if (dottedAssemToAssemIdTable.ContainsKey(dottedAssemblyName)) {
  923.                     // The dotted assembly name has been seen before, get the assembly Id
  924.                     assemId = (int)dottedAssemToAssemIdTable[dottedAssemblyName];
  925.                 }
  926.                 else {
  927.                     // The dotted assembly name has not been seen before, calculate a new
  928.                     // assemId and remember it so that it can be added to the Envelope xml namespaces
  929.                     assemId = dottedAssemId++;
  930.                     assemblyInfos[AssemIdToString(assemId)] = new AssemblyInfo(assemId, dottedAssemblyName, false);
  931.                     dottedAssemToAssemIdTable[dottedAssemblyName] = assemId;
  932.                 }
  933.                
  934.                 // Create a new DottedInfo structure and remember it with the type name
  935.                 dottedInfo = new DottedInfo();
  936.                 dottedInfo.dottedAssemblyName = dottedAssemblyName;
  937.                 dottedInfo.name = name;
  938.                 dottedInfo.nameSpace = nameSpace;
  939.                 dottedInfo.assemId = assemId;
  940.                 typeNameToDottedInfoTable[typeFullName] = dottedInfo;
  941.                 InternalST.Soap(this, "ParseAssemblyName new dotted Assembly name ", dottedInfo.name, ", dottedAssemblyName ", dottedInfo.dottedAssemblyName, ", assemId ", dottedInfo.assemId, " typeFullName ", typeFullName);
  942.             }
  943.             InternalST.Soap(this, "ParseAssemblyName Exit nameSpace ", dottedInfo.nameSpace, " name ", dottedInfo.name, " assemblyName ", dottedInfo.dottedAssemblyName, " assemId ", dottedInfo.assemId);
  944.             return dottedInfo;
  945.         }
  946.        
  947.         StringBuilder sb1 = new StringBuilder("ref-", 15);
  948.         private string IdToString(int objectId)
  949.         {
  950.             sb1.Length = 4;
  951.             sb1.Append(objectId);
  952.             return sb1.ToString();
  953.         }
  954.        
  955.         StringBuilder sb2 = new StringBuilder("a-", 15);
  956.         private string AssemIdToString(int assemId)
  957.         {
  958.             sb2.Length = 1;
  959.             sb2.Append(assemId);
  960.             return sb2.ToString();
  961.         }
  962.        
  963.         StringBuilder sb3 = new StringBuilder("i-", 15);
  964.         private string InteropAssemIdToString(int assemId)
  965.         {
  966.             sb3.Length = 1;
  967.             sb3.Append(assemId);
  968.             return sb3.ToString();
  969.         }
  970.        
  971.         StringBuilder sb4 = new StringBuilder("#ref-", 16);
  972.         private string RefToString(int objectId)
  973.         {
  974.             sb4.Length = 5;
  975.             sb4.Append(objectId);
  976.             return sb4.ToString();
  977.         }
  978.        
  979.         private string MemberElementName(NameInfo memberNameInfo, NameInfo typeNameInfo)
  980.         {
  981.             string memberName = memberNameInfo.NIname;
  982.            
  983.             if (memberNameInfo.NIisHeader) {
  984.                 memberName = memberNameInfo.NIheaderPrefix + ":" + memberNameInfo.NIname;
  985.             }
  986.             else if ((typeNameInfo != null) && (typeNameInfo.NItype == SoapUtil.typeofSoapFault)) {
  987.                 memberName = "SOAP-ENV:Fault";
  988.             }
  989.             else if (memberNameInfo.NIisArray && !memberNameInfo.NIisNestedObject) {
  990.                 memberName = "SOAP-ENC:Array";
  991.                 isUsedEnc = true;
  992.             }
  993.             //else if (memberNameInfo.NItype == SoapUtil.typeofObject)
  994.             //memberName = "SOAP:Object";
  995.             else if (memberNameInfo.NIisArrayItem) {
  996.                 //memberName = memberNameInfo.NIitemName; // occurs for a nested class in an array
  997.                 memberName = "item";
  998.             }
  999.             else if (memberNameInfo.NIisNestedObject) {
  1000.             }
  1001.             // Parameters
  1002.             else if (memberNameInfo.NIisRemoteRecord && !memberNameInfo.NIisTopLevelObject) {
  1003.             }
  1004.             else if (typeNameInfo != null) {
  1005.                 memberName = NameTagResolver(typeNameInfo, true);
  1006.             }
  1007.             return memberName;
  1008.         }
  1009.        
  1010.         private string TypeNameTagResolver(NameInfo typeNameInfo, bool isXsiAppended)
  1011.         {
  1012.             string name = null;
  1013.             if ((typeNameInfo.NIassemId > 0) && (typeNameInfo.NIattributeInfo != null) && (typeNameInfo.NIattributeInfo.AttributeTypeName != null)) {
  1014.                 string assemIdString = InteropAssemIdToString((int)typeNameInfo.NIassemId);
  1015.                 name = assemIdString + ":" + typeNameInfo.NIattributeInfo.AttributeTypeName;
  1016.                 AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1017.                 assemblyInfo.isUsed = true;
  1018.                 assemblyInfo.prefix = assemIdString;
  1019.                 assemblyInfoUsed[assemblyInfo] = 1;
  1020.             }
  1021.             else
  1022.                 name = NameTagResolver(typeNameInfo, isXsiAppended);
  1023.            
  1024.             return name;
  1025.         }
  1026.        
  1027.         private string NameTagResolver(NameInfo typeNameInfo, bool isXsiAppended)
  1028.         {
  1029.             return NameTagResolver(typeNameInfo, isXsiAppended, null);
  1030.         }
  1031.        
  1032.         private string NameTagResolver(NameInfo typeNameInfo, bool isXsiAppended, string arrayItemName)
  1033.         {
  1034.             string name = typeNameInfo.NIname;
  1035.             switch (typeNameInfo.NInameSpaceEnum) {
  1036.                 case InternalNameSpaceE.Soap:
  1037.                     name = "SOAP-ENC:" + typeNameInfo.NIname;
  1038.                     isUsedEnc = true;
  1039.                     break;
  1040.                 case InternalNameSpaceE.XdrPrimitive:
  1041.                     if (isXsiAppended)
  1042.                         name = "xsd:" + typeNameInfo.NIname;
  1043.                     break;
  1044.                 case InternalNameSpaceE.XdrString:
  1045.                     if (isXsiAppended)
  1046.                         name = "xsd:" + typeNameInfo.NIname;
  1047.                     break;
  1048.                 case InternalNameSpaceE.UrtSystem:
  1049.                     if (typeNameInfo.NItype == SoapUtil.typeofObject)
  1050.                         name = "xsd:anyType";
  1051.                     else if (arrayItemName == null) {
  1052.                         // need to generate dotted name spaces
  1053.                         DottedInfo dottedInfo;
  1054.                         if (typeNameToDottedInfoTable.ContainsKey(typeNameInfo.NIname))
  1055.                             dottedInfo = (DottedInfo)typeNameToDottedInfoTable[typeNameInfo.NIname];
  1056.                         else {
  1057.                             dottedInfo = ParseAssemblyName(typeNameInfo.NIname, null);
  1058.                         }
  1059.                         string assemIdString = AssemIdToString(dottedInfo.assemId);
  1060.                         name = assemIdString + ":" + dottedInfo.name;
  1061.                         AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1062.                         assemblyInfo.isUsed = true;
  1063.                         assemblyInfo.prefix = assemIdString;
  1064.                         assemblyInfoUsed[assemblyInfo] = 1;
  1065.                     }
  1066.                     else {
  1067.                         // need to generate dotted name spaces
  1068.                         DottedInfo dottedInfo;
  1069.                         if (typeNameToDottedInfoTable.ContainsKey(arrayItemName))
  1070.                             dottedInfo = (DottedInfo)typeNameToDottedInfoTable[arrayItemName];
  1071.                         else {
  1072.                             dottedInfo = ParseAssemblyName(arrayItemName, null);
  1073.                         }
  1074.                         string assemIdString = AssemIdToString(dottedInfo.assemId);
  1075.                         name = assemIdString + ":" + DottedDimensionName(dottedInfo.name, typeNameInfo.NIname);
  1076.                         AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1077.                         assemblyInfo.isUsed = true;
  1078.                         assemblyInfo.prefix = assemIdString;
  1079.                         assemblyInfoUsed[assemblyInfo] = 1;
  1080.                     }
  1081.                     break;
  1082.                 case InternalNameSpaceE.UrtUser:
  1083.                     if (typeNameInfo.NIassemId > 0) {
  1084.                         if (arrayItemName == null) {
  1085.                             DottedInfo dottedInfo;
  1086.                             InternalST.Soap(this, "NameTagResolver typeNameInfo.NIname ", typeNameInfo.NIname, " table ", typeNameToDottedInfoTable.ContainsKey(typeNameInfo.NIname));
  1087.                             SoapUtil.DumpHash("typeNameToDottedInfoTable", typeNameToDottedInfoTable);
  1088.                             if (typeNameToDottedInfoTable.ContainsKey(typeNameInfo.NIname))
  1089.                                 dottedInfo = (DottedInfo)typeNameToDottedInfoTable[typeNameInfo.NIname];
  1090.                             else
  1091.                                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_Assembly"), typeNameInfo.NIname));
  1092.                            
  1093.                             string assemIdString = AssemIdToString(dottedInfo.assemId);
  1094.                             name = assemIdString + ":" + dottedInfo.name;
  1095.                             AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1096.                             assemblyInfo.isUsed = true;
  1097.                             assemblyInfo.prefix = assemIdString;
  1098.                             assemblyInfoUsed[assemblyInfo] = 1;
  1099.                         }
  1100.                         else {
  1101.                             DottedInfo dottedInfo;
  1102.                             if (typeNameToDottedInfoTable.ContainsKey(arrayItemName))
  1103.                                 dottedInfo = (DottedInfo)typeNameToDottedInfoTable[arrayItemName];
  1104.                             else
  1105.                                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_Assembly"), typeNameInfo.NIname));
  1106.                            
  1107.                             string assemIdString = AssemIdToString(dottedInfo.assemId);
  1108.                             name = assemIdString + ":" + DottedDimensionName(dottedInfo.name, typeNameInfo.NIname);
  1109.                             AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1110.                             assemblyInfo.isUsed = true;
  1111.                             assemblyInfo.prefix = assemIdString;
  1112.                             assemblyInfoUsed[assemblyInfo] = 1;
  1113.                         }
  1114.                     }
  1115.                     break;
  1116.                 case InternalNameSpaceE.CallElement:
  1117.                     if (typeNameInfo.NIassemId > 0) {
  1118.                         string key = InteropAssemIdToString((int)typeNameInfo.NIassemId);
  1119.                         AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[key];
  1120.                         if (assemblyInfo == null)
  1121.                             throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_NameSpaceEnum"), typeNameInfo.NInameSpaceEnum));
  1122.                         name = key + ":" + typeNameInfo.NIname;
  1123.                         assemblyInfo.isUsed = true;
  1124.                         //PDJ check this against checked in code
  1125.                         assemblyInfo.prefix = key;
  1126.                         assemblyInfoUsed[assemblyInfo] = 1;
  1127.                     }
  1128.                     break;
  1129.                 case InternalNameSpaceE.Interop:
  1130.                    
  1131.                     {
  1132.                         if ((typeNameInfo.NIattributeInfo != null) && (typeNameInfo.NIattributeInfo.AttributeElementName != null)) {
  1133.                             if (typeNameInfo.NIassemId > 0) {
  1134.                                 string assemIdString = InteropAssemIdToString((int)typeNameInfo.NIassemId);
  1135.                                 name = assemIdString + ":" + typeNameInfo.NIattributeInfo.AttributeElementName;
  1136.                                 if (arrayItemName != null) {
  1137.                                     int index = typeNameInfo.NIname.IndexOf("[");
  1138.                                     name = name + typeNameInfo.NIname.Substring(index);
  1139.                                 }
  1140.                                 AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1141.                                 assemblyInfo.isUsed = true;
  1142.                                 assemblyInfo.prefix = assemIdString;
  1143.                                 assemblyInfoUsed[assemblyInfo] = 1;
  1144.                             }
  1145.                             else {
  1146.                                 // This is the case of writing out a customized XML element
  1147.                                 // or attribute with no namespace.
  1148.                                 name = typeNameInfo.NIattributeInfo.AttributeElementName;
  1149.                             }
  1150.                         }
  1151.                         break;
  1152.                     }
  1153.                     break;
  1154.                 case InternalNameSpaceE.None:
  1155.                 case InternalNameSpaceE.UserNameSpace:
  1156.                 case InternalNameSpaceE.MemberName:
  1157.                     break;
  1158.                 default:
  1159.                     throw new SerializationException(String.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_NameSpaceEnum"), typeNameInfo.NInameSpaceEnum));
  1160.                     break;
  1161.                
  1162.             }
  1163.             return name;
  1164.         }
  1165.        
  1166.         private string TypeArrayNameTagResolver(NameInfo memberNameInfo, NameInfo typeNameInfo, bool isXsiAppended)
  1167.         {
  1168.             string name = null;
  1169.             if ((typeNameInfo.NIassemId > 0) && (typeNameInfo.NIattributeInfo != null) && (typeNameInfo.NIattributeInfo.AttributeTypeName != null))
  1170.                 name = InteropAssemIdToString((int)typeNameInfo.NIassemId) + ":" + typeNameInfo.NIattributeInfo.AttributeTypeName;
  1171.             else
  1172.                 name = NameTagResolver(typeNameInfo, isXsiAppended, memberNameInfo.NIname);
  1173.             return name;
  1174.         }
  1175.        
  1176.         private void NamespaceAttribute()
  1177.         {
  1178.             IDictionaryEnumerator e = assemblyInfoUsed.GetEnumerator();
  1179.             while (e.MoveNext()) {
  1180.                 AssemblyInfo assemblyInfo = (AssemblyInfo)e.Key;
  1181.                 attrList.Put("xmlns:" + assemblyInfo.prefix, assemblyInfo.name);
  1182.             }
  1183.             assemblyInfoUsed.Clear();
  1184.         }
  1185.        
  1186.         private string DottedDimensionName(string dottedName, string dimensionName)
  1187.         {
  1188.             string newName = null;
  1189.             int dottedIndex = dottedName.IndexOf('[');
  1190.             int dimensionIndex = dimensionName.IndexOf('[');
  1191.             newName = dottedName.Substring(0, dottedIndex) + dimensionName.Substring(dimensionIndex);
  1192.             InternalST.Soap(this, "DottedDimensionName " + newName);
  1193.             return newName;
  1194.            
  1195.         }
  1196.        
  1197.         internal sealed class AssemblyInfo
  1198.         {
  1199.             internal int id;
  1200.             internal string name;
  1201.             internal string prefix;
  1202.             internal bool isInteropType;
  1203.             internal bool isUsed;
  1204.            
  1205.             internal AssemblyInfo(int id, string name, bool isInteropType)
  1206.             {
  1207.                 this.id = id;
  1208.                 this.name = name;
  1209.                 this.isInteropType = isInteropType;
  1210.                 isUsed = false;
  1211.             }
  1212.         }
  1213.     }
  1214. }

Developer Fusion