The Labs \ Source Viewer \ SSCLI \ System.Xml.Serialization \ ReflectionAwareCodeGen

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlSerializationWriter.cs" company="Microsoft">
  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. // </copyright>
  14. // <owner current="true" primary="true">ElenaK</owner>
  15. //------------------------------------------------------------------------------
  16. namespace System.Xml.Serialization
  17. {
  18.    
  19.     using System;
  20.     using System.IO;
  21.     using System.Collections;
  22.     using System.Reflection;
  23.     using System.Reflection.Emit;
  24.     using System.Xml.Schema;
  25.     using System.ComponentModel;
  26.     using System.Diagnostics;
  27.     using System.CodeDom.Compiler;
  28.     using System.Globalization;
  29.     using System.Text;
  30.     using System.Threading;
  31.     using System.Security.Permissions;
  32.    
  33.     /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter"]/*' />
  34.     ///<internalonly/>
  35.     public abstract class XmlSerializationWriter : XmlSerializationGeneratedCode
  36.     {
  37.         XmlWriter w;
  38.         XmlSerializerNamespaces namespaces;
  39.         int tempNamespacePrefix;
  40.         Hashtable usedPrefixes;
  41.         Hashtable references;
  42.         string idBase;
  43.         int nextId;
  44.         Hashtable typeEntries;
  45.         ArrayList referencesToWrite;
  46.         Hashtable objectsInUse;
  47.         string aliasBase = "q";
  48.         bool soap12;
  49.         bool escapeName = true;
  50.        
  51.         // this method must be called before any generated serialization methods are called
  52.         internal void Init(XmlWriter w, XmlSerializerNamespaces namespaces, string encodingStyle, string idBase, TempAssembly tempAssembly)
  53.         {
  54.             this.w = w;
  55.             this.namespaces = namespaces;
  56.             this.soap12 = (encodingStyle == Soap12.Encoding);
  57.             this.idBase = idBase;
  58.             Init(tempAssembly);
  59.         }
  60.        
  61.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.EscapeName"]/*' />
  62.         protected bool EscapeName {
  63.             get { return escapeName; }
  64.             set { escapeName = value; }
  65.         }
  66.        
  67.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.Writer"]/*' />
  68.         protected XmlWriter Writer {
  69.             get { return w; }
  70.             set { w = value; }
  71.         }
  72.        
  73.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.Namespaces"]/*' />
  74.         /// <devdoc>
  75.         /// <para>[To be supplied.]</para>
  76.         /// </devdoc>
  77.         protected ArrayList Namespaces {
  78.             get { return namespaces == null ? null : namespaces.NamespaceList; }
  79.             set {
  80.                 if (value == null) {
  81.                     namespaces = null;
  82.                 }
  83.                 else {
  84.                     XmlQualifiedName[] qnames = (XmlQualifiedName[])value.ToArray(typeof(XmlQualifiedName));
  85.                     namespaces = new XmlSerializerNamespaces(qnames);
  86.                 }
  87.             }
  88.         }
  89.        
  90.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromByteArrayBase64"]/*' />
  91.         protected static byte[] FromByteArrayBase64(byte[] value)
  92.         {
  93.             // Unlike other "From" functions that one is just a place holder for automatic code generation.
  94.             // The reason is performance and memory consumption for (potentially) big 64base-encoded chunks
  95.             // And it is assumed that the caller generates the code that will distinguish between byte[] and string return types
  96.             //
  97.             return value;
  98.         }
  99.        
  100.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.ResolveDynamicAssembly"]/*' />
  101.         ///<internalonly/>
  102.         protected static Assembly ResolveDynamicAssembly(string assemblyFullName)
  103.         {
  104.             return DynamicAssemblies.Get(assemblyFullName);
  105.         }
  106.        
  107.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromByteArrayHex"]/*' />
  108.         protected static string FromByteArrayHex(byte[] value)
  109.         {
  110.             return XmlCustomFormatter.FromByteArrayHex(value);
  111.         }
  112.        
  113.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromDateTime"]/*' />
  114.         protected static string FromDateTime(DateTime value)
  115.         {
  116.             return XmlCustomFormatter.FromDateTime(value);
  117.         }
  118.        
  119.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromDate"]/*' />
  120.         protected static string FromDate(DateTime value)
  121.         {
  122.             return XmlCustomFormatter.FromDate(value);
  123.         }
  124.        
  125.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromTime"]/*' />
  126.         protected static string FromTime(DateTime value)
  127.         {
  128.             return XmlCustomFormatter.FromTime(value);
  129.         }
  130.        
  131.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromChar"]/*' />
  132.         protected static string FromChar(char value)
  133.         {
  134.             return XmlCustomFormatter.FromChar(value);
  135.         }
  136.        
  137.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromEnum"]/*' />
  138.         protected static string FromEnum(long value, string[] values, long[] ids)
  139.         {
  140.             return XmlCustomFormatter.FromEnum(value, values, ids, null);
  141.         }
  142.        
  143.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromEnum1"]/*' />
  144.         protected static string FromEnum(long value, string[] values, long[] ids, string typeName)
  145.         {
  146.             return XmlCustomFormatter.FromEnum(value, values, ids, typeName);
  147.         }
  148.        
  149.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromXmlName"]/*' />
  150.         protected static string FromXmlName(string name)
  151.         {
  152.             return XmlCustomFormatter.FromXmlName(name);
  153.         }
  154.        
  155.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromXmlNCName"]/*' />
  156.         protected static string FromXmlNCName(string ncName)
  157.         {
  158.             return XmlCustomFormatter.FromXmlNCName(ncName);
  159.         }
  160.        
  161.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromXmlNmToken"]/*' />
  162.         protected static string FromXmlNmToken(string nmToken)
  163.         {
  164.             return XmlCustomFormatter.FromXmlNmToken(nmToken);
  165.         }
  166.        
  167.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromXmlNmTokens"]/*' />
  168.         protected static string FromXmlNmTokens(string nmTokens)
  169.         {
  170.             return XmlCustomFormatter.FromXmlNmTokens(nmTokens);
  171.         }
  172.        
  173.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteXsiType"]/*' />
  174.         protected void WriteXsiType(string name, string ns)
  175.         {
  176.             WriteAttribute("type", XmlSchema.InstanceNamespace, GetQualifiedName(name, ns));
  177.         }
  178.        
  179.         XmlQualifiedName GetPrimitiveTypeName(Type type)
  180.         {
  181.             return GetPrimitiveTypeName(type, true);
  182.         }
  183.        
  184.         XmlQualifiedName GetPrimitiveTypeName(Type type, bool throwIfUnknown)
  185.         {
  186.             XmlQualifiedName qname = GetPrimitiveTypeNameInternal(type);
  187.             if (throwIfUnknown && qname == null)
  188.                 throw CreateUnknownTypeException(type);
  189.             return qname;
  190.         }
  191.        
  192.         static internal XmlQualifiedName GetPrimitiveTypeNameInternal(Type type)
  193.         {
  194.             string typeName;
  195.             string typeNs = XmlSchema.Namespace;
  196.            
  197.             switch (Type.GetTypeCode(type)) {
  198.                 case TypeCode.String:
  199.                     typeName = "string";
  200.                     break;
  201.                 case TypeCode.Int32:
  202.                     typeName = "int";
  203.                     break;
  204.                 case TypeCode.Boolean:
  205.                     typeName = "boolean";
  206.                     break;
  207.                 case TypeCode.Int16:
  208.                     typeName = "short";
  209.                     break;
  210.                 case TypeCode.Int64:
  211.                     typeName = "long";
  212.                     break;
  213.                 case TypeCode.Single:
  214.                     typeName = "float";
  215.                     break;
  216.                 case TypeCode.Double:
  217.                     typeName = "double";
  218.                     break;
  219.                 case TypeCode.Decimal:
  220.                     typeName = "decimal";
  221.                     break;
  222.                 case TypeCode.DateTime:
  223.                     typeName = "dateTime";
  224.                     break;
  225.                 case TypeCode.Byte:
  226.                     typeName = "unsignedByte";
  227.                     break;
  228.                 case TypeCode.SByte:
  229.                     typeName = "byte";
  230.                     break;
  231.                 case TypeCode.UInt16:
  232.                     typeName = "unsignedShort";
  233.                     break;
  234.                 case TypeCode.UInt32:
  235.                     typeName = "unsignedInt";
  236.                     break;
  237.                 case TypeCode.UInt64:
  238.                     typeName = "unsignedLong";
  239.                     break;
  240.                 case TypeCode.Char:
  241.                     typeName = "char";
  242.                     typeNs = UrtTypes.Namespace;
  243.                     break;
  244.                 default:
  245.                     if (type == typeof(XmlQualifiedName))
  246.                         typeName = "QName";
  247.                     else if (type == typeof(byte[]))
  248.                         typeName = "base64Binary";
  249.                     else if (type == typeof(Guid)) {
  250.                         typeName = "guid";
  251.                         typeNs = UrtTypes.Namespace;
  252.                     }
  253.                     else if (type == typeof(XmlNode[])) {
  254.                         typeName = Soap.UrType;
  255.                     }
  256.                     else
  257.                         return null;
  258.                     break;
  259.             }
  260.             return new XmlQualifiedName(typeName, typeNs);
  261.         }
  262.        
  263.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteTypedPrimitive"]/*' />
  264.         protected void WriteTypedPrimitive(string name, string ns, object o, bool xsiType)
  265.         {
  266.             string value = null;
  267.             string type;
  268.             string typeNs = XmlSchema.Namespace;
  269.             bool writeRaw = true;
  270.             bool writeDirect = false;
  271.             Type t = o.GetType();
  272.             bool wroteStartElement = false;
  273.            
  274.             switch (Type.GetTypeCode(t)) {
  275.                 case TypeCode.String:
  276.                     value = (string)o;
  277.                     type = "string";
  278.                     writeRaw = false;
  279.                     break;
  280.                 case TypeCode.Int32:
  281.                     value = XmlConvert.ToString((int)o);
  282.                     type = "int";
  283.                     break;
  284.                 case TypeCode.Boolean:
  285.                     value = XmlConvert.ToString((bool)o);
  286.                     type = "boolean";
  287.                     break;
  288.                 case TypeCode.Int16:
  289.                     value = XmlConvert.ToString((short)o);
  290.                     type = "short";
  291.                     break;
  292.                 case TypeCode.Int64:
  293.                     value = XmlConvert.ToString((long)o);
  294.                     type = "long";
  295.                     break;
  296.                 case TypeCode.Single:
  297.                     value = XmlConvert.ToString((float)o);
  298.                     type = "float";
  299.                     break;
  300.                 case TypeCode.Double:
  301.                     value = XmlConvert.ToString((double)o);
  302.                     type = "double";
  303.                     break;
  304.                 case TypeCode.Decimal:
  305.                     value = XmlConvert.ToString((decimal)o);
  306.                     type = "decimal";
  307.                     break;
  308.                 case TypeCode.DateTime:
  309.                     value = FromDateTime((DateTime)o);
  310.                     type = "dateTime";
  311.                     break;
  312.                 case TypeCode.Char:
  313.                     value = FromChar((char)o);
  314.                     type = "char";
  315.                     typeNs = UrtTypes.Namespace;
  316.                     break;
  317.                 case TypeCode.Byte:
  318.                     value = XmlConvert.ToString((byte)o);
  319.                     type = "unsignedByte";
  320.                     break;
  321.                 case TypeCode.SByte:
  322.                     value = XmlConvert.ToString((sbyte)o);
  323.                     type = "byte";
  324.                     break;
  325.                 case TypeCode.UInt16:
  326.                     value = XmlConvert.ToString((UInt16)o);
  327.                     type = "unsignedShort";
  328.                     break;
  329.                 case TypeCode.UInt32:
  330.                     value = XmlConvert.ToString((UInt32)o);
  331.                     type = "unsignedInt";
  332.                     break;
  333.                 case TypeCode.UInt64:
  334.                     value = XmlConvert.ToString((UInt64)o);
  335.                     type = "unsignedLong";
  336.                     break;
  337.                 default:
  338.                    
  339.                     if (t == typeof(XmlQualifiedName)) {
  340.                         type = "QName";
  341.                         // need to write start element ahead of time to establish context
  342.                         // for ns definitions by FromXmlQualifiedName
  343.                         wroteStartElement = true;
  344.                         if (name == null)
  345.                             w.WriteStartElement(type, typeNs);
  346.                         else
  347.                             w.WriteStartElement(name, ns);
  348.                         value = FromXmlQualifiedName((XmlQualifiedName)o, false);
  349.                     }
  350.                     else if (t == typeof(byte[])) {
  351.                         value = String.Empty;
  352.                         writeDirect = true;
  353.                         type = "base64Binary";
  354.                     }
  355.                     else if (t == typeof(Guid)) {
  356.                         value = XmlConvert.ToString((Guid)o);
  357.                         type = "guid";
  358.                         typeNs = UrtTypes.Namespace;
  359.                     }
  360.                     else if (typeof(XmlNode[]).IsAssignableFrom(t)) {
  361.                         if (name == null)
  362.                             w.WriteStartElement(Soap.UrType, XmlSchema.Namespace);
  363.                         else
  364.                             w.WriteStartElement(name, ns);
  365.                        
  366.                         XmlNode[] xmlNodes = (XmlNode[])o;
  367.                         for (int i = 0; i < xmlNodes.Length; i++) {
  368.                             if (xmlNodes[i] == null)
  369.                                 continue;
  370.                             xmlNodes[i].WriteTo(w);
  371.                         }
  372.                         w.WriteEndElement();
  373.                         return;
  374.                     }
  375.                     else
  376.                         throw CreateUnknownTypeException(t);
  377.                     break;
  378.             }
  379.             if (!wroteStartElement) {
  380.                 if (name == null)
  381.                     w.WriteStartElement(type, typeNs);
  382.                 else
  383.                     w.WriteStartElement(name, ns);
  384.             }
  385.            
  386.             if (xsiType)
  387.                 WriteXsiType(type, typeNs);
  388.            
  389.             if (value == null) {
  390.                 w.WriteAttributeString("nil", XmlSchema.InstanceNamespace, "true");
  391.             }
  392.             else if (writeDirect) {
  393.                 // only one type currently writes directly to XML stream
  394.                 XmlCustomFormatter.WriteArrayBase64(w, (byte[])o, 0, ((byte[])o).Length);
  395.             }
  396.             else if (writeRaw) {
  397.                 w.WriteRaw(value);
  398.             }
  399.             else
  400.                 w.WriteString(value);
  401.             w.WriteEndElement();
  402.         }
  403.        
  404.         string GetQualifiedName(string name, string ns)
  405.         {
  406.             if (ns == null || ns.Length == 0)
  407.                 return name;
  408.             string prefix = w.LookupPrefix(ns);
  409.             if (prefix == null) {
  410.                 if (ns == XmlReservedNs.NsXml) {
  411.                     prefix = "xml";
  412.                 }
  413.                 else {
  414.                     prefix = NextPrefix();
  415.                     WriteAttribute("xmlns", prefix, null, ns);
  416.                 }
  417.             }
  418.             else if (prefix.Length == 0) {
  419.                 return name;
  420.             }
  421.             return prefix + ":" + name;
  422.         }
  423.        
  424.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromXmlQualifiedName"]/*' />
  425.         protected string FromXmlQualifiedName(XmlQualifiedName xmlQualifiedName)
  426.         {
  427.             return FromXmlQualifiedName(xmlQualifiedName, true);
  428.         }
  429.        
  430.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.FromXmlQualifiedName"]/*' />
  431.         protected string FromXmlQualifiedName(XmlQualifiedName xmlQualifiedName, bool ignoreEmpty)
  432.         {
  433.             if (xmlQualifiedName == null)
  434.                 return null;
  435.             if (xmlQualifiedName.IsEmpty && ignoreEmpty)
  436.                 return null;
  437.             return GetQualifiedName(EscapeName ? XmlConvert.EncodeLocalName(xmlQualifiedName.Name) : xmlQualifiedName.Name, xmlQualifiedName.Namespace);
  438.         }
  439.        
  440.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteStartElement"]/*' />
  441.         protected void WriteStartElement(string name)
  442.         {
  443.             WriteStartElement(name, null, null, false, null);
  444.         }
  445.        
  446.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteStartElement1"]/*' />
  447.         protected void WriteStartElement(string name, string ns)
  448.         {
  449.             WriteStartElement(name, ns, null, false, null);
  450.         }
  451.        
  452.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteStartElement4"]/*' />
  453.         protected void WriteStartElement(string name, string ns, bool writePrefixed)
  454.         {
  455.             WriteStartElement(name, ns, null, writePrefixed, null);
  456.         }
  457.        
  458.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteStartElement2"]/*' />
  459.         protected void WriteStartElement(string name, string ns, object o)
  460.         {
  461.             WriteStartElement(name, ns, o, false, null);
  462.         }
  463.        
  464.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteStartElement3"]/*' />
  465.         protected void WriteStartElement(string name, string ns, object o, bool writePrefixed)
  466.         {
  467.             WriteStartElement(name, ns, o, writePrefixed, null);
  468.         }
  469.        
  470.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteStartElement5"]/*' />
  471.         protected void WriteStartElement(string name, string ns, object o, bool writePrefixed, XmlSerializerNamespaces xmlns)
  472.         {
  473.             if (o != null && objectsInUse != null) {
  474.                 if (objectsInUse.ContainsKey(o))
  475.                     throw new InvalidOperationException(Res.GetString(Res.XmlCircularReference, o.GetType().FullName));
  476.                 objectsInUse.Add(o, o);
  477.             }
  478.            
  479.             string prefix = null;
  480.             bool needEmptyDefaultNamespace = false;
  481.             if (namespaces != null) {
  482.                 foreach (string alias in namespaces.Namespaces.Keys) {
  483.                     string aliasNs = (string)namespaces.Namespaces[alias];
  484.                    
  485.                     if (alias.Length > 0 && aliasNs == ns)
  486.                         prefix = alias;
  487.                     if (alias.Length == 0) {
  488.                         if (aliasNs == null || aliasNs.Length == 0)
  489.                             needEmptyDefaultNamespace = true;
  490.                         if (ns != aliasNs)
  491.                             writePrefixed = true;
  492.                     }
  493.                 }
  494.                 usedPrefixes = ListUsedPrefixes(namespaces.Namespaces, aliasBase);
  495.             }
  496.             if (writePrefixed && prefix == null && ns != null && ns.Length > 0) {
  497.                 prefix = w.LookupPrefix(ns);
  498.                 if (prefix == null || prefix.Length == 0) {
  499.                     prefix = NextPrefix();
  500.                 }
  501.             }
  502.             if (needEmptyDefaultNamespace && prefix == null && ns != null && ns.Length != 0)
  503.                 prefix = NextPrefix();
  504.             w.WriteStartElement(prefix, name, ns);
  505.             if (namespaces != null) {
  506.                 foreach (string alias in namespaces.Namespaces.Keys) {
  507.                     string aliasNs = (string)namespaces.Namespaces[alias];
  508.                     if (alias.Length == 0 && (aliasNs == null || aliasNs.Length == 0))
  509.                         continue;
  510.                     if (aliasNs == null || aliasNs.Length == 0) {
  511.                         if (alias.Length > 0)
  512.                             throw new InvalidOperationException(Res.GetString(Res.XmlInvalidXmlns, alias));
  513.                         WriteAttribute("xmlns", alias, null, aliasNs);
  514.                     }
  515.                     else {
  516.                         if (w.LookupPrefix(aliasNs) == null) {
  517.                             // write the default namespace declaration only if we have not written it already, over wise we just ignore one provided by the user
  518.                             if (prefix == null && alias.Length == 0)
  519.                                 break;
  520.                             WriteAttribute("xmlns", alias, null, aliasNs);
  521.                         }
  522.                     }
  523.                 }
  524.             }
  525.             WriteNamespaceDeclarations(xmlns);
  526.         }
  527.        
  528.         Hashtable ListUsedPrefixes(Hashtable nsList, string prefix)
  529.         {
  530.             Hashtable qnIndexes = new Hashtable();
  531.             int prefixLength = prefix.Length;
  532.             const string MaxInt32 = "2147483647";
  533.             foreach (string alias in namespaces.Namespaces.Keys) {
  534.                 string name;
  535.                 if (alias.Length > prefixLength) {
  536.                     name = alias;
  537.                     int nameLength = name.Length;
  538.                     if (name.Length > prefixLength && name.Length <= prefixLength + MaxInt32.Length && name.StartsWith(prefix, StringComparison.Ordinal)) {
  539.                         bool numeric = true;
  540.                         for (int j = prefixLength; j < name.Length; j++) {
  541.                             if (!Char.IsDigit(name, j)) {
  542.                                 numeric = false;
  543.                                 break;
  544.                             }
  545.                         }
  546.                         if (numeric) {
  547.                             Int64 index = Int64.Parse(name.Substring(prefixLength), CultureInfo.InvariantCulture);
  548.                             if (index <= Int32.MaxValue) {
  549.                                 Int32 newIndex = (Int32)index;
  550.                                 if (!qnIndexes.ContainsKey(newIndex)) {
  551.                                     qnIndexes.Add(newIndex, newIndex);
  552.                                 }
  553.                             }
  554.                         }
  555.                     }
  556.                 }
  557.             }
  558.             if (qnIndexes.Count > 0) {
  559.                 return qnIndexes;
  560.             }
  561.             return null;
  562.         }
  563.        
  564.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullTagEncoded"]/*' />
  565.         protected void WriteNullTagEncoded(string name)
  566.         {
  567.             WriteNullTagEncoded(name, null);
  568.         }
  569.        
  570.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullTagEncoded1"]/*' />
  571.         protected void WriteNullTagEncoded(string name, string ns)
  572.         {
  573.             if (name == null || name.Length == 0)
  574.                 return;
  575.             WriteStartElement(name, ns, null, true);
  576.             w.WriteAttributeString("nil", XmlSchema.InstanceNamespace, "true");
  577.             w.WriteEndElement();
  578.         }
  579.        
  580.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullTagLiteral"]/*' />
  581.         protected void WriteNullTagLiteral(string name)
  582.         {
  583.             WriteNullTagLiteral(name, null);
  584.         }
  585.        
  586.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullTag1"]/*' />
  587.         protected void WriteNullTagLiteral(string name, string ns)
  588.         {
  589.             if (name == null || name.Length == 0)
  590.                 return;
  591.             WriteStartElement(name, ns, null, false);
  592.             w.WriteAttributeString("nil", XmlSchema.InstanceNamespace, "true");
  593.             w.WriteEndElement();
  594.         }
  595.        
  596.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteEmptyTag"]/*' />
  597.         protected void WriteEmptyTag(string name)
  598.         {
  599.             WriteEmptyTag(name, null);
  600.         }
  601.        
  602.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteEmptyTag1"]/*' />
  603.         protected void WriteEmptyTag(string name, string ns)
  604.         {
  605.             if (name == null || name.Length == 0)
  606.                 return;
  607.             WriteStartElement(name, ns, null, false);
  608.             w.WriteEndElement();
  609.         }
  610.        
  611.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteEndElement"]/*' />
  612.         protected void WriteEndElement()
  613.         {
  614.             w.WriteEndElement();
  615.         }
  616.        
  617.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteEndElement1"]/*' />
  618.         protected void WriteEndElement(object o)
  619.         {
  620.             w.WriteEndElement();
  621.            
  622.             if (o != null && objectsInUse != null) {
  623.                 #if DEBUG
  624.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  625.                 if (!objectsInUse.ContainsKey(o))
  626.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "missing stack object of type " + o.GetType().FullName));
  627.                 #endif
  628.                
  629.                 objectsInUse.Remove(o);
  630.             }
  631.         }
  632.        
  633.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteSerializable"]/*' />
  634.         protected void WriteSerializable(IXmlSerializable serializable, string name, string ns, bool isNullable)
  635.         {
  636.             WriteSerializable(serializable, name, ns, isNullable, true);
  637.         }
  638.        
  639.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteSerializable1"]/*' />
  640.         protected void WriteSerializable(IXmlSerializable serializable, string name, string ns, bool isNullable, bool wrapped)
  641.         {
  642.             if (serializable == null) {
  643.                 if (isNullable)
  644.                     WriteNullTagLiteral(name, ns);
  645.                 return;
  646.             }
  647.             if (wrapped) {
  648.                 w.WriteStartElement(name, ns);
  649.             }
  650.             serializable.WriteXml(w);
  651.             if (wrapped) {
  652.                 w.WriteEndElement();
  653.             }
  654.         }
  655.        
  656.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullableStringEncoded"]/*' />
  657.         protected void WriteNullableStringEncoded(string name, string ns, string value, XmlQualifiedName xsiType)
  658.         {
  659.             if (value == null)
  660.                 WriteNullTagEncoded(name, ns);
  661.             else
  662.                 WriteElementString(name, ns, value, xsiType);
  663.         }
  664.        
  665.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullableStringLiteral"]/*' />
  666.         protected void WriteNullableStringLiteral(string name, string ns, string value)
  667.         {
  668.             if (value == null)
  669.                 WriteNullTagLiteral(name, ns);
  670.             else
  671.                 WriteElementString(name, ns, value, null);
  672.         }
  673.        
  674.        
  675.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullableStringEncodedRaw"]/*' />
  676.         protected void WriteNullableStringEncodedRaw(string name, string ns, string value, XmlQualifiedName xsiType)
  677.         {
  678.             if (value == null)
  679.                 WriteNullTagEncoded(name, ns);
  680.             else
  681.                 WriteElementStringRaw(name, ns, value, xsiType);
  682.         }
  683.        
  684.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullableStringEncodedRaw1"]/*' />
  685.         protected void WriteNullableStringEncodedRaw(string name, string ns, byte[] value, XmlQualifiedName xsiType)
  686.         {
  687.             if (value == null)
  688.                 WriteNullTagEncoded(name, ns);
  689.             else
  690.                 WriteElementStringRaw(name, ns, value, xsiType);
  691.         }
  692.        
  693.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullableStringLiteralRaw"]/*' />
  694.         protected void WriteNullableStringLiteralRaw(string name, string ns, string value)
  695.         {
  696.             if (value == null)
  697.                 WriteNullTagLiteral(name, ns);
  698.             else
  699.                 WriteElementStringRaw(name, ns, value, null);
  700.         }
  701.        
  702.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullableStringLiteralRaw1"]/*' />
  703.         protected void WriteNullableStringLiteralRaw(string name, string ns, byte[] value)
  704.         {
  705.             if (value == null)
  706.                 WriteNullTagLiteral(name, ns);
  707.             else
  708.                 WriteElementStringRaw(name, ns, value, null);
  709.         }
  710.        
  711.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullableQualifiedNameEncoded"]/*' />
  712.         /// <devdoc>
  713.         /// <para>[To be supplied.]</para>
  714.         /// </devdoc>
  715.         protected void WriteNullableQualifiedNameEncoded(string name, string ns, XmlQualifiedName value, XmlQualifiedName xsiType)
  716.         {
  717.             if (value == null)
  718.                 WriteNullTagEncoded(name, ns);
  719.             else
  720.                 WriteElementQualifiedName(name, ns, value, xsiType);
  721.         }
  722.        
  723.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNullableQualifiedNameLiteral"]/*' />
  724.         /// <devdoc>
  725.         /// <para>[To be supplied.]</para>
  726.         /// </devdoc>
  727.         protected void WriteNullableQualifiedNameLiteral(string name, string ns, XmlQualifiedName value)
  728.         {
  729.             if (value == null)
  730.                 WriteNullTagLiteral(name, ns);
  731.             else
  732.                 WriteElementQualifiedName(name, ns, value, null);
  733.         }
  734.        
  735.        
  736.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementEncoded"]/*' />
  737.         protected void WriteElementEncoded(XmlNode node, string name, string ns, bool isNullable, bool any)
  738.         {
  739.             if (node == null) {
  740.                 if (isNullable)
  741.                     WriteNullTagEncoded(name, ns);
  742.                 return;
  743.             }
  744.             WriteElement(node, name, ns, isNullable, any);
  745.         }
  746.        
  747.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementLiteral"]/*' />
  748.         protected void WriteElementLiteral(XmlNode node, string name, string ns, bool isNullable, bool any)
  749.         {
  750.             if (node == null) {
  751.                 if (isNullable)
  752.                     WriteNullTagLiteral(name, ns);
  753.                 return;
  754.             }
  755.             WriteElement(node, name, ns, isNullable, any);
  756.         }
  757.        
  758.         private void WriteElement(XmlNode node, string name, string ns, bool isNullable, bool any)
  759.         {
  760.             if (typeof(XmlAttribute).IsAssignableFrom(node.GetType()))
  761.                 throw new InvalidOperationException(Res.GetString(Res.XmlNoAttributeHere));
  762.             if (node is XmlDocument) {
  763.                 node = ((XmlDocument)node).DocumentElement;
  764.                 if (node == null) {
  765.                     if (isNullable)
  766.                         WriteNullTagEncoded(name, ns);
  767.                     return;
  768.                 }
  769.             }
  770.             if (any) {
  771.                 if (node is XmlElement && name != null && name.Length > 0) {
  772.                     // need to check against schema
  773.                     if (node.LocalName != name || node.NamespaceURI != ns)
  774.                         throw new InvalidOperationException(Res.GetString(Res.XmlElementNameMismatch, node.LocalName, node.NamespaceURI, name, ns));
  775.                 }
  776.             }
  777.             else
  778.                 w.WriteStartElement(name, ns);
  779.            
  780.             node.WriteTo(w);
  781.            
  782.             if (!any)
  783.                 w.WriteEndElement();
  784.         }
  785.        
  786.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateUnknownTypeException"]/*' />
  787.         protected Exception CreateUnknownTypeException(object o)
  788.         {
  789.             return CreateUnknownTypeException(o.GetType());
  790.         }
  791.        
  792.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateUnknownTypeException1"]/*' />
  793.         protected Exception CreateUnknownTypeException(Type type)
  794.         {
  795.             if (typeof(IXmlSerializable).IsAssignableFrom(type))
  796.                 return new InvalidOperationException(Res.GetString(Res.XmlInvalidSerializable, type.FullName));
  797.             TypeDesc typeDesc = new TypeScope().GetTypeDesc(type);
  798.             if (!typeDesc.IsStructLike)
  799.                 return new InvalidOperationException(Res.GetString(Res.XmlInvalidUseOfType, type.FullName));
  800.             return new InvalidOperationException(Res.GetString(Res.XmlUnxpectedType, type.FullName));
  801.         }
  802.        
  803.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateMismatchChoiceException"]/*' />
  804.         protected Exception CreateMismatchChoiceException(string value, string elementName, string enumValue)
  805.         {
  806.             // Value of {0} mismatches the type of {1}, you need to set it to {2}.
  807.             return new InvalidOperationException(Res.GetString(Res.XmlChoiceMismatchChoiceException, elementName, value, enumValue));
  808.         }
  809.        
  810.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateUnknownAnyElementException"]/*' />
  811.         protected Exception CreateUnknownAnyElementException(string name, string ns)
  812.         {
  813.             return new InvalidOperationException(Res.GetString(Res.XmlUnknownAnyElement, name, ns));
  814.         }
  815.        
  816.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateInvalidChoiceIdentifierValueException"]/*' />
  817.         protected Exception CreateInvalidChoiceIdentifierValueException(string type, string identifier)
  818.         {
  819.             return new InvalidOperationException(Res.GetString(Res.XmlInvalidChoiceIdentifierValue, type, identifier));
  820.         }
  821.        
  822.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateChoiceIdentifierValueException"]/*' />
  823.         protected Exception CreateChoiceIdentifierValueException(string value, string identifier, string name, string ns)
  824.         {
  825.             // XmlChoiceIdentifierMismatch=Value '{0}' of the choice identifier '{1}' does not match element '{2}' from namespace '{3}'.
  826.             return new InvalidOperationException(Res.GetString(Res.XmlChoiceIdentifierMismatch, value, identifier, name, ns));
  827.         }
  828.        
  829.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateInvalidEnumValueException"]/*' />
  830.         protected Exception CreateInvalidEnumValueException(object value, string typeName)
  831.         {
  832.             return new InvalidOperationException(Res.GetString(Res.XmlUnknownConstant, value, typeName));
  833.         }
  834.        
  835.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateInvalidAnyTypeException"]/*' />
  836.         protected Exception CreateInvalidAnyTypeException(object o)
  837.         {
  838.             return CreateInvalidAnyTypeException(o.GetType());
  839.         }
  840.        
  841.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.CreateInvalidAnyTypeException1"]/*' />
  842.         protected Exception CreateInvalidAnyTypeException(Type type)
  843.         {
  844.             return new InvalidOperationException(Res.GetString(Res.XmlIllegalAnyElement, type.FullName));
  845.         }
  846.        
  847.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteReferencingElement"]/*' />
  848.         protected void WriteReferencingElement(string n, string ns, object o)
  849.         {
  850.             WriteReferencingElement(n, ns, o, false);
  851.         }
  852.        
  853.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteReferencingElement1"]/*' />
  854.         protected void WriteReferencingElement(string n, string ns, object o, bool isNullable)
  855.         {
  856.             if (o == null) {
  857.                 if (isNullable)
  858.                     WriteNullTagEncoded(n, ns);
  859.                 return;
  860.             }
  861.             WriteStartElement(n, ns, null, true);
  862.             if (soap12)
  863.                 w.WriteAttributeString("ref", Soap12.Encoding, GetId(o, true));
  864.             else
  865.                 w.WriteAttributeString("href", "#" + GetId(o, true));
  866.             w.WriteEndElement();
  867.         }
  868.        
  869.         bool IsIdDefined(object o)
  870.         {
  871.             if (references != null)
  872.                 return references.Contains(o);
  873.             else
  874.                 return false;
  875.         }
  876.        
  877.         string GetId(object o, bool addToReferencesList)
  878.         {
  879.             if (references == null) {
  880.                 references = new Hashtable();
  881.                 referencesToWrite = new ArrayList();
  882.             }
  883.             string id = (string)references[o];
  884.             if (id == null) {
  885.                 id = idBase + "id" + (++nextId).ToString(CultureInfo.InvariantCulture);
  886.                 references.Add(o, id);
  887.                 if (addToReferencesList)
  888.                     referencesToWrite.Add(o);
  889.             }
  890.             return id;
  891.         }
  892.        
  893.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteId"]/*' />
  894.         protected void WriteId(object o)
  895.         {
  896.             WriteId(o, true);
  897.         }
  898.        
  899.         void WriteId(object o, bool addToReferencesList)
  900.         {
  901.             if (soap12)
  902.                 w.WriteAttributeString("id", Soap12.Encoding, GetId(o, addToReferencesList));
  903.             else
  904.                 w.WriteAttributeString("id", GetId(o, addToReferencesList));
  905.         }
  906.        
  907.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteXmlAttribute1"]/*' />
  908.         protected void WriteXmlAttribute(XmlNode node)
  909.         {
  910.             WriteXmlAttribute(node, null);
  911.         }
  912.        
  913.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteXmlAttribute2"]/*' />
  914.         protected void WriteXmlAttribute(XmlNode node, object container)
  915.         {
  916.             XmlAttribute attr = node as XmlAttribute;
  917.             if (attr == null)
  918.                 throw new InvalidOperationException(Res.GetString(Res.XmlNeedAttributeHere));
  919.             if (attr.Value != null) {
  920.                 if (attr.NamespaceURI == Wsdl.Namespace && attr.LocalName == Wsdl.ArrayType) {
  921.                     string dims;
  922.                     XmlQualifiedName qname = TypeScope.ParseWsdlArrayType(attr.Value, out dims, (container is XmlSchemaObject) ? (XmlSchemaObject)container : null);
  923.                    
  924.                     string value = FromXmlQualifiedName(qname, true) + dims;
  925.                    
  926.                     //<xsd:attribute xmlns:q3="s0" wsdl:arrayType="q3:FoosBase[]" xmlns:q4="http://schemas.xmlsoap.org/soap/encoding/" ref="q4:arrayType" />
  927.                     WriteAttribute(Wsdl.ArrayType, Wsdl.Namespace, value);
  928.                 }
  929.                 else {
  930.                     WriteAttribute(attr.Name, attr.NamespaceURI, attr.Value);
  931.                 }
  932.             }
  933.         }
  934.        
  935.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteAttribute"]/*' />
  936.         protected void WriteAttribute(string localName, string ns, string value)
  937.         {
  938.             if (value == null)
  939.                 return;
  940.             if (localName == "xmlns" || localName.StartsWith("xmlns:", StringComparison.Ordinal)) {
  941.                 ;
  942.             }
  943.             else {
  944.                 int colon = localName.IndexOf(':');
  945.                 if (colon < 0) {
  946.                     if (ns == XmlReservedNs.NsXml) {
  947.                         string prefix = w.LookupPrefix(ns);
  948.                         if (prefix == null || prefix.Length == 0)
  949.                             prefix = "xml";
  950.                         w.WriteAttributeString(prefix, localName, ns, value);
  951.                     }
  952.                     else {
  953.                         w.WriteAttributeString(localName, ns, value);
  954.                     }
  955.                 }
  956.                 else {
  957.                     string prefix = localName.Substring(0, colon);
  958.                     w.WriteAttributeString(prefix, localName.Substring(colon + 1), ns, value);
  959.                 }
  960.             }
  961.         }
  962.        
  963.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteAttribute0"]/*' />
  964.         protected void WriteAttribute(string localName, string ns, byte[] value)
  965.         {
  966.             if (value == null)
  967.                 return;
  968.             if (localName == "xmlns" || localName.StartsWith("xmlns:", StringComparison.Ordinal)) {
  969.                 ;
  970.             }
  971.             else {
  972.                 int colon = localName.IndexOf(':');
  973.                 if (colon < 0) {
  974.                     if (ns == XmlReservedNs.NsXml) {
  975.                         string prefix = w.LookupPrefix(ns);
  976.                         if (prefix == null || prefix.Length == 0)
  977.                             prefix = "xml";
  978.                         w.WriteStartAttribute("xml", localName, ns);
  979.                     }
  980.                     else {
  981.                         w.WriteStartAttribute(null, localName, ns);
  982.                     }
  983.                 }
  984.                 else {
  985.                     string prefix = localName.Substring(0, colon);
  986.                     prefix = w.LookupPrefix(ns);
  987.                     w.WriteStartAttribute(prefix, localName.Substring(colon + 1), ns);
  988.                 }
  989.                 XmlCustomFormatter.WriteArrayBase64(w, value, 0, value.Length);
  990.                 w.WriteEndAttribute();
  991.             }
  992.         }
  993.        
  994.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteAttribute1"]/*' />
  995.         protected void WriteAttribute(string localName, string value)
  996.         {
  997.             if (value == null)
  998.                 return;
  999.             w.WriteAttributeString(localName, null, value);
  1000.         }
  1001.        
  1002.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteAttribute01"]/*' />
  1003.         protected void WriteAttribute(string localName, byte[] value)
  1004.         {
  1005.             if (value == null)
  1006.                 return;
  1007.            
  1008.             w.WriteStartAttribute(null, localName, (string)null);
  1009.             XmlCustomFormatter.WriteArrayBase64(w, value, 0, value.Length);
  1010.             w.WriteEndAttribute();
  1011.         }
  1012.        
  1013.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteAttribute2"]/*' />
  1014.         protected void WriteAttribute(string prefix, string localName, string ns, string value)
  1015.         {
  1016.             if (value == null)
  1017.                 return;
  1018.             w.WriteAttributeString(prefix, localName, null, value);
  1019.         }
  1020.        
  1021.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteValue"]/*' />
  1022.         protected void WriteValue(string value)
  1023.         {
  1024.             if (value == null)
  1025.                 return;
  1026.             w.WriteString(value);
  1027.         }
  1028.        
  1029.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteValue01"]/*' />
  1030.         protected void WriteValue(byte[] value)
  1031.         {
  1032.             if (value == null)
  1033.                 return;
  1034.             XmlCustomFormatter.WriteArrayBase64(w, value, 0, value.Length);
  1035.         }
  1036.        
  1037.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteStartDocument"]/*' />
  1038.         protected void WriteStartDocument()
  1039.         {
  1040.             if (w.WriteState == WriteState.Start) {
  1041.                 w.WriteStartDocument();
  1042.             }
  1043.         }
  1044.        
  1045.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementString"]/*' />
  1046.         protected void WriteElementString(string localName, string value)
  1047.         {
  1048.             WriteElementString(localName, null, value, null);
  1049.         }
  1050.        
  1051.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementString1"]/*' />
  1052.         protected void WriteElementString(string localName, string ns, string value)
  1053.         {
  1054.             WriteElementString(localName, ns, value, null);
  1055.         }
  1056.        
  1057.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementString2"]/*' />
  1058.         protected void WriteElementString(string localName, string value, XmlQualifiedName xsiType)
  1059.         {
  1060.             WriteElementString(localName, null, value, xsiType);
  1061.         }
  1062.        
  1063.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementString3"]/*' />
  1064.         protected void WriteElementString(string localName, string ns, string value, XmlQualifiedName xsiType)
  1065.         {
  1066.             if (value == null)
  1067.                 return;
  1068.             if (xsiType == null)
  1069.                 w.WriteElementString(localName, ns, value);
  1070.             else {
  1071.                 w.WriteStartElement(localName, ns);
  1072.                 WriteXsiType(xsiType.Name, xsiType.Namespace);
  1073.                 w.WriteString(value);
  1074.                 w.WriteEndElement();
  1075.             }
  1076.         }
  1077.        
  1078.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementStringRaw"]/*' />
  1079.         protected void WriteElementStringRaw(string localName, string value)
  1080.         {
  1081.             WriteElementStringRaw(localName, null, value, null);
  1082.         }
  1083.        
  1084.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementStringRaw0"]/*' />
  1085.         protected void WriteElementStringRaw(string localName, byte[] value)
  1086.         {
  1087.             WriteElementStringRaw(localName, null, value, null);
  1088.         }
  1089.        
  1090.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementStringRaw1"]/*' />
  1091.         protected void WriteElementStringRaw(string localName, string ns, string value)
  1092.         {
  1093.             WriteElementStringRaw(localName, ns, value, null);
  1094.         }
  1095.        
  1096.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementStringRaw01"]/*' />
  1097.         protected void WriteElementStringRaw(string localName, string ns, byte[] value)
  1098.         {
  1099.             WriteElementStringRaw(localName, ns, value, null);
  1100.         }
  1101.        
  1102.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementStringRaw2"]/*' />
  1103.         protected void WriteElementStringRaw(string localName, string value, XmlQualifiedName xsiType)
  1104.         {
  1105.             WriteElementStringRaw(localName, null, value, xsiType);
  1106.         }
  1107.        
  1108.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementStringRaw02"]/*' />
  1109.         protected void WriteElementStringRaw(string localName, byte[] value, XmlQualifiedName xsiType)
  1110.         {
  1111.             WriteElementStringRaw(localName, null, value, xsiType);
  1112.         }
  1113.        
  1114.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementStringRaw3"]/*' />
  1115.         protected void WriteElementStringRaw(string localName, string ns, string value, XmlQualifiedName xsiType)
  1116.         {
  1117.             if (value == null)
  1118.                 return;
  1119.             w.WriteStartElement(localName, ns);
  1120.             if (xsiType != null)
  1121.                 WriteXsiType(xsiType.Name, xsiType.Namespace);
  1122.             w.WriteRaw(value);
  1123.             w.WriteEndElement();
  1124.         }
  1125.        
  1126.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementStringRaw03"]/*' />
  1127.         protected void WriteElementStringRaw(string localName, string ns, byte[] value, XmlQualifiedName xsiType)
  1128.         {
  1129.             if (value == null)
  1130.                 return;
  1131.             w.WriteStartElement(localName, ns);
  1132.             if (xsiType != null)
  1133.                 WriteXsiType(xsiType.Name, xsiType.Namespace);
  1134.             XmlCustomFormatter.WriteArrayBase64(w, value, 0, value.Length);
  1135.             w.WriteEndElement();
  1136.         }
  1137.        
  1138.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteRpcResult"]/*' />
  1139.         protected void WriteRpcResult(string name, string ns)
  1140.         {
  1141.             if (!soap12)
  1142.                 return;
  1143.             WriteElementQualifiedName(Soap12.RpcResult, Soap12.RpcNamespace, new XmlQualifiedName(name, ns), null);
  1144.         }
  1145.        
  1146.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementQualifiedName"]/*' />
  1147.         /// <devdoc>
  1148.         /// <para>[To be supplied.]</para>
  1149.         /// </devdoc>
  1150.         protected void WriteElementQualifiedName(string localName, XmlQualifiedName value)
  1151.         {
  1152.             WriteElementQualifiedName(localName, null, value, null);
  1153.         }
  1154.        
  1155.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementQualifiedName1"]/*' />
  1156.         protected void WriteElementQualifiedName(string localName, XmlQualifiedName value, XmlQualifiedName xsiType)
  1157.         {
  1158.             WriteElementQualifiedName(localName, null, value, xsiType);
  1159.         }
  1160.        
  1161.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementQualifiedName2"]/*' />
  1162.         /// <devdoc>
  1163.         /// <para>[To be supplied.]</para>
  1164.         /// </devdoc>
  1165.         protected void WriteElementQualifiedName(string localName, string ns, XmlQualifiedName value)
  1166.         {
  1167.             WriteElementQualifiedName(localName, ns, value, null);
  1168.         }
  1169.        
  1170.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteElementQualifiedName3"]/*' />
  1171.         protected void WriteElementQualifiedName(string localName, string ns, XmlQualifiedName value, XmlQualifiedName xsiType)
  1172.         {
  1173.             if (value == null)
  1174.                 return;
  1175.             if (value.Namespace == null || value.Namespace.Length == 0) {
  1176.                 WriteStartElement(localName, ns, null, true);
  1177.                 WriteAttribute("xmlns", "");
  1178.             }
  1179.             else
  1180.                 w.WriteStartElement(localName, ns);
  1181.             if (xsiType != null)
  1182.                 WriteXsiType(xsiType.Name, xsiType.Namespace);
  1183.             w.WriteString(FromXmlQualifiedName(value, false));
  1184.             w.WriteEndElement();
  1185.         }
  1186.        
  1187.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.AddWriteCallback"]/*' />
  1188.         protected void AddWriteCallback(Type type, string typeName, string typeNs, XmlSerializationWriteCallback callback)
  1189.         {
  1190.             TypeEntry entry = new TypeEntry();
  1191.             entry.typeName = typeName;
  1192.             entry.typeNs = typeNs;
  1193.             entry.type = type;
  1194.             entry.callback = callback;
  1195.             typeEntries.Add(type, entry);
  1196.         }
  1197.        
  1198.         void WriteArray(string name, string ns, object o, Type type)
  1199.         {
  1200.             Type elementType = TypeScope.GetArrayElementType(type, null);
  1201.             string typeName;
  1202.             string typeNs;
  1203.            
  1204.             StringBuilder arrayDims = new StringBuilder();
  1205.             if (!soap12) {
  1206.                 while ((elementType.IsArray || typeof(IEnumerable).IsAssignableFrom(elementType)) && GetPrimitiveTypeName(elementType, false) == null) {
  1207.                     elementType = TypeScope.GetArrayElementType(elementType, null);
  1208.                     arrayDims.Append("[]");
  1209.                 }
  1210.             }
  1211.            
  1212.             if (elementType == typeof(object)) {
  1213.                 typeName = Soap.UrType;
  1214.                 typeNs = XmlSchema.Namespace;
  1215.             }
  1216.             else {
  1217.                 TypeEntry entry = GetTypeEntry(elementType);
  1218.                 if (entry != null) {
  1219.                     typeName = entry.typeName;
  1220.                     typeNs = entry.typeNs;
  1221.                 }
  1222.                 else if (soap12) {
  1223.                     XmlQualifiedName qualName = GetPrimitiveTypeName(elementType, false);
  1224.                     if (qualName != null) {
  1225.                         typeName = qualName.Name;
  1226.                         typeNs = qualName.Namespace;
  1227.                     }
  1228.                     else {
  1229.                         Type elementBaseType = elementType.BaseType;
  1230.                         while (elementBaseType != null) {
  1231.                             entry = GetTypeEntry(elementBaseType);
  1232.                             if (entry != null)
  1233.                                 break;
  1234.                             elementBaseType = elementBaseType.BaseType;
  1235.                         }
  1236.                         if (entry != null) {
  1237.                             typeName = entry.typeName;
  1238.                             typeNs = entry.typeNs;
  1239.                         }
  1240.                         else {
  1241.                             typeName = Soap.UrType;
  1242.                             typeNs = XmlSchema.Namespace;
  1243.                         }
  1244.                     }
  1245.                 }
  1246.                 else {
  1247.                     XmlQualifiedName qualName = GetPrimitiveTypeName(elementType);
  1248.                     typeName = qualName.Name;
  1249.                     typeNs = qualName.Namespace;
  1250.                 }
  1251.             }
  1252.            
  1253.             if (arrayDims.Length > 0)
  1254.                 typeName = typeName + arrayDims.ToString();
  1255.            
  1256.             if (soap12 && name != null && name.Length > 0)
  1257.                 WriteStartElement(name, ns, null, false);
  1258.             else
  1259.                 WriteStartElement(Soap.Array, Soap.Encoding, null, true);
  1260.            
  1261.             WriteId(o, false);
  1262.            
  1263.             if (type.IsArray) {
  1264.                 Array a = (Array)o;
  1265.                 int arrayLength = a.Length;
  1266.                 if (soap12) {
  1267.                     w.WriteAttributeString("itemType", Soap12.Encoding, GetQualifiedName(typeName, typeNs));
  1268.                     w.WriteAttributeString("arraySize", Soap12.Encoding, arrayLength.ToString(CultureInfo.InvariantCulture));
  1269.                 }
  1270.                 else {
  1271.                     w.WriteAttributeString("arrayType", Soap.Encoding, GetQualifiedName(typeName, typeNs) + "[" + arrayLength.ToString(CultureInfo.InvariantCulture) + "]");
  1272.                 }
  1273.                 for (int i = 0; i < arrayLength; i++) {
  1274.                     WritePotentiallyReferencingElement("Item", "", a.GetValue(i), elementType, false, true);
  1275.                 }
  1276.             }
  1277.             else {
  1278.                 #if DEBUG
  1279.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  1280.                 if (!typeof(IEnumerable).IsAssignableFrom(type))
  1281.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "not array like type " + type.FullName));
  1282.                 #endif
  1283.                
  1284.                 int arrayLength = typeof(ICollection).IsAssignableFrom(type) ? ((ICollection)o).Count : -1;
  1285.                 if (soap12) {
  1286.                     w.WriteAttributeString("itemType", Soap12.Encoding, GetQualifiedName(typeName, typeNs));
  1287.                     if (arrayLength >= 0)
  1288.                         w.WriteAttributeString("arraySize", Soap12.Encoding, arrayLength.ToString(CultureInfo.InvariantCulture));
  1289.                 }
  1290.                 else {
  1291.                     string brackets = arrayLength >= 0 ? "[" + arrayLength + "]" : "[]";
  1292.                     w.WriteAttributeString("arrayType", Soap.Encoding, GetQualifiedName(typeName, typeNs) + brackets);
  1293.                 }
  1294.                 IEnumerator e = ((IEnumerable)o).GetEnumerator();
  1295.                 if (e != null) {
  1296.                     while (e.MoveNext()) {
  1297.                         WritePotentiallyReferencingElement("Item", "", e.Current, elementType, false, true);
  1298.                     }
  1299.                 }
  1300.             }
  1301.             w.WriteEndElement();
  1302.         }
  1303.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WritePotentiallyReferencingElement"]/*' />
  1304.         protected void WritePotentiallyReferencingElement(string n, string ns, object o)
  1305.         {
  1306.             WritePotentiallyReferencingElement(n, ns, o, null, false, false);
  1307.         }
  1308.        
  1309.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WritePotentiallyReferencingElement1"]/*' />
  1310.         protected void WritePotentiallyReferencingElement(string n, string ns, object o, Type ambientType)
  1311.         {
  1312.             WritePotentiallyReferencingElement(n, ns, o, ambientType, false, false);
  1313.         }
  1314.        
  1315.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WritePotentiallyReferencingElement2"]/*' />
  1316.         protected void WritePotentiallyReferencingElement(string n, string ns, object o, Type ambientType, bool suppressReference)
  1317.         {
  1318.             WritePotentiallyReferencingElement(n, ns, o, ambientType, suppressReference, false);
  1319.         }
  1320.        
  1321.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WritePotentiallyReferencingElement3"]/*' />
  1322.         protected void WritePotentiallyReferencingElement(string n, string ns, object o, Type ambientType, bool suppressReference, bool isNullable)
  1323.         {
  1324.             if (o == null) {
  1325.                 if (isNullable)
  1326.                     WriteNullTagEncoded(n, ns);
  1327.                 return;
  1328.             }
  1329.             Type t = o.GetType();
  1330.             if (Convert.GetTypeCode(o) == TypeCode.Object && !(o is Guid) && (t != typeof(XmlQualifiedName)) && !(o is XmlNode[]) && (t != typeof(byte[]))) {
  1331.                 if ((suppressReference || soap12) && !IsIdDefined(o)) {
  1332.                     WriteReferencedElement(n, ns, o, ambientType);
  1333.                 }
  1334.                 else {
  1335.                     if (n == null) {
  1336.                         TypeEntry entry = GetTypeEntry(t);
  1337.                         WriteReferencingElement(entry.typeName, entry.typeNs, o, isNullable);
  1338.                     }
  1339.                     else
  1340.                         WriteReferencingElement(n, ns, o, isNullable);
  1341.                 }
  1342.             }
  1343.             else {
  1344.                 // Enums always write xsi:type, so don't write it again here.
  1345.                 bool needXsiType = t != ambientType && !t.IsEnum;
  1346.                 TypeEntry entry = GetTypeEntry(t);
  1347.                 if (entry != null) {
  1348.                     if (n == null)
  1349.                         WriteStartElement(entry.typeName, entry.typeNs, null, true);
  1350.                     else
  1351.                         WriteStartElement(n, ns, null, true);
  1352.                    
  1353.                     if (needXsiType)
  1354.                         WriteXsiType(entry.typeName, entry.typeNs);
  1355.                     entry.callback(o);
  1356.                     w.WriteEndElement();
  1357.                 }
  1358.                 else {
  1359.                     WriteTypedPrimitive(n, ns, o, needXsiType);
  1360.                 }
  1361.             }
  1362.         }
  1363.        
  1364.        
  1365.         void WriteReferencedElement(object o, Type ambientType)
  1366.         {
  1367.             WriteReferencedElement(null, null, o, ambientType);
  1368.         }
  1369.        
  1370.         void WriteReferencedElement(string name, string ns, object o, Type ambientType)
  1371.         {
  1372.             if (name == null)
  1373.                 name = String.Empty;
  1374.             Type t = o.GetType();
  1375.             if (t.IsArray || typeof(IEnumerable).IsAssignableFrom(t)) {
  1376.                 WriteArray(name, ns, o, t);
  1377.             }
  1378.             else {
  1379.                 TypeEntry entry = GetTypeEntry(t);
  1380.                 if (entry == null)
  1381.                     throw CreateUnknownTypeException(t);
  1382.                 WriteStartElement(name.Length == 0 ? entry.typeName : name, ns == null ? entry.typeNs : ns, null, true);
  1383.                 WriteId(o, false);
  1384.                 if (ambientType != t)
  1385.                     WriteXsiType(entry.typeName, entry.typeNs);
  1386.                 entry.callback(o);
  1387.                 w.WriteEndElement();
  1388.             }
  1389.         }
  1390.        
  1391.         TypeEntry GetTypeEntry(Type t)
  1392.         {
  1393.             if (typeEntries == null) {
  1394.                 typeEntries = new Hashtable();
  1395.                 InitCallbacks();
  1396.             }
  1397.             return (TypeEntry)typeEntries[t];
  1398.         }
  1399.        
  1400.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.InitCallbacks"]/*' />
  1401.         protected abstract void InitCallbacks();
  1402.        
  1403.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteReferencedElements"]/*' />
  1404.         protected void WriteReferencedElements()
  1405.         {
  1406.             if (referencesToWrite == null)
  1407.                 return;
  1408.            
  1409.             for (int i = 0; i < referencesToWrite.Count; i++) {
  1410.                 WriteReferencedElement(referencesToWrite[i], null);
  1411.             }
  1412.         }
  1413.        
  1414.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.TopLevelElement"]/*' />
  1415.         protected void TopLevelElement()
  1416.         {
  1417.             objectsInUse = new Hashtable();
  1418.         }
  1419.        
  1420.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteNamespaceDeclarations"]/*' />
  1421.         ///<internalonly/>
  1422.         protected void WriteNamespaceDeclarations(XmlSerializerNamespaces xmlns)
  1423.         {
  1424.             if (xmlns != null) {
  1425.                 foreach (DictionaryEntry entry in xmlns.Namespaces) {
  1426.                     string prefix = (string)entry.Key;
  1427.                     string ns = (string)entry.Value;
  1428.                     if (namespaces != null) {
  1429.                         string oldNs = namespaces.Namespaces[prefix] as string;
  1430.                         if (oldNs != null && oldNs != ns) {
  1431.                             throw new InvalidOperationException(Res.GetString(Res.XmlDuplicateNs, prefix, ns));
  1432.                         }
  1433.                     }
  1434.                     string oldPrefix = (ns == null || ns.Length == 0) ? null : Writer.LookupPrefix(ns);
  1435.                    
  1436.                     if (oldPrefix == null || oldPrefix != prefix) {
  1437.                         WriteAttribute("xmlns", prefix, null, ns);
  1438.                     }
  1439.                 }
  1440.             }
  1441.             namespaces = null;
  1442.         }
  1443.        
  1444.         string NextPrefix()
  1445.         {
  1446.             if (usedPrefixes == null) {
  1447.                 return aliasBase + (++tempNamespacePrefix);
  1448.             }
  1449.             while (usedPrefixes.ContainsKey(++tempNamespacePrefix)) {
  1450.                 ;
  1451.             }
  1452.             return aliasBase + tempNamespacePrefix;
  1453.         }
  1454.        
  1455.         internal class TypeEntry
  1456.         {
  1457.             internal XmlSerializationWriteCallback callback;
  1458.             internal string typeNs;
  1459.             internal string typeName;
  1460.             internal Type type;
  1461.         }
  1462.     }
  1463.    
  1464.    
  1465.     /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriteCallback"]/*' />
  1466.     ///<internalonly/>
  1467.     public delegate void XmlSerializationWriteCallback(object o);
  1468.    
  1469.     internal class XmlSerializationWriterCodeGen : XmlSerializationCodeGen
  1470.     {
  1471.        
  1472.         internal XmlSerializationWriterCodeGen(IndentedWriter writer, TypeScope[] scopes, string access, string className) : base(writer, scopes, access, className)
  1473.         {
  1474.         }
  1475.        
  1476.         internal void GenerateBegin()
  1477.         {
  1478.             Writer.Write(Access);
  1479.             Writer.Write(" class ");
  1480.             Writer.Write(ClassName);
  1481.             Writer.Write(" : ");
  1482.             Writer.Write(typeof(XmlSerializationWriter).FullName);
  1483.             Writer.WriteLine(" {");
  1484.             Writer.Indent++;
  1485.            
  1486.             foreach (TypeScope scope in Scopes) {
  1487.                 foreach (TypeMapping mapping in scope.TypeMappings) {
  1488.                     if (mapping is StructMapping || mapping is EnumMapping) {
  1489.                         MethodNames.Add(mapping, NextMethodName(mapping.TypeDesc.Name));
  1490.                     }
  1491.                 }
  1492.                 RaCodeGen.WriteReflectionInit(scope);
  1493.             }
  1494.            
  1495.             // pre-generate write methods only for the encoded soap
  1496.             foreach (TypeScope scope in Scopes) {
  1497.                 foreach (TypeMapping mapping in scope.TypeMappings) {
  1498.                     if (!mapping.IsSoap)
  1499.                         continue;
  1500.                    
  1501.                     if (mapping is StructMapping)
  1502.                         WriteStructMethod((StructMapping)mapping);
  1503.                     else if (mapping is EnumMapping)
  1504.                         WriteEnumMethod((EnumMapping)mapping);
  1505.                 }
  1506.             }
  1507.         }
  1508.        
  1509.         internal override void GenerateMethod(TypeMapping mapping)
  1510.         {
  1511.             if (GeneratedMethods.Contains(mapping))
  1512.                 return;
  1513.            
  1514.             GeneratedMethods[mapping] = mapping;
  1515.             if (mapping is StructMapping) {
  1516.                 WriteStructMethod((StructMapping)mapping);
  1517.             }
  1518.             else if (mapping is EnumMapping) {
  1519.                 WriteEnumMethod((EnumMapping)mapping);
  1520.             }
  1521.         }
  1522.         internal void GenerateEnd()
  1523.         {
  1524.             GenerateReferencedMethods();
  1525.             GenerateInitCallbacksMethod();
  1526.             Writer.Indent--;
  1527.             Writer.WriteLine("}");
  1528.         }
  1529.        
  1530.         internal string GenerateElement(XmlMapping xmlMapping)
  1531.         {
  1532.             if (!xmlMapping.IsWriteable)
  1533.                 return null;
  1534.             if (!xmlMapping.GenerateSerializer)
  1535.                 throw new ArgumentException(Res.GetString(Res.XmlInternalError), "xmlMapping");
  1536.             if (xmlMapping is XmlTypeMapping)
  1537.                 return GenerateTypeElement((XmlTypeMapping)xmlMapping);
  1538.             else if (xmlMapping is XmlMembersMapping)
  1539.                 return GenerateMembersElement((XmlMembersMapping)xmlMapping);
  1540.             else
  1541.                 throw new ArgumentException(Res.GetString(Res.XmlInternalError), "xmlMapping");
  1542.         }
  1543.        
  1544.         void GenerateInitCallbacksMethod()
  1545.         {
  1546.             Writer.WriteLine();
  1547.             Writer.WriteLine("protected override void InitCallbacks() {");
  1548.             Writer.Indent++;
  1549.            
  1550.             foreach (TypeScope scope in Scopes) {
  1551.                 foreach (TypeMapping typeMapping in scope.TypeMappings) {
  1552.                     if (typeMapping.IsSoap && (typeMapping is StructMapping || typeMapping is EnumMapping) && !typeMapping.TypeDesc.IsRoot) {
  1553.                        
  1554.                         string methodName = (string)MethodNames[typeMapping];
  1555.                         Writer.Write("AddWriteCallback(");
  1556.                         Writer.Write(RaCodeGen.GetStringForTypeof(typeMapping.TypeDesc.CSharpName, typeMapping.TypeDesc.UseReflection));
  1557.                         Writer.Write(", ");
  1558.                         WriteQuotedCSharpString(typeMapping.TypeName);
  1559.                         Writer.Write(", ");
  1560.                         WriteQuotedCSharpString(typeMapping.Namespace);
  1561.                         Writer.Write(", new ");
  1562.                         Writer.Write(typeof(XmlSerializationWriteCallback).FullName);
  1563.                         Writer.Write("(this.");
  1564.                         Writer.Write(methodName);
  1565.                         Writer.WriteLine("));");
  1566.                     }
  1567.                 }
  1568.             }
  1569.             Writer.Indent--;
  1570.             Writer.WriteLine("}");
  1571.         }
  1572.        
  1573.         void WriteQualifiedNameElement(string name, string ns, object defaultValue, string source, bool nullable, bool IsSoap, TypeMapping mapping)
  1574.         {
  1575.             bool hasDefault = defaultValue != null && defaultValue != DBNull.Value;
  1576.             if (hasDefault) {
  1577.                 WriteCheckDefault(source, defaultValue, nullable);
  1578.                 Writer.WriteLine(" {");
  1579.                 Writer.Indent++;
  1580.             }
  1581.             string suffix = IsSoap ? "Encoded" : "Literal";
  1582.             Writer.Write(nullable ? ("WriteNullableQualifiedName" + suffix) : "WriteElementQualifiedName");
  1583.             Writer.Write("(");
  1584.             WriteQuotedCSharpString(name);
  1585.             if (ns != null) {
  1586.                 Writer.Write(", ");
  1587.                 WriteQuotedCSharpString(ns);
  1588.             }
  1589.             Writer.Write(", ");
  1590.             Writer.Write(source);
  1591.            
  1592.             if (IsSoap) {
  1593.                 Writer.Write(", new System.Xml.XmlQualifiedName(");
  1594.                 WriteQuotedCSharpString(mapping.TypeName);
  1595.                 Writer.Write(", ");
  1596.                 WriteQuotedCSharpString(mapping.Namespace);
  1597.                 Writer.Write(")");
  1598.             }
  1599.            
  1600.             Writer.WriteLine(");");
  1601.            
  1602.             if (hasDefault) {
  1603.                 Writer.Indent--;
  1604.                 Writer.WriteLine("}");
  1605.             }
  1606.         }
  1607.        
  1608.         void WriteEnumValue(EnumMapping mapping, string source)
  1609.         {
  1610.             string methodName = ReferenceMapping(mapping);
  1611.            
  1612.             #if DEBUG
  1613.             // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  1614.             if (methodName == null)
  1615.                 throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name) + Environment.StackTrace);
  1616.             #endif
  1617.            
  1618.             Writer.Write(methodName);
  1619.             Writer.Write("(");
  1620.             Writer.Write(source);
  1621.             Writer.Write(")");
  1622.         }
  1623.        
  1624.         void WritePrimitiveValue(TypeDesc typeDesc, string source, bool isElement)
  1625.         {
  1626.             if (typeDesc == StringTypeDesc || typeDesc.FormatterName == "String") {
  1627.                 Writer.Write(source);
  1628.             }
  1629.             else {
  1630.                 if (!typeDesc.HasCustomFormatter) {
  1631.                     Writer.Write(typeof(XmlConvert).FullName);
  1632.                     Writer.Write(".ToString((");
  1633.                     Writer.Write(typeDesc.CSharpName);
  1634.                     Writer.Write(")");
  1635.                     Writer.Write(source);
  1636.                     Writer.Write(")");
  1637.                 }
  1638.                 else {
  1639.                     Writer.Write("From");
  1640.                     Writer.Write(typeDesc.FormatterName);
  1641.                     Writer.Write("(");
  1642.                     Writer.Write(source);
  1643.                     Writer.Write(")");
  1644.                 }
  1645.             }
  1646.         }
  1647.        
  1648.         void WritePrimitive(string method, string name, string ns, object defaultValue, string source, TypeMapping mapping, bool writeXsiType, bool isElement, bool isNullable)
  1649.         {
  1650.             TypeDesc typeDesc = mapping.TypeDesc;
  1651.             bool hasDefault = defaultValue != null && defaultValue != DBNull.Value && mapping.TypeDesc.HasDefaultSupport;
  1652.             if (hasDefault) {
  1653.                 if (mapping is EnumMapping) {
  1654.                     #if DEBUG
  1655.                     // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  1656.                     if (defaultValue.GetType() != typeof(string))
  1657.                         throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, name + " has invalid default type " + defaultValue.GetType().Name));
  1658.                     #endif
  1659.                    
  1660.                     Writer.Write("if (");
  1661.                     if (mapping.TypeDesc.UseReflection)
  1662.                         Writer.Write(RaCodeGen.GetStringForEnumLongValue(source, mapping.TypeDesc.UseReflection));
  1663.                     else
  1664.                         Writer.Write(source);
  1665.                     Writer.Write(" != ");
  1666.                     if (((EnumMapping)mapping).IsFlags) {
  1667.                         Writer.Write("(");
  1668.                         string[] values = ((string)defaultValue).Split(null);
  1669.                         for (int i = 0; i < values.Length; i++) {
  1670.                             if (values[i] == null || values[i].Length == 0)
  1671.                                 continue;
  1672.                             if (i > 0)
  1673.                                 Writer.WriteLine(" | ");
  1674.                             Writer.Write(RaCodeGen.GetStringForEnumCompare((EnumMapping)mapping, values[i], mapping.TypeDesc.UseReflection));
  1675.                         }
  1676.                         Writer.Write(")");
  1677.                     }
  1678.                     else {
  1679.                         Writer.Write(RaCodeGen.GetStringForEnumCompare((EnumMapping)mapping, (string)defaultValue, mapping.TypeDesc.UseReflection));
  1680.                     }
  1681.                     Writer.Write(")");
  1682.                 }
  1683.                 else {
  1684.                     WriteCheckDefault(source, defaultValue, isNullable);
  1685.                 }
  1686.                 Writer.WriteLine(" {");
  1687.                 Writer.Indent++;
  1688.             }
  1689.             Writer.Write(method);
  1690.             Writer.Write("(");
  1691.             WriteQuotedCSharpString(name);
  1692.             if (ns != null) {
  1693.                 Writer.Write(", ");
  1694.                 WriteQuotedCSharpString(ns);
  1695.             }
  1696.             Writer.Write(", ");
  1697.            
  1698.             if (mapping is EnumMapping) {
  1699.                 WriteEnumValue((EnumMapping)mapping, source);
  1700.             }
  1701.             else {
  1702.                 WritePrimitiveValue(typeDesc, source, isElement);
  1703.             }
  1704.            
  1705.             if (writeXsiType) {
  1706.                 Writer.Write(", new System.Xml.XmlQualifiedName(");
  1707.                 WriteQuotedCSharpString(mapping.TypeName);
  1708.                 Writer.Write(", ");
  1709.                 WriteQuotedCSharpString(mapping.Namespace);
  1710.                 Writer.Write(")");
  1711.             }
  1712.            
  1713.             Writer.WriteLine(");");
  1714.            
  1715.             if (hasDefault) {
  1716.                 Writer.Indent--;
  1717.                 Writer.WriteLine("}");
  1718.             }
  1719.         }
  1720.        
  1721.         void WriteTag(string methodName, string name, string ns)
  1722.         {
  1723.             Writer.Write(methodName);
  1724.             Writer.Write("(");
  1725.             WriteQuotedCSharpString(name);
  1726.             Writer.Write(", ");
  1727.             if (ns == null) {
  1728.                 Writer.Write("null");
  1729.             }
  1730.             else {
  1731.                 WriteQuotedCSharpString(ns);
  1732.             }
  1733.             Writer.WriteLine(");");
  1734.         }
  1735.        
  1736.         void WriteTag(string methodName, string name, string ns, bool writePrefixed)
  1737.         {
  1738.             Writer.Write(methodName);
  1739.             Writer.Write("(");
  1740.             WriteQuotedCSharpString(name);
  1741.             Writer.Write(", ");
  1742.             if (ns == null) {
  1743.                 Writer.Write("null");
  1744.             }
  1745.             else {
  1746.                 WriteQuotedCSharpString(ns);
  1747.             }
  1748.             Writer.Write(", null, ");
  1749.             if (writePrefixed)
  1750.                 Writer.Write("true");
  1751.             else
  1752.                 Writer.Write("false");
  1753.             Writer.WriteLine(");");
  1754.         }
  1755.        
  1756.         void WriteStartElement(string name, string ns, bool writePrefixed)
  1757.         {
  1758.             WriteTag("WriteStartElement", name, ns, writePrefixed);
  1759.         }
  1760.        
  1761.         void WriteEndElement()
  1762.         {
  1763.             Writer.WriteLine("WriteEndElement();");
  1764.         }
  1765.         void WriteEndElement(string source)
  1766.         {
  1767.             Writer.Write("WriteEndElement(");
  1768.             Writer.Write(source);
  1769.             Writer.WriteLine(");");
  1770.         }
  1771.        
  1772.         void WriteEncodedNullTag(string name, string ns)
  1773.         {
  1774.             WriteTag("WriteNullTagEncoded", name, ns);
  1775.         }
  1776.        
  1777.         void WriteLiteralNullTag(string name, string ns)
  1778.         {
  1779.             WriteTag("WriteNullTagLiteral", name, ns);
  1780.         }
  1781.        
  1782.         void WriteEmptyTag(string name, string ns)
  1783.         {
  1784.             WriteTag("WriteEmptyTag", name, ns);
  1785.         }
  1786.        
  1787.         string GenerateMembersElement(XmlMembersMapping xmlMembersMapping)
  1788.         {
  1789.             ElementAccessor element = xmlMembersMapping.Accessor;
  1790.             MembersMapping mapping = (MembersMapping)element.Mapping;
  1791.             bool hasWrapperElement = mapping.HasWrapperElement;
  1792.             bool writeAccessors = mapping.WriteAccessors;
  1793.             bool isRpc = xmlMembersMapping.IsSoap && writeAccessors;
  1794.             string methodName = NextMethodName(element.Name);
  1795.             Writer.WriteLine();
  1796.             Writer.Write("public void ");
  1797.             Writer.Write(methodName);
  1798.             Writer.WriteLine("(object[] p) {");
  1799.             Writer.Indent++;
  1800.            
  1801.             Writer.WriteLine("WriteStartDocument();");
  1802.            
  1803.             if (!mapping.IsSoap) {
  1804.                 Writer.WriteLine("TopLevelElement();");
  1805.             }
  1806.            
  1807.             // in the top-level method add check for the parameters length,
  1808.             // because visual basic does not have a concept of an <out> parameter it uses <ByRef> instead
  1809.             // so sometime we think that we have more parameters then supplied
  1810.             Writer.WriteLine("int pLength = p.Length;");
  1811.            
  1812.             if (hasWrapperElement) {
  1813.                 WriteStartElement(element.Name, (element.Form == XmlSchemaForm.Qualified ? element.Namespace : ""), mapping.IsSoap);
  1814.                
  1815.                 int xmlnsMember = FindXmlnsIndex(mapping.Members);
  1816.                 if (xmlnsMember >= 0) {
  1817.                     MemberMapping member = mapping.Members[xmlnsMember];
  1818.                     string source = "((" + typeof(XmlSerializerNamespaces).FullName + ")p[" + xmlnsMember.ToString(CultureInfo.InvariantCulture) + "])";
  1819.                    
  1820.                     Writer.Write("if (pLength > ");
  1821.                     Writer.Write(xmlnsMember.ToString(CultureInfo.InvariantCulture));
  1822.                     Writer.WriteLine(") {");
  1823.                     Writer.Indent++;
  1824.                     WriteNamespaces(source);
  1825.                     Writer.Indent--;
  1826.                     Writer.WriteLine("}");
  1827.                 }
  1828.                
  1829.                 for (int i = 0; i < mapping.Members.Length; i++) {
  1830.                     MemberMapping member = mapping.Members[i];
  1831.                    
  1832.                     if (member.Attribute != null && !member.Ignore) {
  1833.                         string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  1834.                        
  1835.                         string specifiedSource = null;
  1836.                         int specifiedPosition = 0;
  1837.                         if (member.CheckSpecified) {
  1838.                             string memberNameSpecified = member.Name + "Specified";
  1839.                             for (int j = 0; j < mapping.Members.Length; j++) {
  1840.                                 if (mapping.Members[j].Name == memberNameSpecified) {
  1841.                                     specifiedSource = "((bool) p[" + j.ToString(CultureInfo.InvariantCulture) + "])";
  1842.                                     specifiedPosition = j;
  1843.                                     break;
  1844.                                 }
  1845.                             }
  1846.                         }
  1847.                        
  1848.                         Writer.Write("if (pLength > ");
  1849.                         Writer.Write(i.ToString(CultureInfo.InvariantCulture));
  1850.                         Writer.WriteLine(") {");
  1851.                         Writer.Indent++;
  1852.                        
  1853.                         if (specifiedSource != null) {
  1854.                             Writer.Write("if (pLength <= ");
  1855.                             Writer.Write(specifiedPosition.ToString(CultureInfo.InvariantCulture));
  1856.                             Writer.Write(" || ");
  1857.                             Writer.Write(specifiedSource);
  1858.                             Writer.WriteLine(") {");
  1859.                             Writer.Indent++;
  1860.                         }
  1861.                        
  1862.                         WriteMember(source, member.Attribute, member.TypeDesc, "p");
  1863.                        
  1864.                         if (specifiedSource != null) {
  1865.                             Writer.Indent--;
  1866.                             Writer.WriteLine("}");
  1867.                         }
  1868.                        
  1869.                         Writer.Indent--;
  1870.                         Writer.WriteLine("}");
  1871.                     }
  1872.                 }
  1873.             }
  1874.            
  1875.             for (int i = 0; i < mapping.Members.Length; i++) {
  1876.                 MemberMapping member = mapping.Members[i];
  1877.                 if (member.Xmlns != null)
  1878.                     continue;
  1879.                 if (member.Ignore)
  1880.                     continue;
  1881.                
  1882.                 string specifiedSource = null;
  1883.                 int specifiedPosition = 0;
  1884.                 if (member.CheckSpecified) {
  1885.                     string memberNameSpecified = member.Name + "Specified";
  1886.                    
  1887.                     for (int j = 0; j < mapping.Members.Length; j++) {
  1888.                         if (mapping.Members[j].Name == memberNameSpecified) {
  1889.                             specifiedSource = "((bool) p[" + j.ToString(CultureInfo.InvariantCulture) + "])";
  1890.                             specifiedPosition = j;
  1891.                             break;
  1892.                         }
  1893.                     }
  1894.                 }
  1895.                
  1896.                 Writer.Write("if (pLength > ");
  1897.                 Writer.Write(i.ToString(CultureInfo.InvariantCulture));
  1898.                 Writer.WriteLine(") {");
  1899.                 Writer.Indent++;
  1900.                
  1901.                 if (specifiedSource != null) {
  1902.                     Writer.Write("if (pLength <= ");
  1903.                     Writer.Write(specifiedPosition.ToString(CultureInfo.InvariantCulture));
  1904.                     Writer.Write(" || ");
  1905.                     Writer.Write(specifiedSource);
  1906.                     Writer.WriteLine(") {");
  1907.                     Writer.Indent++;
  1908.                 }
  1909.                
  1910.                 string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  1911.                 string enumSource = null;
  1912.                 if (member.ChoiceIdentifier != null) {
  1913.                     for (int j = 0; j < mapping.Members.Length; j++) {
  1914.                         if (mapping.Members[j].Name == member.ChoiceIdentifier.MemberName) {
  1915.                             if (member.ChoiceIdentifier.Mapping.TypeDesc.UseReflection)
  1916.                                 enumSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
  1917.                             else
  1918.                                 enumSource = "((" + mapping.Members[j].TypeDesc.CSharpName + ")p[" + j.ToString(CultureInfo.InvariantCulture) + "]" + ")";
  1919.                             break;
  1920.                         }
  1921.                     }
  1922.                    
  1923.                     #if DEBUG
  1924.                     // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  1925.                     if (enumSource == null)
  1926.                         throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Can not find " + member.ChoiceIdentifier.MemberName + " in the members mapping."));
  1927.                     #endif
  1928.                    
  1929.                 }
  1930.                
  1931.                 if (isRpc && member.IsReturnValue && member.Elements.Length > 0) {
  1932.                     Writer.Write("WriteRpcResult(");
  1933.                     WriteQuotedCSharpString(member.Elements[0].Name);
  1934.                     Writer.Write(", ");
  1935.                     WriteQuotedCSharpString("");
  1936.                     Writer.WriteLine(");");
  1937.                 }
  1938.                
  1939.                 // override writeAccessors choice when we've written a wrapper element
  1940.                 WriteMember(source, enumSource, member.ElementsSortedByDerivation, member.Text, member.ChoiceIdentifier, member.TypeDesc, writeAccessors || hasWrapperElement);
  1941.                
  1942.                 if (specifiedSource != null) {
  1943.                     Writer.Indent--;
  1944.                     Writer.WriteLine("}");
  1945.                 }
  1946.                
  1947.                 Writer.Indent--;
  1948.                 Writer.WriteLine("}");
  1949.             }
  1950.            
  1951.             if (hasWrapperElement) {
  1952.                 WriteEndElement();
  1953.             }
  1954.             if (element.IsSoap) {
  1955.                 if (!hasWrapperElement && !writeAccessors) {
  1956.                     // doc/bare case -- allow extra members
  1957.                     Writer.Write("if (pLength > ");
  1958.                     Writer.Write(mapping.Members.Length.ToString(CultureInfo.InvariantCulture));
  1959.                     Writer.WriteLine(") {");
  1960.                     Writer.Indent++;
  1961.                    
  1962.                     WriteExtraMembers(mapping.Members.Length.ToString(CultureInfo.InvariantCulture), "pLength");
  1963.                    
  1964.                     Writer.Indent--;
  1965.                     Writer.WriteLine("}");
  1966.                 }
  1967.                 Writer.WriteLine("WriteReferencedElements();");
  1968.             }
  1969.             Writer.Indent--;
  1970.             Writer.WriteLine("}");
  1971.             return methodName;
  1972.         }
  1973.        
  1974.         string GenerateTypeElement(XmlTypeMapping xmlTypeMapping)
  1975.         {
  1976.             ElementAccessor element = xmlTypeMapping.Accessor;
  1977.             TypeMapping mapping = element.Mapping;
  1978.             string methodName = NextMethodName(element.Name);
  1979.             Writer.WriteLine();
  1980.             Writer.Write("public void ");
  1981.             Writer.Write(methodName);
  1982.             Writer.WriteLine("(object o) {");
  1983.             Writer.Indent++;
  1984.            
  1985.             Writer.WriteLine("WriteStartDocument();");
  1986.            
  1987.             Writer.WriteLine("if (o == null) {");
  1988.             Writer.Indent++;
  1989.             if (element.IsNullable) {
  1990.                 if (mapping.IsSoap)
  1991.                     WriteEncodedNullTag(element.Name, (element.Form == XmlSchemaForm.Qualified ? element.Namespace : ""));
  1992.                 else
  1993.                     WriteLiteralNullTag(element.Name, (element.Form == XmlSchemaForm.Qualified ? element.Namespace : ""));
  1994.             }
  1995.             else
  1996.                 WriteEmptyTag(element.Name, (element.Form == XmlSchemaForm.Qualified ? element.Namespace : ""));
  1997.             Writer.WriteLine("return;");
  1998.             Writer.Indent--;
  1999.             Writer.WriteLine("}");
  2000.            
  2001.             if (!mapping.IsSoap && !mapping.TypeDesc.IsValueType && !mapping.TypeDesc.Type.IsPrimitive) {
  2002.                 Writer.WriteLine("TopLevelElement();");
  2003.             }
  2004.            
  2005.             WriteMember("o", null, new ElementAccessor[] {element}, null, null, mapping.TypeDesc, !element.IsSoap);
  2006.            
  2007.             if (mapping.IsSoap) {
  2008.                 Writer.WriteLine("WriteReferencedElements();");
  2009.             }
  2010.             Writer.Indent--;
  2011.             Writer.WriteLine("}");
  2012.             return methodName;
  2013.         }
  2014.        
  2015.         string NextMethodName(string name)
  2016.         {
  2017.             return "Write" + (++NextMethodNumber).ToString(null, NumberFormatInfo.InvariantInfo) + "_" + CodeIdentifier.MakeValidInternal(name);
  2018.         }
  2019.        
  2020.         void WriteEnumMethod(EnumMapping mapping)
  2021.         {
  2022.             string methodName = (string)MethodNames[mapping];
  2023.             Writer.WriteLine();
  2024.             string fullTypeName = mapping.TypeDesc.CSharpName;
  2025.             if (mapping.IsSoap) {
  2026.                 Writer.Write("void ");
  2027.                 Writer.Write(methodName);
  2028.                 Writer.WriteLine("(object e) {");
  2029.                 WriteLocalDecl(fullTypeName, "v", "e", mapping.TypeDesc.UseReflection);
  2030.             }
  2031.             else {
  2032.                 Writer.Write("string ");
  2033.                 Writer.Write(methodName);
  2034.                 Writer.Write("(");
  2035.                 Writer.Write(mapping.TypeDesc.UseReflection ? "object" : fullTypeName);
  2036.                 Writer.WriteLine(" v) {");
  2037.             }
  2038.             Writer.Indent++;
  2039.             Writer.WriteLine("string s = null;");
  2040.             ConstantMapping[] constants = mapping.Constants;
  2041.            
  2042.             if (constants.Length > 0) {
  2043.                 Hashtable values = new Hashtable();
  2044.                 if (mapping.TypeDesc.UseReflection)
  2045.                     Writer.WriteLine("switch (" + RaCodeGen.GetStringForEnumLongValue("v", mapping.TypeDesc.UseReflection) + " ){");
  2046.                 else
  2047.                     Writer.WriteLine("switch (v) {");
  2048.                 Writer.Indent++;
  2049.                 for (int i = 0; i < constants.Length; i++) {
  2050.                     ConstantMapping c = constants[i];
  2051.                     if (values[c.Value] == null) {
  2052.                         WriteEnumCase(fullTypeName, c, mapping.TypeDesc.UseReflection);
  2053.                         Writer.Write("s = ");
  2054.                         WriteQuotedCSharpString(c.XmlName);
  2055.                         Writer.WriteLine("; break;");
  2056.                         values.Add(c.Value, c.Value);
  2057.                     }
  2058.                 }
  2059.                
  2060.                
  2061.                 if (mapping.IsFlags) {
  2062.                     Writer.Write("default: s = FromEnum(");
  2063.                     Writer.Write(RaCodeGen.GetStringForEnumLongValue("v", mapping.TypeDesc.UseReflection));
  2064.                     Writer.Write(", new string[] {");
  2065.                     Writer.Indent++;
  2066.                     for (int i = 0; i < constants.Length; i++) {
  2067.                         ConstantMapping c = constants[i];
  2068.                         if (i > 0)
  2069.                             Writer.WriteLine(", ");
  2070.                         WriteQuotedCSharpString(c.XmlName);
  2071.                     }
  2072.                     Writer.Write("}, new ");
  2073.                     Writer.Write(typeof(long).FullName);
  2074.                     Writer.Write("[] {");
  2075.                    
  2076.                     for (int i = 0; i < constants.Length; i++) {
  2077.                         ConstantMapping c = constants[i];
  2078.                         if (i > 0)
  2079.                             Writer.WriteLine(", ");
  2080.                         Writer.Write("(long)");
  2081.                         if (mapping.TypeDesc.UseReflection)
  2082.                             Writer.Write(c.Value.ToString(CultureInfo.InvariantCulture));
  2083.                         else {
  2084.                             Writer.Write(fullTypeName);
  2085.                             Writer.Write(".@");
  2086.                             CodeIdentifier.CheckValidIdentifier(c.Name);
  2087.                             Writer.Write(c.Name);
  2088.                         }
  2089.                     }
  2090.                     Writer.Indent--;
  2091.                     Writer.Write("}, ");
  2092.                     WriteQuotedCSharpString(mapping.TypeDesc.FullName);
  2093.                     Writer.WriteLine("); break;");
  2094.                 }
  2095.                 else {
  2096.                     Writer.Write("default: throw CreateInvalidEnumValueException(");
  2097.                     Writer.Write(RaCodeGen.GetStringForEnumLongValue("v", mapping.TypeDesc.UseReflection));
  2098.                     Writer.Write(".ToString(System.Globalization.CultureInfo.InvariantCulture), ");
  2099.                     WriteQuotedCSharpString(mapping.TypeDesc.FullName);
  2100.                     Writer.WriteLine(");");
  2101.                 }
  2102.                 Writer.Indent--;
  2103.                 Writer.WriteLine("}");
  2104.             }
  2105.             if (mapping.IsSoap) {
  2106.                 Writer.Write("WriteXsiType(");
  2107.                 WriteQuotedCSharpString(mapping.TypeName);
  2108.                 Writer.Write(", ");
  2109.                 WriteQuotedCSharpString(mapping.Namespace);
  2110.                 Writer.WriteLine(");");
  2111.                 Writer.WriteLine("Writer.WriteString(s);");
  2112.             }
  2113.             else {
  2114.                 Writer.WriteLine("return s;");
  2115.             }
  2116.             Writer.Indent--;
  2117.             Writer.WriteLine("}");
  2118.         }
  2119.        
  2120.         void WriteDerivedTypes(StructMapping mapping)
  2121.         {
  2122.             for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) {
  2123.                 string fullTypeName = derived.TypeDesc.CSharpName;
  2124.                 Writer.Write("else if (");
  2125.                 WriteTypeCompare("t", fullTypeName, derived.TypeDesc.UseReflection);
  2126.                 Writer.WriteLine(") {");
  2127.                 Writer.Indent++;
  2128.                
  2129.                 string methodName = ReferenceMapping(derived);
  2130.                
  2131.                 #if DEBUG
  2132.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  2133.                 if (methodName == null)
  2134.                     throw new InvalidOperationException("deriaved from " + mapping.TypeDesc.FullName + ", " + Res.GetString(Res.XmlInternalErrorMethod, derived.TypeDesc.Name) + Environment.StackTrace);
  2135.                 #endif
  2136.                
  2137.                 Writer.Write(methodName);
  2138.                 Writer.Write("(n, ns,");
  2139.                 if (!derived.TypeDesc.UseReflection)
  2140.                     Writer.Write("(" + fullTypeName + ")");
  2141.                 Writer.Write("o");
  2142.                 if (derived.TypeDesc.IsNullable)
  2143.                     Writer.Write(", isNullable");
  2144.                 Writer.Write(", true");
  2145.                 Writer.WriteLine(");");
  2146.                 Writer.WriteLine("return;");
  2147.                 Writer.Indent--;
  2148.                 Writer.WriteLine("}");
  2149.                
  2150.                 WriteDerivedTypes(derived);
  2151.             }
  2152.         }
  2153.        
  2154.         void WriteEnumAndArrayTypes()
  2155.         {
  2156.             foreach (TypeScope scope in Scopes) {
  2157.                 foreach (Mapping m in scope.TypeMappings) {
  2158.                     if (m is EnumMapping && !m.IsSoap) {
  2159.                         EnumMapping mapping = (EnumMapping)m;
  2160.                         string fullTypeName = mapping.TypeDesc.CSharpName;
  2161.                         Writer.Write("else if (");
  2162.                         WriteTypeCompare("t", fullTypeName, mapping.TypeDesc.UseReflection);
  2163.                         Writer.WriteLine(") {");
  2164.                         Writer.Indent++;
  2165.                        
  2166.                         string methodName = ReferenceMapping(mapping);
  2167.                        
  2168.                         #if DEBUG
  2169.                         // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  2170.                         if (methodName == null)
  2171.                             throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name) + Environment.StackTrace);
  2172.                         #endif
  2173.                         Writer.WriteLine("Writer.WriteStartElement(n, ns);");
  2174.                         Writer.Write("WriteXsiType(");
  2175.                         WriteQuotedCSharpString(mapping.TypeName);
  2176.                         Writer.Write(", ");
  2177.                         WriteQuotedCSharpString(mapping.Namespace);
  2178.                         Writer.WriteLine(");");
  2179.                         Writer.Write("Writer.WriteString(");
  2180.                         Writer.Write(methodName);
  2181.                         Writer.Write("(");
  2182.                         if (!mapping.TypeDesc.UseReflection)
  2183.                             Writer.Write("(" + fullTypeName + ")");
  2184.                         Writer.WriteLine("o));");
  2185.                         Writer.WriteLine("Writer.WriteEndElement();");
  2186.                         Writer.WriteLine("return;");
  2187.                         Writer.Indent--;
  2188.                         Writer.WriteLine("}");
  2189.                     }
  2190.                     else if (m is ArrayMapping && !m.IsSoap) {
  2191.                         ArrayMapping mapping = m as ArrayMapping;
  2192.                         if (mapping == null || m.IsSoap)
  2193.                             continue;
  2194.                         string fullTypeName = mapping.TypeDesc.CSharpName;
  2195.                         Writer.Write("else if (");
  2196.                         if (mapping.TypeDesc.IsArray)
  2197.                             WriteArrayTypeCompare("t", fullTypeName, mapping.TypeDesc.ArrayElementTypeDesc.CSharpName, mapping.TypeDesc.UseReflection);
  2198.                         else
  2199.                             WriteTypeCompare("t", fullTypeName, mapping.TypeDesc.UseReflection);
  2200.                         Writer.WriteLine(") {");
  2201.                         Writer.Indent++;
  2202.                        
  2203.                         Writer.WriteLine("Writer.WriteStartElement(n, ns);");
  2204.                         Writer.Write("WriteXsiType(");
  2205.                         WriteQuotedCSharpString(mapping.TypeName);
  2206.                         Writer.Write(", ");
  2207.                         WriteQuotedCSharpString(mapping.Namespace);
  2208.                         Writer.WriteLine(");");
  2209.                        
  2210.                         WriteMember("o", null, mapping.ElementsSortedByDerivation, null, null, mapping.TypeDesc, true);
  2211.                        
  2212.                         Writer.WriteLine("Writer.WriteEndElement();");
  2213.                         Writer.WriteLine("return;");
  2214.                         Writer.Indent--;
  2215.                         Writer.WriteLine("}");
  2216.                     }
  2217.                 }
  2218.             }
  2219.         }
  2220.        
  2221.         void WriteStructMethod(StructMapping mapping)
  2222.         {
  2223.             if (mapping.IsSoap && mapping.TypeDesc.IsRoot)
  2224.                 return;
  2225.             string methodName = (string)MethodNames[mapping];
  2226.            
  2227.             Writer.WriteLine();
  2228.             Writer.Write("void ");
  2229.             Writer.Write(methodName);
  2230.            
  2231.             string fullTypeName = mapping.TypeDesc.CSharpName;
  2232.            
  2233.             if (mapping.IsSoap) {
  2234.                 Writer.WriteLine("(object s) {");
  2235.                 Writer.Indent++;
  2236.                 WriteLocalDecl(fullTypeName, "o", "s", mapping.TypeDesc.UseReflection);
  2237.             }
  2238.             else {
  2239.                 Writer.Write("(string n, string ns, ");
  2240.                 Writer.Write(mapping.TypeDesc.UseReflection ? "object" : fullTypeName);
  2241.                 Writer.Write(" o");
  2242.                 if (mapping.TypeDesc.IsNullable)
  2243.                     Writer.Write(", bool isNullable");
  2244.                 Writer.WriteLine(", bool needType) {");
  2245.                 Writer.Indent++;
  2246.                 if (mapping.TypeDesc.IsNullable) {
  2247.                     Writer.WriteLine("if ((object)o == null) {");
  2248.                     Writer.Indent++;
  2249.                     Writer.WriteLine("if (isNullable) WriteNullTagLiteral(n, ns);");
  2250.                     Writer.WriteLine("return;");
  2251.                     Writer.Indent--;
  2252.                     Writer.WriteLine("}");
  2253.                 }
  2254.                 Writer.WriteLine("if (!needType) {");
  2255.                 Writer.Indent++;
  2256.                
  2257.                 Writer.Write(typeof(Type).FullName);
  2258.                 Writer.WriteLine(" t = o.GetType();");
  2259.                 Writer.Write("if (");
  2260.                 WriteTypeCompare("t", fullTypeName, mapping.TypeDesc.UseReflection);
  2261.                 Writer.WriteLine(") {");
  2262.                 Writer.WriteLine("}");
  2263.                 WriteDerivedTypes(mapping);
  2264.                 if (mapping.TypeDesc.IsRoot)
  2265.                     WriteEnumAndArrayTypes();
  2266.                 Writer.WriteLine("else {");
  2267.                
  2268.                 Writer.Indent++;
  2269.                 if (mapping.TypeDesc.IsRoot) {
  2270.                     Writer.WriteLine("WriteTypedPrimitive(n, ns, o, true);");
  2271.                     Writer.WriteLine("return;");
  2272.                 }
  2273.                 else {
  2274.                     Writer.WriteLine("throw CreateUnknownTypeException(o);");
  2275.                 }
  2276.                 Writer.Indent--;
  2277.                 Writer.WriteLine("}");
  2278.                 Writer.Indent--;
  2279.                 Writer.WriteLine("}");
  2280.             }
  2281.            
  2282.             if (!mapping.TypeDesc.IsAbstract) {
  2283.                 if (mapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(mapping.TypeDesc.Type)) {
  2284.                     Writer.WriteLine("EscapeName = false;");
  2285.                 }
  2286.                
  2287.                 string xmlnsSource = null;
  2288.                 MemberMapping[] members = TypeScope.GetAllMembers(mapping);
  2289.                 int xmlnsMember = FindXmlnsIndex(members);
  2290.                 if (xmlnsMember >= 0) {
  2291.                     MemberMapping member = members[xmlnsMember];
  2292.                     CodeIdentifier.CheckValidIdentifier(member.Name);
  2293.                     xmlnsSource = RaCodeGen.GetStringForMember("o", member.Name, mapping.TypeDesc);
  2294.                     if (mapping.TypeDesc.UseReflection) {
  2295.                         xmlnsSource = "((" + member.TypeDesc.CSharpName + ")" + xmlnsSource + ")";
  2296.                     }
  2297.                 }
  2298.                
  2299.                 if (!mapping.IsSoap) {
  2300.                     Writer.Write("WriteStartElement(n, ns, o, false, ");
  2301.                     if (xmlnsSource == null)
  2302.                         Writer.Write("null");
  2303.                     else
  2304.                         Writer.Write(xmlnsSource);
  2305.                    
  2306.                     Writer.WriteLine(");");
  2307.                     if (!mapping.TypeDesc.IsRoot) {
  2308.                         Writer.Write("if (needType) WriteXsiType(");
  2309.                         WriteQuotedCSharpString(mapping.TypeName);
  2310.                         Writer.Write(", ");
  2311.                         WriteQuotedCSharpString(mapping.Namespace);
  2312.                         Writer.WriteLine(");");
  2313.                     }
  2314.                 }
  2315.                 else if (xmlnsSource != null) {
  2316.                     WriteNamespaces(xmlnsSource);
  2317.                 }
  2318.                 for (int i = 0; i < members.Length; i++) {
  2319.                     MemberMapping m = members[i];
  2320.                     if (m.Attribute != null) {
  2321.                         CodeIdentifier.CheckValidIdentifier(m.Name);
  2322.                         if (m.CheckShouldPersist) {
  2323.                             Writer.Write("if (");
  2324.                             string methodInvoke = RaCodeGen.GetStringForMethodInvoke("o", fullTypeName, "ShouldSerialize" + m.Name, mapping.TypeDesc.UseReflection);
  2325.                             if (mapping.TypeDesc.UseReflection)
  2326.                                 methodInvoke = "((" + typeof(bool).FullName + ")" + methodInvoke + ")";
  2327.                             Writer.Write(methodInvoke);
  2328.                             Writer.WriteLine(") {");
  2329.                             Writer.Indent++;
  2330.                         }
  2331.                         if (m.CheckSpecified) {
  2332.                             Writer.Write("if (");
  2333.                             string memberGet = RaCodeGen.GetStringForMember("o", m.Name + "Specified", mapping.TypeDesc);
  2334.                             if (mapping.TypeDesc.UseReflection)
  2335.                                 memberGet = "((" + typeof(bool).FullName + ")" + memberGet + ")";
  2336.                             Writer.Write(memberGet);
  2337.                             Writer.WriteLine(") {");
  2338.                             Writer.Indent++;
  2339.                         }
  2340.                         WriteMember(RaCodeGen.GetStringForMember("o", m.Name, mapping.TypeDesc), m.Attribute, m.TypeDesc, "o");
  2341.                        
  2342.                         if (m.CheckSpecified) {
  2343.                             Writer.Indent--;
  2344.                             Writer.WriteLine("}");
  2345.                         }
  2346.                         if (m.CheckShouldPersist) {
  2347.                             Writer.Indent--;
  2348.                             Writer.WriteLine("}");
  2349.                         }
  2350.                     }
  2351.                 }
  2352.                
  2353.                 for (int i = 0; i < members.Length; i++) {
  2354.                     MemberMapping m = members[i];
  2355.                     if (m.Xmlns != null)
  2356.                         continue;
  2357.                     CodeIdentifier.CheckValidIdentifier(m.Name);
  2358.                     bool checkShouldPersist = m.CheckShouldPersist && (m.Elements.Length > 0 || m.Text != null);
  2359.                    
  2360.                     if (checkShouldPersist) {
  2361.                         Writer.Write("if (");
  2362.                         string methodInvoke = RaCodeGen.GetStringForMethodInvoke("o", fullTypeName, "ShouldSerialize" + m.Name, mapping.TypeDesc.UseReflection);
  2363.                         if (mapping.TypeDesc.UseReflection)
  2364.                             methodInvoke = "((" + typeof(bool).FullName + ")" + methodInvoke + ")";
  2365.                         Writer.Write(methodInvoke);
  2366.                         Writer.WriteLine(") {");
  2367.                         Writer.Indent++;
  2368.                     }
  2369.                     if (m.CheckSpecified) {
  2370.                         Writer.Write("if (");
  2371.                         string memberGet = RaCodeGen.GetStringForMember("o", m.Name + "Specified", mapping.TypeDesc);
  2372.                         if (mapping.TypeDesc.UseReflection)
  2373.                             memberGet = "((" + typeof(bool).FullName + ")" + memberGet + ")";
  2374.                         Writer.Write(memberGet);
  2375.                         Writer.WriteLine(") {");
  2376.                         Writer.Indent++;
  2377.                     }
  2378.                    
  2379.                     string choiceSource = null;
  2380.                     if (m.ChoiceIdentifier != null) {
  2381.                         CodeIdentifier.CheckValidIdentifier(m.ChoiceIdentifier.MemberName);
  2382.                         choiceSource = RaCodeGen.GetStringForMember("o", m.ChoiceIdentifier.MemberName, mapping.TypeDesc);
  2383.                     }
  2384.                     WriteMember(RaCodeGen.GetStringForMember("o", m.Name, mapping.TypeDesc), choiceSource, m.ElementsSortedByDerivation, m.Text, m.ChoiceIdentifier, m.TypeDesc, true);
  2385.                    
  2386.                     if (m.CheckSpecified) {
  2387.                         Writer.Indent--;
  2388.                         Writer.WriteLine("}");
  2389.                     }
  2390.                     if (checkShouldPersist) {
  2391.                         Writer.Indent--;
  2392.                         Writer.WriteLine("}");
  2393.                     }
  2394.                 }
  2395.                 if (!mapping.IsSoap) {
  2396.                     WriteEndElement("o");
  2397.                 }
  2398.             }
  2399.             Writer.Indent--;
  2400.             Writer.WriteLine("}");
  2401.         }
  2402.        
  2403.         bool CanOptimizeWriteListSequence(TypeDesc listElementTypeDesc)
  2404.         {
  2405.            
  2406.             // check to see if we can write values of the attribute sequentially
  2407.             // currently we have only one data type (XmlQualifiedName) that we can not write "inline",
  2408.             // because we need to output xmlns:qx="..." for each of the qnames
  2409.            
  2410.             return (listElementTypeDesc != null && listElementTypeDesc != QnameTypeDesc);
  2411.         }
  2412.        
  2413.         void WriteMember(string source, AttributeAccessor attribute, TypeDesc memberTypeDesc, string parent)
  2414.         {
  2415.             if (memberTypeDesc.IsAbstract)
  2416.                 return;
  2417.             if (memberTypeDesc.IsArrayLike) {
  2418.                 Writer.WriteLine("{");
  2419.                 Writer.Indent++;
  2420.                 string fullTypeName = memberTypeDesc.CSharpName;
  2421.                 WriteArrayLocalDecl(fullTypeName, "a", source, memberTypeDesc);
  2422.                 if (memberTypeDesc.IsNullable) {
  2423.                     Writer.WriteLine("if (a != null) {");
  2424.                     Writer.Indent++;
  2425.                 }
  2426.                 if (attribute.IsList) {
  2427.                     if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
  2428.                         Writer.Write("Writer.WriteStartAttribute(null, ");
  2429.                         WriteQuotedCSharpString(attribute.Name);
  2430.                         Writer.Write(", ");
  2431.                         string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
  2432.                         if (ns != null) {
  2433.                             WriteQuotedCSharpString(ns);
  2434.                         }
  2435.                         else {
  2436.                             Writer.Write("null");
  2437.                         }
  2438.                         Writer.WriteLine(");");
  2439.                     }
  2440.                     else {
  2441.                         Writer.Write(typeof(StringBuilder).FullName);
  2442.                         Writer.Write(" sb = new ");
  2443.                         Writer.Write(typeof(StringBuilder).FullName);
  2444.                         Writer.WriteLine("();");
  2445.                     }
  2446.                 }
  2447.                 TypeDesc arrayElementTypeDesc = memberTypeDesc.ArrayElementTypeDesc;
  2448.                
  2449.                 if (memberTypeDesc.IsEnumerable) {
  2450.                     Writer.Write(" e = ");
  2451.                     Writer.Write(typeof(IEnumerator).FullName);
  2452.                     if (memberTypeDesc.IsPrivateImplementation) {
  2453.                         Writer.Write("((");
  2454.                         Writer.Write(typeof(IEnumerable).FullName);
  2455.                         Writer.WriteLine(").GetEnumerator();");
  2456.                     }
  2457.                     else if (memberTypeDesc.IsGenericInterface) {
  2458.                         if (memberTypeDesc.UseReflection) {
  2459.                             // we use wildcard method name for generic GetEnumerator method, so we cannot use GetStringForMethodInvoke call here
  2460.                             Writer.Write("(");
  2461.                             Writer.Write(typeof(IEnumerator).FullName);
  2462.                             Writer.Write(")");
  2463.                             Writer.Write(RaCodeGen.GetReflectionVariable(memberTypeDesc.CSharpName, "System.Collections.Generic.IEnumerable*"));
  2464.                             Writer.WriteLine(".Invoke(a, new object[0]);");
  2465.                         }
  2466.                         else {
  2467.                             Writer.Write("((System.Collections.Generic.IEnumerable<");
  2468.                             Writer.Write(arrayElementTypeDesc.CSharpName);
  2469.                             Writer.WriteLine(">)a).GetEnumerator();");
  2470.                         }
  2471.                     }
  2472.                     else {
  2473.                         if (memberTypeDesc.UseReflection) {
  2474.                             Writer.Write("(");
  2475.                             Writer.Write(typeof(IEnumerator).FullName);
  2476.                             Writer.Write(")");
  2477.                         }
  2478.                         Writer.Write(RaCodeGen.GetStringForMethodInvoke("a", memberTypeDesc.CSharpName, "GetEnumerator", memberTypeDesc.UseReflection));
  2479.                         Writer.WriteLine(";");
  2480.                     }
  2481.                     Writer.WriteLine("if (e != null)");
  2482.                     Writer.WriteLine("while (e.MoveNext()) {");
  2483.                     Writer.Indent++;
  2484.                    
  2485.                     string arrayTypeFullName = arrayElementTypeDesc.CSharpName;
  2486.                     WriteLocalDecl(arrayTypeFullName, "ai", "e.Current", arrayElementTypeDesc.UseReflection);
  2487.                 }
  2488.                 else {
  2489.                     Writer.Write("for (int i = 0; i < ");
  2490.                     if (memberTypeDesc.IsArray) {
  2491.                         Writer.WriteLine("a.Length; i++) {");
  2492.                     }
  2493.                     else {
  2494.                         Writer.Write("((");
  2495.                         Writer.Write(typeof(ICollection).FullName);
  2496.                         Writer.WriteLine(")a).Count; i++) {");
  2497.                     }
  2498.                     Writer.Indent++;
  2499.                     string arrayTypeFullName = arrayElementTypeDesc.CSharpName;
  2500.                     WriteLocalDecl(arrayTypeFullName, "ai", RaCodeGen.GetStringForArrayMember("a", "i", memberTypeDesc), arrayElementTypeDesc.UseReflection);
  2501.                 }
  2502.                 if (attribute.IsList) {
  2503.                     // check to see if we can write values of the attribute sequentially
  2504.                     if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
  2505.                         Writer.WriteLine("if (i != 0) Writer.WriteString(\" \");");
  2506.                         Writer.Write("WriteValue(");
  2507.                     }
  2508.                     else {
  2509.                         Writer.WriteLine("if (i != 0) sb.Append(\" \");");
  2510.                         Writer.Write("sb.Append(");
  2511.                     }
  2512.                     if (attribute.Mapping is EnumMapping)
  2513.                         WriteEnumValue((EnumMapping)attribute.Mapping, "ai");
  2514.                     else
  2515.                         WritePrimitiveValue(arrayElementTypeDesc, "ai", true);
  2516.                     Writer.WriteLine(");");
  2517.                 }
  2518.                 else {
  2519.                     WriteAttribute("ai", attribute, parent);
  2520.                 }
  2521.                 Writer.Indent--;
  2522.                 Writer.WriteLine("}");
  2523.                 if (attribute.IsList) {
  2524.                     // check to see if we can write values of the attribute sequentially
  2525.                     if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc)) {
  2526.                         Writer.WriteLine("Writer.WriteEndAttribute();");
  2527.                     }
  2528.                     else {
  2529.                         Writer.WriteLine("if (sb.Length != 0) {");
  2530.                         Writer.Indent++;
  2531.                        
  2532.                         Writer.Write("WriteAttribute(");
  2533.                         WriteQuotedCSharpString(attribute.Name);
  2534.                         Writer.Write(", ");
  2535.                         string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
  2536.                         if (ns != null) {
  2537.                             WriteQuotedCSharpString(ns);
  2538.                             Writer.Write(", ");
  2539.                         }
  2540.                         Writer.WriteLine("sb.ToString());");
  2541.                         Writer.Indent--;
  2542.                         Writer.WriteLine("}");
  2543.                     }
  2544.                 }
  2545.                
  2546.                 if (memberTypeDesc.IsNullable) {
  2547.                     Writer.Indent--;
  2548.                     Writer.WriteLine("}");
  2549.                 }
  2550.                 Writer.Indent--;
  2551.                 Writer.WriteLine("}");
  2552.             }
  2553.             else {
  2554.                 WriteAttribute(source, attribute, parent);
  2555.             }
  2556.         }
  2557.        
  2558.         void WriteAttribute(string source, AttributeAccessor attribute, string parent)
  2559.         {
  2560.             if (attribute.Mapping is SpecialMapping) {
  2561.                 SpecialMapping special = (SpecialMapping)attribute.Mapping;
  2562.                 if (special.TypeDesc.Kind == TypeKind.Attribute || special.TypeDesc.CanBeAttributeValue) {
  2563.                     Writer.Write("WriteXmlAttribute(");
  2564.                     Writer.Write(source);
  2565.                     Writer.Write(", ");
  2566.                     Writer.Write(parent);
  2567.                     Writer.WriteLine(");");
  2568.                 }
  2569.                 else
  2570.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  2571.             }
  2572.             else {
  2573.                 TypeDesc typeDesc = attribute.Mapping.TypeDesc;
  2574.                 if (!typeDesc.UseReflection)
  2575.                     source = "((" + typeDesc.CSharpName + ")" + source + ")";
  2576.                 WritePrimitive("WriteAttribute", attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "", attribute.Default, source, attribute.Mapping, false, false, false);
  2577.             }
  2578.         }
  2579.        
  2580.         void WriteMember(string source, string choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc memberTypeDesc, bool writeAccessors)
  2581.         {
  2582.             if (memberTypeDesc.IsArrayLike && !(elements.Length == 1 && elements[0].Mapping is ArrayMapping))
  2583.                 WriteArray(source, choiceSource, elements, text, choice, memberTypeDesc);
  2584.             else
  2585.                 WriteElements(source, choiceSource, elements, text, choice, "a", writeAccessors, memberTypeDesc.IsNullable);
  2586.         }
  2587.        
  2588.        
  2589.         void WriteArray(string source, string choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc)
  2590.         {
  2591.             if (elements.Length == 0 && text == null)
  2592.                 return;
  2593.             Writer.WriteLine("{");
  2594.             Writer.Indent++;
  2595.             string arrayTypeName = arrayTypeDesc.CSharpName;
  2596.             WriteArrayLocalDecl(arrayTypeName, "a", source, arrayTypeDesc);
  2597.             if (arrayTypeDesc.IsNullable) {
  2598.                 Writer.WriteLine("if (a != null) {");
  2599.                 Writer.Indent++;
  2600.             }
  2601.            
  2602.             if (choice != null) {
  2603.                 bool choiceUseReflection = choice.Mapping.TypeDesc.UseReflection;
  2604.                 string choiceFullName = choice.Mapping.TypeDesc.CSharpName;
  2605.                 WriteArrayLocalDecl(choiceFullName + "[]", "c", choiceSource, choice.Mapping.TypeDesc);
  2606.                 // write check for the choice identifier array
  2607.                 Writer.WriteLine("if (c == null || c.Length < a.Length) {");
  2608.                 Writer.Indent++;
  2609.                 Writer.Write("throw CreateInvalidChoiceIdentifierValueException(");
  2610.                 WriteQuotedCSharpString(choice.Mapping.TypeDesc.FullName);
  2611.                 Writer.Write(", ");
  2612.                 WriteQuotedCSharpString(choice.MemberName);
  2613.                 Writer.Write(");");
  2614.                 Writer.Indent--;
  2615.                 Writer.WriteLine("}");
  2616.             }
  2617.            
  2618.             WriteArrayItems(elements, text, choice, arrayTypeDesc, "a", "c");
  2619.             if (arrayTypeDesc.IsNullable) {
  2620.                 Writer.Indent--;
  2621.                 Writer.WriteLine("}");
  2622.             }
  2623.             Writer.Indent--;
  2624.             Writer.WriteLine("}");
  2625.         }
  2626.        
  2627.         void WriteArrayItems(ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc, string arrayName, string choiceName)
  2628.         {
  2629.             TypeDesc arrayElementTypeDesc = arrayTypeDesc.ArrayElementTypeDesc;
  2630.            
  2631.             if (arrayTypeDesc.IsEnumerable) {
  2632.                 Writer.Write(typeof(IEnumerator).FullName);
  2633.                 Writer.Write(" e = ");
  2634.                 if (arrayTypeDesc.IsPrivateImplementation) {
  2635.                     Writer.Write("((");
  2636.                     Writer.Write(typeof(IEnumerable).FullName);
  2637.                     Writer.Write(")");
  2638.                     Writer.Write(arrayName);
  2639.                     Writer.WriteLine(").GetEnumerator();");
  2640.                 }
  2641.                 else if (arrayTypeDesc.IsGenericInterface) {
  2642.                     if (arrayTypeDesc.UseReflection) {
  2643.                         // we use wildcard method name for generic GetEnumerator method, so we cannot use GetStringForMethodInvoke call here
  2644.                         Writer.Write("(");
  2645.                         Writer.Write(typeof(IEnumerator).FullName);
  2646.                         Writer.Write(")");
  2647.                         Writer.Write(RaCodeGen.GetReflectionVariable(arrayTypeDesc.CSharpName, "System.Collections.Generic.IEnumerable*"));
  2648.                         Writer.Write(".Invoke(");
  2649.                         Writer.Write(arrayName);
  2650.                         Writer.WriteLine(", new object[0]);");
  2651.                     }
  2652.                     else {
  2653.                         Writer.Write("((System.Collections.Generic.IEnumerable<");
  2654.                         Writer.Write(arrayElementTypeDesc.CSharpName);
  2655.                         Writer.Write(">)");
  2656.                         Writer.Write(arrayName);
  2657.                         Writer.WriteLine(").GetEnumerator();");
  2658.                     }
  2659.                 }
  2660.                 else {
  2661.                     if (arrayTypeDesc.UseReflection) {
  2662.                         Writer.Write("(");
  2663.                         Writer.Write(typeof(IEnumerator).FullName);
  2664.                         Writer.Write(")");
  2665.                     }
  2666.                     Writer.Write(RaCodeGen.GetStringForMethodInvoke(arrayName, arrayTypeDesc.CSharpName, "GetEnumerator", arrayTypeDesc.UseReflection));
  2667.                     Writer.WriteLine(";");
  2668.                 }
  2669.                 Writer.WriteLine("if (e != null)");
  2670.                 Writer.WriteLine("while (e.MoveNext()) {");
  2671.                 Writer.Indent++;
  2672.                 string arrayTypeFullName = arrayElementTypeDesc.CSharpName;
  2673.                 WriteLocalDecl(arrayTypeFullName, arrayName + "i", "e.Current", arrayElementTypeDesc.UseReflection);
  2674.                 WriteElements(arrayName + "i", choiceName + "i", elements, text, choice, arrayName + "a", true, true);
  2675.             }
  2676.             else {
  2677.                 Writer.Write("for (int i");
  2678.                 Writer.Write(arrayName);
  2679.                 Writer.Write(" = 0; i");
  2680.                 Writer.Write(arrayName);
  2681.                 Writer.Write(" < ");
  2682.                 if (arrayTypeDesc.IsArray) {
  2683.                     Writer.Write(arrayName);
  2684.                     Writer.Write(".Length");
  2685.                 }
  2686.                 else {
  2687.                     Writer.Write("((");
  2688.                     Writer.Write(typeof(ICollection).FullName);
  2689.                     Writer.Write(")");
  2690.                     Writer.Write(arrayName);
  2691.                     Writer.Write(").Count");
  2692.                 }
  2693.                 Writer.Write("; i");
  2694.                 Writer.Write(arrayName);
  2695.                 Writer.WriteLine("++) {");
  2696.                 Writer.Indent++;
  2697.                 int count = elements.Length + (text == null ? 0 : 1);
  2698.                 if (count > 1) {
  2699.                     string arrayTypeFullName = arrayElementTypeDesc.CSharpName;
  2700.                     WriteLocalDecl(arrayTypeFullName, arrayName + "i", RaCodeGen.GetStringForArrayMember(arrayName, "i" + arrayName, arrayTypeDesc), arrayElementTypeDesc.UseReflection);
  2701.                     if (choice != null) {
  2702.                         string choiceFullName = choice.Mapping.TypeDesc.CSharpName;
  2703.                         WriteLocalDecl(choiceFullName, choiceName + "i", RaCodeGen.GetStringForArrayMember(choiceName, "i" + arrayName, choice.Mapping.TypeDesc), choice.Mapping.TypeDesc.UseReflection);
  2704.                     }
  2705.                     WriteElements(arrayName + "i", choiceName + "i", elements, text, choice, arrayName + "a", true, arrayElementTypeDesc.IsNullable);
  2706.                 }
  2707.                 else {
  2708.                     WriteElements(RaCodeGen.GetStringForArrayMember(arrayName, "i" + arrayName, arrayTypeDesc), elements, text, choice, arrayName + "a", true, arrayElementTypeDesc.IsNullable);
  2709.                 }
  2710.             }
  2711.             Writer.Indent--;
  2712.             Writer.WriteLine("}");
  2713.         }
  2714.        
  2715.         void WriteElements(string source, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable)
  2716.         {
  2717.             WriteElements(source, null, elements, text, choice, arrayName, writeAccessors, isNullable);
  2718.         }
  2719.        
  2720.         void WriteElements(string source, string enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable)
  2721.         {
  2722.             if (elements.Length == 0 && text == null)
  2723.                 return;
  2724.             if (elements.Length == 1 && text == null) {
  2725.                 TypeDesc td = elements[0].IsUnbounded ? elements[0].Mapping.TypeDesc.CreateArrayTypeDesc() : elements[0].Mapping.TypeDesc;
  2726.                 if (!elements[0].Any && !elements[0].Mapping.TypeDesc.UseReflection && !elements[0].Mapping.TypeDesc.IsOptionalValue)
  2727.                     source = "((" + td.CSharpName + ")" + source + ")";
  2728.                 WriteElement(source, elements[0], arrayName, writeAccessors);
  2729.             }
  2730.             else {
  2731.                
  2732.                 Writer.WriteLine("{");
  2733.                 Writer.Indent++;
  2734.                 int anyCount = 0;
  2735.                 ArrayList namedAnys = new ArrayList();
  2736.                 ElementAccessor unnamedAny = null;
  2737.                 // can only have one
  2738.                 bool wroteFirstIf = false;
  2739.                 string enumTypeName = choice == null ? null : choice.Mapping.TypeDesc.FullName;
  2740.                
  2741.                 for (int i = 0; i < elements.Length; i++) {
  2742.                     ElementAccessor element = elements[i];
  2743.                    
  2744.                     if (element.Any) {
  2745.                         anyCount++;
  2746.                         if (element.Name != null && element.Name.Length > 0)
  2747.                             namedAnys.Add(element);
  2748.                         else if (unnamedAny == null)
  2749.                             unnamedAny = element;
  2750.                     }
  2751.                     else if (choice != null) {
  2752.                         bool useReflection = element.Mapping.TypeDesc.UseReflection;
  2753.                         string fullTypeName = element.Mapping.TypeDesc.CSharpName;
  2754.                         bool enumUseReflection = choice.Mapping.TypeDesc.UseReflection;
  2755.                         string enumFullName = (enumUseReflection ? "" : enumTypeName + ".@") + FindChoiceEnumValue(element, (EnumMapping)choice.Mapping, enumUseReflection);
  2756.                        
  2757.                         if (wroteFirstIf)
  2758.                             Writer.Write("else ");
  2759.                         else
  2760.                             wroteFirstIf = true;
  2761.                         Writer.Write("if (");
  2762.                         Writer.Write(enumUseReflection ? RaCodeGen.GetStringForEnumLongValue(enumSource, enumUseReflection) : enumSource);
  2763.                         Writer.Write(" == ");
  2764.                         Writer.Write(enumFullName);
  2765.                         Writer.WriteLine(") {");
  2766.                         Writer.Indent++;
  2767.                        
  2768.                         WriteChoiceTypeCheck(source, fullTypeName, useReflection, choice, enumFullName, element.Mapping.TypeDesc);
  2769.                        
  2770.                         string castedSource = source;
  2771.                         if (!useReflection)
  2772.                             castedSource = "((" + fullTypeName + ")" + source + ")";
  2773.                         WriteElement(element.Any ? source : castedSource, element, arrayName, writeAccessors);
  2774.                         Writer.Indent--;
  2775.                         Writer.WriteLine("}");
  2776.                     }
  2777.                     else {
  2778.                         bool useReflection = element.Mapping.TypeDesc.UseReflection;
  2779.                         TypeDesc td = element.IsUnbounded ? element.Mapping.TypeDesc.CreateArrayTypeDesc() : element.Mapping.TypeDesc;
  2780.                         string fullTypeName = td.CSharpName;
  2781.                         if (wroteFirstIf)
  2782.                             Writer.Write("else ");
  2783.                         else
  2784.                             wroteFirstIf = true;
  2785.                         Writer.Write("if (");
  2786.                         WriteInstanceOf(source, fullTypeName, useReflection);
  2787.                         Writer.WriteLine(") {");
  2788.                         Writer.Indent++;
  2789.                         string castedSource = source;
  2790.                         if (!useReflection)
  2791.                             castedSource = "((" + fullTypeName + ")" + source + ")";
  2792.                         WriteElement(element.Any ? source : castedSource, element, arrayName, writeAccessors);
  2793.                         Writer.Indent--;
  2794.                         Writer.WriteLine("}");
  2795.                     }
  2796.                 }
  2797.                 if (anyCount > 0) {
  2798.                     if (elements.Length - anyCount > 0)
  2799.                         Writer.Write("else ");
  2800.                    
  2801.                     string fullTypeName = typeof(XmlElement).FullName;
  2802.                    
  2803.                     Writer.Write("if (");
  2804.                     Writer.Write(source);
  2805.                     Writer.Write(" is ");
  2806.                     Writer.Write(fullTypeName);
  2807.                     Writer.WriteLine(") {");
  2808.                     Writer.Indent++;
  2809.                    
  2810.                     Writer.Write(fullTypeName);
  2811.                     Writer.Write(" elem = (");
  2812.                     Writer.Write(fullTypeName);
  2813.                     Writer.Write(")");
  2814.                     Writer.Write(source);
  2815.                     Writer.WriteLine(";");
  2816.                    
  2817.                     int c = 0;
  2818.                    
  2819.                     foreach (ElementAccessor element in namedAnys) {
  2820.                         if (c++ > 0)
  2821.                             Writer.Write("else ");
  2822.                        
  2823.                         string enumFullName = null;
  2824.                        
  2825.                         bool useReflection = element.Mapping.TypeDesc.UseReflection;
  2826.                         if (choice != null) {
  2827.                             bool enumUseReflection = choice.Mapping.TypeDesc.UseReflection;
  2828.                             enumFullName = (enumUseReflection ? "" : enumTypeName + ".@") + FindChoiceEnumValue(element, (EnumMapping)choice.Mapping, enumUseReflection);
  2829.                             Writer.Write("if (");
  2830.                             Writer.Write(enumUseReflection ? RaCodeGen.GetStringForEnumLongValue(enumSource, enumUseReflection) : enumSource);
  2831.                             Writer.Write(" == ");
  2832.                             Writer.Write(enumFullName);
  2833.                             Writer.WriteLine(") {");
  2834.                             Writer.Indent++;
  2835.                         }
  2836.                         Writer.Write("if (elem.Name == ");
  2837.                         WriteQuotedCSharpString(element.Name);
  2838.                         Writer.Write(" && elem.NamespaceURI == ");
  2839.                         WriteQuotedCSharpString(element.Namespace);
  2840.                         Writer.WriteLine(") {");
  2841.                         Writer.Indent++;
  2842.                         WriteElement("elem", element, arrayName, writeAccessors);
  2843.                        
  2844.                         if (choice != null) {
  2845.                             Writer.Indent--;
  2846.                             Writer.WriteLine("}");
  2847.                             Writer.WriteLine("else {");
  2848.                             Writer.Indent++;
  2849.                            
  2850.                             Writer.WriteLine("// throw Value '{0}' of the choice identifier '{1}' does not match element '{2}' from namespace '{3}'.");
  2851.                            
  2852.                             Writer.Write("throw CreateChoiceIdentifierValueException(");
  2853.                             WriteQuotedCSharpString(enumFullName);
  2854.                             Writer.Write(", ");
  2855.                             WriteQuotedCSharpString(choice.MemberName);
  2856.                             Writer.WriteLine(", elem.Name, elem.NamespaceURI);");
  2857.                             Writer.Indent--;
  2858.                             Writer.WriteLine("}");
  2859.                         }
  2860.                         Writer.Indent--;
  2861.                         Writer.WriteLine("}");
  2862.                     }
  2863.                     if (c > 0) {
  2864.                         Writer.WriteLine("else {");
  2865.                         Writer.Indent++;
  2866.                     }
  2867.                     if (unnamedAny != null) {
  2868.                         WriteElement("elem", unnamedAny, arrayName, writeAccessors);
  2869.                     }
  2870.                     else {
  2871.                         Writer.WriteLine("throw CreateUnknownAnyElementException(elem.Name, elem.NamespaceURI);");
  2872.                     }
  2873.                     if (c > 0) {
  2874.                         Writer.Indent--;
  2875.                         Writer.WriteLine("}");
  2876.                     }
  2877.                     Writer.Indent--;
  2878.                     Writer.WriteLine("}");
  2879.                 }
  2880.                 if (text != null) {
  2881.                     bool useReflection = text.Mapping.TypeDesc.UseReflection;
  2882.                     string fullTypeName = text.Mapping.TypeDesc.CSharpName;
  2883.                     if (elements.Length > 0) {
  2884.                         Writer.Write("else ");
  2885.                         Writer.Write("if (");
  2886.                         WriteInstanceOf(source, fullTypeName, useReflection);
  2887.                         Writer.WriteLine(") {");
  2888.                         Writer.Indent++;
  2889.                         string castedSource = source;
  2890.                         if (!useReflection)
  2891.                             castedSource = "((" + fullTypeName + ")" + source + ")";
  2892.                         WriteText(castedSource, text);
  2893.                         Writer.Indent--;
  2894.                         Writer.WriteLine("}");
  2895.                     }
  2896.                     else {
  2897.                         string castedSource = source;
  2898.                         if (!useReflection)
  2899.                             castedSource = "((" + fullTypeName + ")" + source + ")";
  2900.                         WriteText(castedSource, text);
  2901.                     }
  2902.                 }
  2903.                 if (elements.Length > 0) {
  2904.                     Writer.WriteLine("else {");
  2905.                    
  2906.                     Writer.Indent++;
  2907.                     if (isNullable) {
  2908.                         Writer.Write("if (");
  2909.                         Writer.Write(source);
  2910.                         Writer.WriteLine(" != null) {");
  2911.                         Writer.Indent++;
  2912.                     }
  2913.                     Writer.Write("throw CreateUnknownTypeException(");
  2914.                     Writer.Write(source);
  2915.                     Writer.WriteLine(");");
  2916.                     if (isNullable) {
  2917.                         Writer.Indent--;
  2918.                         Writer.WriteLine("}");
  2919.                     }
  2920.                     Writer.Indent--;
  2921.                     Writer.WriteLine("}");
  2922.                 }
  2923.                 Writer.Indent--;
  2924.                 Writer.WriteLine("}");
  2925.             }
  2926.         }
  2927.        
  2928.         void WriteText(string source, TextAccessor text)
  2929.         {
  2930.             if (text.Mapping is PrimitiveMapping) {
  2931.                 PrimitiveMapping mapping = (PrimitiveMapping)text.Mapping;
  2932.                 Writer.Write("WriteValue(");
  2933.                 if (text.Mapping is EnumMapping) {
  2934.                     WriteEnumValue((EnumMapping)text.Mapping, source);
  2935.                 }
  2936.                 else {
  2937.                     WritePrimitiveValue(mapping.TypeDesc, source, false);
  2938.                 }
  2939.                 Writer.WriteLine(");");
  2940.             }
  2941.             else if (text.Mapping is SpecialMapping) {
  2942.                 SpecialMapping mapping = (SpecialMapping)text.Mapping;
  2943.                 switch (mapping.TypeDesc.Kind) {
  2944.                     case TypeKind.Node:
  2945.                         Writer.Write(source);
  2946.                         Writer.WriteLine(".WriteTo(Writer);");
  2947.                         break;
  2948.                     default:
  2949.                         throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  2950.                         break;
  2951.                 }
  2952.             }
  2953.         }
  2954.        
  2955.         void WriteElement(string source, ElementAccessor element, string arrayName, bool writeAccessor)
  2956.         {
  2957.             string name = writeAccessor ? element.Name : element.Mapping.TypeName;
  2958.             string ns = element.Any && element.Name.Length == 0 ? null : (element.Form == XmlSchemaForm.Qualified ? (writeAccessor ? element.Namespace : element.Mapping.Namespace) : "");
  2959.             if (element.Mapping is NullableMapping) {
  2960.                 Writer.Write("if (");
  2961.                 Writer.Write(source);
  2962.                 Writer.WriteLine(" != null) {");
  2963.                 Writer.Indent++;
  2964.                 string fullTypeName = element.Mapping.TypeDesc.BaseTypeDesc.CSharpName;
  2965.                 string castedSource = source;
  2966.                 if (!element.Mapping.TypeDesc.BaseTypeDesc.UseReflection)
  2967.                     castedSource = "((" + fullTypeName + ")" + source + ")";
  2968.                 ElementAccessor e = element.Clone();
  2969.                 e.Mapping = ((NullableMapping)element.Mapping).BaseMapping;
  2970.                 WriteElement(e.Any ? source : castedSource, e, arrayName, writeAccessor);
  2971.                 Writer.Indent--;
  2972.                 Writer.WriteLine("}");
  2973.                 if (element.IsNullable) {
  2974.                     Writer.WriteLine("else {");
  2975.                     Writer.Indent++;
  2976.                     WriteLiteralNullTag(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
  2977.                     Writer.Indent--;
  2978.                     Writer.WriteLine("}");
  2979.                 }
  2980.             }
  2981.             else if (element.Mapping is ArrayMapping) {
  2982.                 ArrayMapping mapping = (ArrayMapping)element.Mapping;
  2983.                 if (mapping.IsSoap) {
  2984.                     Writer.Write("WritePotentiallyReferencingElement(");
  2985.                     WriteQuotedCSharpString(name);
  2986.                     Writer.Write(", ");
  2987.                     WriteQuotedCSharpString(ns);
  2988.                     Writer.Write(", ");
  2989.                     Writer.Write(source);
  2990.                     if (!writeAccessor) {
  2991.                         Writer.Write(", ");
  2992.                         Writer.Write(RaCodeGen.GetStringForTypeof(mapping.TypeDesc.CSharpName, mapping.TypeDesc.UseReflection));
  2993.                         Writer.Write(", true, ");
  2994.                     }
  2995.                     else {
  2996.                         Writer.Write(", null, false, ");
  2997.                     }
  2998.                     WriteValue(element.IsNullable);
  2999.                     Writer.WriteLine(");");
  3000.                 }
  3001.                 else if (element.IsUnbounded) {
  3002.                     TypeDesc td = mapping.TypeDesc.CreateArrayTypeDesc();
  3003.                     string fullTypeName = td.CSharpName;
  3004.                     string elementArrayName = "el" + arrayName;
  3005.                     string arrayIndex = "c" + elementArrayName;
  3006.                     Writer.WriteLine("{");
  3007.                     Writer.Indent++;
  3008.                     WriteArrayLocalDecl(fullTypeName, elementArrayName, source, mapping.TypeDesc);
  3009.                     if (element.IsNullable) {
  3010.                         WriteNullCheckBegin(elementArrayName, element);
  3011.                     }
  3012.                     else {
  3013.                         if (mapping.TypeDesc.IsNullable) {
  3014.                             Writer.Write("if (");
  3015.                             Writer.Write(elementArrayName);
  3016.                             Writer.Write(" != null)");
  3017.                         }
  3018.                         Writer.WriteLine("{");
  3019.                         Writer.Indent++;
  3020.                     }
  3021.                    
  3022.                     Writer.Write("for (int ");
  3023.                     Writer.Write(arrayIndex);
  3024.                     Writer.Write(" = 0; ");
  3025.                     Writer.Write(arrayIndex);
  3026.                     Writer.Write(" < ");
  3027.                    
  3028.                     if (td.IsArray) {
  3029.                         Writer.Write(elementArrayName);
  3030.                         Writer.Write(".Length");
  3031.                     }
  3032.                     else {
  3033.                         Writer.Write("((");
  3034.                         Writer.Write(typeof(ICollection).FullName);
  3035.                         Writer.Write(")");
  3036.                         Writer.Write(elementArrayName);
  3037.                         Writer.Write(").Count");
  3038.                     }
  3039.                     Writer.Write("; ");
  3040.                     Writer.Write(arrayIndex);
  3041.                     Writer.WriteLine("++) {");
  3042.                     Writer.Indent++;
  3043.                    
  3044.                     element.IsUnbounded = false;
  3045.                     WriteElement(elementArrayName + "[" + arrayIndex + "]", element, arrayName, writeAccessor);
  3046.                     element.IsUnbounded = true;
  3047.                    
  3048.                     Writer.Indent--;
  3049.                     Writer.WriteLine("}");
  3050.                    
  3051.                     Writer.Indent--;
  3052.                     Writer.WriteLine("}");
  3053.                     Writer.Indent--;
  3054.                     Writer.WriteLine("}");
  3055.                 }
  3056.                 else {
  3057.                     string fullTypeName = mapping.TypeDesc.CSharpName;
  3058.                     Writer.WriteLine("{");
  3059.                     Writer.Indent++;
  3060.                     WriteArrayLocalDecl(fullTypeName, arrayName, source, mapping.TypeDesc);
  3061.                     if (element.IsNullable) {
  3062.                         WriteNullCheckBegin(arrayName, element);
  3063.                     }
  3064.                     else {
  3065.                         if (mapping.TypeDesc.IsNullable) {
  3066.                             Writer.Write("if (");
  3067.                             Writer.Write(arrayName);
  3068.                             Writer.Write(" != null)");
  3069.                         }
  3070.                         Writer.WriteLine("{");
  3071.                         Writer.Indent++;
  3072.                     }
  3073.                     WriteStartElement(name, ns, false);
  3074.                     WriteArrayItems(mapping.ElementsSortedByDerivation, null, null, mapping.TypeDesc, arrayName, null);
  3075.                     WriteEndElement();
  3076.                     Writer.Indent--;
  3077.                     Writer.WriteLine("}");
  3078.                     Writer.Indent--;
  3079.                     Writer.WriteLine("}");
  3080.                 }
  3081.             }
  3082.             else if (element.Mapping is EnumMapping) {
  3083.                 if (element.Mapping.IsSoap) {
  3084.                     string methodName = (string)MethodNames[element.Mapping];
  3085.                     Writer.Write("Writer.WriteStartElement(");
  3086.                     WriteQuotedCSharpString(name);
  3087.                     Writer.Write(", ");
  3088.                     WriteQuotedCSharpString(ns);
  3089.                     Writer.WriteLine(");");
  3090.                     Writer.Write(methodName);
  3091.                     Writer.Write("(");
  3092.                     Writer.Write(source);
  3093.                     Writer.WriteLine(");");
  3094.                     WriteEndElement();
  3095.                 }
  3096.                 else {
  3097.                     WritePrimitive("WriteElementString", name, ns, element.Default, source, element.Mapping, false, true, element.IsNullable);
  3098.                 }
  3099.             }
  3100.             else if (element.Mapping is PrimitiveMapping) {
  3101.                 PrimitiveMapping mapping = (PrimitiveMapping)element.Mapping;
  3102.                 if (mapping.TypeDesc == QnameTypeDesc)
  3103.                     WriteQualifiedNameElement(name, ns, element.Default, source, element.IsNullable, mapping.IsSoap, mapping);
  3104.                 else {
  3105.                     string suffixNullable = mapping.IsSoap ? "Encoded" : "Literal";
  3106.                     string suffixRaw = mapping.TypeDesc.XmlEncodingNotRequired ? "Raw" : "";
  3107.                     WritePrimitive(element.IsNullable ? ("WriteNullableString" + suffixNullable + suffixRaw) : ("WriteElementString" + suffixRaw), name, ns, element.Default, source, mapping, mapping.IsSoap, true, element.IsNullable);
  3108.                 }
  3109.             }
  3110.             else if (element.Mapping is StructMapping) {
  3111.                 StructMapping mapping = (StructMapping)element.Mapping;
  3112.                
  3113.                 if (mapping.IsSoap) {
  3114.                     Writer.Write("WritePotentiallyReferencingElement(");
  3115.                     WriteQuotedCSharpString(name);
  3116.                     Writer.Write(", ");
  3117.                     WriteQuotedCSharpString(ns);
  3118.                     Writer.Write(", ");
  3119.                     Writer.Write(source);
  3120.                     if (!writeAccessor) {
  3121.                         Writer.Write(", ");
  3122.                         Writer.Write(RaCodeGen.GetStringForTypeof(mapping.TypeDesc.CSharpName, mapping.TypeDesc.UseReflection));
  3123.                         Writer.Write(", true, ");
  3124.                     }
  3125.                     else {
  3126.                         Writer.Write(", null, false, ");
  3127.                     }
  3128.                     WriteValue(element.IsNullable);
  3129.                 }
  3130.                 else {
  3131.                     string methodName = ReferenceMapping(mapping);
  3132.                    
  3133.                     #if DEBUG
  3134.                     // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  3135.                     if (methodName == null)
  3136.                         throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name) + Environment.StackTrace);
  3137.                     #endif
  3138.                     Writer.Write(methodName);
  3139.                     Writer.Write("(");
  3140.                     WriteQuotedCSharpString(name);
  3141.                     Writer.Write(", ");
  3142.                     if (ns == null)
  3143.                         Writer.Write("null");
  3144.                     else {
  3145.                         WriteQuotedCSharpString(ns);
  3146.                     }
  3147.                     Writer.Write(", ");
  3148.                     Writer.Write(source);
  3149.                     if (mapping.TypeDesc.IsNullable) {
  3150.                         Writer.Write(", ");
  3151.                         WriteValue(element.IsNullable);
  3152.                     }
  3153.                     Writer.Write(", false");
  3154.                 }
  3155.                 Writer.WriteLine(");");
  3156.             }
  3157.             else if (element.Mapping is SpecialMapping) {
  3158.                 SpecialMapping mapping = (SpecialMapping)element.Mapping;
  3159.                 bool useReflection = mapping.TypeDesc.UseReflection;
  3160.                 TypeDesc td = mapping.TypeDesc;
  3161.                 string fullTypeName = td.CSharpName;
  3162.                
  3163.                
  3164.                 if (element.Mapping is SerializableMapping) {
  3165.                     WriteElementCall("WriteSerializable", typeof(IXmlSerializable), source, name, ns, element.IsNullable, !IsAnyElement(mapping));
  3166.                 }
  3167.                 else {
  3168.                     // XmlNode, XmlElement
  3169.                     Writer.Write("if ((");
  3170.                     Writer.Write(source);
  3171.                     Writer.Write(") is ");
  3172.                     Writer.Write(typeof(XmlNode).FullName);
  3173.                     Writer.Write(" || ");
  3174.                     Writer.Write(source);
  3175.                     Writer.Write(" == null");
  3176.                     Writer.WriteLine(") {");
  3177.                     Writer.Indent++;
  3178.                    
  3179.                     WriteElementCall("WriteElementLiteral", typeof(XmlNode), source, name, ns, element.IsNullable, element.Any);
  3180.                    
  3181.                     Writer.Indent--;
  3182.                     Writer.WriteLine("}");
  3183.                     Writer.WriteLine("else {");
  3184.                     Writer.Indent++;
  3185.                    
  3186.                     Writer.Write("throw CreateInvalidAnyTypeException(");
  3187.                     Writer.Write(source);
  3188.                     Writer.WriteLine(");");
  3189.                    
  3190.                     Writer.Indent--;
  3191.                     Writer.WriteLine("}");
  3192.                 }
  3193.             }
  3194.             else {
  3195.                 throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  3196.             }
  3197.         }
  3198.        
  3199.         void WriteElementCall(string func, Type cast, string source, string name, string ns, bool isNullable, bool isAny)
  3200.         {
  3201.             Writer.Write(func);
  3202.             Writer.Write("((");
  3203.             Writer.Write(cast.FullName);
  3204.             Writer.Write(")");
  3205.             Writer.Write(source);
  3206.             Writer.Write(", ");
  3207.             WriteQuotedCSharpString(name);
  3208.             Writer.Write(", ");
  3209.             WriteQuotedCSharpString(ns);
  3210.             Writer.Write(", ");
  3211.             WriteValue(isNullable);
  3212.             Writer.Write(", ");
  3213.             WriteValue(isAny);
  3214.             Writer.WriteLine(");");
  3215.         }
  3216.        
  3217.         void WriteCheckDefault(string source, object value, bool isNullable)
  3218.         {
  3219.             Writer.Write("if (");
  3220.            
  3221.             if (value is string && ((string)value).Length == 0) {
  3222.                 // special case for string compare
  3223.                 Writer.Write("(");
  3224.                 Writer.Write(source);
  3225.                 if (isNullable)
  3226.                     Writer.Write(" == null) || (");
  3227.                 else
  3228.                     Writer.Write(" != null) && (");
  3229.                 Writer.Write(source);
  3230.                 Writer.Write(".Length != 0)");
  3231.             }
  3232.             else {
  3233.                 Writer.Write(source);
  3234.                 Writer.Write(" != ");
  3235.                 WriteValue(value);
  3236.             }
  3237.             Writer.Write(")");
  3238.         }
  3239.        
  3240.         void WriteChoiceTypeCheck(string source, string fullTypeName, bool useReflection, ChoiceIdentifierAccessor choice, string enumName, TypeDesc typeDesc)
  3241.         {
  3242.            
  3243.             Writer.Write("if (((object)");
  3244.             Writer.Write(source);
  3245.             Writer.Write(") != null && !(");
  3246.             WriteInstanceOf(source, fullTypeName, useReflection);
  3247.             Writer.Write(")) throw CreateMismatchChoiceException(");
  3248.             WriteQuotedCSharpString(typeDesc.FullName);
  3249.             Writer.Write(", ");
  3250.             WriteQuotedCSharpString(choice.MemberName);
  3251.             Writer.Write(", ");
  3252.             WriteQuotedCSharpString(enumName);
  3253.             Writer.WriteLine(");");
  3254.         }
  3255.        
  3256.         void WriteNullCheckBegin(string source, ElementAccessor element)
  3257.         {
  3258.             Writer.Write("if ((object)(");
  3259.             Writer.Write(source);
  3260.             Writer.WriteLine(") == null) {");
  3261.             Writer.Indent++;
  3262.             WriteLiteralNullTag(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
  3263.             Writer.Indent--;
  3264.             Writer.WriteLine("}");
  3265.             Writer.WriteLine("else {");
  3266.             Writer.Indent++;
  3267.         }
  3268.        
  3269.         void WriteValue(object value)
  3270.         {
  3271.             if (value == null) {
  3272.                 Writer.Write("null");
  3273.             }
  3274.             else {
  3275.                 Type type = value.GetType();
  3276.                
  3277.                 switch (Type.GetTypeCode(type)) {
  3278.                     case TypeCode.String:
  3279.                        
  3280.                         {
  3281.                             string s = (string)value;
  3282.                             WriteQuotedCSharpString(s);
  3283.                         }
  3284.                         break;
  3285.                     case TypeCode.Char:
  3286.                        
  3287.                         {
  3288.                             Writer.Write('\'');
  3289.                             char ch = (char)value;
  3290.                             if (ch == '\'')
  3291.                                 Writer.Write("'");
  3292.                             else
  3293.                                 Writer.Write(ch);
  3294.                             Writer.Write('\'');
  3295.                         }
  3296.                         break;
  3297.                     case TypeCode.Int32:
  3298.                         Writer.Write(((Int32)value).ToString(null, NumberFormatInfo.InvariantInfo));
  3299.                         break;
  3300.                     case TypeCode.Double:
  3301.                         Writer.Write(((double)value).ToString("R", NumberFormatInfo.InvariantInfo));
  3302.                         break;
  3303.                     case TypeCode.Boolean:
  3304.                         Writer.Write((bool)value ? "true" : "false");
  3305.                         break;
  3306.                     case TypeCode.Int16:
  3307.                     case TypeCode.Int64:
  3308.                     case TypeCode.UInt16:
  3309.                     case TypeCode.UInt32:
  3310.                     case TypeCode.UInt64:
  3311.                     case TypeCode.Byte:
  3312.                     case TypeCode.SByte:
  3313.                         Writer.Write("(");
  3314.                         Writer.Write(type.FullName);
  3315.                         Writer.Write(")");
  3316.                         Writer.Write("(");
  3317.                         Writer.Write(Convert.ToString(value, NumberFormatInfo.InvariantInfo));
  3318.                         Writer.Write(")");
  3319.                         break;
  3320.                     case TypeCode.Single:
  3321.                         Writer.Write(((float)value).ToString("R", NumberFormatInfo.InvariantInfo));
  3322.                         Writer.Write("f");
  3323.                         break;
  3324.                     case TypeCode.Decimal:
  3325.                         Writer.Write(((decimal)value).ToString(null, NumberFormatInfo.InvariantInfo));
  3326.                         Writer.Write("m");
  3327.                         break;
  3328.                     case TypeCode.DateTime:
  3329.                         Writer.Write(" new ");
  3330.                         Writer.Write(type.FullName);
  3331.                         Writer.Write("(");
  3332.                         Writer.Write(((DateTime)value).Ticks.ToString(CultureInfo.InvariantCulture));
  3333.                         Writer.Write(")");
  3334.                         break;
  3335.                     default:
  3336.                         if (type.IsEnum) {
  3337.                             Writer.Write(((int)value).ToString(null, NumberFormatInfo.InvariantInfo));
  3338.                         }
  3339.                         else {
  3340.                             throw new InvalidOperationException(Res.GetString(Res.XmlUnsupportedDefaultType, type.FullName));
  3341.                         }
  3342.                         break;
  3343.                 }
  3344.             }
  3345.         }
  3346.        
  3347.         void WriteNamespaces(string source)
  3348.         {
  3349.             Writer.Write("WriteNamespaceDeclarations(");
  3350.             Writer.Write(source);
  3351.             Writer.WriteLine(");");
  3352.         }
  3353.        
  3354.         int FindXmlnsIndex(MemberMapping[] members)
  3355.         {
  3356.             for (int i = 0; i < members.Length; i++) {
  3357.                 if (members[i].Xmlns == null)
  3358.                     continue;
  3359.                 return i;
  3360.             }
  3361.             return -1;
  3362.         }
  3363.        
  3364.         void WriteExtraMembers(string loopStartSource, string loopEndSource)
  3365.         {
  3366.             Writer.Write("for (int i = ");
  3367.             Writer.Write(loopStartSource);
  3368.             Writer.Write("; i < ");
  3369.             Writer.Write(loopEndSource);
  3370.             Writer.WriteLine("; i++) {");
  3371.             Writer.Indent++;
  3372.             Writer.WriteLine("if (p[i] != null) {");
  3373.             Writer.Indent++;
  3374.             Writer.WriteLine("WritePotentiallyReferencingElement(null, null, p[i], p[i].GetType(), true, false);");
  3375.             Writer.Indent--;
  3376.             Writer.WriteLine("}");
  3377.             Writer.Indent--;
  3378.             Writer.WriteLine("}");
  3379.         }
  3380.        
  3381.         void WriteLocalDecl(string typeName, string variableName, string initValue, bool useReflection)
  3382.         {
  3383.             RaCodeGen.WriteLocalDecl(typeName, variableName, initValue, useReflection);
  3384.         }
  3385.        
  3386.         void WriteArrayLocalDecl(string typeName, string variableName, string initValue, TypeDesc arrayTypeDesc)
  3387.         {
  3388.             RaCodeGen.WriteArrayLocalDecl(typeName, variableName, initValue, arrayTypeDesc);
  3389.         }
  3390.         void WriteTypeCompare(string variable, string escapedTypeName, bool useReflection)
  3391.         {
  3392.             RaCodeGen.WriteTypeCompare(variable, escapedTypeName, useReflection);
  3393.         }
  3394.         void WriteInstanceOf(string source, string escapedTypeName, bool useReflection)
  3395.         {
  3396.             RaCodeGen.WriteInstanceOf(source, escapedTypeName, useReflection);
  3397.         }
  3398.         void WriteArrayTypeCompare(string variable, string escapedTypeName, string elementTypeName, bool useReflection)
  3399.         {
  3400.             RaCodeGen.WriteArrayTypeCompare(variable, escapedTypeName, elementTypeName, useReflection);
  3401.         }
  3402.        
  3403.         void WriteEnumCase(string fullTypeName, ConstantMapping c, bool useReflection)
  3404.         {
  3405.             RaCodeGen.WriteEnumCase(fullTypeName, c, useReflection);
  3406.         }
  3407.        
  3408.         string FindChoiceEnumValue(ElementAccessor element, EnumMapping choiceMapping, bool useReflection)
  3409.         {
  3410.             string enumValue = null;
  3411.            
  3412.             for (int i = 0; i < choiceMapping.Constants.Length; i++) {
  3413.                 string xmlName = choiceMapping.Constants[i].XmlName;
  3414.                
  3415.                 if (element.Any && element.Name.Length == 0) {
  3416.                     if (xmlName == "##any:") {
  3417.                         if (useReflection)
  3418.                             enumValue = choiceMapping.Constants[i].Value.ToString(CultureInfo.InvariantCulture);
  3419.                         else
  3420.                             enumValue = choiceMapping.Constants[i].Name;
  3421.                         break;
  3422.                     }
  3423.                     continue;
  3424.                 }
  3425.                 int colon = xmlName.LastIndexOf(':');
  3426.                 string choiceNs = colon < 0 ? choiceMapping.Namespace : xmlName.Substring(0, colon);
  3427.                 string choiceName = colon < 0 ? xmlName : xmlName.Substring(colon + 1);
  3428.                
  3429.                 if (element.Name == choiceName) {
  3430.                     if ((element.Form == XmlSchemaForm.Unqualified && string.IsNullOrEmpty(choiceNs)) || element.Namespace == choiceNs) {
  3431.                         if (useReflection)
  3432.                             enumValue = choiceMapping.Constants[i].Value.ToString(CultureInfo.InvariantCulture);
  3433.                         else
  3434.                             enumValue = choiceMapping.Constants[i].Name;
  3435.                         break;
  3436.                     }
  3437.                 }
  3438.             }
  3439.             if (enumValue == null || enumValue.Length == 0) {
  3440.                 if (element.Any && element.Name.Length == 0) {
  3441.                     // Type {0} is missing enumeration value '##any' for XmlAnyElementAttribute.
  3442.                     throw new InvalidOperationException(Res.GetString(Res.XmlChoiceMissingAnyValue, choiceMapping.TypeDesc.FullName));
  3443.                 }
  3444.                 // Type {0} is missing value for '{1}'.
  3445.                 throw new InvalidOperationException(Res.GetString(Res.XmlChoiceMissingValue, choiceMapping.TypeDesc.FullName, element.Namespace + ":" + element.Name, element.Name, element.Namespace));
  3446.             }
  3447.             if (!useReflection)
  3448.                 CodeIdentifier.CheckValidIdentifier(enumValue);
  3449.             return enumValue;
  3450.         }
  3451.     }
  3452.    
  3453.     internal class DynamicAssemblies
  3454.     {
  3455.         private DynamicAssemblies()
  3456.         {
  3457.         }
  3458.         static ArrayList assembliesInConfig = new ArrayList();
  3459.         static Hashtable nameToAssemblyMap;
  3460.         static Hashtable assemblyToNameMap;
  3461.         static Hashtable tableIsTypeDynamic = new Hashtable();
  3462.         static FileIOPermission fileIOPermission;
  3463.         static FileIOPermission UnrestrictedFileIOPermission {
  3464.             get {
  3465.                 if (fileIOPermission == null) {
  3466.                     fileIOPermission = new FileIOPermission(PermissionState.Unrestricted);
  3467.                 }
  3468.                 return fileIOPermission;
  3469.             }
  3470.         }
  3471.        
  3472.         static internal bool IsTypeDynamic(Type type)
  3473.         {
  3474.             object oIsTypeDynamic = tableIsTypeDynamic[type];
  3475.             if (oIsTypeDynamic == null) {
  3476.                 UnrestrictedFileIOPermission.Assert();
  3477.                 Module module = type.Module;
  3478.                 Assembly assembly = module.Assembly;
  3479.                 bool isTypeDynamic = (module is ModuleBuilder || assembly.Location == null || assembly.Location.Length == 0);
  3480.                 if (!isTypeDynamic) {
  3481.                     if (type.IsArray) {
  3482.                         isTypeDynamic = IsTypeDynamic(type.GetElementType());
  3483.                     }
  3484.                     else if (type.IsGenericType) {
  3485.                         Type[] parameterTypes = type.GetGenericArguments();
  3486.                         if (parameterTypes != null) {
  3487.                             for (int i = 0; i < parameterTypes.Length; i++) {
  3488.                                 Type parameterType = parameterTypes[i];
  3489.                                 if (!(parameterType == null || parameterType.IsGenericParameter)) {
  3490.                                     isTypeDynamic = IsTypeDynamic(parameterType);
  3491.                                     if (isTypeDynamic)
  3492.                                         break;
  3493.                                 }
  3494.                             }
  3495.                         }
  3496.                     }
  3497.                 }
  3498.                 tableIsTypeDynamic[type] = oIsTypeDynamic = isTypeDynamic;
  3499.             }
  3500.             return (bool)oIsTypeDynamic;
  3501.         }
  3502.        
  3503.        
  3504.         static internal bool IsTypeDynamic(Type[] arguments)
  3505.         {
  3506.             foreach (Type t in arguments) {
  3507.                 if (DynamicAssemblies.IsTypeDynamic(t)) {
  3508.                     return true;
  3509.                 }
  3510.             }
  3511.             return false;
  3512.         }
  3513.        
  3514.         private static object s_InternalSyncObject;
  3515.         private static object InternalSyncObject {
  3516.             get {
  3517.                 if (s_InternalSyncObject == null) {
  3518.                     object o = new object();
  3519.                     Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
  3520.                 }
  3521.                 return s_InternalSyncObject;
  3522.             }
  3523.         }
  3524.        
  3525.         static internal void Add(Assembly a)
  3526.         {
  3527.             if (nameToAssemblyMap == null) {
  3528.                 lock (InternalSyncObject) {
  3529.                     if (nameToAssemblyMap == null) {
  3530.                         nameToAssemblyMap = new Hashtable();
  3531.                         assemblyToNameMap = new Hashtable();
  3532.                     }
  3533.                 }
  3534.             }
  3535.             lock (nameToAssemblyMap) {
  3536.                 if (assemblyToNameMap[a] != null) {
  3537.                     //already added
  3538.                     return;
  3539.                 }
  3540.                 Assembly oldAssembly = nameToAssemblyMap[a.FullName] as Assembly;
  3541.                 string key = null;
  3542.                 if (oldAssembly == null) {
  3543.                     key = a.FullName;
  3544.                 }
  3545.                 else if (oldAssembly != a) {
  3546.                     //more than one assembly with same name
  3547.                     key = a.FullName + ", " + nameToAssemblyMap.Count;
  3548.                 }
  3549.                 if (key != null) {
  3550.                     nameToAssemblyMap.Add(key, a);
  3551.                     assemblyToNameMap.Add(a, key);
  3552.                 }
  3553.             }
  3554.         }
  3555.         static internal Assembly Get(string fullName)
  3556.         {
  3557.             return nameToAssemblyMap != null ? (Assembly)nameToAssemblyMap[fullName] : null;
  3558.         }
  3559.         static internal string GetName(Assembly a)
  3560.         {
  3561.             return assemblyToNameMap != null ? (string)assemblyToNameMap[a] : null;
  3562.         }
  3563.     }
  3564.     internal class ReflectionAwareCodeGen
  3565.     {
  3566.         private const string hexDigits = "0123456789ABCDEF";
  3567.         const string arrayMemberKey = "0";
  3568.         // reflectionVariables holds mapping between a reflection entity
  3569.         // referenced in the generated code (such as TypeInfo,
  3570.         // FieldInfo) and the variable which represent the entity (and
  3571.         // initialized before).
  3572.         // The types of reflection entity and corresponding key is
  3573.         // given below.
  3574.         // ----------------------------------------------------------------------------------
  3575.         // Entity Key
  3576.         // ----------------------------------------------------------------------------------
  3577.         // Assembly assembly.FullName
  3578.         // Type CodeIdentifier.EscapedKeywords(type.FullName)
  3579.         // Field fieldName+":"+CodeIdentifier.EscapedKeywords(containingType.FullName>)
  3580.         // Property propertyName+":"+CodeIdentifier.EscapedKeywords(containingType.FullName)
  3581.         // ArrayAccessor "0:"+CodeIdentifier.EscapedKeywords(typeof(Array).FullName)
  3582.         // MyCollectionAccessor "0:"+CodeIdentifier.EscapedKeywords(typeof(MyCollection).FullName)
  3583.         // ----------------------------------------------------------------------------------
  3584.         Hashtable reflectionVariables = null;
  3585.         int nextReflectionVariableNumber = 0;
  3586.         IndentedWriter writer;
  3587.         internal ReflectionAwareCodeGen(IndentedWriter writer)
  3588.         {
  3589.             this.writer = writer;
  3590.         }
  3591.        
  3592.         internal void WriteReflectionInit(TypeScope scope)
  3593.         {
  3594.             foreach (Type type in scope.Types) {
  3595.                 TypeDesc typeDesc = scope.GetTypeDesc(type);
  3596.                 if (typeDesc.UseReflection)
  3597.                     WriteTypeInfo(scope, typeDesc, type);
  3598.             }
  3599.         }
  3600.        
  3601.         string WriteTypeInfo(TypeScope scope, TypeDesc typeDesc, Type type)
  3602.         {
  3603.             InitTheFirstTime();
  3604.             string typeFullName = typeDesc.CSharpName;
  3605.             string typeVariable = (string)reflectionVariables[typeFullName];
  3606.             if (typeVariable != null)
  3607.                 return typeVariable;
  3608.            
  3609.             if (type.IsArray) {
  3610.                 typeVariable = GenerateVariableName("array", typeDesc.CSharpName);
  3611.                 TypeDesc elementTypeDesc = typeDesc.ArrayElementTypeDesc;
  3612.                 if (elementTypeDesc.UseReflection) {
  3613.                     string elementTypeVariable = WriteTypeInfo(scope, elementTypeDesc, scope.GetTypeFromTypeDesc(elementTypeDesc));
  3614.                     writer.WriteLine("static " + typeof(Type).FullName + " " + typeVariable + " = " + elementTypeVariable + ".MakeArrayType();");
  3615.                 }
  3616.                 else {
  3617.                     string assemblyVariable = WriteAssemblyInfo(type);
  3618.                     writer.Write("static " + typeof(Type).FullName + " " + typeVariable + " = " + assemblyVariable + ".GetType(");
  3619.                     WriteQuotedCSharpString(type.FullName);
  3620.                     writer.WriteLine(");");
  3621.                 }
  3622.             }
  3623.             else {
  3624.                 typeVariable = GenerateVariableName("type", typeDesc.CSharpName);
  3625.                
  3626.                 Type parameterType = Nullable.GetUnderlyingType(type);
  3627.                 if (parameterType != null) {
  3628.                     string parameterTypeVariable = WriteTypeInfo(scope, scope.GetTypeDesc(parameterType), parameterType);
  3629.                     writer.WriteLine("static " + typeof(Type).FullName + " " + typeVariable + " = typeof(System.Nullable<>).MakeGenericType(new " + typeof(Type).FullName + "[] {" + parameterTypeVariable + "});");
  3630.                 }
  3631.                 else {
  3632.                     string assemblyVariable = WriteAssemblyInfo(type);
  3633.                     writer.Write("static " + typeof(Type).FullName + " " + typeVariable + " = " + assemblyVariable + ".GetType(");
  3634.                     WriteQuotedCSharpString(type.FullName);
  3635.                     writer.WriteLine(");");
  3636.                 }
  3637.             }
  3638.            
  3639.             reflectionVariables.Add(typeFullName, typeVariable);
  3640.            
  3641.             TypeMapping mapping = scope.GetTypeMappingFromTypeDesc(typeDesc);
  3642.             if (mapping != null)
  3643.                 WriteMappingInfo(mapping, typeVariable, type);
  3644.             if (typeDesc.IsCollection || typeDesc.IsEnumerable) {
  3645.                 // Arrays use the generic item_Array
  3646.                 TypeDesc elementTypeDesc = typeDesc.ArrayElementTypeDesc;
  3647.                 if (elementTypeDesc.UseReflection)
  3648.                     WriteTypeInfo(scope, elementTypeDesc, scope.GetTypeFromTypeDesc(elementTypeDesc));
  3649.                 WriteCollectionInfo(typeVariable, typeDesc, type);
  3650.             }
  3651.             return typeVariable;
  3652.         }
  3653.        
  3654.         void InitTheFirstTime()
  3655.         {
  3656.             if (reflectionVariables == null) {
  3657.                 reflectionVariables = new Hashtable();
  3658.                 writer.Write(String.Format(CultureInfo.InvariantCulture, helperClassesForUseReflection, "object", "string", typeof(Type).FullName, typeof(FieldInfo).FullName, typeof(PropertyInfo).FullName, typeof(MemberInfo).FullName, typeof(MemberTypes).FullName));
  3659.                
  3660.                 WriteDefaultIndexerInit(typeof(IList), typeof(Array).FullName, false, false);
  3661.             }
  3662.         }
  3663.        
  3664.         void WriteMappingInfo(TypeMapping mapping, string typeVariable, Type type)
  3665.         {
  3666.             string typeFullName = mapping.TypeDesc.CSharpName;
  3667.             if (mapping is StructMapping) {
  3668.                 StructMapping structMapping = mapping as StructMapping;
  3669.                 for (int i = 0; i < structMapping.Members.Length; i++) {
  3670.                     MemberMapping member = structMapping.Members[i];
  3671.                     string memberVariable = WriteMemberInfo(type, typeFullName, typeVariable, member.Name);
  3672.                     if (member.CheckShouldPersist) {
  3673.                         string memberName = "ShouldSerialize" + member.Name;
  3674.                         memberVariable = WriteMethodInfo(typeFullName, typeVariable, memberName, false);
  3675.                     }
  3676.                     if (member.CheckSpecified) {
  3677.                         string memberName = member.Name + "Specified";
  3678.                         memberVariable = WriteMemberInfo(type, typeFullName, typeVariable, memberName);
  3679.                     }
  3680.                     if (member.ChoiceIdentifier != null) {
  3681.                         string memberName = member.ChoiceIdentifier.MemberName;
  3682.                         memberVariable = WriteMemberInfo(type, typeFullName, typeVariable, memberName);
  3683.                     }
  3684.                 }
  3685.             }
  3686.             else if (mapping is EnumMapping) {
  3687.                 FieldInfo[] enumFields = type.GetFields();
  3688.                 for (int i = 0; i < enumFields.Length; i++) {
  3689.                     WriteMemberInfo(type, typeFullName, typeVariable, enumFields[i].Name);
  3690.                 }
  3691.             }
  3692.         }
  3693.         void WriteCollectionInfo(string typeVariable, TypeDesc typeDesc, Type type)
  3694.         {
  3695.             string typeFullName = CodeIdentifier.GetCSharpName(type);
  3696.             string elementTypeFullName = typeDesc.ArrayElementTypeDesc.CSharpName;
  3697.             bool elementUseReflection = typeDesc.ArrayElementTypeDesc.UseReflection;
  3698.             if (typeDesc.IsCollection) {
  3699.                 WriteDefaultIndexerInit(type, typeFullName, typeDesc.UseReflection, elementUseReflection);
  3700.             }
  3701.             else if (typeDesc.IsEnumerable) {
  3702.                 if (typeDesc.IsGenericInterface) {
  3703.                     WriteMethodInfo(typeFullName, typeVariable, "System.Collections.Generic.IEnumerable*", true);
  3704.                 }
  3705.                 else if (!typeDesc.IsPrivateImplementation) {
  3706.                     WriteMethodInfo(typeFullName, typeVariable, "GetEnumerator", true);
  3707.                 }
  3708.             }
  3709.             WriteMethodInfo(typeFullName, typeVariable, "Add", false, GetStringForTypeof(elementTypeFullName, elementUseReflection));
  3710.         }
  3711.        
  3712.         string WriteAssemblyInfo(Type type)
  3713.         {
  3714.             string assemblyFullName = type.Assembly.FullName;
  3715.             string assemblyVariable = (string)reflectionVariables[assemblyFullName];
  3716.             if (assemblyVariable == null) {
  3717.                 int iComma = assemblyFullName.IndexOf(',');
  3718.                 string assemblyName = (iComma > -1) ? assemblyFullName.Substring(0, iComma) : assemblyFullName;
  3719.                 assemblyVariable = GenerateVariableName("assembly", assemblyName);
  3720.                 //writer.WriteLine("static "+ typeof(Assembly).FullName+" "+assemblyVariable+" = "+typeof(Assembly).FullName+".Load(");
  3721.                 writer.Write("static " + typeof(Assembly).FullName + " " + assemblyVariable + " = " + "ResolveDynamicAssembly(");
  3722.                     /*assemblyFullName*/                WriteQuotedCSharpString(DynamicAssemblies.GetName(type.Assembly));
  3723.                 writer.WriteLine(");");
  3724.                 reflectionVariables.Add(assemblyFullName, assemblyVariable);
  3725.             }
  3726.             return assemblyVariable;
  3727.         }
  3728.        
  3729.         string WriteMemberInfo(Type type, string escapedName, string typeVariable, string memberName)
  3730.         {
  3731.             MemberInfo[] memberInfos = type.GetMember(memberName);
  3732.             for (int i = 0; i < memberInfos.Length; i++) {
  3733.                 MemberTypes memberType = memberInfos[i].MemberType;
  3734.                 if (memberType == MemberTypes.Property) {
  3735.                     string propVariable = GenerateVariableName("prop", memberName);
  3736.                     writer.Write("static XSPropInfo " + propVariable + " = new XSPropInfo(" + typeVariable + ", ");
  3737.                     WriteQuotedCSharpString(memberName);
  3738.                     writer.WriteLine(");");
  3739.                     reflectionVariables.Add(memberName + ":" + escapedName, propVariable);
  3740.                     return propVariable;
  3741.                 }
  3742.                 else if (memberType == MemberTypes.Field) {
  3743.                     string fieldVariable = GenerateVariableName("field", memberName);
  3744.                     writer.Write("static XSFieldInfo " + fieldVariable + " = new XSFieldInfo(" + typeVariable + ", ");
  3745.                     WriteQuotedCSharpString(memberName);
  3746.                     writer.WriteLine(");");
  3747.                     reflectionVariables.Add(memberName + ":" + escapedName, fieldVariable);
  3748.                     return fieldVariable;
  3749.                 }
  3750.             }
  3751.             throw new InvalidOperationException(Res.GetString(Res.XmlSerializerUnsupportedType, memberInfos[0].ToString()));
  3752.         }
  3753.        
  3754.         string WriteMethodInfo(string escapedName, string typeVariable, string memberName, bool isNonPublic, params string[] paramTypes)
  3755.         {
  3756.             string methodVariable = GenerateVariableName("method", memberName);
  3757.             writer.Write("static " + typeof(MethodInfo).FullName + " " + methodVariable + " = " + typeVariable + ".GetMethod(");
  3758.             WriteQuotedCSharpString(memberName);
  3759.             writer.Write(", ");
  3760.            
  3761.             string bindingFlags = typeof(BindingFlags).FullName;
  3762.             writer.Write(bindingFlags);
  3763.             writer.Write(".Public | ");
  3764.             writer.Write(bindingFlags);
  3765.             writer.Write(".Instance | ");
  3766.             writer.Write(bindingFlags);
  3767.             writer.Write(".Static");
  3768.            
  3769.             if (isNonPublic) {
  3770.                 writer.Write(" | ");
  3771.                 writer.Write(bindingFlags);
  3772.                 writer.Write(".NonPublic");
  3773.             }
  3774.             writer.Write(", null, ");
  3775.             writer.Write("new " + typeof(Type).FullName + "[] { ");
  3776.             for (int i = 0; i < paramTypes.Length; i++) {
  3777.                 writer.Write(paramTypes[i]);
  3778.                 if (i < (paramTypes.Length - 1))
  3779.                     writer.Write(", ");
  3780.             }
  3781.             writer.WriteLine("}, null);");
  3782.             reflectionVariables.Add(memberName + ":" + escapedName, methodVariable);
  3783.             return methodVariable;
  3784.         }
  3785.        
  3786.         string WriteDefaultIndexerInit(Type type, string escapedName, bool collectionUseReflection, bool elementUseReflection)
  3787.         {
  3788.             string itemVariable = GenerateVariableName("item", escapedName);
  3789.             PropertyInfo defaultIndexer = TypeScope.GetDefaultIndexer(type, null);
  3790.             writer.Write("static XSArrayInfo ");
  3791.             writer.Write(itemVariable);
  3792.             writer.Write("= new XSArrayInfo(");
  3793.             writer.Write(GetStringForTypeof(CodeIdentifier.GetCSharpName(type), collectionUseReflection));
  3794.             writer.Write(".GetProperty(");
  3795.             WriteQuotedCSharpString(defaultIndexer.Name);
  3796.             writer.Write(",");
  3797.             //defaultIndexer.PropertyType is same as TypeDesc.ElementTypeDesc
  3798.             writer.Write(GetStringForTypeof(CodeIdentifier.GetCSharpName(defaultIndexer.PropertyType), elementUseReflection));
  3799.             writer.Write(",new ");
  3800.             writer.Write(typeof(Type[]).FullName);
  3801.             writer.WriteLine("{typeof(int)}));");
  3802.             reflectionVariables.Add(arrayMemberKey + ":" + escapedName, itemVariable);
  3803.             return itemVariable;
  3804.         }
  3805.        
  3806.         private string GenerateVariableName(string prefix, string fullName)
  3807.         {
  3808.             ++nextReflectionVariableNumber;
  3809.             return prefix + nextReflectionVariableNumber + "_" + CodeIdentifier.MakeValidInternal(fullName.Replace('.', '_'));
  3810.         }
  3811.         internal string GetReflectionVariable(string typeFullName, string memberName)
  3812.         {
  3813.             string key;
  3814.             if (memberName == null)
  3815.                 key = typeFullName;
  3816.             else
  3817.                 key = memberName + ":" + typeFullName;
  3818.             return (string)reflectionVariables[key];
  3819.         }
  3820.        
  3821.        
  3822.         internal string GetStringForMethodInvoke(string obj, string escapedTypeName, string methodName, bool useReflection, params string[] args)
  3823.         {
  3824.             StringBuilder sb = new StringBuilder();
  3825.             if (useReflection) {
  3826.                 sb.Append(GetReflectionVariable(escapedTypeName, methodName));
  3827.                 sb.Append(".Invoke(");
  3828.                 sb.Append(obj);
  3829.                 sb.Append(", new object[] {");
  3830.             }
  3831.             else {
  3832.                 sb.Append(obj);
  3833.                 sb.Append(".@");
  3834.                 sb.Append(methodName);
  3835.                 sb.Append("(");
  3836.             }
  3837.             for (int i = 0; i < args.Length; i++) {
  3838.                 if (i != 0)
  3839.                     sb.Append(", ");
  3840.                 sb.Append(args[i]);
  3841.             }
  3842.             if (useReflection)
  3843.                 sb.Append("})");
  3844.             else
  3845.                 sb.Append(")");
  3846.             return sb.ToString();
  3847.         }
  3848.        
  3849.         internal string GetStringForEnumCompare(EnumMapping mapping, string memberName, bool useReflection)
  3850.         {
  3851.             if (!useReflection) {
  3852.                 CodeIdentifier.CheckValidIdentifier(memberName);
  3853.                 return mapping.TypeDesc.CSharpName + ".@" + memberName;
  3854.             }
  3855.             string memberAccess = GetStringForEnumMember(mapping.TypeDesc.CSharpName, memberName, useReflection);
  3856.             return GetStringForEnumLongValue(memberAccess, useReflection);
  3857.         }
  3858.         internal string GetStringForEnumLongValue(string variable, bool useReflection)
  3859.         {
  3860.             if (useReflection)
  3861.                 return typeof(Convert).FullName + ".ToInt64(" + variable + ")";
  3862.             return "((" + typeof(long).FullName + ")" + variable + ")";
  3863.         }
  3864.        
  3865.         internal string GetStringForTypeof(string typeFullName, bool useReflection)
  3866.         {
  3867.             if (useReflection) {
  3868.                 return GetReflectionVariable(typeFullName, null);
  3869.             }
  3870.             else {
  3871.                 return "typeof(" + typeFullName + ")";
  3872.             }
  3873.         }
  3874.         internal string GetStringForMember(string obj, string memberName, TypeDesc typeDesc)
  3875.         {
  3876.             if (!typeDesc.UseReflection)
  3877.                 return obj + ".@" + memberName;
  3878.            
  3879.             TypeDesc saveTypeDesc = typeDesc;
  3880.             while (typeDesc != null) {
  3881.                 string typeFullName = typeDesc.CSharpName;
  3882.                 string memberInfoName = GetReflectionVariable(typeFullName, memberName);
  3883.                 if (memberInfoName != null)
  3884.                     return memberInfoName + "[" + obj + "]";
  3885.                 // member may be part of the basetype
  3886.                 typeDesc = typeDesc.BaseTypeDesc;
  3887.                 if (typeDesc != null && !typeDesc.UseReflection)
  3888.                     return "((" + typeDesc.CSharpName + ")" + obj + ").@" + memberName;
  3889.             }
  3890.             return "[" + obj + "]";
  3891.         }
  3892. /*
  3893.         Exception GetReflectionVariableException(string typeFullName, string memberName){
  3894.             string key;
  3895.             if(memberName == null)
  3896.                 key = typeFullName;
  3897.             else
  3898.                 key = memberName+":"+typeFullName;
  3899.             System.Text.StringBuilder sb = new System.Text.StringBuilder();
  3900.             foreach(object varAvail in reflectionVariables.Keys){
  3901.                 sb.Append(varAvail.ToString());
  3902.                 sb.Append("\n");
  3903.             }
  3904.             return new Exception("No reflection variable for " + key + "\nAvailable keys\n"+sb.ToString());
  3905.         }*/       
  3906.        
  3907.         internal string GetStringForEnumMember(string typeFullName, string memberName, bool useReflection)
  3908.         {
  3909.             if (!useReflection)
  3910.                 return typeFullName + ".@" + memberName;
  3911.            
  3912.             string memberInfoName = GetReflectionVariable(typeFullName, memberName);
  3913.             return memberInfoName + "[null]";
  3914.         }
  3915.         internal string GetStringForArrayMember(string arrayName, string subscript, TypeDesc arrayTypeDesc)
  3916.         {
  3917.             if (!arrayTypeDesc.UseReflection) {
  3918.                 return arrayName + "[" + subscript + "]";
  3919.             }
  3920.             string typeFullName = arrayTypeDesc.IsCollection ? arrayTypeDesc.CSharpName : typeof(Array).FullName;
  3921.             string arrayInfo = GetReflectionVariable(typeFullName, arrayMemberKey);
  3922.             return arrayInfo + "[" + arrayName + ", " + subscript + "]";
  3923.            
  3924.         }
  3925.         internal string GetStringForMethod(string obj, string typeFullName, string memberName, bool useReflection)
  3926.         {
  3927.             if (!useReflection)
  3928.                 return obj + "." + memberName + "(";
  3929.            
  3930.             string memberInfoName = GetReflectionVariable(typeFullName, memberName);
  3931.             return memberInfoName + ".Invoke(" + obj + ", new object[]{";
  3932.         }
  3933.         internal string GetStringForCreateInstance(string escapedTypeName, bool useReflection, bool ctorInaccessible, bool cast)
  3934.         {
  3935.             return GetStringForCreateInstance(escapedTypeName, useReflection, ctorInaccessible, cast, string.Empty);
  3936.         }
  3937.        
  3938.         internal string GetStringForCreateInstance(string escapedTypeName, bool useReflection, bool ctorInaccessible, bool cast, string arg)
  3939.         {
  3940.             if (!useReflection && !ctorInaccessible)
  3941.                 return "new " + escapedTypeName + "(" + arg + ")";
  3942.             return GetStringForCreateInstance(GetStringForTypeof(escapedTypeName, useReflection), cast && !useReflection ? escapedTypeName : null, ctorInaccessible, arg);
  3943.         }
  3944.        
  3945.         internal string GetStringForCreateInstance(string type, string cast, bool nonPublic, string arg)
  3946.         {
  3947.             StringBuilder createInstance = new StringBuilder();
  3948.             if (cast != null && cast.Length > 0) {
  3949.                 createInstance.Append("(");
  3950.                 createInstance.Append(cast);
  3951.                 createInstance.Append(")");
  3952.             }
  3953.             createInstance.Append(typeof(Activator).FullName);
  3954.             createInstance.Append(".CreateInstance(");
  3955.             createInstance.Append(type);
  3956.             createInstance.Append(", ");
  3957.             string bindingFlags = typeof(BindingFlags).FullName;
  3958.             createInstance.Append(bindingFlags);
  3959.             createInstance.Append(".Instance | ");
  3960.             createInstance.Append(bindingFlags);
  3961.             createInstance.Append(".Public | ");
  3962.             createInstance.Append(bindingFlags);
  3963.             createInstance.Append(".CreateInstance");
  3964.            
  3965.             if (nonPublic) {
  3966.                 createInstance.Append(" | ");
  3967.                 createInstance.Append(bindingFlags);
  3968.                 createInstance.Append(".NonPublic");
  3969.             }
  3970.             if (arg == null || arg.Length == 0) {
  3971.                 createInstance.Append(", null, new object[0], null)");
  3972.             }
  3973.             else {
  3974.                 createInstance.Append(", null, new object[] { ");
  3975.                 createInstance.Append(arg);
  3976.                 createInstance.Append(" }, null)");
  3977.             }
  3978.             return createInstance.ToString();
  3979.         }
  3980.        
  3981.         internal void WriteLocalDecl(string typeFullName, string variableName, string initValue, bool useReflection)
  3982.         {
  3983.             if (useReflection)
  3984.                 typeFullName = "object";
  3985.             writer.Write(typeFullName);
  3986.             writer.Write(" ");
  3987.             writer.Write(variableName);
  3988.             if (initValue != null) {
  3989.                 writer.Write(" = ");
  3990.                 if (!useReflection && initValue != "null") {
  3991.                     writer.Write("(" + typeFullName + ")");
  3992.                 }
  3993.                 writer.Write(initValue);
  3994.             }
  3995.             writer.WriteLine(";");
  3996.         }
  3997.        
  3998.         internal void WriteCreateInstance(string escapedName, string source, bool useReflection, bool ctorInaccessible)
  3999.         {
  4000.             writer.Write(useReflection ? "object" : escapedName);
  4001.             writer.Write(" ");
  4002.             writer.Write(source);
  4003.             writer.Write(" = ");
  4004.             writer.Write(GetStringForCreateInstance(escapedName, useReflection, ctorInaccessible, !useReflection && ctorInaccessible));
  4005.             writer.WriteLine(";");
  4006.         }
  4007.         internal void WriteInstanceOf(string source, string escapedTypeName, bool useReflection)
  4008.         {
  4009.             if (!useReflection) {
  4010.                 writer.Write(source);
  4011.                 writer.Write(" is ");
  4012.                 writer.Write(escapedTypeName);
  4013.                 return;
  4014.             }
  4015.             writer.Write(GetReflectionVariable(escapedTypeName, null));
  4016.             writer.Write(".IsAssignableFrom(");
  4017.             writer.Write(source);
  4018.             writer.Write(".GetType())");
  4019.            
  4020.         }
  4021.        
  4022.         internal void WriteArrayLocalDecl(string typeName, string variableName, string initValue, TypeDesc arrayTypeDesc)
  4023.         {
  4024.             if (arrayTypeDesc.UseReflection) {
  4025.                 if (arrayTypeDesc.IsEnumerable)
  4026.                     typeName = typeof(IEnumerable).FullName;
  4027.                 else if (arrayTypeDesc.IsCollection)
  4028.                     typeName = typeof(ICollection).FullName;
  4029.                 else
  4030.                     typeName = typeof(Array).FullName;
  4031.             }
  4032.             writer.Write(typeName);
  4033.             writer.Write(" ");
  4034.             writer.Write(variableName);
  4035.             if (initValue != null) {
  4036.                 writer.Write(" = ");
  4037.                 if (initValue != "null")
  4038.                     writer.Write("(" + typeName + ")");
  4039.                 writer.Write(initValue);
  4040.             }
  4041.             writer.WriteLine(";");
  4042.         }
  4043.         internal void WriteEnumCase(string fullTypeName, ConstantMapping c, bool useReflection)
  4044.         {
  4045.             writer.Write("case ");
  4046.             if (useReflection) {
  4047.                 writer.Write(c.Value.ToString(CultureInfo.InvariantCulture));
  4048.             }
  4049.             else {
  4050.                 writer.Write(fullTypeName);
  4051.                 writer.Write(".@");
  4052.                 CodeIdentifier.CheckValidIdentifier(c.Name);
  4053.                 writer.Write(c.Name);
  4054.             }
  4055.             writer.Write(": ");
  4056.         }
  4057.         internal void WriteTypeCompare(string variable, string escapedTypeName, bool useReflection)
  4058.         {
  4059.             writer.Write(variable);
  4060.             writer.Write(" == ");
  4061.             writer.Write(GetStringForTypeof(escapedTypeName, useReflection));
  4062.         }
  4063.         internal void WriteArrayTypeCompare(string variable, string escapedTypeName, string elementTypeName, bool useReflection)
  4064.         {
  4065.             if (!useReflection) {
  4066.                 writer.Write(variable);
  4067.                 writer.Write(" == typeof(");
  4068.                 writer.Write(escapedTypeName);
  4069.                 writer.Write(")");
  4070.                 return;
  4071.             }
  4072.             writer.Write(variable);
  4073.             writer.Write(".IsArray ");
  4074.             writer.Write(" && ");
  4075.             WriteTypeCompare(variable + ".GetElementType()", elementTypeName, useReflection);
  4076.         }
  4077.        
  4078.         static internal void WriteQuotedCSharpString(IndentedWriter writer, string value)
  4079.         {
  4080.             if (value == null) {
  4081.                 writer.Write("null");
  4082.                 return;
  4083.             }
  4084.             writer.Write("@\"");
  4085.             foreach (char ch in value) {
  4086.                 if (ch < 32) {
  4087.                    
  4088.                     if (ch == '\r')
  4089.                         writer.Write("\\r");
  4090.                     else if (ch == '\n')
  4091.                         writer.Write("\\n");
  4092.                     else if (ch == '\t')
  4093.                         writer.Write("\\t");
  4094.                     else {
  4095.                         byte b = (byte)ch;
  4096.                         writer.Write("\\x");
  4097.                         writer.Write(hexDigits[b >> 4]);
  4098.                         writer.Write(hexDigits[b & 15]);
  4099.                     }
  4100.                 }
  4101.                 else if (ch == '"') {
  4102.                     writer.Write("\"\"");
  4103.                 }
  4104.                 else {
  4105.                     writer.Write(ch);
  4106.                 }
  4107.             }
  4108.             writer.Write("\"");
  4109.         }
  4110.        
  4111.         internal void WriteQuotedCSharpString(string value)
  4112.         {
  4113.             WriteQuotedCSharpString(writer, value);
  4114.         }
  4115.        
  4116.         static string helperClassesForUseReflection = "\r\n sealed class XSFieldInfo {{\r\n {3} fieldInfo;\r\n public XSFieldInfo({2} t, {1} memberName){{\r\n fieldInfo = t.GetField(memberName);\r\n }}\r\n public {0} this[{0} o] {{\r\n get {{\r\n return fieldInfo.GetValue(o);\r\n }}\r\n set {{\r\n fieldInfo.SetValue(o, value);\r\n }}\r\n }}\r\n\r\n }}\r\n sealed class XSPropInfo {{\r\n {4} propInfo;\r\n public XSPropInfo({2} t, {1} memberName){{\r\n propInfo = t.GetProperty(memberName);\r\n }}\r\n public {0} this[{0} o] {{\r\n get {{\r\n return propInfo.GetValue(o, null);\r\n }}\r\n set {{\r\n propInfo.SetValue(o, value, null);\r\n }}\r\n }}\r\n }}\r\n sealed class XSArrayInfo {{\r\n {4} propInfo;\r\n public XSArrayInfo({4} propInfo){{\r\n this.propInfo = propInfo;\r\n }}\r\n public {0} this[{0} a, int i] {{\r\n get {{\r\n return propInfo.GetValue(a, new {0}[]{{i}});\r\n }}\r\n set {{\r\n propInfo.SetValue(a, value, new {0}[]{{i}});\r\n }}\r\n }}\r\n }}\r\n";
  4117.     }
  4118.    
  4119. }

Developer Fusion