SoapWriter

 
  1. // ==++==
  2. // 
  3. //   
  4. //    Copyright (c) 2002 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.Reflection;
  29.     using System.IO;
  30.     using System.Globalization;    
  31.     using System.Text;
  32.     using System.Diagnostics;
  33.     using System.Runtime.Remoting;
  34.     using System.Runtime.Remoting.Metadata.W3cXsd2001;
  35.     // This class provides persistence of a COM+ object graph to a stream using
  36.     // the SOAP XML-based format.
  37.      sealed internal class SoapWriter
  38.     {        
  39.         // the start of a soap message always looks like one of these
  40.         // Encoding style not used because of difficulty in interop   
  41.         // "SOAP-ENV:encodingStyle=/"http://schemas.microsoft.com/soap/encoding/clr/1.0 http://schemas.xmlsoap.org/soap/encoding//"";
  42.         private static String _soapStartStr =
  43.                 "<SOAP-ENV:Envelope xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" " +
  44.                 "xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" " +
  45.                 "xmlns:SOAP-ENC=/"http://schemas.xmlsoap.org/soap/encoding//" " +
  46.                 "xmlns:SOAP-ENV=/"http://schemas.xmlsoap.org/soap/envelope//" " +
  47.                 "xmlns:clr=/"http://schemas.microsoft.com/soap/encoding/clr/1.0/" " +
  48.                 "SOAP-ENV:encodingStyle=/"http://schemas.xmlsoap.org/soap/encoding//"";
  49.         private static String _soapStart1999Str =  
  50.                 "<SOAP-ENV:Envelope xmlns:xsi=/"http://www.w3.org/1999/XMLSchema-instance/" " +
  51.                 "xmlns:xsd=/"http://www.w3.org/1999/XMLSchema/" " +
  52.                 "xmlns:SOAP-ENC=/"http://schemas.xmlsoap.org/soap/encoding//" " +
  53.                 "xmlns:SOAP-ENV=/"http://schemas.xmlsoap.org/soap/envelope//" " +
  54.                 "SOAP-ENV:encodingStyle=/"http://schemas.xmlsoap.org/soap/encoding//"";
  55.         private static String _soapStart2000Str = 
  56.             "<SOAP-ENV:Envelope xmlns:xsi=/"http://www.w3.org/2000/10/XMLSchema-instance/" " +
  57.             "xmlns:xsd=/"http://www.w3.org/2000/10/XMLSchema/" " +
  58.             "xmlns:SOAP-ENC=/"http://schemas.xmlsoap.org/soap/encoding//" " +
  59.             "xmlns:SOAP-ENV=/"http://schemas.xmlsoap.org/soap/envelope//" " +
  60.             "SOAP-ENV:encodingStyle=/"http://schemas.xmlsoap.org/soap/encoding//"";
  61.         private static byte[] _soapStart = Encoding.UTF8.GetBytes(_soapStartStr);
  62.         private static byte[] _soapStart1999 = Encoding.UTF8.GetBytes(_soapStart1999Str);
  63.         private static byte[] _soapStart2000 = Encoding.UTF8.GetBytes(_soapStart2000Str);
  64.         private AttributeList attrList = new AttributeList();
  65.         private AttributeList attrValueList = new AttributeList();
  66.         const int StringBuilderSize = 1024;
  67.         // used for emitting into the text stream    
  68.         private int lineIndent = 4;
  69.         private int instanceIndent = 1;
  70.         // used to escape strings.  cache it as a member variable because its used frequently.
  71.         private StringBuilder stringBuffer = new StringBuilder(120);
  72.         private StringBuilder sb = new StringBuilder(120);
  73.         private int topId;
  74.         private int headerId;
  75.         //Assembly information
  76.         Hashtable assemblyInfos = new Hashtable(10);
  77.         StreamWriter writer;
  78.         Stream stream;
  79.         // Support for combining assembly names with namespaces
  80.         Hashtable typeNameToDottedInfoTable = null;
  81.         Hashtable dottedAssemToAssemIdTable = null;
  82.         Hashtable assemblyInfoUsed = new Hashtable(10); // for each xml element keeps track of unique types used
  83.         int dottedAssemId = 1;
  84.         internal bool isUsedEnc = false;
  85.         XsdVersion xsdVersion = XsdVersion.V2001;
  86.         internal struct DottedInfo
  87.         {
  88.             internal String dottedAssemblyName;
  89.             internal String name;
  90.             internal String nameSpace;
  91.             internal int assemId;
  92.         }
  93.         internal SoapWriter(Stream stream)
  94.         {
  95.             this.stream = stream;
  96.             UTF8Encoding enc = new UTF8Encoding(falsetrue);
  97.             this.writer = new StreamWriter(stream, enc, StringBuilderSize);
  98.             // Need to combine the type namespace with the assembly name for an element
  99.             typeNameToDottedInfoTable = new Hashtable(20);
  100.             dottedAssemToAssemIdTable = new Hashtable(20);
  101.         }
  102.         // Emit first Soap element
  103.         private void EmitHeader()
  104.         {
  105.             InternalST.Soap( this,"EmitHeader: ");
  106.             writer.Write("<?xml version=/"1.0/" ?>");
  107.             EmitLine();
  108.         }
  109.         // Emit spaces for indentation
  110.         [Conditional("_DEBUG")]
  111.         private void EmitIndent(int count)
  112.         {
  113.             while (--count >= 0) {
  114.                 for (int i = 0; i < lineIndent; i++)
  115.                 {
  116.                     TraceSoap(" ");
  117.                     writer.Write(' ');
  118.                 }
  119.             }
  120.         }
  121.         // Emit a line
  122.         [Conditional("_DEBUG")]                
  123.         private void EmitLine(int indent, String value) {
  124.             InternalST.Soap( this,"EmitLine: ",value);
  125.             EmitIndent(indent);
  126.             writer.Write(value);
  127.             EmitLine();
  128.         }
  129.         // Emit a blank line
  130.         private void EmitLine()
  131.         {
  132.             WriteTraceSoap();
  133.             writer.Write("/r/n");
  134.         }
  135.         // Add xml escape characters to the string value, if necessary.
  136.         private String Escape(String value)
  137.         {
  138.             stringBuffer.Length = 0;
  139.             int index = value.IndexOf('&');
  140.             if (index > -1)
  141.             {
  142.                 stringBuffer.Append(value);
  143.                 stringBuffer.Replace("&""&", index, stringBuffer.Length - index);
  144.             }
  145.             index = value.IndexOf('"');
  146.             if (index > -1)
  147.             {
  148.                 if (stringBuffer.Length == 0)
  149.                     stringBuffer.Append(value);
  150.                 stringBuffer.Replace("/""""", index, stringBuffer.Length - index);
  151.             }
  152.             index = value.IndexOf('/'');
  153.             if (index > -1)
  154.             {
  155.                 if (stringBuffer.Length == 0)
  156.                     stringBuffer.Append(value);
  157.                 stringBuffer.Replace("/'""'", index, stringBuffer.Length - index);
  158.             }
  159.             index = value.IndexOf('<');
  160.             if (index > -1)
  161.             {
  162.                 if (stringBuffer.Length == 0)
  163.                     stringBuffer.Append(value);
  164.                 stringBuffer.Replace("<""<", index, stringBuffer.Length - index);
  165.             }
  166.             index = value.IndexOf('>');
  167.             if (index > -1)
  168.             {
  169.                 if (stringBuffer.Length == 0)
  170.                     stringBuffer.Append(value);
  171.                 stringBuffer.Replace(">"">", index, stringBuffer.Length - index);
  172.             }
  173.             index = value.IndexOf(Char.MinValue);
  174.             if (index > -1)
  175.             {
  176.                 if (stringBuffer.Length == 0)
  177.                     stringBuffer.Append(value);
  178.                 stringBuffer.Replace(Char.MinValue.ToString(), "&#0;", index, stringBuffer.Length - index);
  179.             }
  180.             String returnValue = null;
  181.             if (stringBuffer.Length > 0)
  182.                 returnValue = stringBuffer.ToString();
  183.             else
  184.                 returnValue = value;
  185.             return returnValue;
  186.         }
  187.         // Add escape character for a $ and . in an element name
  188.         NameCache nameCache = new NameCache();
  189.         private String NameEscape(String name)
  190.         {
  191.             String value = (String)nameCache.GetCachedValue(name);
  192.             if (value == null)
  193.             {
  194.                 value = System.Xml.XmlConvert.EncodeName(name);
  195.                 nameCache.SetCachedValue(value);
  196.             }
  197.            return value;
  198.         }
  199.         // Initial writer
  200.         internal void Reset() {
  201.             writer = null;
  202.             stringBuffer = null;
  203.         }
  204.         internal void InternalWrite(String s)
  205.         {
  206.             TraceSoap(s);
  207.             writer.Write(s);
  208.         }
  209.         StringBuilder traceBuffer = null;
  210.         [Conditional("_LOGGING")]                        
  211.         internal void TraceSoap(String s)
  212.         {
  213.             if (traceBuffer == null)
  214.                 traceBuffer = new StringBuilder();
  215.             traceBuffer.Append(s);
  216.         }
  217.         [Conditional("_LOGGING")]                        
  218.         internal void WriteTraceSoap()
  219.         {
  220.             InternalST.InfoSoap(traceBuffer.ToString());
  221.             traceBuffer.Length = 0;
  222.         }        
  223.         // Write an XML element
  224.         internal void Write(InternalElementTypeE use, String name, AttributeList attrList, String value, bool isNameEscape, bool isValueEscape)
  225.         {
  226.             InternalST.Soap( this,"Write ",((Enum)use).ToString(),", name "+name+", value ",value, " isNameEscape ",isNameEscape," isValueEscape ",isValueEscape);
  227.             String elementName = name;
  228.             if (isNameEscape)
  229.                 elementName = NameEscape(name);
  230.             if (use == InternalElementTypeE.ObjectEnd)
  231.                 instanceIndent--;
  232.             
  233.             EmitIndent(instanceIndent);            
  234.             InternalWrite("<");
  235.             if (use == InternalElementTypeE.ObjectEnd)
  236.                 InternalWrite("/");
  237.             InternalWrite(elementName);
  238.             WriteAttributeList(attrList);
  239.             
  240.             switch(use)
  241.             {
  242.                 case InternalElementTypeE.ObjectBegin:
  243.                     InternalWrite(">");
  244.                     instanceIndent++;
  245.                     break;
  246.                 case InternalElementTypeE.ObjectEnd:
  247.                     InternalWrite(">");
  248.                     break;
  249.                 case InternalElementTypeE.Member:
  250.                     if (value == null)
  251.                         InternalWrite("/>");
  252.                     else
  253.                     {
  254.                         InternalWrite(">");
  255.                         if (isValueEscape)
  256.                             InternalWrite(Escape(value));
  257.                         else
  258.                             InternalWrite(value);
  259.                         InternalWrite("</");
  260.                         InternalWrite(elementName);
  261.                         InternalWrite(">");                    
  262.                     }
  263.                     break;
  264.                 default:
  265.                     throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_UseCode"),((Enum)use).ToString()));                                    
  266.             }
  267.             EmitLine();
  268.         }
  269.         void WriteAttributeList(AttributeList attrList)
  270.         {
  271.             for (int i=0; i<attrList.Count; i++)
  272.             {
  273.                 String aName;
  274.                 String aValue;
  275.                 attrList.Get(i, out aName, out aValue);
  276.                 InternalWrite(" ");
  277.                 InternalWrite(aName);
  278.                 InternalWrite("=");
  279.                 InternalWrite("/"");
  280.                 //InternalWrite(Escape(aValue));
  281.                 InternalWrite(aValue);
  282.                 InternalWrite("/"");
  283.             }
  284.         } // WriteAttributeList
  285.         // Begin a new XML stream
  286.         internal void WriteBegin()
  287.         {
  288.             InternalST.InfoSoap("******************** Start Serialized Stream *****************");                        
  289.         }
  290.         // Finish an XML stream
  291.         internal void WriteEnd()
  292.         {
  293.             writer.Flush();
  294.             InternalST.InfoSoap("******************** End Serialized Stream  *******************");                    
  295.             Reset();
  296.         }
  297.         internal void WriteXsdVersion(XsdVersion xsdVersion)
  298.         {
  299.             this.xsdVersion = xsdVersion;
  300.         }
  301.         // Methods to write XML Serialization Record onto the stream, 
  302.         internal void WriteObjectEnd(NameInfo memberNameInfo, NameInfo typeNameInfo)
  303.         {
  304.             //nameInfo.Dump("WriteObjectEnd nameInfo");
  305.             attrList.Clear();
  306.             Write(InternalElementTypeE.ObjectEnd, MemberElementName(memberNameInfo, typeNameInfo), attrList, nulltruefalse);                        
  307.             assemblyInfoUsed.Clear();
  308.         }
  309.         internal void WriteMemberEnd(NameInfo nameInfo)
  310.         {
  311.         }
  312.         internal void WriteSerializationHeaderEnd()
  313.         {
  314.             attrList.Clear();
  315.             Write(InternalElementTypeE.ObjectEnd, "SOAP-ENV:Body", attrList, nullfalsefalse);                
  316.             Write(InternalElementTypeE.ObjectEnd, "SOAP-ENV:Envelope", attrList,    nullfalsefalse);
  317.             writer.Flush();
  318.         }
  319.         internal void WriteItemEnd()
  320.         {
  321.         }
  322.         internal void WriteHeaderArrayEnd()
  323.         {
  324.             //attrList.Clear();
  325.             //Write(InternalElementTypeE.ObjectEnd, "SOAP:HeaderRoots",attrList, null);                        
  326.         }
  327.         internal void WriteHeaderSectionEnd()
  328.         {
  329.             attrList.Clear();            
  330.             Write(InternalElementTypeE.ObjectEnd, "SOAP-ENV:Header", attrList, nullfalsefalse);                            
  331.         }
  332.         internal void WriteSerializationHeader(int topId, int headerId, int minorVersion, int majorVersion)
  333.         {
  334.             InternalST.Soap( this,"WriteSerializationHeader");
  335.             this.topId = topId;
  336.             this.headerId = headerId;
  337.             // write start of header directly to stream
  338.             switch(xsdVersion)
  339.             {
  340.                 case XsdVersion.V1999:
  341.                     InternalST.InfoSoap(_soapStart1999Str,">");
  342.                     stream.Write(_soapStart1999, 0, _soapStart1999.Length);
  343.                     break;
  344.                 case XsdVersion.V2000:
  345.                     InternalST.InfoSoap(_soapStart2000Str,">");
  346.                     stream.Write(_soapStart1999, 0, _soapStart2000.Length);
  347.                     break;
  348.                 case XsdVersion.V2001:
  349.                     InternalST.InfoSoap(_soapStartStr,">");
  350.                     stream.Write(_soapStart, 0, _soapStart.Length);
  351.                     break;
  352.             }
  353.             writer.Write(">/r/n");
  354.         } // InternalWriteSerializationHeader
  355.         internal void WriteObject(NameInfo nameInfo, NameInfo typeNameInfo, int numMembers, String[] memberNames, Type[] memberTypes, WriteObjectInfo[] objectInfos)
  356.         {
  357.             nameInfo.Dump("WriteObject nameInfo");
  358.             typeNameInfo.Dump("WriteObject typeNameInfo");                        
  359.             int objectId = (int)nameInfo.NIobjectId;
  360.             attrList.Clear();
  361.             if (objectId == topId)
  362.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, nullfalsefalse);
  363.             // Only write the objectId in the top record if the header has been written or
  364.             if    (objectId > 0)
  365.                 attrList.Put("id", IdToString((int)nameInfo.NIobjectId));
  366.             // Types when Object is embedded member and types needed            
  367.             if (((nameInfo.NItransmitTypeOnObject || nameInfo.NItransmitTypeOnMember) && (nameInfo.NIisNestedObject || nameInfo.NIisArrayItem)))
  368.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true)); 
  369.             if (nameInfo.NIisMustUnderstand)
  370.             {
  371.                 attrList.Put("SOAP-ENV:mustUnderstand""1");
  372.                 isUsedEnc = true;
  373.             }
  374.             if (nameInfo.NIisHeader)
  375.             {
  376.                 attrList.Put("xmlns:"+nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  377.                 attrList.Put("SOAP-ENC:root""1"); 
  378.             }
  379.             if (attrValueList.Count > 0)
  380.             {
  381.                 // Combine the values from the XmlAttributes with the object attributes
  382.                 for (int i=0; i<attrValueList.Count; i++)
  383.                 {
  384.                     String aName;
  385.                     String aValue;
  386.                     attrValueList.Get(i, out aName, out aValue);
  387.                     attrList.Put(aName, aValue);
  388.                 }
  389.                 attrValueList.Clear();
  390.             }
  391.             String memberName =  MemberElementName(nameInfo, typeNameInfo);
  392.             NamespaceAttribute();
  393.             Write(InternalElementTypeE.ObjectBegin, memberName, attrList, nulltruefalse); 
  394.         }
  395.         internal void WriteAttributeValue(NameInfo memberNameInfo, NameInfo typeNameInfo, Object value)
  396.         {
  397.             // Called when the XmlAttribute is specified on a member
  398.             InternalST.Soap( this,"WriteAttributeValues ",value);
  399.             String stringValue = null;
  400.             if (value is String)
  401.                 stringValue = (String)value;
  402.             else
  403.                 stringValue = Converter.SoapToString(value, typeNameInfo.NIprimitiveTypeEnum);
  404.             attrValueList.Put(MemberElementName(memberNameInfo, typeNameInfo), stringValue);
  405.         }
  406.         internal void WriteObjectString(NameInfo nameInfo, String value)
  407.         {
  408.             InternalST.Soap( this,"WriteObjectString value ",value);
  409.             nameInfo.Dump("WriteObjectString nameInfo");            
  410.             attrList.Clear();
  411.             if (nameInfo.NIobjectId == topId)
  412.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, nullfalsefalse);
  413.             if (nameInfo.NIobjectId >0)
  414.             {
  415.                 attrList.Put("id", IdToString((int)nameInfo.NIobjectId));
  416.             }
  417.             String stringType = null;
  418.             if (nameInfo.NIobjectId > 0)
  419.             {
  420.                 stringType = "SOAP-ENC:string";
  421.                 isUsedEnc = true;                                            
  422.             }
  423.             else
  424.                 stringType = "xsd:string";                
  425.             Write(InternalElementTypeE.Member, stringType, attrList, value, false, Converter.IsEscaped(nameInfo.NIprimitiveTypeEnum));
  426.         }
  427.         internal void WriteTopPrimitive(NameInfo nameInfo, Object value)
  428.         {
  429.             nameInfo.Dump("WriteMember memberNameInfo");
  430.             attrList.Clear();
  431.             Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, nullfalsefalse);
  432.             if (nameInfo.NIobjectId >0)
  433.             {
  434.                 attrList.Put("id", IdToString((int)nameInfo.NIobjectId));
  435.             }
  436.             String stringValue = null;
  437.             if (value is String)
  438.                 stringValue = (String)value;
  439.             else
  440.                 stringValue = Converter.SoapToString(value, nameInfo.NIprimitiveTypeEnum);
  441.             Write(InternalElementTypeE.Member, "xsd:"+(Converter.ToXmlDataType(nameInfo.NIprimitiveTypeEnum)), attrList, stringValue, truefalse);
  442.         }
  443.         internal void WriteObjectByteArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, Byte[] byteA)
  444.         {
  445.             memberNameInfo.Dump("WriteObjectByteArray memberNameInfo");
  446.             arrayNameInfo.Dump("WriteObjectByteArray arrayNameInfo");
  447.             arrayElemTypeNameInfo.Dump("WriteObjectByteArray arrayElemTypeNameInfo");
  448.             String byteString = Convert.ToBase64String(byteA);        
  449.             attrList.Clear();
  450.             if (memberNameInfo.NIobjectId == topId)
  451.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, nullfalsefalse);                        
  452.             if (arrayNameInfo.NIobjectId > 1)
  453.                 attrList.Put("id", IdToString((int)arrayNameInfo.NIobjectId));
  454.             attrList.Put("xsi:type""SOAP-ENC:Base64");
  455.             isUsedEnc = true;    
  456.             String memberName = MemberElementName(memberNameInfo, null);
  457.             NamespaceAttribute();
  458.             Write(InternalElementTypeE.Member, memberName, attrList, byteString, truefalse);
  459.         }
  460.         internal void WriteMember(NameInfo memberNameInfo, NameInfo typeNameInfo, Object value)
  461.         {
  462.             memberNameInfo.Dump("WriteMember memberNameInfo");
  463.             typeNameInfo.Dump("WriteMember typeNameInfo");
  464.             attrList.Clear();
  465.             if ((typeNameInfo.NItype != null) && (memberNameInfo.NItransmitTypeOnMember || (memberNameInfo.NItransmitTypeOnObject && !memberNameInfo.NIisArrayItem)))            
  466.             {
  467.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  468.             }
  469.              String stringValue = null;
  470.              if (value != null)
  471.              {
  472.                  if (typeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.QName)
  473.                  {
  474.                      SoapQName soapQName = (SoapQName)value;
  475.                      if (soapQName.Key == null || soapQName.Key.Length == 0)
  476.                          attrList.Put("xmlns""");
  477.                      else
  478.                          attrList.Put("xmlns:"+soapQName.Key, soapQName.Namespace);
  479.                      
  480.                      stringValue = soapQName.ToString();
  481.                  }
  482.                  else
  483.                  {
  484.                      if (value is String)
  485.                          stringValue = (String)value;
  486.                      else
  487.                          stringValue = Converter.SoapToString(value, typeNameInfo.NIprimitiveTypeEnum);
  488.                  }
  489.              }
  490.             NameInfo tempNameInfo = null;
  491.             // If XmlElement attribute was defined on member, then an alternate member name has been specifed
  492.             if (typeNameInfo.NInameSpaceEnum == InternalNameSpaceE.Interop)
  493.                 tempNameInfo = typeNameInfo;
  494.             String memberName = MemberElementName(memberNameInfo, tempNameInfo);
  495.             NamespaceAttribute();
  496.             Write(InternalElementTypeE.Member, memberName, attrList, stringValue, true, Converter.IsEscaped(typeNameInfo.NIprimitiveTypeEnum));
  497.         }
  498.         //internal void WriteNullMember(String memberName, Type memberType, Boolean isTyped, Type objType)
  499.         internal void WriteNullMember(NameInfo memberNameInfo, NameInfo typeNameInfo)                
  500.         {
  501.             memberNameInfo.Dump("WriteNullMember memberNameInfo");            
  502.             typeNameInfo.Dump("WriteNullMember typeNameInfo");
  503.             attrList.Clear();
  504.             if ((typeNameInfo.NItype != null) &
  505.                   (memberNameInfo.NItransmitTypeOnMember ||
  506.                    (memberNameInfo.NItransmitTypeOnObject && !memberNameInfo.NIisArrayItem)))
  507.             {
  508.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  509.             }
  510.             attrList.Put("xsi:null""1");
  511.             /*
  512.             NameInfo tempNameInfo = null;
  513.             // If XmlElement attribute was defined on member, then an alternate member name has been specifed
  514.             if (typeNameInfo.NInameSpaceEnum == InternalNameSpaceE.Interop)
  515.                 tempNameInfo = typeNameInfo;
  516.                 */
  517.             String memberName = MemberElementName(memberNameInfo, null);
  518.             NamespaceAttribute();
  519.             Write(InternalElementTypeE.Member, memberName, attrList, nulltruefalse); 
  520.         }
  521.         internal void WriteMemberObjectRef(NameInfo memberNameInfo, int idRef)
  522.         {
  523.             memberNameInfo.Dump("WriteMemberObjectRef memberNameInfo");                        
  524.             attrList.Clear();
  525.             attrList.Put("href", RefToString(idRef));
  526.             String memberName = MemberElementName(memberNameInfo, null);
  527.             NamespaceAttribute();
  528.             Write(InternalElementTypeE.Member, memberName, attrList, nulltruefalse);
  529.         }
  530.         internal void WriteMemberNested(NameInfo memberNameInfo)
  531.         {
  532.         }
  533.         //internal void WriteMemberString(String memberName, int objectId, String value, Boolean isTyped, Type objType)
  534.         internal void WriteMemberString(NameInfo memberNameInfo, NameInfo typeNameInfo, String value)
  535.         {
  536.             memberNameInfo.Dump("WriteMemberString memberNameInfo");                        
  537.             typeNameInfo.Dump("WriteMemberString typeNameInfo");
  538.             InternalST.Soap( this"WriteMemberString memberName ",memberNameInfo.NIname," objectId ",typeNameInfo.NIobjectId," value ",value);
  539.             int objectId = (int)typeNameInfo.NIobjectId;
  540.             attrList.Clear();
  541.             if (objectId > 0)
  542.                 attrList.Put("id", IdToString((int)typeNameInfo.NIobjectId));
  543.             if ((typeNameInfo.NItype != null) && (memberNameInfo.NItransmitTypeOnMember || (memberNameInfo.NItransmitTypeOnObject && !memberNameInfo.NIisArrayItem)))                        
  544.             {
  545.                 if (typeNameInfo.NIobjectId > 0)
  546.                 {
  547.                     attrList.Put("xsi:type""SOAP-ENC:string");
  548.                     isUsedEnc = true;                                            
  549.                 }
  550.                 else
  551.                     attrList.Put("xsi:type""xsd:string");                        
  552.             }
  553.             NameInfo tempNameInfo = null;
  554.             // If XmlElement attribute was defined on member, then an alternate member name has been specifed
  555.             if (typeNameInfo.NInameSpaceEnum == InternalNameSpaceE.Interop)
  556.                 tempNameInfo = typeNameInfo;
  557.             String memberName = MemberElementName(memberNameInfo, tempNameInfo);
  558.             NamespaceAttribute();
  559.             Write(InternalElementTypeE.Member, memberName, attrList, value, true, Converter.IsEscaped(typeNameInfo.NIprimitiveTypeEnum));
  560.         }
  561.         internal void WriteSingleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, Array array)
  562.         {
  563.             memberNameInfo.Dump("WriteSingleArray memberNameInfo");                                    
  564.             arrayNameInfo.Dump("WriteSingleArray arrayNameInfo");
  565.             arrayElemTypeNameInfo.Dump("WriteSingleArray arrayElemTypeNameInfo");
  566.             attrList.Clear();
  567.             if (memberNameInfo.NIobjectId == topId)
  568.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, nullfalsefalse);            
  569.             if (arrayNameInfo.NIobjectId > 1)
  570.                 attrList.Put("id", IdToString((int)arrayNameInfo.NIobjectId));
  571.             arrayElemTypeNameInfo.NIitemName = NameTagResolver(arrayElemTypeNameInfo, true);
  572.             attrList.Put("SOAP-ENC:arrayType", NameTagResolver(arrayNameInfo, true, memberNameInfo.NIname));
  573.             isUsedEnc = true;            
  574.             if (lowerBound != 0)
  575.                 attrList.Put("SOAP-ENC:offset","["+lowerBound+"]");
  576.             String memberName = MemberElementName(memberNameInfo, null);
  577.             NamespaceAttribute();
  578.             Write(InternalElementTypeE.ObjectBegin, memberName, attrList, nullfalsefalse);
  579.         }
  580.         internal void WriteJaggedArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound)                
  581.         {
  582.             memberNameInfo.Dump("WriteJaggedArray memberNameInfo");                                                
  583.             arrayNameInfo.Dump("WriteJaggedArray arrayNameInfo");
  584.             arrayElemTypeNameInfo.Dump("WriteJaggedArray arrayElemTypeNameInfo");
  585.             attrList.Clear();
  586.             if (memberNameInfo.NIobjectId == topId)
  587.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, nullfalsefalse);                        
  588.             if (arrayNameInfo.NIobjectId > 1)
  589.                 attrList.Put("id", IdToString((int)arrayNameInfo.NIobjectId));
  590.             arrayElemTypeNameInfo.NIitemName = "SOAP-ENC:Array";
  591.             isUsedEnc = true;            
  592.             attrList.Put("SOAP-ENC:arrayType", TypeArrayNameTagResolver(memberNameInfo, arrayNameInfo, true));            
  593.             if (lowerBound != 0)
  594.                 attrList.Put("SOAP-ENC:offset","["+lowerBound+"]");
  595.             String memberName = MemberElementName(memberNameInfo, null);
  596.             NamespaceAttribute();
  597.             Write(InternalElementTypeE.ObjectBegin, memberName, attrList, nullfalsefalse);
  598.         }
  599.         private StringBuilder sbOffset = new StringBuilder(10);
  600.         internal    void WriteRectangleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int rank, int[] lengthA, int[] lowerBoundA)                
  601.         {
  602.             memberNameInfo.Dump("WriteRectangleArray memberNameInfo");                                                
  603.             arrayNameInfo.Dump("WriteRectangleArray arrayNameInfo");
  604.             arrayElemTypeNameInfo.Dump("WriteRectangleArray arrayElemTypeNameInfo");
  605.             sbOffset.Length = 0;
  606.             sbOffset.Append("[");
  607.             Boolean isZero = true;
  608.             for (int i = 0; i<rank; i++)
  609.             {
  610.                 if (lowerBoundA[i] != 0)
  611.                     isZero = false;
  612.                 if (i > 0)
  613.                     sbOffset.Append(",");
  614.                 sbOffset.Append(lowerBoundA[i]);
  615.             }
  616.             sbOffset.Append("]");
  617.             attrList.Clear();
  618.             if (memberNameInfo.NIobjectId == topId)
  619.                 Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Body", attrList, nullfalsefalse);                        
  620.             if (arrayNameInfo.NIobjectId > 1)
  621.                 attrList.Put("id", IdToString((int)arrayNameInfo.NIobjectId));
  622.             arrayElemTypeNameInfo.NIitemName = NameTagResolver(arrayElemTypeNameInfo, true);
  623.             attrList.Put("SOAP-ENC:arrayType", TypeArrayNameTagResolver(memberNameInfo, arrayNameInfo, true));
  624.             isUsedEnc = true;            
  625.             if (!isZero)
  626.                 attrList.Put("SOAP-ENC:offset", sbOffset.ToString());
  627.             String memberName = MemberElementName(memberNameInfo, null);
  628.             NamespaceAttribute();
  629.             Write(InternalElementTypeE.ObjectBegin, memberName, attrList, nullfalsefalse); 
  630.         }
  631.         //internal void WriteItem(Variant value, InternalPrimitiveTypeE code, Boolean isTyped, Type objType)
  632.         internal void WriteItem(NameInfo itemNameInfo, NameInfo typeNameInfo, Object value)
  633.         {
  634.             itemNameInfo.Dump("WriteItem itemNameInfo");                                                
  635.             typeNameInfo.Dump("WriteItem typeNameInfo");
  636.             attrList.Clear();
  637.             if (itemNameInfo.NItransmitTypeOnMember)
  638.             {
  639.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  640.             }
  641.             String stringValue = null;
  642.             if (typeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.QName)
  643.             {
  644.                 if (value != null)
  645.                 {
  646.                     SoapQName soapQName = (SoapQName)value;
  647.                     if (soapQName.Key == null || soapQName.Key.Length == 0)
  648.                         attrList.Put("xmlns""");
  649.                     else
  650.                         attrList.Put("xmlns:"+soapQName.Key, soapQName.Namespace);
  651.                     stringValue = soapQName.ToString();
  652.                 }
  653.             }
  654.             else
  655.                 stringValue = Converter.SoapToString(value, typeNameInfo.NIprimitiveTypeEnum);
  656.             NamespaceAttribute();
  657.             Write(InternalElementTypeE.Member, "item", attrList, stringValue, false, (typeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.Invalid));
  658.         }
  659.         internal void WriteNullItem(NameInfo memberNameInfo, NameInfo typeNameInfo)                
  660.         {
  661.             memberNameInfo.Dump("WriteNullItem memberNameInfo");                                                
  662.             typeNameInfo.Dump("WriteNullItem typeNameInfo");
  663.             String typeName = typeNameInfo.NIname;
  664.             attrList.Clear();
  665.             if (typeNameInfo.NItransmitTypeOnMember &
  666.                   !((typeName.Equals("System.Object")) ||
  667.                     (typeName.Equals("Object")) ||                        
  668.                     (typeName.Equals("System.Empty") ||
  669.                     (typeName.Equals("ur-type")) ||
  670.                     (typeName.Equals("anyType"))
  671.                      )))
  672.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  673.             attrList.Put("xsi:null""1");        
  674.             NamespaceAttribute();
  675.             Write(InternalElementTypeE.Member, "item", attrList, nullfalsefalse);
  676.         }
  677.         //internal void WriteItemObjectRef(int idRef)
  678.         internal void WriteItemObjectRef(NameInfo itemNameInfo, int arrayId)
  679.         {
  680.             itemNameInfo.Dump("WriteItemObjectRef itemNameInfo");                                                
  681.             attrList.Clear();
  682.             attrList.Put("href", RefToString(arrayId));
  683.             Write(InternalElementTypeE.Member, "item", attrList, nullfalsefalse);
  684.         }
  685.         // Type of string or primitive type which has already been converted to string
  686.         internal    void WriteItemString(NameInfo itemNameInfo, NameInfo typeNameInfo, String value)        
  687.         {
  688.             itemNameInfo.Dump("WriteItemString itemNameInfo");                                                
  689.             typeNameInfo.Dump("WriteItemString typeNameInfo");
  690.             attrList.Clear();
  691.             if (typeNameInfo.NIobjectId > 0)
  692.             {
  693.                 attrList.Put("id", IdToString((int)typeNameInfo.NIobjectId));
  694.             }
  695.             if (itemNameInfo.NItransmitTypeOnMember)
  696.             {
  697.                 if (typeNameInfo.NItype == SoapUtil.typeofString)
  698.                 {
  699.                     if (typeNameInfo.NIobjectId > 0)
  700.                     {
  701.                         attrList.Put("xsi:type""SOAP-ENC:string");
  702.                         isUsedEnc = true;                                            
  703.                     }
  704.                     else
  705.                         attrList.Put("xsi:type""xsd:string");                        
  706.                 }
  707.                 else
  708.                     attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  709.             }
  710.             NamespaceAttribute();
  711.             Write(InternalElementTypeE.Member, "item", attrList, value, false, Converter.IsEscaped(typeNameInfo.NIprimitiveTypeEnum));
  712.         }
  713.         internal void WriteHeader(int objectId, int numMembers)
  714.         {
  715.             attrList.Clear();
  716.             Write(InternalElementTypeE.ObjectBegin, "SOAP-ENV:Header",attrList, nullfalsefalse);
  717.             //Write(InternalElementTypeE.ObjectBegin, "SOAP:HeaderRoots",attrList, null);            
  718.         }
  719.         //internal void WriteHeaderEntry(String name, Boolean isMustUnderstand, InternalPrimitiveTypeE code, Variant value)
  720.         internal void WriteHeaderEntry(NameInfo nameInfo, NameInfo typeNameInfo, Object value)                
  721.         {
  722.             nameInfo.Dump("WriteHeaderEntry nameInfo");
  723.             if (typeNameInfo != null)
  724.             {
  725.                 typeNameInfo.Dump("WriteHeaderEntry typeNameInfo");
  726.             }
  727.             attrList.Clear();
  728.             if (value == null)
  729.                 attrList.Put("xsi:null""1");                            
  730.             else
  731.                 attrList.Put("xsi:type", TypeNameTagResolver(typeNameInfo, true));
  732.             if (nameInfo.NIisMustUnderstand)
  733.             {
  734.                 attrList.Put("SOAP-ENV:mustUnderstand""1");
  735.                 isUsedEnc = true;
  736.             }
  737.             attrList.Put("xmlns:"+nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  738.             attrList.Put("SOAP-ENC:root""1");
  739.             String stringValue = null;
  740.             if (value != null)
  741.             {
  742.                 if (typeNameInfo != null && typeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.QName)
  743.                 {
  744.                     SoapQName soapQName = (SoapQName)value;
  745.                     if (soapQName.Key == null || soapQName.Key.Length == 0)
  746.                         attrList.Put("xmlns""");
  747.                     else
  748.                         attrList.Put("xmlns:"+soapQName.Key, soapQName.Namespace);
  749.                     stringValue = soapQName.ToString();
  750.                 }
  751.                 else
  752.                     stringValue = Converter.SoapToString(value, typeNameInfo.NIprimitiveTypeEnum);
  753.             }
  754.             NamespaceAttribute();
  755.             Write(InternalElementTypeE.Member, nameInfo.NIheaderPrefix+":"+nameInfo.NIname, attrList, stringValue, truetrue);
  756.         }
  757.         //internal void WriteHeaderObjectRef(String name, Boolean isMustUnderstand, int idRef)
  758.         internal    void WriteHeaderObjectRef(NameInfo nameInfo)
  759.         {
  760.             nameInfo.Dump("WriteHeaderObjectRef nameInfo");                        
  761.             attrList.Clear();
  762.             attrList.Put("href", RefToString((int)nameInfo.NIobjectId));
  763.             if (nameInfo.NIisMustUnderstand)
  764.             {                
  765.                 attrList.Put("SOAP-ENV:mustUnderstand""1");
  766.                 isUsedEnc = true;
  767.             }
  768.             attrList.Put("xmlns:"+nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  769.             attrList.Put("SOAP-ENC:root""1");                        
  770.             Write(InternalElementTypeE.Member, nameInfo.NIheaderPrefix+":"+nameInfo.NIname, attrList, nulltruetrue);
  771.         }
  772.         internal void WriteHeaderNested(NameInfo nameInfo)
  773.         {
  774.         }
  775.         //internal void WriteHeaderString(String name, Boolean isMustUnderstand, int objectId, String value)
  776.         internal    void WriteHeaderString(NameInfo nameInfo, String value)
  777.         {
  778.             nameInfo.Dump("WriteHeaderString nameInfo");
  779.             attrList.Clear();
  780.             attrList.Put("xsi:type""SOAP-ENC:string");
  781.             isUsedEnc = true;        
  782.             if (nameInfo.NIisMustUnderstand)
  783.                 attrList.Put("SOAP-ENV:mustUnderstand""1");
  784.             attrList.Put("xmlns:"+nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  785.             attrList.Put("SOAP-ENC:root""1");                                    
  786.             Write(InternalElementTypeE.Member, nameInfo.NIheaderPrefix+":"+nameInfo.NIname, attrList, value, truetrue);
  787.         }
  788.         internal void WriteHeaderMethodSignature(NameInfo nameInfo, NameInfo[] typeNameInfos)
  789.         {
  790.             nameInfo.Dump("WriteHeaderString nameInfo");
  791.             attrList.Clear();
  792.             attrList.Put("xsi:type""SOAP-ENC:methodSignature");
  793.             isUsedEnc = true;            
  794.             if (nameInfo.NIisMustUnderstand)
  795.                 attrList.Put("SOAP-ENV:mustUnderstand""1");
  796.             attrList.Put("xmlns:"+nameInfo.NIheaderPrefix, nameInfo.NInamespace);
  797.             attrList.Put("SOAP-ENC:root""1");
  798.             StringBuilder sb = new StringBuilder();
  799.             
  800.             // The signature string is an sequence of prefixed types, where the prefix is the key to the namespace.
  801.             for (int i=0; i<typeNameInfos.Length; i++)
  802.             {    if (i > 0)
  803.                     sb.Append(' ');
  804.                 sb.Append(NameTagResolver(typeNameInfos[i], true));
  805.             }
  806.             
  807.             NamespaceAttribute();
  808.             Write(InternalElementTypeE.Member, nameInfo.NIheaderPrefix+":"+nameInfo.NIname, attrList, sb.ToString(), truetrue);
  809.         }
  810.         internal void WriteAssembly(String typeFullName, Type type, String assemName, int assemId, bool isNew, bool isInteropType)
  811.         {
  812.             InternalST.Soap( this"WriteAssembly ",typeFullName," ",type," ",assemId," ",assemName," isNew ",isNew, " isInteropType ", isInteropType);
  813.             if (isNew)
  814.             {
  815.                 InternalST.Soap( this"WriteAssembly new Assembly ");
  816.                 if (isInteropType)
  817.                 {
  818.                     // Interop type
  819.                     assemblyInfos[InteropAssemIdToString(assemId)] = new AssemblyInfo(assemId, assemName, isInteropType);
  820.                 }
  821.             }
  822.             if (!isInteropType)
  823.             {
  824.                 // assembly name and dotted namespaces are combined
  825.                 ParseAssemblyName(typeFullName, assemName);
  826.             }
  827.         }
  828.         private DottedInfo ParseAssemblyName(String typeFullName, String assemName)
  829.         {
  830.             InternalST.Soap( this"ParseAssemblyName Entry typeFullName ",typeFullName," assemName ",assemName);
  831.             DottedInfo dottedInfo;
  832.             String nameSpace = null;
  833.             String name = null;
  834.             String dottedAssemblyName = null;
  835.             int assemId;
  836.             if (typeNameToDottedInfoTable.ContainsKey(typeFullName))
  837.             {
  838.                 // type name already seen 
  839.                 dottedInfo = (DottedInfo)typeNameToDottedInfoTable[typeFullName];
  840.             }
  841.             else
  842.             {
  843.                 // type name new, find nameSpace and concatenate the assembly name to it.
  844.                 int index = typeFullName.LastIndexOf('.');
  845.                 if (index > 0)
  846.                     nameSpace = typeFullName.Substring(0, index);
  847.                 else
  848.                     nameSpace = "";
  849.                 dottedAssemblyName = SoapServices.CodeXmlNamespaceForClrTypeNamespace(nameSpace, assemName);
  850.                 name = typeFullName.Substring(index+1);                
  851.                 if (dottedAssemToAssemIdTable.ContainsKey(dottedAssemblyName))
  852.                 {
  853.                     // The dotted assembly name has been seen before, get the assembly Id
  854.                     assemId = (int)dottedAssemToAssemIdTable[dottedAssemblyName];
  855.                 }
  856.                 else
  857.                 {
  858.                     // The dotted assembly name has not been seen before, calculate a new
  859.                     // assemId and remember it so that it can be added to the Envelope xml namespaces
  860.                     assemId = dottedAssemId++;
  861.                     assemblyInfos[AssemIdToString(assemId)] = new AssemblyInfo(assemId, dottedAssemblyName, false);
  862.                     dottedAssemToAssemIdTable[dottedAssemblyName] = assemId;
  863.                 }
  864.                 // Create a new DottedInfo structure and remember it with the type name
  865.                 dottedInfo = new DottedInfo();
  866.                 dottedInfo.dottedAssemblyName = dottedAssemblyName;
  867.                 dottedInfo.name = name;
  868.                 dottedInfo.nameSpace = nameSpace;
  869.                 dottedInfo.assemId = assemId;
  870.                 typeNameToDottedInfoTable[typeFullName] = dottedInfo;            
  871.                 InternalST.Soap( this"ParseAssemblyName new dotted Assembly name ",dottedInfo.name,", dottedAssemblyName ",dottedInfo.dottedAssemblyName,", assemId ",dottedInfo.assemId, " typeFullName ", typeFullName);
  872.             }
  873.             InternalST.Soap( this"ParseAssemblyName Exit nameSpace ",dottedInfo.nameSpace," name ",dottedInfo.name," assemblyName ",dottedInfo.dottedAssemblyName," assemId ",dottedInfo.assemId);
  874.             return dottedInfo;
  875.         }
  876.         StringBuilder sb1 = new StringBuilder("ref-",15);
  877.         private String IdToString(int objectId)
  878.         {
  879.             sb1.Length=4;
  880.             sb1.Append(objectId);
  881.             return sb1.ToString();
  882.         }
  883.         StringBuilder sb2 = new StringBuilder("a-",15);
  884.         private String AssemIdToString(int assemId)
  885.         {
  886.             sb2.Length=1;
  887.             sb2.Append(assemId);
  888.             return sb2.ToString();
  889.         }
  890.         StringBuilder sb3 = new StringBuilder("i-",15);
  891.         private String InteropAssemIdToString(int assemId)
  892.         {
  893.             sb3.Length=1;
  894.             sb3.Append(assemId);
  895.             return sb3.ToString();
  896.         }        
  897.         StringBuilder sb4 = new StringBuilder("#ref-",16);
  898.         private String RefToString(int objectId)
  899.         {
  900.             sb4.Length=5;
  901.             sb4.Append(objectId);
  902.             return sb4.ToString();
  903.         }
  904.         private String MemberElementName(NameInfo memberNameInfo, NameInfo typeNameInfo)
  905.         {
  906.             String memberName = memberNameInfo.NIname;
  907.             if (memberNameInfo.NIisHeader)
  908.             {
  909.                 memberName = memberNameInfo.NIheaderPrefix+":"+memberNameInfo.NIname;
  910.             }
  911.             else if ((typeNameInfo != null) &&(typeNameInfo.NItype == SoapUtil.typeofSoapFault))
  912.             {
  913.                 memberName = "SOAP-ENV:Fault";
  914.             }
  915.             else if (memberNameInfo.NIisArray && !memberNameInfo.NIisNestedObject)
  916.             {
  917.                 memberName = "SOAP-ENC:Array";
  918.                 isUsedEnc = true;
  919.             }
  920.             //else if (memberNameInfo.NItype == SoapUtil.typeofObject)
  921.             //memberName = "SOAP:Object";
  922.             else if (memberNameInfo.NIisArrayItem)
  923.             {
  924.                 //memberName = memberNameInfo.NIitemName; // occurs for a nested class in an array
  925.                 memberName = "item";
  926.             }
  927.             else if (memberNameInfo.NIisNestedObject)
  928.             {
  929.             }
  930.             else if (memberNameInfo.NIisRemoteRecord && !memberNameInfo.NIisTopLevelObject) // Parameters
  931.             {
  932.             }
  933.             else if (typeNameInfo != null)
  934.             {
  935.                 memberName = NameTagResolver(typeNameInfo, true); 
  936.             }
  937.             return memberName;
  938.         }
  939.         private String TypeNameTagResolver(NameInfo typeNameInfo, bool isXsiAppended)
  940.         {
  941.             String name = null;
  942.             if ((typeNameInfo.NIassemId > 0) && (typeNameInfo.NIattributeInfo != null) && (typeNameInfo.NIattributeInfo.AttributeTypeName != null))
  943.             {
  944.                 String assemIdString = InteropAssemIdToString((int)typeNameInfo.NIassemId);
  945.                 name = assemIdString+":"+typeNameInfo.NIattributeInfo.AttributeTypeName;
  946.                 AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  947.                 assemblyInfo.isUsed = true;
  948.                 assemblyInfo.prefix = assemIdString;
  949.                 assemblyInfoUsed[assemblyInfo] = 1;
  950.             }
  951.             else
  952.                 name = NameTagResolver(typeNameInfo, isXsiAppended);
  953.             return name;
  954.         }
  955.         private String NameTagResolver(NameInfo typeNameInfo, bool isXsiAppended)
  956.         {
  957.             return NameTagResolver(typeNameInfo, isXsiAppended, null);
  958.         }
  959.         
  960.         private String NameTagResolver(NameInfo typeNameInfo, bool isXsiAppended, String arrayItemName)
  961.         {
  962.             String name = typeNameInfo.NIname;
  963.             switch(typeNameInfo.NInameSpaceEnum)
  964.             {
  965.                 case InternalNameSpaceE.Soap:
  966.                     name = "SOAP-ENC:"+typeNameInfo.NIname;
  967.                     isUsedEnc = true;                    
  968.                     break;
  969.                 case InternalNameSpaceE.XdrPrimitive:
  970.                     if (isXsiAppended)
  971.                         name = "xsd:"+typeNameInfo.NIname;
  972.                     break;
  973.                 case InternalNameSpaceE.XdrString:
  974.                     if (isXsiAppended)                    
  975.                         name = "xsd:"+typeNameInfo.NIname;
  976.                     break;                    
  977.                 case InternalNameSpaceE.UrtSystem:
  978.                     if (typeNameInfo.NItype == SoapUtil.typeofObject)
  979.                         name = "xsd:anyType";                    
  980.                     else if (arrayItemName == null)
  981.                     {
  982.                         // need to generate dotted name spaces
  983.                         DottedInfo dottedInfo;
  984.                         if (typeNameToDottedInfoTable.ContainsKey(typeNameInfo.NIname))
  985.                             dottedInfo = (DottedInfo)typeNameToDottedInfoTable[typeNameInfo.NIname];
  986.                         else
  987.                         {
  988.                             dottedInfo = ParseAssemblyName(typeNameInfo.NIname, null);
  989.                         }
  990.                         String assemIdString = AssemIdToString(dottedInfo.assemId);
  991.                         name = assemIdString+":"+dottedInfo.name;
  992.                         AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  993.                         assemblyInfo.isUsed = true;
  994.                         assemblyInfo.prefix = assemIdString;
  995.                         assemblyInfoUsed[assemblyInfo] = 1;
  996.                     }
  997.                     else
  998.                     {
  999.                         // need to generate dotted name spaces
  1000.                         DottedInfo dottedInfo;
  1001.                         if (typeNameToDottedInfoTable.ContainsKey(arrayItemName))
  1002.                             dottedInfo = (DottedInfo)typeNameToDottedInfoTable[arrayItemName];
  1003.                         else
  1004.                         {
  1005.                             dottedInfo = ParseAssemblyName(arrayItemName, null);
  1006.                         }
  1007.                         String assemIdString = AssemIdToString(dottedInfo.assemId);                        
  1008.                         name = assemIdString+":"+DottedDimensionName(dottedInfo.name, typeNameInfo.NIname);
  1009.                         AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1010.                         assemblyInfo.isUsed = true;
  1011.                         assemblyInfo.prefix = assemIdString;
  1012.                         assemblyInfoUsed[assemblyInfo] = 1;
  1013.                     }
  1014.                     break;
  1015.                 case InternalNameSpaceE.UrtUser:
  1016.                     if (typeNameInfo.NIassemId > 0)
  1017.                     {
  1018.                         if (arrayItemName == null)
  1019.                         {
  1020.                             DottedInfo dottedInfo;
  1021.                             InternalST.Soap( this"NameTagResolver typeNameInfo.NIname ",typeNameInfo.NIname," table ", typeNameToDottedInfoTable.ContainsKey(typeNameInfo.NIname));
  1022.                             SoapUtil.DumpHash("typeNameToDottedInfoTable", typeNameToDottedInfoTable);
  1023.                             if (typeNameToDottedInfoTable.ContainsKey(typeNameInfo.NIname))
  1024.                                 dottedInfo = (DottedInfo)typeNameToDottedInfoTable[typeNameInfo.NIname];                                
  1025.                             else
  1026.                                 throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_Assembly"),typeNameInfo.NIname));
  1027.                             String assemIdString = AssemIdToString(dottedInfo.assemId);
  1028.                             name = assemIdString+":"+dottedInfo.name;
  1029.                             AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1030.                             assemblyInfo.isUsed = true;
  1031.                             assemblyInfo.prefix = assemIdString;
  1032.                             assemblyInfoUsed[assemblyInfo] = 1;
  1033.                         }
  1034.                         else
  1035.                         {
  1036.                             DottedInfo dottedInfo;
  1037.                             if (typeNameToDottedInfoTable.ContainsKey(arrayItemName))
  1038.                                 dottedInfo = (DottedInfo)typeNameToDottedInfoTable[arrayItemName];                                
  1039.                             else
  1040.                                 throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_Assembly"),typeNameInfo.NIname));                                                    
  1041.                             String assemIdString = AssemIdToString(dottedInfo.assemId);                            
  1042.                             name = assemIdString+":"+DottedDimensionName(dottedInfo.name, typeNameInfo.NIname);
  1043.                             AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1044.                             assemblyInfo.isUsed = true;
  1045.                             assemblyInfo.prefix = assemIdString;
  1046.                             assemblyInfoUsed[assemblyInfo] = 1;
  1047.                         }
  1048.                     }
  1049.                     break;
  1050.                 case InternalNameSpaceE.CallElement:
  1051.                     if (typeNameInfo.NIassemId > 0)
  1052.                     {
  1053.                             String key = InteropAssemIdToString((int)typeNameInfo.NIassemId);
  1054.                             AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[key];
  1055.                             if (assemblyInfo == null)
  1056.                                 throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_NameSpaceEnum"),typeNameInfo.NInameSpaceEnum));                                                                    
  1057.                             name = key+":"+typeNameInfo.NIname;
  1058.                             assemblyInfo.isUsed = true//PDJ check this against checked in code
  1059.                             assemblyInfo.prefix = key;
  1060.                             assemblyInfoUsed[assemblyInfo] = 1;
  1061.                     }
  1062.                     break;
  1063.                 case InternalNameSpaceE.Interop:
  1064.                 {
  1065.                     if ((typeNameInfo.NIattributeInfo != null) && (typeNameInfo.NIattributeInfo.AttributeElementName != null))
  1066.                     {
  1067.                         if (typeNameInfo.NIassemId > 0) 
  1068.                         {
  1069.                             String assemIdString = InteropAssemIdToString((int)typeNameInfo.NIassemId);     
  1070.                             name = assemIdString+":"+typeNameInfo.NIattributeInfo.AttributeElementName;
  1071.                             if (arrayItemName != null)
  1072.                             {
  1073.                                 int index = typeNameInfo.NIname.IndexOf("[");
  1074.                                 name = name+typeNameInfo.NIname.Substring(index);
  1075.                             }
  1076.                             AssemblyInfo assemblyInfo = (AssemblyInfo)assemblyInfos[assemIdString];
  1077.                             assemblyInfo.isUsed = true;
  1078.                             assemblyInfo.prefix = assemIdString;
  1079.                             assemblyInfoUsed[assemblyInfo] = 1;
  1080.                         }
  1081.                         else
  1082.                         {
  1083.                             // This is the case of writing out a customized XML element
  1084.                             //   or attribute with no namespace.
  1085.                             name = typeNameInfo.NIattributeInfo.AttributeElementName;
  1086.                         }
  1087.                     }
  1088.                     break;
  1089.                 }
  1090.                 case InternalNameSpaceE.None:
  1091.                 case InternalNameSpaceE.UserNameSpace:
  1092.                 case InternalNameSpaceE.MemberName:
  1093.                     break;
  1094.                 default:
  1095.                     throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_NameSpaceEnum"),typeNameInfo.NInameSpaceEnum));                    
  1096.             }
  1097.             return name;
  1098.         }
  1099.         private String TypeArrayNameTagResolver(NameInfo memberNameInfo, NameInfo typeNameInfo, bool isXsiAppended)
  1100.         {
  1101.             String name = null;
  1102.             if ((typeNameInfo.NIassemId > 0) && (typeNameInfo.NIattributeInfo != null) && (typeNameInfo.NIattributeInfo.AttributeTypeName != null))
  1103.                 name = InteropAssemIdToString((int)typeNameInfo.NIassemId)+":"+typeNameInfo.NIattributeInfo.AttributeTypeName;
  1104.             else
  1105.                 name = NameTagResolver(typeNameInfo, isXsiAppended, memberNameInfo.NIname);
  1106.             return name;
  1107.         }
  1108.         
  1109.         private void NamespaceAttribute()
  1110.         {
  1111.             IDictionaryEnumerator e = assemblyInfoUsed.GetEnumerator();
  1112.             while(e.MoveNext())
  1113.             {
  1114.                 AssemblyInfo assemblyInfo = (AssemblyInfo)e.Key;
  1115.                 attrList.Put("xmlns:"+assemblyInfo.prefix, assemblyInfo.name);
  1116.             }
  1117.             assemblyInfoUsed.Clear();
  1118.         }
  1119.         private String DottedDimensionName(String dottedName, String dimensionName)
  1120.         {
  1121.             String newName = null;
  1122.             int dottedIndex = dottedName.IndexOf('[');
  1123.             int dimensionIndex = dimensionName.IndexOf('[');
  1124.             newName = dottedName.Substring(0,dottedIndex)+dimensionName.Substring(dimensionIndex);
  1125.             InternalST.Soap( this"DottedDimensionName "+newName);
  1126.             return newName;
  1127.         }
  1128.         internal sealed class AssemblyInfo
  1129.         {
  1130.             internal int id;
  1131.             internal String name;
  1132.             internal String prefix;
  1133.             internal bool isInteropType;
  1134.             internal bool isUsed;
  1135.             internal AssemblyInfo(int id, String name, bool isInteropType)
  1136.             {
  1137.                 this.id = id;
  1138.                 this.name = name;
  1139.                 this.isInteropType = isInteropType;
  1140.                 isUsed = false;
  1141.             }
  1142.         }
  1143.     }
  1144. }
《Tecplot与MIKE结合教程》是一份详细介绍如何将Tecplot与MIKE软件进行协同工作的学习资料。这份教程旨在帮助用户理解并掌握这两款强大的科学计算与数据可视化工具的整合应用,从而提高在流体动力学、环境工程、海洋科学等领域的模拟分析效率。 Tecplot是一款广泛应用于科研和工程领域的数据可视化和分析软件,它能够处理大量数据,快速生成高质量的2D和3D图形,便于用户理解和解释复杂的数值模拟结果。其强大的后处理能力,如等值线绘制、颜色梯度图、矢量场显示等功能,使得数据的呈现更加直观。 MIKE(原名DHI软件)是由丹麦水力研究所开发的一系列专业仿真软件,主要用于水资源管理、环境流动、海岸工程等领域。MIKE软件家族包括MIKE 11(河流模拟)、MIKE 21(海洋模型)、MIKE 3(三维流体动力学模型)等,可以解决从河流、湖泊到海洋的各类水动力问题。 当Tecplot与MIKE结合使用时,Tecplot作为后处理器,可以接收MIKE软件产生的计算结果,进行更深入的数据解析和可视化。通过这种方式,用户不仅可以查看MIKE模拟出的流场、浓度分布等数据,还能进行多变量分析、动画制作,以及生成专业报告所需的图表,极大地提高了数据分析的效率和质量。 教程中可能会涵盖以下内容: 1. **数据导入**:讲解如何从MIKE软件导出适合Tecplot处理的文件格式,如ASCII或二进制文件。 2. **Tecplot界面操作**:介绍Tecplot的基本操作,如数据加载、变量选择、区域定义等。 3. **数据可视化**:教学如何使用Tecplot创建等值线图、颜色梯度图、矢量图等,以及调整色彩映射、透明度等参数,以清晰地展示MIKE的模拟结果。 4. **动画制作**:说明如何通过Tecplot制作时间序列动画,动态展示流动过程。 5. **高级分析**:可能涉及统计分析、插值运算、剖面图绘制等高级功能,帮助用户深入理解模拟数据。 6. **定制化和脚本编程**:介绍如何利用Tecplot的内置脚本语言(如TecScript或Python)自动化处理MIKE数据,进行批量分析或自定义功能的实现。 7. **案例研究**:提供实际案例,演示Tecplot与MIKE结合的具体应用,如河流污染扩散分析、海岸线变化模拟等。 通过学习这份教程,用户将能够熟练地将Tecplot与MIKE结合使用,提升在复杂水动力问题上的建模和分析能力,为科学研究和工程决策提供有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值