* SerializationCodeGenerator.cs: Added support for generation of readers
authorLluis Sanchez <lluis@novell.com>
Tue, 24 Feb 2004 12:03:28 +0000 (12:03 -0000)
committerLluis Sanchez <lluis@novell.com>
Tue, 24 Feb 2004 12:03:28 +0000 (12:03 -0000)
  and writers for several maps in a single class. Added support for
  XmlMemberMapping. Fixed generation of serializers that use encoded format.
* SoapAttributeAttribute.cs, SoapAttributeOverrides.cs, SoapAttributes.cs,
  SoapElementAttribute.cs, SoapEnumAttribute.cs, SoapTypeAttribute.cs,
  XmlAnyElementAttribute.cs, XmlAnyElementAttributes.cs, XmlArrayAttribute.cs,
  XmlArrayItemAttribute.cs, XmlArrayItemAttributes.cs, XmlAttributeAttribute.cs,
  XmlAttributeOverrides.cs, XmlChoiceIdentifierAttribute.cs, XmlRootAttribute.cs,
  XmlElementAttribute.cs, XmlElementAttributes.cs, XmlEnumAttribute.cs,
  XmlReflectionMember.cs, XmlTextAttribute.cs, XmlTypeAttribute.cs:
  Added InternalEquals method.
* XmlAttributes.cs: Removed a lot of unused code. Added InternalEquals method.
* SoapReflectionImporter.cs: Set SerializationSource to generated maps.
* XmlCustomFormatter.cs: Fixed little bug.
* XmlMapping.cs: Added Source property. This a global identifier of the map.
* XmlReflectionImporter.cs: Set SerializationSource to generated maps.
* XmlSchemaImporter.cs: Set the correct value for IsNillable when importing
  mapping members.
* XmlSerializationReaderInterpreter.cs, XmlSerializationWriter.cs: Minor fixes.
* XmlSerializationWriterInterpreter.cs: WriteObject and WriteEnum were not
  correctly used.
* XmlSerializer.cs: Added support for generation of serializers.

svn path=/trunk/mcs/; revision=23392

33 files changed:
mcs/class/System.XML/System.Xml.Serialization/ChangeLog
mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs
mcs/class/System.XML/System.Xml.Serialization/SoapAttributeAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/SoapAttributeOverrides.cs
mcs/class/System.XML/System.Xml.Serialization/SoapAttributes.cs
mcs/class/System.XML/System.Xml.Serialization/SoapElementAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/SoapEnumAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/SoapReflectionImporter.cs
mcs/class/System.XML/System.Xml.Serialization/SoapTypeAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlAnyElementAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlAnyElementAttributes.cs
mcs/class/System.XML/System.Xml.Serialization/XmlArrayAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlArrayItemAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlArrayItemAttributes.cs
mcs/class/System.XML/System.Xml.Serialization/XmlAttributeAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlAttributeOverrides.cs
mcs/class/System.XML/System.Xml.Serialization/XmlAttributes.cs
mcs/class/System.XML/System.Xml.Serialization/XmlChoiceIdentifierAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlCustomFormatter.cs
mcs/class/System.XML/System.Xml.Serialization/XmlElementAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlElementAttributes.cs
mcs/class/System.XML/System.Xml.Serialization/XmlEnumAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlMapping.cs
mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs
mcs/class/System.XML/System.Xml.Serialization/XmlReflectionMember.cs
mcs/class/System.XML/System.Xml.Serialization/XmlRootAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlSchemaImporter.cs
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationWriter.cs
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationWriterInterpreter.cs
mcs/class/System.XML/System.Xml.Serialization/XmlSerializer.cs
mcs/class/System.XML/System.Xml.Serialization/XmlTextAttribute.cs
mcs/class/System.XML/System.Xml.Serialization/XmlTypeAttribute.cs

index f6ae24b592b2fbd71f0fce8ca1ad9357703c2336..34ee7a3a9fba18982507efa30c82f8f49fd202ab 100755 (executable)
@@ -1,3 +1,28 @@
+2004-02-24  Lluis Sanchez Gual  <lluis@ximian.com>
+
+       * SerializationCodeGenerator.cs: Added support for generation of readers
+         and writers for several maps in a single class. Added support for
+         XmlMemberMapping. Fixed generation of serializers that use encoded format.
+       * SoapAttributeAttribute.cs, SoapAttributeOverrides.cs, SoapAttributes.cs,
+         SoapElementAttribute.cs, SoapEnumAttribute.cs, SoapTypeAttribute.cs, 
+         XmlAnyElementAttribute.cs, XmlAnyElementAttributes.cs, XmlArrayAttribute.cs,
+         XmlArrayItemAttribute.cs, XmlArrayItemAttributes.cs, XmlAttributeAttribute.cs,
+         XmlAttributeOverrides.cs, XmlChoiceIdentifierAttribute.cs, XmlRootAttribute.cs,
+         XmlElementAttribute.cs, XmlElementAttributes.cs, XmlEnumAttribute.cs,
+         XmlReflectionMember.cs, XmlTextAttribute.cs, XmlTypeAttribute.cs:
+         Added InternalEquals method.
+       * XmlAttributes.cs: Removed a lot of unused code. Added InternalEquals method.
+       * SoapReflectionImporter.cs: Set SerializationSource to generated maps.
+       * XmlCustomFormatter.cs: Fixed little bug.
+       * XmlMapping.cs: Added Source property. This a global identifier of the map.
+       * XmlReflectionImporter.cs: Set SerializationSource to generated maps.
+       * XmlSchemaImporter.cs: Set the correct value for IsNillable when importing
+         mapping members.
+       * XmlSerializationReaderInterpreter.cs, XmlSerializationWriter.cs: Minor fixes.
+       * XmlSerializationWriterInterpreter.cs: WriteObject and WriteEnum were not
+         correctly used.
+       * XmlSerializer.cs: Added support for generation of serializers.
+
 2004-02-18  Atsushi Enomoto  <atsushi@ximian.com>
 
        * SerializationCodeGenerator.cs,
index 762d8187c0a552d8752cbfe0e9878c3256c50f74..d497f14dfeaf81039237c1486654e79f50db822a 100644 (file)
@@ -25,9 +25,28 @@ namespace System.Xml.Serialization
                int _methodId = 0;
                SerializerInfo _config;
                ArrayList _mapsToGenerate = new ArrayList ();
+               ArrayList _fixupCallbacks;
+               ArrayList _referencedTypes = new ArrayList ();
+               GenerationResult[] _results;
+               GenerationResult _result;
+               XmlMapping[] _xmlMaps;
+               
+               static CodeIdentifiers classNames = new CodeIdentifiers ();
 
-               public SerializationCodeGenerator (XmlMapping typeMap): this (typeMap, null)
+               public SerializationCodeGenerator (XmlMapping[] xmlMaps): this (xmlMaps, null)
+               {
+               }
+               
+               public SerializationCodeGenerator (XmlMapping[] xmlMaps, SerializerInfo config)
+               {
+                       _xmlMaps = xmlMaps;
+                       _config = config;
+               }
+               
+               public SerializationCodeGenerator (XmlMapping xmlMap, SerializerInfo config)
                {
+                       _xmlMaps = new XmlMapping [] {xmlMap};
+                       _config = config;
                }
                
                public static void Generate (string configFileName, string outputPath)
@@ -102,53 +121,114 @@ namespace System.Xml.Serialization
                        }
                }
                
-               public SerializationCodeGenerator (XmlMapping typeMap, SerializerInfo config)
-               {
-                       _typeMap = typeMap;
-                       _format = typeMap.Format;
-                       
-                       string typeName;
-                       if (_typeMap is XmlTypeMapping) typeName = ((XmlTypeMapping)_typeMap).TypeName;
-                       else typeName = ((XmlMembersMapping)_typeMap).ElementName;
-                               
-                       if (config == null)
-                               config = new SerializerInfo();
-                       
-                       if (config.ReaderClassName == null || config.ReaderClassName == "")
-                               config.ReaderClassName = typeName + "_Reader";
-
-                       if (config.WriterClassName == null || config.WriterClassName == "")
-                               config.WriterClassName = typeName + "_Writer";
-
-                       if (config.Namespace == null || config.Namespace == "")
-                               config.Namespace = "CustomSerializers";
-
-                       _config = config;
-               }
-               
                public void GenerateSerializers (TextWriter writer)
                {
                        _writer = writer;
-
+                       _results = new GenerationResult [_xmlMaps.Length];
+                       
                        WriteLine ("using System;");
                        WriteLine ("using System.Xml;");
+                       WriteLine ("using System.Xml.Schema;");
                        WriteLine ("using System.Xml.Serialization;");
                        WriteLine ("using System.Text;");
                        WriteLine ("using System.Collections;");
                        WriteLine ("using System.Globalization;");
-                       if (_config.NamespaceImports != null && _config.NamespaceImports.Length > 0) {
+                       if (_config != null && _config.NamespaceImports != null && _config.NamespaceImports.Length > 0) {
                                foreach (string ns in _config.NamespaceImports)
                                        WriteLine ("using " + ns + ";");
                        }
                        WriteLine ("");
-                       WriteLine ("namespace " + _config.Namespace);
-                       WriteLineInd ("{");
                        
-                       GenerateReader ();
-                       WriteLine ("");
-                       GenerateWriter ();
+                       string readerClassName = null;
+                       string writerClassName = null;
+                       string namspace = null;
                        
-                       WriteLineUni ("}");
+                       if (_config != null)
+                       {
+                               readerClassName = _config.ReaderClassName;
+                               writerClassName = _config.WriterClassName;
+                               namspace = _config.Namespace;
+                       }
+                       
+                       if (readerClassName == null || readerClassName == "")
+                               readerClassName = "GeneratedReader";
+                               
+                       if (writerClassName == null || writerClassName == "")
+                               writerClassName = "GeneratedWriter";
+                               
+                       lock (classNames)
+                       {
+                               readerClassName = classNames.AddUnique (readerClassName, null);
+                               writerClassName = classNames.AddUnique (writerClassName, null);
+                       }
+                       
+                       Hashtable mapsByNamespace = new Hashtable ();
+                       
+                       for (int n=0; n<_xmlMaps.Length; n++)
+                       {
+                               _typeMap = _xmlMaps [n];
+                               if (_typeMap == null) continue;
+                               
+                               _result = new GenerationResult ();
+                               _results[n] = _result;
+                               
+                               string typeName;
+                               if (_typeMap is XmlTypeMapping) typeName = ((XmlTypeMapping)_typeMap).TypeName;
+                               else typeName = ((XmlMembersMapping)_typeMap).ElementName;
+                               
+                               _result.ReaderClassName = readerClassName;
+                               _result.WriterClassName = writerClassName;
+                               
+                               if (namspace == null || namspace == "")
+                                       _result.Namespace = "Mono.GeneratedSerializers." + _typeMap.Format;
+                               else
+                                       _result.Namespace = namspace;
+                               
+                               _result.WriteMethodName = "WriteRoot_" + typeName;
+                               _result.ReadMethodName = "ReadRoot_" + typeName;
+                               _result.Mapping = _typeMap;
+                               
+                               ArrayList maps = (ArrayList) mapsByNamespace [_result.Namespace];
+                               if (maps == null) {
+                                       maps = new ArrayList ();
+                                       mapsByNamespace [_result.Namespace] = maps;
+                               }
+                               maps.Add (_result);
+                       }
+                       
+                       foreach (DictionaryEntry entry in mapsByNamespace)
+                       {
+                               WriteLine ("namespace " + entry.Key);
+                               WriteLineInd ("{");
+                               
+                               GenerateReader (readerClassName, (ArrayList) entry.Value);
+                               WriteLine ("");
+                               GenerateWriter (writerClassName, (ArrayList) entry.Value);
+                               WriteLine ("");
+                               
+                               WriteLineUni ("}");
+                               WriteLine ("");
+                       }
+               }
+               
+               public GenerationResult[] GenerationResults
+               {
+                       get { return _results; }
+               }
+               
+               public ArrayList ReferencedTypes
+               {
+                       get { return _referencedTypes; }
+               }
+               
+               void UpdateGeneratedTypes (ArrayList list)
+               {
+                       for (int n=0; n<list.Count; n++)
+                       {
+                               XmlTypeMapping map = list[n] as XmlTypeMapping;
+                               if (map != null && !_referencedTypes.Contains (map.TypeData.Type))
+                                       _referencedTypes.Add (map.TypeData.Type);
+                       }
                }
 
                #region Writer Generation
@@ -157,18 +237,24 @@ namespace System.Xml.Serialization
                // Writer generation
                //
 
-               public void GenerateWriter ()
+               public void GenerateWriter (string writerClassName, ArrayList maps)
                {
-                       WriteLine ("public class " + _config.WriterClassName + " : XmlSerializationWriter");
-                       WriteLineInd ("{");
-
                        _mapsToGenerate = new ArrayList ();
                        
                        InitHooks ();
-                       GenerateWriteTree ();
                        
-                       if (_typeMap is XmlMembersMapping)
-                               GenerateWriteMessage ((XmlMembersMapping)_typeMap);
+                       WriteLine ("public class " + writerClassName + " : XmlSerializationWriter");
+                       WriteLineInd ("{");
+                       
+                       for (int n=0; n<maps.Count; n++)
+                       {
+                               GenerationResult res = (GenerationResult) maps [n];
+                               _typeMap = res.Mapping;
+                               _format = _typeMap.Format;
+                               _result = res;
+                               
+                               GenerateWriteRoot ();
+                       }
                        
                        for (int n=0; n<_mapsToGenerate.Count; n++)
                        {
@@ -179,18 +265,20 @@ namespace System.Xml.Serialization
                        }
                        
                        GenerateWriteInitCallbacks ();
-
+                       UpdateGeneratedTypes (_mapsToGenerate);
+                       
                        WriteLineUni ("}");
                }
                
-               void GenerateWriteTree ()
+               void GenerateWriteRoot ()
                {
-                       WriteLine ("public void WriteTree (" + GetRootTypeName () + " ob)");
+                       WriteLine ("public void " +_result.WriteMethodName + " (object o)");
                        WriteLineInd ("{");
                        WriteLine ("WriteStartDocument ();");
                        
                        if (_typeMap is XmlTypeMapping)
                        {
+                               WriteLine (GetRootTypeName () + " ob = (" + GetRootTypeName () + ") o;");
                                XmlTypeMapping mp = (XmlTypeMapping) _typeMap;
                                if (mp.TypeData.SchemaType == SchemaTypes.Class || mp.TypeData.SchemaType == SchemaTypes.Array) 
                                        WriteLine ("TopLevelElement ();");
@@ -198,11 +286,14 @@ namespace System.Xml.Serialization
                                if (_format == SerializationFormat.Literal) {
                                        WriteLine (GetWriteObjectName (mp) + " (ob, " + GetLiteral(mp.ElementName) + ", " + GetLiteral(mp.Namespace) + ", true, false, true);");
                                }
-                               else
+                               else {
+                                       RegisterReferencingMap (mp);
                                        WriteLine ("WritePotentiallyReferencingElement (" + GetLiteral(mp.ElementName) + ", " + GetLiteral(mp.Namespace) + ", ob, " + GetTypeOf(mp.TypeData) + ", true, false);");
+                               }
                        }
                        else if (_typeMap is XmlMembersMapping) {
-                               WriteLine ("WriteMessage (ob);");
+                               WriteLine ("object[] pars = (object[]) o;");
+                               GenerateWriteMessage ((XmlMembersMapping) _typeMap);
                        }
                        else
                                throw new InvalidOperationException ("Unknown type map");
@@ -214,8 +305,26 @@ namespace System.Xml.Serialization
                        WriteLine ("");
                }
                
-               void GenerateWriteMessage (XmlMembersMapping map)
+               void GenerateWriteMessage (XmlMembersMapping membersMap)
                {
+                       if (membersMap.HasWrapperElement) {
+                               WriteLine ("TopLevelElement ();");
+                               WriteLine ("WriteStartElement (" + GetLiteral (membersMap.ElementName) + ", " + GetLiteral (membersMap.Namespace) + ", (" + GetLiteral(_format == SerializationFormat.Encoded) + "));");
+
+/*                             WriteLineInd ("if (Writer.LookupPrefix (XmlSchema.Namespace) == null)");
+                               WriteLine ("WriteAttribute (\"xmlns\",\"xsd\",XmlSchema.Namespace,XmlSchema.Namespace);");
+                               Unindent ();
+       
+                               WriteLineInd ("if (Writer.LookupPrefix (XmlSchema.InstanceNamespace) == null)");
+                               WriteLine ("WriteAttribute (\"xmlns\",\"xsi\",XmlSchema.InstanceNamespace,XmlSchema.InstanceNamespace);");
+                               Unindent ();
+*/
+                       }
+                       
+                       GenerateWriteObjectElement (membersMap, "pars", true);
+
+                       if (membersMap.HasWrapperElement)
+                               WriteLine ("WriteEndElement();");
                }
                
                void GenerateGetXmlEnumValue (XmlTypeMapping map)
@@ -280,7 +389,7 @@ namespace System.Xml.Serialization
                                return;
                        }
                        
-                       if (typeMap.TypeData.SchemaType != SchemaTypes.Enum)
+                       if (!typeMap.TypeData.IsValueType)
                        {
                                WriteLine ("if (ob == null)");
                                WriteLineInd ("{");
@@ -328,53 +437,59 @@ namespace System.Xml.Serialization
                                XmlTypeMapping map = (XmlTypeMapping)types[n];
                                
                                WriteLineInd ((first?"else ":"") + "if (ob is " + map.TypeFullName + ") { ");
-                               WriteLine (GetWriteObjectName (map) + "((" + map.TypeFullName + ")ob, element, namesp, isNullable, true, false);");
+                               WriteLine (GetWriteObjectName (map) + "((" + map.TypeFullName + ")ob, element, namesp, isNullable, true, writeWrappingElem);");
                                WriteLine ("return;");
                                WriteLineUni ("}");
                                first = false;
                        }
+                       
                        if (typeMap.TypeData.Type == typeof (object)) {
                                WriteLineInd ("else {");
                                WriteLine ("WriteTypedPrimitive (element, namesp, ob, true);");
                                WriteLine ("return;");
                                WriteLineUni ("}");
                        }
-
-                       if (types.Count > 0)
-                               WriteLine ("");
-                       
-                       WriteLineInd ("if (writeWrappingElem) {");
-                       if (_format == SerializationFormat.Encoded) WriteLine ("needType = true;");
-                       WriteLine ("WriteStartElement (element, namesp, ob);");
-                       WriteLineUni ("}");
-                       WriteLine ("");
-
-                       WriteLine ("if (needType) WriteXsiType(" + GetLiteral(typeMap.XmlType) + ", " + GetLiteral(typeMap.Namespace) + ");");
-                       WriteLine ("");
-
-                       switch (typeMap.TypeData.SchemaType)
+                       else
                        {
-                               case SchemaTypes.Class: GenerateWriteObjectElement (typeMap, "ob", false); break;
-                               case SchemaTypes.Array: GenerateWriteListElement (typeMap, "ob"); break;
-                               case SchemaTypes.Primitive: GenerateWritePrimitiveElement (typeMap, "ob"); break;
-                               case SchemaTypes.Enum: GenerateWriteEnumElement (typeMap, "ob"); break;
+                               if (types.Count > 0)
+                                       WriteLine ("");
+                               
+                               WriteLineInd ("if (writeWrappingElem) {");
+                               if (_format == SerializationFormat.Encoded) WriteLine ("needType = true;");
+                               WriteLine ("WriteStartElement (element, namesp, ob);");
+                               WriteLineUni ("}");
+                               WriteLine ("");
+       
+                               WriteLine ("if (needType) WriteXsiType(" + GetLiteral(typeMap.XmlType) + ", " + GetLiteral(typeMap.XmlTypeNamespace) + ");");
+                               WriteLine ("");
+       
+                               switch (typeMap.TypeData.SchemaType)
+                               {
+                                       case SchemaTypes.Class: GenerateWriteObjectElement (typeMap, "ob", false); break;
+                                       case SchemaTypes.Array: GenerateWriteListElement (typeMap, "ob"); break;
+                                       case SchemaTypes.Primitive: GenerateWritePrimitiveElement (typeMap, "ob"); break;
+                                       case SchemaTypes.Enum: GenerateWriteEnumElement (typeMap, "ob"); break;
+                               }
+       
+                               WriteLine ("if (writeWrappingElem) WriteEndElement (ob);");
                        }
-
-                       WriteLine ("if (writeWrappingElem) WriteEndElement (ob);");
-
+                       
                        GenerateEndHook ();
                        WriteLineUni ("}");
                        WriteLine ("");
                        PopHookContext ();
                }
 
-               void GenerateWriteObjectElement (XmlTypeMapping typeMap, string ob, bool isValueList)
+               void GenerateWriteObjectElement (XmlMapping xmlMap, string ob, bool isValueList)
                {
-                       ClassMap map = (ClassMap)typeMap.ObjectMap;
-                       if (!GenerateWriteHook (HookType.attributes, typeMap.TypeData.Type))
+                       XmlTypeMapping typeMap = xmlMap as XmlTypeMapping;
+                       Type xmlMapType = (typeMap != null) ? typeMap.TypeData.Type : typeof(object[]);
+                       
+                       ClassMap map = (ClassMap)xmlMap.ObjectMap;
+                       if (!GenerateWriteHook (HookType.attributes, xmlMapType))
                        {
                                if (map.NamespaceDeclarations != null) {
-                                       WriteLine ("WriteNamespaceDeclarations ((XmlSerializerNamespaces) " + ob + "." + map.NamespaceDeclarations.Name + ");");
+                                       WriteLine ("WriteNamespaceDeclarations ((XmlSerializerNamespaces) " + ob + ".@" + map.NamespaceDeclarations.Name + ");");
                                        WriteLine ("");
                                }
                                
@@ -383,7 +498,7 @@ namespace System.Xml.Serialization
                                {
                                        foreach (XmlTypeMapMemberAttribute attr in attributes) 
                                        {
-                                               if (GenerateWriteMemberHook (typeMap.TypeData.Type, attr)) continue;
+                                               if (GenerateWriteMemberHook (xmlMapType, attr)) continue;
                                        
                                                string val = GenerateGetMemberValue (attr, ob, isValueList);
                                                string cond = GenerateMemberHasValueCondition (attr, ob, isValueList);
@@ -402,7 +517,7 @@ namespace System.Xml.Serialization
                                XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
                                if (anyAttrMember != null) 
                                {
-                                       if (!GenerateWriteMemberHook (typeMap.TypeData.Type, anyAttrMember))
+                                       if (!GenerateWriteMemberHook (xmlMapType, anyAttrMember))
                                        {
                                                string cond = GenerateMemberHasValueCondition (anyAttrMember, ob, isValueList);
                                                if (cond != null) WriteLineInd ("if (" + cond + ") {");
@@ -425,14 +540,14 @@ namespace System.Xml.Serialization
                                GenerateEndHook ();
                        }
                        
-                       if (!GenerateWriteHook (HookType.elements, typeMap.TypeData.Type))
+                       if (!GenerateWriteHook (HookType.elements, xmlMapType))
                        {
                                ICollection members = map.ElementMembers;
                                if (members != null)
                                {
                                        foreach (XmlTypeMapMemberElement member in members)
                                        {
-                                               if (GenerateWriteMemberHook (typeMap.TypeData.Type, member)) continue;
+                                               if (GenerateWriteMemberHook (xmlMapType, member)) continue;
                                                
                                                string cond = GenerateMemberHasValueCondition (member, ob, isValueList);
                                                if (cond != null) WriteLineInd ("if (" + cond + ") {");
@@ -442,9 +557,7 @@ namespace System.Xml.Serialization
        
                                                if (memType == typeof(XmlTypeMapMemberList))
                                                {
-                                                       WriteLineInd ("if (" + memberValue + " != null) {"); 
                                                        GenerateWriteMemberElement ((XmlTypeMapElementInfo) member.ElementInfo[0], memberValue);
-                                                       WriteLineUni ("}");
                                                }
                                                else if (memType == typeof(XmlTypeMapMemberFlatList))
                                                {
@@ -475,7 +588,7 @@ namespace System.Xml.Serialization
                                                        }
                                                        else if (member.ChoiceMember != null)
                                                        {
-                                                               string choiceValue = ob + "." + member.ChoiceMember;
+                                                               string choiceValue = ob + ".@" + member.ChoiceMember;
                                                                foreach (XmlTypeMapElementInfo elem in member.ElementInfo) {
                                                                        WriteLineInd ("if (" + choiceValue + " == " + GetLiteral(elem.ChoiceValue) + ") {");
                                                                        GenerateWriteMemberElement (elem, GetCast(elem.TypeData, member.TypeData, memberValue));
@@ -533,23 +646,33 @@ namespace System.Xml.Serialization
                                        break;
 
                                case SchemaTypes.Array:
-                                       if (memberValue == null) {
-                                               if (_format == SerializationFormat.Literal) 
-                                                       WriteMetCall ("WriteNullTagLiteral", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace));
-                                               else
-                                                       WriteMetCall ("WriteNullTagEncoded", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace));
-                                       }
-                                       else if (elem.MappedType.MultiReferenceType) 
+                                       WriteLineInd ("if (" + memberValue + " != null) {");
+                                       
+                                       if (elem.MappedType.MultiReferenceType) {
                                                WriteMetCall ("WriteReferencingElement", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), memberValue, GetLiteral(elem.IsNullable));
+                                               RegisterReferencingMap (elem.MappedType);
+                                       }
                                        else {
                                                WriteMetCall ("WriteStartElement", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), memberValue);
                                                GenerateWriteListContent (elem.TypeData, (ListMap) elem.MappedType.ObjectMap, memberValue, false);
                                                WriteMetCall ("WriteEndElement", memberValue);
                                        }
+                                       WriteLineUni ("}");
+                                       
+                                       if (elem.IsNullable) {
+                                               WriteLineInd ("else");
+                                               if (_format == SerializationFormat.Literal) 
+                                                       WriteMetCall ("WriteNullTagLiteral", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace));
+                                               else
+                                                       WriteMetCall ("WriteNullTagEncoded", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace));
+                                               Unindent ();
+                                       }
+                                       
                                        break;
 
                                case SchemaTypes.Class:
                                        if (elem.MappedType.MultiReferenceType) {
+                                               RegisterReferencingMap (elem.MappedType);
                                                if (elem.MappedType.TypeData.Type == typeof(object))
                                                        WriteMetCall ("WritePotentiallyReferencingElement", GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), memberValue, "null", "false", GetLiteral(elem.IsNullable));
                                                else
@@ -582,7 +705,7 @@ namespace System.Xml.Serialization
                                else
                                        arrayType = GetLiteral (n);
                                
-                               WriteMetCall ("WriteAttribute", GetLiteral("arrayType"), GetLiteral(XmlSerializer.WsdlNamespace), arrayType);
+                               WriteMetCall ("WriteAttribute", GetLiteral("arrayType"), GetLiteral(XmlSerializer.EncodingNamespace), arrayType);
                        }
                        GenerateWriteListContent (typeMap.TypeData, (ListMap) typeMap.ObjectMap, ob, false);
                }
@@ -747,11 +870,15 @@ namespace System.Xml.Serialization
                
                void GenerateListLoop (ListMap map, string item, TypeData itemTypeData, string targetString)
                {
-                       bool first = true;
+                       bool multichoice = (map.ItemInfo.Count > 1);
+
+                       if (multichoice)
+                               WriteLine ("if (" + item + " == null) { }");
+                       
                        foreach (XmlTypeMapElementInfo info in map.ItemInfo)
                        {
-                               if (map.ItemInfo.Count > 1)
-                                       WriteLineInd ((first?"":"else ") + "if (" + item + " is " + info.TypeData.FullTypeName + ") {");
+                               if (multichoice)
+                                       WriteLineInd ("else if (" + item + ".GetType() == typeof(" + info.TypeData.FullTypeName + ")) {");
 
                                if (targetString == null) 
                                        GenerateWriteMemberElement (info, GetCast (info.TypeData, itemTypeData, item));
@@ -761,14 +888,12 @@ namespace System.Xml.Serialization
                                        WriteLine (targetString + ".Append (" + strVal + ").Append (\" \");");
                                }
 
-                               if (map.ItemInfo.Count > 1)
+                               if (multichoice)
                                        WriteLineUni ("}");
-                               
-                               first = false;
                        }
                        
-                       if (map.ItemInfo.Count > 1)
-                               WriteLine ("else if (" + item + " != null) throw CreateUnknownTypeException (" + item + ");");
+                       if (multichoice)
+                               WriteLine ("else throw CreateUnknownTypeException (" + item + ");");
                }
 
                void GenerateWritePrimitiveValueLiteral (string memberValue, string name, string ns, XmlTypeMapping mappedType, TypeData typeData, bool wrapped, bool isNullable)
@@ -821,17 +946,17 @@ namespace System.Xml.Serialization
 
                string GenerateGetMemberValue (XmlTypeMapMember member, string ob, bool isValueList)
                {
-                       if (isValueList) return ob + "[" + member.Index + "]";
-                       else return ob + "." + member.Name;
+                       if (isValueList) return GetCast (member.TypeData, TypeTranslator.GetTypeData (typeof(object)), ob + "[" + member.Index + "]");
+                       else return ob + ".@" + member.Name;
                }
                
                string GenerateMemberHasValueCondition (XmlTypeMapMember member, string ob, bool isValueList)
                {
                        if (isValueList) {
-                               return member.Index + " < " + ob + ".Length";
+                               return null; //member.Index + " < " + ob + ".Length";
                        }
                        else if (member.DefaultValue != System.DBNull.Value) {
-                               string mem = ob + "." + member.Name;
+                               string mem = ob + ".@" + member.Name;
                                if (member.DefaultValue == null) 
                                        return mem + " != null";
                                else if (member.TypeData.SchemaType == SchemaTypes.Enum)
@@ -839,6 +964,8 @@ namespace System.Xml.Serialization
                                else 
                                        return mem + " != " + GetLiteral (member.DefaultValue);
                        }
+                       else if (member.IsOptionalValueType)
+                               return ob + ".@" + member.Name + "Specified";
                        return null;
                }
 
@@ -849,8 +976,10 @@ namespace System.Xml.Serialization
                        
                        if (_format == SerializationFormat.Encoded)
                        {
-                               foreach (XmlTypeMapping map in _mapsToGenerate)  {
-                                       WriteMetCall ("AddWriteCallback", GetTypeOf(map.TypeData), GetLiteral(map.XmlType), GetLiteral(map.Namespace), "new XmlSerializationWriteCallback (" + GetWriteObjectCallbackName (map) + ")");
+                               foreach (XmlMapping xmap in _mapsToGenerate)  {
+                                       XmlTypeMapping map = xmap as XmlTypeMapping;
+                                       if (map != null)
+                                               WriteMetCall ("AddWriteCallback", GetTypeOf(map.TypeData), GetLiteral(map.XmlType), GetLiteral(map.Namespace), "new XmlSerializationWriteCallback (" + GetWriteObjectCallbackName (map) + ")");
                                }
                        }       
                        
@@ -859,7 +988,9 @@ namespace System.Xml.Serialization
                                
                        if (_format == SerializationFormat.Encoded)
                        {
-                               foreach (XmlTypeMapping map in _mapsToGenerate)  {
+                               foreach (XmlTypeMapping xmap in _mapsToGenerate)  {
+                                       XmlTypeMapping map = xmap as XmlTypeMapping;
+                                       if (map == null) continue;
                                        if (map.TypeData.SchemaType == SchemaTypes.Enum)
                                                WriteWriteEnumCallback (map);
                                        else
@@ -872,7 +1003,7 @@ namespace System.Xml.Serialization
                {
                        WriteLine ("void " + GetWriteObjectCallbackName (map) + " (object ob)");
                        WriteLineInd ("{");
-                       WriteMetCall (GetWriteObjectName(map), GetCast (map.TypeData, "ob"), GetLiteral(map.ElementName), GetLiteral(map.Namespace), "false", "false", "false");
+                       WriteMetCall (GetWriteObjectName(map), GetCast (map.TypeData, "ob"), GetLiteral(map.ElementName), GetLiteral(map.Namespace), "false", "true", "false");
                        WriteLineUni ("}");
                        WriteLine ("");
                }
@@ -881,7 +1012,7 @@ namespace System.Xml.Serialization
                {
                        WriteLine ("void " + GetWriteObjectCallbackName (map) + " (object ob)");
                        WriteLineInd ("{");
-                       WriteMetCall (GetWriteObjectName(map), GetCast (map.TypeData, "ob"), GetLiteral(map.ElementName), GetLiteral(map.Namespace), "false", "true", "false");
+                       WriteMetCall (GetWriteObjectName(map), GetCast (map.TypeData, "ob"), GetLiteral(map.ElementName), GetLiteral(map.Namespace), "false", "false", "false");
                        WriteLineUni ("}");
                        WriteLine ("");
                }
@@ -894,21 +1025,30 @@ namespace System.Xml.Serialization
                // Reader generation
                //
                
-               public void GenerateReader ()
+               public void GenerateReader (string readerClassName, ArrayList maps)
                {
-                       WriteLine ("public class " + _config.ReaderClassName + " : XmlSerializationReader");
+                       WriteLine ("public class " + readerClassName + " : XmlSerializationReader");
                        WriteLineInd ("{");
 
                        _mapsToGenerate = new ArrayList ();
+                       _fixupCallbacks = new ArrayList ();
                        InitHooks ();
-                       GenerateReadTree ();
                        
-                       if (_typeMap is XmlMembersMapping)
-                               GenerateReadMessage ((XmlMembersMapping)_typeMap);
-
+                       for (int n=0; n<maps.Count; n++)
+                       {
+                               GenerationResult res = (GenerationResult) maps [n];
+                               _typeMap = res.Mapping;
+                               _format = _typeMap.Format;
+                               _result = res;
+                               
+                               GenerateReadRoot ();
+                       }
+                       
                        for (int n=0; n<_mapsToGenerate.Count; n++)
                        {
-                               XmlTypeMapping map = (XmlTypeMapping) _mapsToGenerate [n];
+                               XmlTypeMapping map = _mapsToGenerate [n] as XmlTypeMapping;
+                               if (map == null) continue;
+                               
                                GenerateReadObject (map);
                                if (map.TypeData.SchemaType == SchemaTypes.Enum)
                                        GenerateGetEnumValue (map);
@@ -923,23 +1063,34 @@ namespace System.Xml.Serialization
                        }
                        
                        WriteLineUni ("}");
+                       UpdateGeneratedTypes (_mapsToGenerate);
                }
                
-               void GenerateReadTree ()
+               void GenerateReadRoot ()
                {
-                       WriteLine ("public " + GetRootTypeName () + " ReadTree ()");
+                       WriteLine ("public object " + _result.ReadMethodName + " ()");
                        WriteLineInd ("{");
                        WriteLine ("Reader.MoveToContent();");
                        
                        if (_typeMap is XmlTypeMapping)
                        {
                                XmlTypeMapping typeMap = (XmlTypeMapping) _typeMap;
+//                             Console.WriteLine ("> " + typeMap.TypeName);
 
                                if (_format == SerializationFormat.Literal)
-                                       WriteMetCall ("return " + GetReadObjectName (typeMap), "true", "true");
+                               {
+                                       if (typeMap.TypeData.SchemaType == SchemaTypes.XmlNode)
+                                               throw new Exception ("Not supported for XmlNode types");
+                                               
+                                       WriteLineInd ("if (Reader.LocalName != " + GetLiteral (typeMap.ElementName) + " || Reader.NamespaceURI != " + GetLiteral (typeMap.Namespace) + ")");
+                                       WriteLine ("throw CreateUnknownNodeException();");
+                                       Unindent ();
+
+                                       WriteLine ("return " + GetReadObjectCall (typeMap, "true", "true") + ";");
+                               }
                                else
                                {
-                                       WriteLine (typeMap.TypeFullName + " ob = null;");
+                                       WriteLine ("object ob = null;");
                                        WriteLine ("Reader.MoveToContent();");
                                        WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
                                        WriteLineInd ("{");
@@ -956,26 +1107,88 @@ namespace System.Xml.Serialization
                                        WriteLine ("");
                                        WriteLine ("ReadReferencedElements();");
                                        WriteLine ("return ob;");
+                                       RegisterReferencingMap (typeMap);
                                }
                        }
                        else {
-                               WriteLine ("return ReadMessage ();");
+                               WriteLine ("return " + GenerateReadMessage ((XmlMembersMapping)_typeMap) + ";");
                        }
 
                        WriteLineUni ("}");
                        WriteLine ("");
                }
                
-               void GenerateReadMessage (XmlMembersMapping map)
+               string GenerateReadMessage (XmlMembersMapping typeMap)
                {
+                       WriteLine ("object[] parameters = new object[" + typeMap.Count + "];");
+                       WriteLine ("");
+
+                       if (typeMap.HasWrapperElement)
+                       {
+                               if (_format == SerializationFormat.Encoded)
+                               {
+                                       WriteLine ("while (Reader.NodeType == System.Xml.XmlNodeType.Element)");
+                                       WriteLineInd ("{");
+                                       WriteLine ("string root = Reader.GetAttribute (\"root\", " + GetLiteral(XmlSerializer.EncodingNamespace) + ");");
+                                       WriteLine ("if (root == null || System.Xml.XmlConvert.ToBoolean(root)) break;");
+                                       WriteLine ("ReadReferencedElement ();");
+                                       WriteLine ("Reader.MoveToContent ();");
+                                       WriteLineUni ("}");
+                                       WriteLine ("");
+                                       WriteLine ("if (Reader.NodeType != System.Xml.XmlNodeType.EndElement)");
+                                       WriteLineInd ("{");
+                                       WriteLineInd ("if (Reader.IsEmptyElement) {");
+                                       WriteLine ("Reader.Skip();");
+                                       WriteLineUni ("}");
+                                       WriteLineInd ("else {");
+                                       WriteLine ("Reader.ReadStartElement();");
+                                       GenerateReadMembers (typeMap, (ClassMap)typeMap.ObjectMap, "parameters", true, false);
+                                       WriteLine ("ReadEndElement();");
+                                       WriteLineUni ("}");
+                                       WriteLine ("");
+                                       WriteLine ("Reader.MoveToContent();");
+                                       WriteLineUni ("}");
+                               }
+                               else
+                               {
+                                       WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement)");
+                                       WriteLineInd ("{");
+                                       WriteLine ("if (Reader.IsStartElement(" + GetLiteral(typeMap.ElementName) + ", " + GetLiteral(typeMap.Namespace) + "))");
+                                       WriteLineInd ("{");
+                                       WriteLine ("if (Reader.IsEmptyElement) { Reader.Skip(); Reader.MoveToContent(); continue; }");
+                                       WriteLine ("Reader.ReadStartElement();");
+                                       GenerateReadMembers (typeMap, (ClassMap)typeMap.ObjectMap, "parameters", true, false);
+                                       WriteLine ("ReadEndElement();");
+                                       WriteLine ("break;");
+                                       WriteLineUni ("}");
+                                       WriteLineInd ("else ");
+                                       WriteLine ("UnknownNode(null);");
+                                       Unindent ();
+                                       WriteLine ("");
+                                       WriteLine ("Reader.MoveToContent();");
+                                       WriteLineUni ("}");
+                               }
+                       }
+                       else
+                               GenerateReadMembers (typeMap, (ClassMap)typeMap.ObjectMap, "parameters", true, _format == SerializationFormat.Encoded);
+
+                       if (_format == SerializationFormat.Encoded)
+                               WriteLine ("ReadReferencedElements();");
+
+                       return "parameters";
                }
                
                void GenerateReadObject (XmlTypeMapping typeMap)
                {
-                       if (_format == SerializationFormat.Literal)
+                       string isNullable;
+                       if (_format == SerializationFormat.Literal) {
                                WriteLine ("public " + typeMap.TypeFullName + " " + GetReadObjectName (typeMap) + " (bool isNullable, bool checkType)");
-                       else
-                               WriteLine ("public " + typeMap.TypeFullName + " " + GetReadObjectName (typeMap) + " ()");
+                               isNullable = "isNullable";
+                       }
+                       else {
+                               WriteLine ("public object " + GetReadObjectName (typeMap) + " ()");
+                               isNullable = "true";
+                       }
                        
                        WriteLineInd ("{");
 
@@ -987,14 +1200,14 @@ namespace System.Xml.Serialization
                        
                        switch (typeMap.TypeData.SchemaType)
                        {
-                               case SchemaTypes.Class: GenerateReadClassInstance (typeMap, "isNullable", "checkType"); break;
+                               case SchemaTypes.Class: GenerateReadClassInstance (typeMap, isNullable, "checkType"); break;
                                case SchemaTypes.Array: 
-                                       WriteLine ("return " + GenerateReadListElement (typeMap, null, "isNullable", true)); 
+                                       WriteLine ("return " + GenerateReadListElement (typeMap, null, isNullable, true) + ";"); 
                                        break;
-                               case SchemaTypes.XmlNode: GenerateReadXmlNodeElement (typeMap, "isNullable"); break;
-                               case SchemaTypes.Primitive: GenerateReadPrimitiveElement (typeMap, "isNullable"); break;
-                               case SchemaTypes.Enum: GenerateReadEnumElement (typeMap, "isNullable"); break;
-                               case SchemaTypes.XmlSerializable: GenerateReadXmlSerializableElement (typeMap, "isNullable"); break;
+                               case SchemaTypes.XmlNode: GenerateReadXmlNodeElement (typeMap, isNullable); break;
+                               case SchemaTypes.Primitive: GenerateReadPrimitiveElement (typeMap, isNullable); break;
+                               case SchemaTypes.Enum: GenerateReadEnumElement (typeMap, isNullable); break;
+                               case SchemaTypes.XmlSerializable: GenerateReadXmlSerializableElement (typeMap, isNullable); break;
                                default: throw new Exception ("Unsupported map type");
                        }
                        
@@ -1005,23 +1218,35 @@ namespace System.Xml.Serialization
                                
                void GenerateReadClassInstance (XmlTypeMapping typeMap, string isNullable, string checkType)
                {
-                       WriteLine (typeMap.TypeFullName + " ob = null;");
                        SetHookVar ("$OBJECT", "ob");
-               
-                       if (GenerateReadHook (HookType.type, typeMap.TypeData.Type)) {
-                               WriteLine ("return ob;");
-                               return;
-                       }
+                       if (!typeMap.TypeData.IsValueType)
+                       {
+                               WriteLine (typeMap.TypeFullName + " ob = null;");
                        
-                       if (_format == SerializationFormat.Literal) {
-                               WriteLine ("if (" + isNullable + " && ReadNull()) return null;");
-                               WriteLine ("");
-                               WriteLine ("if (checkType) ");
-                               WriteLineInd ("{");
+                               if (GenerateReadHook (HookType.type, typeMap.TypeData.Type)) {
+                                       WriteLine ("return ob;");
+                                       return;
+                               }
+                               
+                               if (_format == SerializationFormat.Literal) {
+                                       WriteLine ("if (" + isNullable + " && ReadNull()) return null;");
+                                       WriteLine ("");
+                                       WriteLine ("if (checkType) ");
+                                       WriteLineInd ("{");
+                               }
+                               else {
+                                       WriteLine ("if (ReadNull()) return null;");
+                                       WriteLine ("");
+                               }
                        }
-                       else {
-                               WriteLine ("if (ReadNull()) return null;");
-                               WriteLine ("");
+                       else
+                       {
+                               WriteLine (typeMap.TypeFullName + " ob = new " + typeMap.TypeFullName + " ();");
+                       
+                               if (GenerateReadHook (HookType.type, typeMap.TypeData.Type)) {
+                                       WriteLine ("return ob;");
+                                       return;
+                               }
                        }
                        
                        WriteLine ("System.Xml.XmlQualifiedName t = GetXsiType();");
@@ -1031,13 +1256,13 @@ namespace System.Xml.Serialization
                        bool first = true;
                        foreach (XmlTypeMapping realMap in typeMap.DerivedTypes)
                        {
-                               WriteLineInd ((first?"":"else ") + "if (t.Name == " + GetLiteral (realMap.XmlType) + " && t.Namespace == " + GetLiteral (realMap.Namespace) + ")");
-                               WriteLine ("return " + GetReadObjectName(realMap) + " (" + isNullable + ", " + checkType + ");");
+                               WriteLineInd ((first?"":"else ") + "if (t.Name == " + GetLiteral (realMap.XmlType) + " && t.Namespace == " + GetLiteral (realMap.XmlTypeNamespace) + ")");
+                               WriteLine ("return " + GetReadObjectCall(realMap, isNullable, checkType) + ";");
                                Unindent ();
                                first = false;
                        }
 
-                       WriteLine ((first?"":"else ") + "if (t.Name != " + GetLiteral (typeMap.XmlType) + " || t.Namespace != " + GetLiteral (typeMap.Namespace) + ")");
+                       WriteLine ((first?"":"else ") + "if (t.Name != " + GetLiteral (typeMap.XmlType) + " || t.Namespace != " + GetLiteral (typeMap.XmlTypeNamespace) + ")");
                        if (typeMap.TypeData.Type == typeof(object))
                                WriteLine ("\treturn ReadTypedPrimitive (t);");
                        else
@@ -1045,23 +1270,27 @@ namespace System.Xml.Serialization
 
                        WriteLineUni ("}");
                        
-                       if (_format == SerializationFormat.Literal)
-                               WriteLineUni ("}");
+                       if (!typeMap.TypeData.IsValueType)
+                       {
+                               if (_format == SerializationFormat.Literal)
+                                       WriteLineUni ("}");
 
-                       if (typeMap.TypeData.Type.IsAbstract) {
-                               GenerateEndHook ();
-                               WriteLine ("return ob;");
-                               return;
+                               if (typeMap.TypeData.Type.IsAbstract) {
+                                       GenerateEndHook ();
+                                       WriteLine ("return ob;");
+                                       return;
+                               }
+       
+                               WriteLine ("");
+                               WriteLine ("ob = new " + typeMap.TypeFullName + " ();");
                        }
-
-                       WriteLine ("");
-                       WriteLine ("ob = new " + typeMap.TypeFullName + " ();");
+                       
                        WriteLine ("");
                        
                        WriteLine ("Reader.MoveToElement();");
                        WriteLine ("");
                        
-                       GenerateReadMembers (typeMap, (ClassMap)typeMap.ObjectMap, "ob", false);
+                       GenerateReadMembers (typeMap, (ClassMap)typeMap.ObjectMap, "ob", false, false);
                        
                        WriteLine ("");
                        
@@ -1069,12 +1298,15 @@ namespace System.Xml.Serialization
                        WriteLine ("return ob;");
                }
 
-               void GenerateReadMembers (XmlTypeMapping typeMap, ClassMap map, string ob, bool isValueList)
+               void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isValueList, bool readByOrder)
                {
+                       XmlTypeMapping typeMap = xmlMap as XmlTypeMapping;
+                       Type xmlMapType = (typeMap != null) ? typeMap.TypeData.Type : typeof(object[]);
+                       
                        // A value list cannot have attributes
 
                        bool first;
-                       if (!isValueList && !GenerateReadHook (HookType.attributes, typeMap.TypeData.Type))
+                       if (!isValueList && !GenerateReadHook (HookType.attributes, xmlMapType))
                        {
                                // Reads attributes
                                
@@ -1093,7 +1325,7 @@ namespace System.Xml.Serialization
                                        foreach (XmlTypeMapMemberAttribute at in map.AttributeMembers)
                                        {
                                                WriteLineInd ((first?"":"else ") + "if (Reader.LocalName == " + GetLiteral (at.AttributeName) + " && Reader.NamespaceURI == " + GetLiteral (at.Namespace) + ") {");
-                                               if (!GenerateReadMemberHook (typeMap.TypeData.Type, at)) {
+                                               if (!GenerateReadMemberHook (xmlMapType, at)) {
                                                        GenerateSetMemberValue (at, ob, GenerateGetValueFromXmlString ("Reader.Value", at.TypeData, at.MappedType), isValueList);
                                                        GenerateEndHook ();
                                                }
@@ -1108,8 +1340,8 @@ namespace System.Xml.Serialization
                                // If the instance doesn't exist, then create.
                                
                                if (map.NamespaceDeclarations != null) {
-                                       if (!GenerateReadMemberHook (typeMap.TypeData.Type,map.NamespaceDeclarations)) {
-                                               string nss = ob + "." + map.NamespaceDeclarations.Name;
+                                       if (!GenerateReadMemberHook (xmlMapType, map.NamespaceDeclarations)) {
+                                               string nss = ob + ".@" + map.NamespaceDeclarations.Name;
                                                WriteLine ("if (" + nss + " == null) " + nss + " = new XmlSerializerNamespaces ();");
                                                WriteLineInd ("if (Reader.Prefix == \"xmlns\")");
                                                WriteLine (nss + ".Add (Reader.LocalName, Reader.Value);");
@@ -1126,9 +1358,9 @@ namespace System.Xml.Serialization
 
                                if (anyAttrMember != null) 
                                {
-                                       if (!GenerateReadArrayMemberHook (typeMap.TypeData.Type, anyAttrMember, "anyAttributeIndex")) {
+                                       if (!GenerateReadArrayMemberHook (xmlMapType, anyAttrMember, "anyAttributeIndex")) {
                                                WriteLine ("System.Xml.XmlAttribute attr = (System.Xml.XmlAttribute) Document.ReadNode(Reader);");
-                                               if (typeof(System.Xml.Schema.XmlSchemaAnnotated).IsAssignableFrom (typeMap.TypeData.Type)) 
+                                               if (typeof(System.Xml.Schema.XmlSchemaAnnotated).IsAssignableFrom (xmlMapType)) 
                                                        WriteLine ("ParseWsdlArrayType (attr);");
                                                GenerateAddListValue (anyAttrMember.TypeData, "anyAttributeArray", "anyAttributeIndex", GetCast (anyAttrMember.TypeData.ListItemTypeData, "attr"), true);
                                                GenerateEndHook ();
@@ -1136,7 +1368,7 @@ namespace System.Xml.Serialization
                                        WriteLine ("anyAttributeIndex++;");
                                }
                                else {
-                                       if (!GenerateReadHook (HookType.unknownAttribute, typeMap.TypeData.Type)) {
+                                       if (!GenerateReadHook (HookType.unknownAttribute, xmlMapType)) {
                                                WriteLine ("UnknownNode (" + ob + ");");
                                                GenerateEndHook ();
                                        }
@@ -1145,7 +1377,7 @@ namespace System.Xml.Serialization
                                WriteLineUni ("}");
                                WriteLineUni ("}");
 
-                               if (anyAttrMember != null && !MemberHasReadReplaceHook (typeMap.TypeData.Type, anyAttrMember))
+                               if (anyAttrMember != null && !MemberHasReadReplaceHook (xmlMapType, anyAttrMember))
                                {
                                        WriteLine ("");
                                        WriteLine("anyAttributeArray = (" + anyAttrMember.TypeData.FullTypeName + ") ShrinkArray (anyAttributeArray, anyAttributeIndex, " + GetTypeOf(anyAttrMember.TypeData.Type.GetElementType()) + ", true);");
@@ -1156,24 +1388,27 @@ namespace System.Xml.Serialization
                                GenerateEndHook ();
                        }
 
-                       WriteLine ("Reader.MoveToElement();");
-                       WriteLineInd ("if (Reader.IsEmptyElement) {"); 
-                       WriteLine ("Reader.Skip ();");
-                       WriteLine ("return " + ob + ";");
-                       WriteLineUni ("}");
-                       WriteLine ("");
-
-                       WriteLine ("Reader.ReadStartElement();");
-
+                       if (!isValueList)
+                       {
+                               WriteLine ("Reader.MoveToElement();");
+                               WriteLineInd ("if (Reader.IsEmptyElement) {"); 
+                               WriteLine ("Reader.Skip ();");
+                               WriteLine ("return " + ob + ";");
+                               WriteLineUni ("}");
+                               WriteLine ("");
+       
+                               WriteLine ("Reader.ReadStartElement();");
+                       }
+                       
                        // Reads elements
 
                        WriteLine("Reader.MoveToContent();");
                        WriteLine ("");
 
-                       if (!GenerateReadHook (HookType.elements, typeMap.TypeData.Type))
+                       if (!GenerateReadHook (HookType.elements, xmlMapType))
                        {
                                string[] readFlag = null;
-                               if (map.ElementMembers != null)
+                               if (map.ElementMembers != null && !readByOrder)
                                {
                                        string readFlagsVars = "bool ";
                                        readFlag = new string[map.ElementMembers.Count];
@@ -1185,7 +1420,7 @@ namespace System.Xml.Serialization
                                        if (map.ElementMembers.Count > 0) WriteLine (readFlagsVars + ";");
                                        WriteLine ("");
                                }
-       
+                               
                                string[] indexes = null;
                                string[] flatLists = null;
        
@@ -1201,10 +1436,10 @@ namespace System.Xml.Serialization
                                                indexes[n] = GetNumTempVar ();
                                                if (n > 0) code += ", ";
                                                code += indexes[n] + "=0";
-                                               if (!MemberHasReadReplaceHook (typeMap.TypeData.Type, mem)) {
+                                               if (!MemberHasReadReplaceHook (xmlMapType, mem)) {
                                                        flatLists[n] = GetObTempVar ();
                                                        string rval = "null";
-                                                       if (IsReadOnly (typeMap, mem, isValueList)) rval = ob + "." + mem.Name;
+                                                       if (IsReadOnly (typeMap, mem, isValueList)) rval = ob + ".@" + mem.Name;
                                                        WriteLine (mem.TypeData.FullTypeName + " " + flatLists[n] + " = " + rval + ";");
                                                }
                                        }
@@ -1214,21 +1449,45 @@ namespace System.Xml.Serialization
                                
                                if (_format == SerializationFormat.Encoded && map.ElementMembers != null)
                                {
-                                       WriteLine ("Fixup fixup = new Fixup(" + ob + ", new XmlSerializationFixupCallback(" + GetFixupCallbackName (typeMap) + "), " + map.ElementMembers.Count + ");");
+                                       _fixupCallbacks.Add (xmlMap);
+                                       WriteLine ("Fixup fixup = new Fixup(" + ob + ", new XmlSerializationFixupCallback(" + GetFixupCallbackName (xmlMap) + "), " + map.ElementMembers.Count + ");");
                                        WriteLine ("AddFixup (fixup);");
                                        WriteLine ("");
                                }
        
-                               WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
-                               WriteLineInd ("{");
-                               WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
-                               WriteLineInd ("{");
+                               ArrayList infos = null;
+                               
+                               int maxInd;
+                               if (readByOrder) {
+                                       if (map.ElementMembers != null) maxInd = map.ElementMembers.Count;
+                                       else maxInd = 0;
+                               }
+                               else
+                               {
+                                       infos = new ArrayList ();
+                                       infos.AddRange (map.AllElementInfos);
+                                       maxInd = infos.Count;
+                                       
+                                       WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
+                                       WriteLineInd ("{");
+                                       WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
+                                       WriteLineInd ("{");
+                               }
                                
                                first = true;
-                               foreach (XmlTypeMapElementInfo info in map.AllElementInfos)
+                               for (int ind = 0; ind < maxInd; ind++)
                                {
-                                       if (info.IsTextElement || info.IsUnnamedAnyElement) continue;
-                                       WriteLineInd ((first?"":"else ") + "if (Reader.LocalName == " + GetLiteral (info.ElementName) + " && Reader.NamespaceURI == " + GetLiteral (info.Namespace) + " && !" + readFlag[info.Member.Index] + ") {");
+                                       XmlTypeMapElementInfo info = readByOrder ? map.GetElement (ind) : (XmlTypeMapElementInfo) infos [ind];
+                                       
+                                       if (!readByOrder)
+                                       {
+                                               if (info.IsTextElement || info.IsUnnamedAnyElement) continue;
+                                               string elemCond = first ? "" : "else ";
+                                               elemCond += "if (Reader.LocalName == " + GetLiteral (info.ElementName);
+                                               if (!map.IgnoreMemberNamespace) elemCond += " && Reader.NamespaceURI == " + GetLiteral (info.Namespace);
+                                               elemCond += " && !" + readFlag[info.Member.Index] + ") {";
+                                               WriteLineInd (elemCond);
+                                       }
        
                                        if (info.Member.GetType() == typeof (XmlTypeMapMemberList))
                                        {
@@ -1236,6 +1495,8 @@ namespace System.Xml.Serialization
                                                {
                                                        string list = GetObTempVar ();
                                                        WriteLine ("object " + list + " = ReadReferencingElement (out fixup.Ids[" + info.Member.Index + "]);");
+                                                       RegisterReferencingMap (info.MappedType);
+
                                                        WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {");   // Already read
                                                        if (IsReadOnly (typeMap, info.Member, isValueList)) 
                                                                WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral(info.TypeData.FullTypeName) + ");");
@@ -1259,18 +1520,19 @@ namespace System.Xml.Serialization
                                                }
                                                else
                                                {
-                                                       if (!GenerateReadMemberHook (typeMap.TypeData.Type, info.Member)) {
+                                                       if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
                                                                if (IsReadOnly (typeMap, info.Member, isValueList)) GenerateReadListElement (info.MappedType, GenerateGetMemberValue (info.Member, ob, isValueList), GetLiteral(info.IsNullable), false);
                                                                else GenerateSetMemberValue (info.Member, ob, GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true), isValueList);
                                                                GenerateEndHook ();
                                                        }
                                                }
-                                               WriteLine (readFlag[info.Member.Index] + " = true;");
+                                               if (!readByOrder)
+                                                       WriteLine (readFlag[info.Member.Index] + " = true;");
                                        }
                                        else if (info.Member.GetType() == typeof (XmlTypeMapMemberFlatList))
                                        {
                                                XmlTypeMapMemberFlatList mem = (XmlTypeMapMemberFlatList)info.Member;
-                                               if (!GenerateReadArrayMemberHook (typeMap.TypeData.Type, info.Member, indexes[mem.FlatArrayIndex])) {
+                                               if (!GenerateReadArrayMemberHook (xmlMapType, info.Member, indexes[mem.FlatArrayIndex])) {
                                                        GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GenerateReadObjectElement (info), !IsReadOnly (typeMap, info.Member, isValueList));
                                                        GenerateEndHook ();
                                                }
@@ -1280,31 +1542,33 @@ namespace System.Xml.Serialization
                                        {
                                                XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement)info.Member;
                                                if (mem.TypeData.IsListType) { 
-                                                       if (!GenerateReadArrayMemberHook (typeMap.TypeData.Type, info.Member, indexes[mem.FlatArrayIndex])) {
-                                                               GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], "ReadXmlNode (false)", true);
+                                                       if (!GenerateReadArrayMemberHook (xmlMapType, info.Member, indexes[mem.FlatArrayIndex])) {
+                                                               GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetReadXmlNode (mem.TypeData.ListItemTypeData), true);
                                                                GenerateEndHook ();
                                                        }
                                                        WriteLine (indexes[mem.FlatArrayIndex] + "++;");
                                                }
                                                else {
-                                                       if (!GenerateReadMemberHook (typeMap.TypeData.Type, info.Member)) {
-                                                               GenerateSetMemberValue (mem, ob, "ReadXmlNode (false)", isValueList);
+                                                       if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
+                                                               GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData), isValueList);
                                                                GenerateEndHook ();
                                                        }
                                                }
                                        }
                                        else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement))
                                        {
-                                               WriteLine (readFlag[info.Member.Index] + " = true;");
+                                               if (!readByOrder)
+                                                       WriteLine (readFlag[info.Member.Index] + " = true;");
                                                if (_format == SerializationFormat.Encoded && info.MultiReferenceType) 
                                                {
                                                        string val = GetObTempVar ();
+                                                       RegisterReferencingMap (info.MappedType);
                                                        WriteLine ("object " + val + " = ReadReferencingElement (out fixup.Ids[" + info.Member.Index + "]);");
                                                        WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {");   // already read
-                                                       GenerateSetMemberValue (info.Member, ob, val, isValueList);
+                                                       GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,val), isValueList);
                                                        WriteLineUni ("}");
                                                }
-                                               else if (!GenerateReadMemberHook (typeMap.TypeData.Type, info.Member)) {
+                                               else if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
                                                        GenerateSetMemberValue (info.Member, ob, GenerateReadObjectElement (info), isValueList);
                                                        GenerateEndHook ();
                                                }
@@ -1312,82 +1576,87 @@ namespace System.Xml.Serialization
                                        else
                                                throw new InvalidOperationException ("Unknown member type");
        
-                                       WriteLineUni ("}");
+                                       if (!readByOrder)
+                                               WriteLineUni ("}");
                                        first = false;
                                }
                                
-                               if (!first) WriteLineInd ("else {");
-                               
-                               if (map.DefaultAnyElementMember != null)
+                               if (!readByOrder)
                                {
-                                       XmlTypeMapMemberAnyElement mem = map.DefaultAnyElementMember;
-                                       if (mem.TypeData.IsListType) {
-                                               if (!GenerateReadArrayMemberHook (typeMap.TypeData.Type, mem, indexes[mem.FlatArrayIndex])) {
-                                                       GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], "ReadXmlNode (false)", true);
+                                       if (!first) WriteLineInd ("else {");
+                                       
+                                       if (map.DefaultAnyElementMember != null)
+                                       {
+                                               XmlTypeMapMemberAnyElement mem = map.DefaultAnyElementMember;
+                                               if (mem.TypeData.IsListType) {
+                                                       if (!GenerateReadArrayMemberHook (xmlMapType, mem, indexes[mem.FlatArrayIndex])) {
+                                                               GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetReadXmlNode(mem.TypeData.ListItemTypeData), true);
+                                                               GenerateEndHook ();
+                                                       }
+                                                       WriteLine (indexes[mem.FlatArrayIndex] + "++;");
+                                               }
+                                               else if (! GenerateReadMemberHook (xmlMapType, mem)) {
+                                                       GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData), isValueList);
                                                        GenerateEndHook ();
                                                }
-                                               WriteLine (indexes[mem.FlatArrayIndex] + "++;");
                                        }
-                                       else if (! GenerateReadMemberHook (typeMap.TypeData.Type, mem)) {
-                                               GenerateSetMemberValue (mem, ob, "ReadXmlNode (false)", isValueList);
-                                               GenerateEndHook ();
-                                       }
-                               }
-                               else {
-                                       if (!GenerateReadHook (HookType.unknownElement, typeMap.TypeData.Type)) {
-                                               WriteLine ("UnknownNode (" + ob + ");");
-                                               GenerateEndHook ();
-                                       }
-                               }
-                               
-                               if (!first) WriteLineUni ("}");
-       
-                               WriteLineUni ("}");
-                               
-                               if (map.XmlTextCollector != null)
-                               {
-                                       WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text)");
-                                       WriteLineInd ("{");
-       
-                                       if (map.XmlTextCollector is XmlTypeMapMemberExpandable)
-                                       {
-                                               XmlTypeMapMemberExpandable mem = (XmlTypeMapMemberExpandable)map.XmlTextCollector;
-                                               XmlTypeMapMemberFlatList flatl = mem as XmlTypeMapMemberFlatList;
-                                               Type itype = (flatl == null) ? mem.TypeData.ListItemType : flatl.ListMap.FindTextElement().TypeData.Type;
-                                               
-                                               if (!GenerateReadArrayMemberHook (typeMap.TypeData.Type, map.XmlTextCollector, indexes[mem.FlatArrayIndex])) {
-                                                       string val = (itype == typeof (string)) ? "Reader.ReadString()" : "ReadXmlNode (false)";
-                                                       GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], val, true);
+                                       else {
+                                               if (!GenerateReadHook (HookType.unknownElement, xmlMapType)) {
+                                                       WriteLine ("UnknownNode (" + ob + ");");
                                                        GenerateEndHook ();
                                                }
-                                               WriteLine (indexes[mem.FlatArrayIndex] + "++;");
                                        }
-                                       else if (!GenerateReadMemberHook (typeMap.TypeData.Type, map.XmlTextCollector))
+                                       
+                                       if (!first) WriteLineUni ("}");
+               
+                                       WriteLineUni ("}");
+                                       
+                                       if (map.XmlTextCollector != null)
                                        {
-                                               XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement) map.XmlTextCollector;
-                                               XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) mem.ElementInfo [0];
-                                               if (info.TypeData.Type == typeof (string))
-                                                       GenerateSetMemberValue (mem, ob, "ReadString (" + GenerateGetMemberValue (mem, ob, isValueList) + ")", isValueList);
-                                               else
-                                                       GenerateSetMemberValue (mem, ob, GenerateGetValueFromXmlString ("Reader.ReadString()", info.TypeData, info.MappedType), isValueList);
-                                               GenerateEndHook ();
+                                               WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text)");
+                                               WriteLineInd ("{");
+               
+                                               if (map.XmlTextCollector is XmlTypeMapMemberExpandable)
+                                               {
+                                                       XmlTypeMapMemberExpandable mem = (XmlTypeMapMemberExpandable)map.XmlTextCollector;
+                                                       XmlTypeMapMemberFlatList flatl = mem as XmlTypeMapMemberFlatList;
+                                                       Type itype = (flatl == null) ? mem.TypeData.ListItemType : flatl.ListMap.FindTextElement().TypeData.Type;
+                                                       
+                                                       if (!GenerateReadArrayMemberHook (xmlMapType, map.XmlTextCollector, indexes[mem.FlatArrayIndex])) {
+                                                               string val = (itype == typeof (string)) ? "Reader.ReadString()" : GetCast(itype,"ReadXmlNode (false)");
+                                                               GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], val, true);
+                                                               GenerateEndHook ();
+                                                       }
+                                                       WriteLine (indexes[mem.FlatArrayIndex] + "++;");
+                                               }
+                                               else if (!GenerateReadMemberHook (xmlMapType, map.XmlTextCollector))
+                                               {
+                                                       XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement) map.XmlTextCollector;
+                                                       XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) mem.ElementInfo [0];
+                                                       if (info.TypeData.Type == typeof (string))
+                                                               GenerateSetMemberValue (mem, ob, "ReadString (" + GenerateGetMemberValue (mem, ob, isValueList) + ")", isValueList);
+                                                       else
+                                                               GenerateSetMemberValue (mem, ob, GenerateGetValueFromXmlString ("Reader.ReadString()", info.TypeData, info.MappedType), isValueList);
+                                                       GenerateEndHook ();
+                                               }
+                                               WriteLineUni ("}");
                                        }
+                                               
+                                       WriteLine ("else");
+                                       WriteLine ("\tUnknownNode(" + ob + ");");
+                                       WriteLine ("");
+                                       WriteLine ("Reader.MoveToContent();");
                                        WriteLineUni ("}");
                                }
-                                       
-                               WriteLine ("else");
-                               WriteLine ("\tUnknownNode(ob);");
-                               WriteLine ("");
-       
-                               WriteLine ("Reader.MoveToContent();");
-                               WriteLineUni ("}");
+                               else
+                                       WriteLine ("Reader.MoveToContent();");
        
                                if (flatLists != null)
                                {
                                        WriteLine ("");
                                        foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
                                        {
-                                               if (MemberHasReadReplaceHook (typeMap.TypeData.Type, mem)) continue;
+                                               if (MemberHasReadReplaceHook (xmlMapType, mem)) continue;
                                                
                                                string list = flatLists[mem.FlatArrayIndex];
                                                if (mem.TypeData.Type.IsArray)
@@ -1399,8 +1668,11 @@ namespace System.Xml.Serialization
                                GenerateEndHook ();
                        }                       
 
-                       WriteLine ("");
-                       WriteLine ("ReadEndElement();");
+                       if (!isValueList)
+                       {
+                               WriteLine ("");
+                               WriteLine ("ReadEndElement();");
+                       }
                }
                
                bool IsReadOnly (XmlTypeMapping map, XmlTypeMapMember member, bool isValueList)
@@ -1412,13 +1684,17 @@ namespace System.Xml.Serialization
                void GenerateSetMemberValue (XmlTypeMapMember member, string ob, string value, bool isValueList)
                {
                        if (isValueList) WriteLine (ob + "[" + member.Index + "] = " + value + ";");
-                       else WriteLine (ob + "." + member.Name + " = " + value + ";");
+                       else {
+                               WriteLine (ob + ".@" + member.Name + " = " + value + ";");
+                               if (member.IsOptionalValueType)
+                                       WriteLine (ob + "." + member.Name + "Specified = true;");
+                       }
                }
 
                object GenerateGetMemberValue (XmlTypeMapMember member, object ob, bool isValueList)
                {
                        if (isValueList) return ob + "[" + member.Index + "]";
-                       else return ob + "." + member.Name;
+                       else return ob + ".@" + member.Name;
                }
 
                string GenerateReadObjectElement (XmlTypeMapElementInfo elem)
@@ -1426,7 +1702,7 @@ namespace System.Xml.Serialization
                        switch (elem.TypeData.SchemaType)
                        {
                                case SchemaTypes.XmlNode:
-                                       return "ReadXmlNode (true)";
+                                       return GetCast (elem.TypeData, TypeTranslator.GetTypeData(typeof(XmlNode)), "ReadXmlNode (true)");
 
                                case SchemaTypes.Primitive:
                                case SchemaTypes.Enum:
@@ -1436,10 +1712,10 @@ namespace System.Xml.Serialization
                                        return GenerateReadListElement (elem.MappedType, null, GetLiteral(elem.IsNullable), true);
 
                                case SchemaTypes.Class:
-                                       return GetReadObjectName(elem.MappedType) + " (" + GetLiteral(elem.IsNullable) + ", true)";
+                                       return GetReadObjectCall (elem.MappedType, GetLiteral(elem.IsNullable), "true");
 
                                case SchemaTypes.XmlSerializable:
-                                       return "ReadSerializable (new " + elem.TypeData.FullTypeName + " ())";
+                                       return GetCast (elem.TypeData, "ReadSerializable (new " + elem.TypeData.FullTypeName + " ())");
 
                                default:
                                        throw new NotSupportedException ("Invalid value type");
@@ -1475,19 +1751,21 @@ namespace System.Xml.Serialization
                        Type listType = typeMap.TypeData.Type;
                        ListMap listMap = (ListMap)typeMap.ObjectMap;
 
-                       if (list == null) {
-                               if (canCreateInstance) {
-                                       list = GetObTempVar ();
-                                       WriteLine (typeMap.TypeFullName + " " + list + " = null;");
-                                       WriteLineInd ("if (!ReadNull()) {");
-                                       WriteLine (list + " = " + GenerateCreateList (listType) + ";");
-                               }
-                               else throw new InvalidOperationException ("Cannot assign array to read only property: " + typeMap.TypeFullName);
+                       if (canCreateInstance) 
+                       {
+                               list = GetObTempVar ();
+                               WriteLine (typeMap.TypeFullName + " " + list + " = null;");
+                               WriteLineInd ("if (!ReadNull()) {");
+                               WriteLine (list + " = " + GenerateCreateList (listType) + ";");
                        }
-                       else {
+                       else
+                       {
+                               WriteLineInd ("if (" + list + " == null)");
+                               WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap.TypeFullName) + ")");
+                               Unindent ();
                                WriteLineInd ("if (!ReadNull()) {");
                        }
-
+                               
                        WriteLineInd ("if (Reader.IsEmptyElement) {");
                        WriteLine ("Reader.Skip();");
                        if (listType.IsArray)
@@ -1615,7 +1893,7 @@ namespace System.Xml.Serialization
 
                void GenerateReadXmlNodeElement (XmlTypeMapping typeMap, string isNullable)
                {
-                       WriteLine ("return ReadXmlNode (false);");
+                       WriteLine ("return " + GetReadXmlNode (typeMap.TypeData) + ";");
                }
 
                void GenerateReadPrimitiveElement (XmlTypeMapping typeMap, string isNullable)
@@ -1686,7 +1964,7 @@ namespace System.Xml.Serialization
                        WriteLine ("return (" + typeMap.TypeFullName + ") Int64.Parse (" + val + ");");
                        WriteLineUni ("}");
                        WriteLineInd ("catch {");
-                       WriteLine ("throw new InvalidOperationException (\"Invalid enumeration value: \" + " + val + ");");
+                       WriteLine ("throw CreateUnknownConstantException (" + val + ", typeof(" + typeMap.TypeFullName + "));");
                        WriteLineUni ("}");
                        Unindent ();
                        WriteLineUni ("}");
@@ -1714,12 +1992,12 @@ namespace System.Xml.Serialization
 
                        if (_format == SerializationFormat.Encoded)
                        {
-                               foreach (XmlTypeMapping map in _mapsToGenerate)  
+                               foreach (XmlMapping xmap in _mapsToGenerate)  
                                {
+                                       XmlTypeMapping map = xmap as XmlTypeMapping;
+                                       if (map == null) continue;
                                        if (map.TypeData.SchemaType == SchemaTypes.Class || map.TypeData.SchemaType == SchemaTypes.Enum)
-                                       {
                                                WriteMetCall ("AddReadCallback", GetLiteral (map.XmlType), GetLiteral(map.Namespace), GetTypeOf(map.TypeData.Type), "new XmlSerializationReadCallback (" + GetReadObjectName (map) + ")");
-                                       }
                                }
                        }
                        
@@ -1734,33 +2012,37 @@ namespace System.Xml.Serialization
 
                void GenerateFixupCallbacks ()
                {
-                       foreach (XmlTypeMapping map in _mapsToGenerate)  
+                       foreach (XmlMapping map in _fixupCallbacks)
                        {
-                               if (map.TypeData.SchemaType == SchemaTypes.Class)
-                               {
-                                       WriteLine ("void " + GetFixupCallbackName (map) + " (object obfixup)");
-                                       WriteLineInd ("{");                                     
-                                       WriteLine ("Fixup fixup = (Fixup)obfixup;");
-                                       WriteLine (map.TypeFullName + " source = (" + map.TypeFullName + ") fixup.Source;");
-                                       WriteLine ("string[] ids = fixup.Ids;");
-                                       WriteLine ("");
+                               bool isList = map is XmlMembersMapping;
+                               string tname = !isList ? ((XmlTypeMapping)map).TypeFullName : "object[]";
+                               WriteLine ("void " + GetFixupCallbackName (map) + " (object obfixup)");
+                               WriteLineInd ("{");                                     
+                               WriteLine ("Fixup fixup = (Fixup)obfixup;");
+                               WriteLine (tname + " source = (" + tname + ") fixup.Source;");
+                               WriteLine ("string[] ids = fixup.Ids;");
+                               WriteLine ("");
 
-                                       ClassMap cmap = (ClassMap)map.ObjectMap;
-                                       ICollection members = cmap.ElementMembers;
-                                       if (members != null) {
-                                               foreach (XmlTypeMapMember member in members)
-                                               {
-                                                       WriteLineInd ("if (ids[" + member.Index + "] != null)");
-                                                       GenerateSetMemberValue (member, "source", GetCast (member.TypeData, "GetTarget(ids[" + member.Index + "])"), false);
-                                                       Unindent ();
-                                               }
+                               ClassMap cmap = (ClassMap)map.ObjectMap;
+                               ICollection members = cmap.ElementMembers;
+                               if (members != null) {
+                                       foreach (XmlTypeMapMember member in members)
+                                       {
+                                               WriteLineInd ("if (ids[" + member.Index + "] != null)");
+                                               GenerateSetMemberValue (member, "source", GetCast (member.TypeData, "GetTarget(ids[" + member.Index + "])"), isList);
+                                               Unindent ();
                                        }
-                                       WriteLineUni ("}");
-                                       WriteLine ("");
                                }
+                               WriteLineUni ("}");
+                               WriteLine ("");
                        }
                }
-       
+
+               string GetReadXmlNode (TypeData type)
+               {
+                       return GetCast (type, TypeTranslator.GetTypeData (typeof(XmlNode)), "ReadXmlNode (false)");
+               }
+               
                #endregion
                
                #region Helper methods
@@ -1836,6 +2118,7 @@ namespace System.Xml.Serialization
        
                bool MemberHasReadReplaceHook (Type type, XmlTypeMapMember member)
                {
+                       if (_config == null) return false;
                        return _config.GetHooks (HookType.member, HookDir.Read, HookAction.Replace, type, member.Name).Count > 0;
                }
                
@@ -1867,6 +2150,7 @@ namespace System.Xml.Serialization
                
                bool GenerateHooks (HookType hookType, HookDir dir, Type type, string member, HookAction action)
                {
+                       if (_config == null) return false;
                        ArrayList hooks = _config.GetHooks (hookType, dir, action, type, null);
                        if (hooks.Count == 0) return false;                     
                        foreach (Hook hook in hooks)
@@ -1923,6 +2207,12 @@ namespace System.Xml.Serialization
                        return name;
                }
                
+               void RegisterReferencingMap (XmlTypeMapping typeMap)
+               {
+                       if (typeMap != null && !_mapsToGenerate.Contains (typeMap))
+                               _mapsToGenerate.Add (typeMap);
+               }
+               
                string GetWriteObjectName (XmlTypeMapping typeMap)
                {
                        if (!_mapsToGenerate.Contains (typeMap)) _mapsToGenerate.Add (typeMap);
@@ -1947,10 +2237,22 @@ namespace System.Xml.Serialization
                        return GetUniqueName ("wc", typeMap, "WriteCallback_" + typeMap.XmlType);
                }
                
-               string GetFixupCallbackName (XmlTypeMapping typeMap)
+               string GetFixupCallbackName (XmlMapping typeMap)
                {
                        if (!_mapsToGenerate.Contains (typeMap)) _mapsToGenerate.Add (typeMap);
-                       return GetUniqueName ("fc", typeMap, "FixupCallback_" + typeMap.XmlType);
+                       
+                       if (typeMap is XmlTypeMapping)
+                               return GetUniqueName ("fc", typeMap, "FixupCallback_" + ((XmlTypeMapping)typeMap).XmlType);
+                       else
+                               return GetUniqueName ("fc", typeMap, "FixupCallback__Message");
+               }
+               
+               string GetReadObjectCall (XmlTypeMapping typeMap, string isNullable, string checkType)
+               {
+                       if (_format == SerializationFormat.Literal)
+                               return GetReadObjectName (typeMap) + " (" + isNullable + ", " + checkType + ")";
+                       else
+                               return GetCast (typeMap.TypeData, GetReadObjectName (typeMap) + " ()");
                }
                
                string GetFillListName (TypeData td)
@@ -1970,6 +2272,11 @@ namespace System.Xml.Serialization
                        return "((" + td.FullTypeName + ") " + val + ")";
                }
 
+               string GetCast (Type td, string val)
+               {
+                       return "((" + td.FullName + ") " + val + ")";
+               }
+
                string GetTypeOf (TypeData td)
                {
                        return "typeof(" + td.FullTypeName + ")";
@@ -2055,4 +2362,15 @@ namespace System.Xml.Serialization
                #endregion
 
        }
+       
+       internal class GenerationResult
+       {
+               public XmlMapping Mapping;
+               public string ReaderClassName;
+               public string ReadMethodName;
+               public string WriterClassName;
+               public string WriteMethodName;
+               public string Namespace;
+       }
+       
 }
index 71311673741763c43c8bb1a1e3d7a7a3a3b743d4..37231617699510d93d9f1c31a4c883554318dd71 100644 (file)
@@ -57,5 +57,13 @@ namespace System.Xml.Serialization
                                ns = value;\r
                        }\r
                }\r
+               \r
+               internal bool InternalEquals (SoapAttributeAttribute other)\r
+               {\r
+                       if (other == null) return false;\r
+                       return (attrName == other.attrName &&\r
+                                       dataType == other.dataType &&\r
+                                       ns == other.ns);\r
+               }\r
        }\r
 }\r
index dcbbca6bcb7263db58781380d51517db0781c8cc..66c6dc493f23766225e8c9916fe0c7d3b769d6ab 100644 (file)
@@ -68,5 +68,17 @@ namespace System.Xml.Serialization
                        return new TypeMember(type, member);\r
                }\r
 \r
+               internal bool InternalEquals (SoapAttributeOverrides other)\r
+               {\r
+                       if (other == null) return false;\r
+                       if (overrides.Count != other.overrides.Count) return false;\r
+                       \r
+                       foreach (DictionaryEntry entry in overrides)\r
+                       {\r
+                               SoapAttributes val = (SoapAttributes) other.overrides [entry.Key];\r
+                               if (val == null || !val.InternalEquals ((SoapAttributes) entry.Value)) return false;\r
+                       }\r
+                       return true;\r
+               }\r
        }\r
 }\r
index 786ca2921f352de4785c93c7e46fda2a93a8306b..c0a752f8adf97da1a87dcd045ce01abcfa4b954c 100644 (file)
@@ -84,5 +84,38 @@ namespace System.Xml.Serialization
                        get { return  soapType; } \r
                        set { soapType = value; }\r
                }\r
+               \r
+               internal bool InternalEquals (SoapAttributes other)\r
+               {\r
+                       if (other == null) return false;\r
+                       if (soapIgnore != other.soapIgnore) return false;\r
+                       \r
+                       if (soapAttribute == null) {\r
+                               if (other.soapAttribute != null) return false; }\r
+                       else\r
+                               if (!soapAttribute.InternalEquals (other.soapAttribute)) return false;\r
+                               \r
+                       if (soapElement == null) {\r
+                               if (other.soapElement != null) return false; }\r
+                       else\r
+                               if (!soapElement.InternalEquals (other.soapElement)) return false;\r
+                               \r
+                       if (soapEnum == null) {\r
+                               if (other.soapEnum != null) return false; }\r
+                       else\r
+                               if (!soapEnum.InternalEquals (other.soapEnum)) return false;\r
+                               \r
+                       if (soapType == null) {\r
+                               if (other.soapType != null) return false; }\r
+                       else\r
+                               if (!soapType.InternalEquals (other.soapType)) return false;\r
+                               \r
+                       if (soapDefaultValue == null) {\r
+                               if (other.soapDefaultValue != null) return false; }\r
+                       else\r
+                               if (!soapDefaultValue.Equals (other.soapDefaultValue)) return false;\r
+                               \r
+                       return true;\r
+               }       \r
        }\r
 }\r
index fbb6527e821dfd3a13978893b2415d43c25fe702..5c6f4e68952ce1153e7f6762bbe61bf11aaf8934 100644 (file)
@@ -56,5 +56,13 @@ namespace System.Xml.Serialization
                                isNullable = value; \r
                        }\r
                }\r
+               \r
+               internal bool InternalEquals (SoapElementAttribute other)\r
+               {\r
+                       if (other == null) return false;\r
+                       return (elementName == other.elementName &&\r
+                                       dataType == other.dataType &&\r
+                                       isNullable == other.isNullable);\r
+               }\r
        }\r
 }\r
index fba4f31112648596f8f20de3cfe371297179f729..1d93f13a4c453343ae94a74c530d02490ae89400 100644 (file)
@@ -36,5 +36,10 @@ namespace System.Xml.Serialization
                                name = value; \r
                        }\r
                }\r
+               \r
+               internal bool InternalEquals (SoapEnumAttribute other)\r
+               {\r
+                       return (other == null && name == other.name);\r
+               }\r
        }\r
 }\r
index e4d2d4ce6a5baf89aa9d5d0f15d19ab92dfb22d7..bf1c6527843b5bf8ba6692feb8a34cc49ed403ff 100644 (file)
@@ -69,6 +69,7 @@ namespace System.Xml.Serialization {
                        XmlMembersMapping mps = new XmlMembersMapping (elementName, ns, hasWrapperElement, writeAccessors, mapping);
                        mps.RelatedMaps = relatedMaps;
                        mps.Format = SerializationFormat.Encoded;
+                       mps.Source = new MembersSerializationSource (elementName, hasWrapperElement, members, writeAccessors, false, null, includedTypes);
                        return mps;
                }
 
@@ -101,6 +102,7 @@ namespace System.Xml.Serialization {
                        }
                        map.RelatedMaps = relatedMaps;
                        map.Format = SerializationFormat.Encoded;
+                       map.Source = new SoapTypeSerializationSource (type, attributeOverrides, defaultNamespace, includedTypes);
                        return map;
                }
 
index d6e68934cc629118124222c67fbec8324c3a4746..d544d048d88fb3d630d76109b21ceb28dd6c411f 100644 (file)
@@ -53,7 +53,13 @@ namespace System.Xml.Serialization
                        set { typeName = value;
                        }\r
                }\r
-\r
-\r
+               \r
+               internal bool InternalEquals (SoapTypeAttribute other)\r
+               {\r
+                       return (other != null &&\r
+                                       ns == other.ns &&\r
+                                       typeName == other.typeName &&\r
+                                       includeInSchema == other.includeInSchema);\r
+               }\r
        }\r
 }\r
index bf133aa9e311d6807eaf5a914955e7f7704ed4c0..4e1aac148c18b838af1ef5ab10c72ad6fd82f23e 100644 (file)
@@ -21,7 +21,6 @@ namespace System.Xml.Serialization
        {
                private string elementName;
                private string ns;
-               private int order;
 
                public XmlAnyElementAttribute ()
                {
@@ -54,13 +53,11 @@ namespace System.Xml.Serialization
                                ns = value;
                        }
                }
-               /// <summary>
-               /// Specifies Order in which Memberswill be serialized as Elements.
-               /// </summary>
-               internal int Order
+               
+               internal bool InternalEquals (XmlAnyElementAttribute other)
                {
-                       get{ return  order; }
-                       set{ order = value; }
+                       if (other == null) return false;
+                       return (elementName == other.elementName && ns == other.ns);
                }
        }
 }
index 86242fe7097982a7b433855f799e9ff4bd358ff6..a369786040b519bc38c5b30ee6e2bd70d57bbc35 100644 (file)
@@ -61,6 +61,16 @@ namespace System.Xml.Serialization
                {\r
                        List.CopyTo(array, index);\r
                }\r
+               \r
+               internal bool InternalEquals (XmlAnyElementAttributes other)\r
+               {\r
+                       if (other == null) return false;\r
+                       \r
+                       if (Count != other.Count) return false;\r
+                       for (int n=0; n<Count; n++)\r
+                               if (!this[n].InternalEquals (other[n])) return false;\r
+                       return true;\r
+               }\r
        }\r
 \r
 }\r
index d0b67ab636d330ac260ebd6a7c05f991029b9a68..7349a86bf58ce454184b722b80da431a80eceeae 100644 (file)
@@ -23,7 +23,6 @@ namespace System.Xml.Serialization
                private XmlSchemaForm form;\r
                private bool isNullable;\r
                private string ns;\r
-               private int order;\r
 \r
                public XmlArrayAttribute()\r
                {\r
@@ -78,13 +77,14 @@ namespace System.Xml.Serialization
                                ns = value;\r
                        }\r
                }\r
-               /// <summary>\r
-               /// Specifies Order in which Memberswill be serialized as Elements.\r
-               /// </summary>\r
-               internal int Order\r
+               \r
+               internal bool InternalEquals (XmlArrayAttribute other)\r
                {\r
-                       get{ return  order; }\r
-                       set{ order = value; }\r
+                       if (other == null) return false;\r
+                       return (elementName == other.elementName &&\r
+                                       form == other.form &&\r
+                                       isNullable == other.isNullable &&\r
+                                       ns == other.ns);\r
                }\r
        }\r
 }\r
index adb16b4c2d7d08ac0a012a667fcb10aee00fb8c0..ef9161045086fc27a348b83280b657812b9acfe5 100644 (file)
@@ -26,7 +26,6 @@ namespace System.Xml.Serialization
                private bool isNullable = true;
                private int nestingLevel;
                private Type type;
-               private int order;
 
                public XmlArrayItemAttribute ()
                {
@@ -73,13 +72,18 @@ namespace System.Xml.Serialization
                        get { return nestingLevel; }
                        set { nestingLevel = value; }
                }
-               /// <summary>
-               /// Specifies Order in which Memberswill be serialized as Elements.
-               /// </summary>
-               public int Order
+               
+               internal bool InternalEquals (XmlArrayItemAttribute other)
                {
-                       get{ return  order; }
-                       set{ order = value; }
+                       if (other == null) return false;
+                       
+                       return (dataType == other.dataType &&
+                                       elementName == other.elementName &&
+                                       form == other.form &&
+                                       ns == other.ns &&
+                                       isNullable == other.isNullable &&
+                                       nestingLevel == other.nestingLevel &&
+                                       type == other.type);
                }
        }
 }
index 51528209a412897da4a35576627e3330ba7a019e..b5bf30be4db806e1b9ab592e17630d599371f237 100644 (file)
@@ -57,5 +57,15 @@ namespace System.Xml.Serialization
                {\r
                        List.Remove(attribute);\r
                }\r
+               \r
+               internal bool InternalEquals (XmlArrayItemAttributes other)\r
+               {\r
+                       if (other == null) return false;\r
+                       \r
+                       if (Count != other.Count) return false;\r
+                       for (int n=0; n<Count; n++)\r
+                               if (!this[n].InternalEquals (other[n])) return false;\r
+                       return true;\r
+               }\r
        }\r
 }\r
index 858297687bf9ecc8a0ad1064dc6516fd3083c9e6..496633e4df250bbc5c11f84878c0849cb3be0313 100644 (file)
@@ -89,6 +89,16 @@ namespace System.Xml.Serialization
                                type = value;
                        }\r
                }\r
-\r
+               \r
+               internal bool InternalEquals (XmlAttributeAttribute other)\r
+               {\r
+                       if (other == null) return false;\r
+                       \r
+                       return (attributeName == other.attributeName &&\r
+                                       dataType == other.dataType &&\r
+                                       type == other.type &&\r
+                                       form == other.form &&\r
+                                       ns == other.ns);\r
+               }\r
        }\r
 }\r
index 75c6112c794c0a72fb699aa4803e672a750592bc..6f79cb7c26c25ba6a44974bae3e2b8cab4a92689 100644 (file)
@@ -56,5 +56,17 @@ namespace System.Xml.Serialization
                        return new TypeMember(type, member);\r
                }\r
 \r
+               internal bool InternalEquals (XmlAttributeOverrides other)\r
+               {\r
+                       if (other == null) return false;\r
+                       if (overrides.Count != other.overrides.Count) return false;\r
+                       \r
+                       foreach (DictionaryEntry entry in overrides)\r
+                       {\r
+                               XmlAttributes val = (XmlAttributes) other.overrides [entry.Key];\r
+                               if (val == null || !val.Equals ((XmlAttributes) entry.Value)) return false;\r
+                       }\r
+                       return true;\r
+               }\r
        }\r
-}
\ No newline at end of file
+}
index fd86174996bce9be54a9d51e8880f98463d60ad9..9e471c6d339d15554dd84f0127fd7cc23e945ffd 100644 (file)
@@ -34,59 +34,10 @@ namespace System.Xml.Serialization
                private XmlTextAttribute xmlText;
                private XmlTypeAttribute xmlType;
 
-               private MemberInfo minfo;
-               private FieldInfo  finfo;
-               private PropertyInfo pinfo;
-               internal ArrayList XmlIncludes = new ArrayList();
-               //internal string ElementName;
-
-               //The element Order in serialization.
-               internal int order;
-               internal bool isAttribute;
-               internal static XmlAttributes.XmlAttributesComparer attrComparer;
-
-               //Sorting Order of Elements: XmlNs, XmlAttributes, XmlElement
-               internal class XmlAttributesComparer : IComparer
-               {
-                       public int Compare(object x,object y)
-                       {
-                               if(x is XmlAttributes && y is XmlAttributes)
-                               {
-                                       XmlAttributes attx = (XmlAttributes)x;
-                                       XmlAttributes atty = (XmlAttributes)y;
-                                       if(attx.xmlns)
-                                               return -1;
-                                       if(atty.xmlns)
-                                               return 1;
-                                       if(attx.isAttribute)
-                                               return -1;
-                                       if(atty.isAttribute)
-                                               return 1;
-                                       int diff = attx.order - atty.order;
-                                       if(diff == 0)
-                                               return 0;
-                                       if(diff > 0)
-                                               return 1;
-                                       if(diff < 0)
-                                               return -1;
-                               }
-                               if(x == null)
-                                       return -1;
-                               if(y == null)
-                                       return 1;
-                               throw new Exception("Should never occur. XmlAttributesComparer.Compare");
-                       }
-               }
-
                public XmlAttributes ()
                {
                }
 
-               static XmlAttributes ()
-               {
-                       attrComparer = new XmlAttributes.XmlAttributesComparer();
-               }
-
                public XmlAttributes (ICustomAttributeProvider provider)
                {
                        object[] attributes = provider.GetCustomAttributes(false);
@@ -262,197 +213,64 @@ namespace System.Xml.Serialization
                        }
                }
                #endregion
-
-               #region internal properties
-               internal MemberInfo MemberInfo
-               {
-                       get { return  minfo; }
-                       set { minfo = value; }
-               }
-
-               internal FieldInfo FieldInfo 
-               {
-                       get { return  finfo; }
-                       set { finfo = value; }
-               }
-
-               internal PropertyInfo PropertyInfo
-               {
-                       get { return  pinfo; }
-                       set { pinfo = value; }
-               }
-               #endregion
-
-               //Only permissible attributes for a class type are: XmlRoot and XmlInclude
-               internal static XmlAttributes FromClass(Type classType)
-               {
-                       XmlAttributes XmlAttr = new XmlAttributes();
-                       object[] attributes = classType.GetCustomAttributes(false);
-                       foreach(object obj in attributes)
-                       {
-                               if(obj is XmlRootAttribute)
-                                       XmlAttr.xmlRoot = (XmlRootAttribute) obj;
-                               else if(obj is XmlIncludeAttribute)
-                                       XmlAttr.XmlIncludes.Add(obj);
-                       }
-                       return XmlAttr;
-               }
-
-               internal static XmlAttributes FromField(MemberInfo member, FieldInfo finfo)
-               {
-                       XmlAttributes XmlAttr = new XmlAttributes();
-                       object[] attributes = member.GetCustomAttributes(false);
-                       XmlAttr.AddMemberAttributes(attributes);
-
-                       XmlAttr.minfo = member;
-                       XmlAttr.finfo = finfo;
-
-                       return XmlAttr;
-               }
-
                
-               internal static XmlAttributes FromProperty(MemberInfo member, PropertyInfo pinfo)
-               {
-
-                       XmlAttributes XmlAttr = new XmlAttributes();
-                       object[] attributes = member.GetCustomAttributes(false);
-                       XmlAttr.AddMemberAttributes(attributes);
-
-                       XmlAttr.minfo = member;
-                       XmlAttr.pinfo = pinfo;
-                       return XmlAttr;
-               }
-
-               internal void AddMemberAttributes(object[] attributes)
-               {
-                       foreach(object obj in attributes)
-                       {
-                               if(obj is XmlAnyAttributeAttribute)
-                               {
-                                       xmlAnyAttribute = (XmlAnyAttributeAttribute) obj;
-                                       isAttribute = true;     
-                               }
-                               else if(obj is XmlAttributeAttribute)
-                               {
-                                       xmlAttribute = (XmlAttributeAttribute) obj;
-                                       isAttribute = true;
-                               }
-                               else if(obj is XmlNamespaceDeclarationsAttribute)
-                               {
-                                       xmlns = true;
-                                       isAttribute = true;
-                               }
-                               else if(obj is XmlAnyElementAttribute)
-                               {
-                                       xmlAnyElements.Add((XmlAnyElementAttribute) obj);
-                                       order = ((XmlAnyElementAttribute) obj).Order;
-                               }
-                               else if(obj is XmlArrayAttribute)
-                               {
-                                       xmlArray = (XmlArrayAttribute) obj;
-                                       order = ((XmlArrayAttribute) obj).Order;
-                               }
-                               else if(obj is XmlArrayItemAttribute)
-                               {
-                                       xmlArrayItems.Add((XmlArrayItemAttribute) obj);
-                                       order = ((XmlArrayItemAttribute) obj).Order;
-                               }
-                               else if(obj is XmlChoiceIdentifierAttribute)
-                               {
-                                       xmlChoiceIdentifier = (XmlChoiceIdentifierAttribute) obj;
-                                       order = ((XmlChoiceIdentifierAttribute) obj).Order;
-                               }
-                               else if(obj is XmlTextAttribute)
-                               {
-                                       xmlText = (XmlTextAttribute) obj;
-                                       order = ((XmlTextAttribute) obj).Order;
-                               }
-                               else if(obj is XmlElementAttribute )
-                               {
-                                       xmlElements.Add((XmlElementAttribute ) obj);
-                                       order = ((XmlElementAttribute ) obj).Order;
-                               }
-                               else if(obj is DefaultValueAttribute)
-                               {
-                                       xmlDefaultValue = ((DefaultValueAttribute ) obj).Value;
-                               }
-                               else if(obj is XmlEnumAttribute)
-                               {
-                                       xmlEnum = (XmlEnumAttribute) obj;
-                               }
-                               else if(obj is XmlIgnoreAttribute)
-                               {
-                                       xmlIgnore = true;
-                               }
-                               else if(obj is XmlRootAttribute)
-                               {
-                                       throw new Exception("should never happen. XmlRoot on a member");
-                               }
-                               else if(obj is XmlTypeAttribute)
-                               {
-                                       xmlType = (XmlTypeAttribute) obj;
-                               }
-                       }
-               }
-
-               internal string GetAttributeName(Type type, string defaultName)
-               {
-                       if(XmlAttribute != null && XmlAttribute.AttributeName != null && XmlAttribute.AttributeName != "")
-                               return XmlAttribute.AttributeName;
-                       else if (XmlType != null && XmlType.TypeName != null && XmlType.TypeName != "")
-                               return XmlType.TypeName;
-                       return defaultName;
-               }
-
-               internal string GetElementName(Type type, string defaultName)
-               {
-                       string anonymousElemAttrName = null;
-                       foreach(XmlElementAttribute elem in XmlElements)
-                       {
-                               if(elem.Type == type && elem.ElementName != null && elem.ElementName != "")
-                                       return elem.ElementName;
-                               else if(elem.Type == null && elem.ElementName != null && elem.ElementName != "")
-                                       anonymousElemAttrName = elem.ElementName;
-                       }
-                       if (anonymousElemAttrName != null)
-                               return anonymousElemAttrName;
-
-                       if (XmlType != null && XmlType.TypeName != null && XmlType.TypeName != "")
-                               return XmlType.TypeName;
-                       return defaultName;
-               }
-
-               internal string GetAttributeNamespace(Type type)
-               {
-                       if(XmlAttribute != null)
-                               return XmlAttribute.Namespace;
-                       return null;
-               }
-
-               internal string GetElementNamespace(Type type)
+               internal bool InternalEquals (XmlAttributes other)
                {
-                       string defaultNS = null;
-                       foreach(XmlElementAttribute elem in XmlElements)
-                       {
-                               if(elem.Type == type )
-                                       return elem.Namespace;
-                               else if(elem.Type == null)
-                                       defaultNS = elem.Namespace;
-                       }
-                       return defaultNS;
-               }
-
-               internal bool GetElementIsNullable (Type type)
-               {
-                       bool defaultIsNullable = false;
-                       foreach(XmlElementAttribute elem in XmlElements)
-                       {
-                               if(elem.Type == type)
-                                       return elem.IsNullable;
-                               else if(elem.Type == null)
-                                       defaultIsNullable = elem.IsNullable;
-                       }
-                       return defaultIsNullable;
+                       if (other == null) return false;
+                       
+                       if (xmlIgnore != other.xmlIgnore) return false;
+                       if (xmlns != other.xmlns) return false;
+                       
+                       if (xmlAnyAttribute == null) {
+                               if (other.xmlAnyAttribute != null) return false; }
+                       else
+                               if (other.xmlAnyAttribute == null) return false;
+                       
+                       if (!xmlAnyElements.Equals (other.xmlAnyElements)) return false; 
+                       if (!xmlArrayItems.Equals (other.xmlArrayItems)) return false;
+                       if (!xmlElements.Equals (other.xmlElements)) return false;
+                               
+                       if (xmlArray == null) {
+                               if (other.xmlArray != null) return false; }
+                       else
+                               if (!xmlArray.InternalEquals (other.xmlArray)) return false;
+                               
+                       if (xmlAttribute == null) {
+                               if (other.xmlAttribute != null) return false; }
+                       else
+                               if (!xmlAttribute.InternalEquals (other.xmlAttribute)) return false;
+                               
+                       if (xmlDefaultValue == null) {
+                               if (other.xmlDefaultValue != null) return false; }
+                       else
+                               if (!xmlDefaultValue.Equals (other.xmlDefaultValue)) return false;
+                               
+                       if (xmlEnum == null) {
+                               if (other.xmlEnum != null) return false; }
+                       else
+                               if (!xmlEnum.InternalEquals (other.xmlEnum)) return false;
+                               
+                       if (xmlRoot == null) {
+                               if (other.xmlRoot != null) return false; }
+                       else
+                               if (!xmlRoot.InternalEquals (other.xmlRoot)) return false;
+                               
+                       if (xmlText == null) {
+                               if (other.xmlText != null) return false; }
+                       else
+                               if (!xmlText.InternalEquals (other.xmlText)) return false;
+                               
+                       if (xmlType == null) {
+                               if (other.xmlType != null) return false; }
+                       else
+                               if (!xmlType.InternalEquals (other.xmlType)) return false;
+                               
+                       if (xmlChoiceIdentifier == null) {
+                               if (other.xmlChoiceIdentifier != null) return false; }
+                       else
+                               if (!xmlChoiceIdentifier.InternalEquals (other.xmlChoiceIdentifier)) return false;
+                               
+                       return true;
                }
        }
 }
index 6b84f761e02be8c9e007b5ec4588601129b6bd2e..a0b7fdaa9fa20a0494be0892a231d7d10ab90c46 100644 (file)
@@ -19,7 +19,6 @@ namespace System.Xml.Serialization
        public class XmlChoiceIdentifierAttribute : Attribute\r
        {\r
                private string memberName;\r
-               private int order;\r
 \r
                public XmlChoiceIdentifierAttribute ()\r
                {\r
@@ -38,13 +37,10 @@ namespace System.Xml.Serialization
                        }\r
                }\r
                \r
-               /// <summary>\r
-               /// Specifies Order in which Memberswill be serialized as Elements.\r
-               /// </summary>\r
-               internal int Order\r
+               internal bool InternalEquals (XmlChoiceIdentifierAttribute ob)\r
                {\r
-                       get{ return  order; }\r
-                       set{ order = value; }\r
+                       if (ob == null) return false;\r
+                       return memberName == ob.memberName;\r
                }\r
 \r
        }\r
index 6ece1f2757c0b7c42f7e6c29b5ba7353ecb8e39d..c470dcf6aba1db3757db266067cb2f26618894f4 100644 (file)
@@ -255,7 +255,7 @@ namespace System.Xml.Serialization {
                        switch (type.XmlType)
                        {
                                case "boolean": return "XmlConvert.ToBoolean (" + value + ")";
-                               case "unsignedByte": return "SByte.Parse(" + value + ")";
+                               case "unsignedByte": return "byte.Parse(" + value + ")";
                                case "char": return "(char)Int32.Parse (" + value + ")";
                                case "dateTime": return "XmlConvert.ToDateTime (" + value + ")";
                                case "date": return "DateTime.ParseExact (" + value + ", \"yyyy-MM-dd\", null)";
index f72e43bc347c2b6c48ea38cf0e27c8238768556a..5ce05f4ee66fe03f0cc2e58d62f6a91ec97cfb87 100644 (file)
@@ -25,7 +25,6 @@ namespace System.Xml.Serialization
                private string ns;\r
                private bool isNullable;\r
                private Type type;\r
-               private int order;\r
 \r
                public XmlElementAttribute ()\r
                {       \r
@@ -92,13 +91,18 @@ namespace System.Xml.Serialization
                                type = value;
                        }\r
                }\r
-               /// <summary>\r
-               /// Specifies Order in which Memberswill be serialized as Elements.\r
-               /// </summary>\r
-               internal int Order\r
+               \r
+               internal bool InternalEquals (XmlElementAttribute other)\r
                {\r
-                       get{ return  order; }\r
-                       set{ order = value; }\r
+                       if (other == null) return false;\r
+                       \r
+                       return (elementName == other.elementName &&\r
+                                       dataType == other.dataType &&\r
+                                       type == other.type &&\r
+                                       form == other.form &&\r
+                                       ns == other.ns &&\r
+                                       isNullable == other.isNullable);\r
                }\r
+                       \r
        }\r
 }\r
index b2a75c1d50ccc0ab4ccabc9249acba025d988bc8..a8290c35322838224b9b234283e8db2ef82b91e0 100644 (file)
@@ -55,5 +55,15 @@ namespace System.Xml.Serialization
                {\r
                        List.CopyTo(array, index);\r
                }\r
+               \r
+               internal bool InternalEquals (XmlElementAttributes other)\r
+               {\r
+                       if (other == null) return false;\r
+                       \r
+                       if (Count != other.Count) return false;\r
+                       for (int n=0; n<Count; n++)\r
+                               if (!this[n].InternalEquals (other[n])) return false;\r
+                       return true;\r
+               }\r
        }\r
 }\r
index e95087c09fb5ed5aa10f62c3f1fb9fd0e1e08150..94e455c60e81eb4290444059f8db2480aab205b8 100644 (file)
@@ -37,5 +37,10 @@ namespace System.Xml.Serialization
                        }\r
                }\r
 \r
+               internal bool InternalEquals (XmlEnumAttribute other)\r
+               {\r
+                       if (other == null) return false;\r
+                       return name == other.name;\r
+               }\r
        }\r
 }\r
index 7bd259ff1dc1739ebfea41553af900ab9a751f04..405d46d737bd84b3bb583623bbf02e04310355d1 100644 (file)
@@ -18,6 +18,7 @@ namespace System.Xml.Serialization
                ObjectMap map;
                ArrayList relatedMaps;
                SerializationFormat format;
+               SerializationSource source;
 
                internal XmlMapping ()
                {
@@ -40,6 +41,12 @@ namespace System.Xml.Serialization
                        get { return format; }
                        set { format = value; }
                }
+               
+               internal SerializationSource Source
+               {
+                       get { return source; }
+                       set { source = value; }
+               }
        }
 
        internal class ObjectMap
index 5abe1a1323ba1d099afd41e9f0683937c60faabe..57bdf9abf1838c257cf8d9e57f201395851c4c60 100644 (file)
@@ -93,6 +93,8 @@ namespace System.Xml.Serialization {
                        XmlMembersMapping mps = new XmlMembersMapping (elementName, ns, hasWrapperElement, false, mapping);
                        mps.RelatedMaps = relatedMaps;
                        mps.Format = SerializationFormat.Literal;
+                       mps.Source = new MembersSerializationSource (elementName, hasWrapperElement, members, false, true, ns, includedTypes);
+                       if (allowPrivateTypes) mps.Source.CanBeGenerated = false;
                        return mps;
                }
 
@@ -137,6 +139,8 @@ namespace System.Xml.Serialization {
 
                        map.RelatedMaps = relatedMaps;
                        map.Format = SerializationFormat.Literal;
+                       map.Source = new XmlTypeSerializationSource (type, root, attributeOverrides, defaultNamespace, includedTypes);
+                       if (allowPrivateTypes) map.Source.CanBeGenerated = false;
                        return map;
                }
 
@@ -263,6 +267,7 @@ namespace System.Xml.Serialization {
                                XmlTypeMapMember mem = classMap.XmlTextCollector;
                                if (mem.TypeData.Type != typeof(string) && 
                                   mem.TypeData.Type != typeof(string[]) && 
+                                  mem.TypeData.Type != typeof(object[]) && 
                                   mem.TypeData.Type != typeof(XmlNode[]))
                                   
                                        throw new InvalidOperationException (String.Format (errSimple2, map.TypeData.TypeName, mem.Name, mem.TypeData.TypeName));
@@ -695,7 +700,7 @@ namespace System.Xml.Serialization {
                                elem.IsNullable = att.IsNullable;
                                
                                if (elem.IsNullable && elem.TypeData.IsValueType)
-                                       throw new InvalidOperationException ("IsNullable may not be 'true' for value type " + elem.TypeData.FullTypeName);
+                                       throw new InvalidOperationException ("IsNullable may not be 'true' for value type " + elem.TypeData.FullTypeName + " in member '" + defaultName + "'");
                                        
                                if (elem.TypeData.IsComplexType)
                                {
index 9539508f6455617ab1823759aa755fad66664764..72dcfd10a623ca8e76507a069ccf124a8305242a 100644 (file)
@@ -80,6 +80,28 @@ namespace System.Xml.Serialization {
                        }\r
                        set { xmlAttributes = value; }\r
                }\r
+               \r
+               internal bool InternalEquals (XmlReflectionMember other)\r
+               {\r
+                       if (other == null) return false;\r
+                       \r
+                       if (isReturnValue != other.isReturnValue) return false;\r
+                       if (memberName != other.memberName) return false;\r
+                       if (memberType != other.memberType) return false;\r
+                       if (overrideIsNullable != other.overrideIsNullable) return false;\r
+                       \r
+                       if (soapAttributes == null) {\r
+                               if (other.soapAttributes != null) return false; }\r
+                       else\r
+                               if (!soapAttributes.InternalEquals (other.soapAttributes)) return false;\r
+                       \r
+                       if (xmlAttributes == null) {\r
+                               if (other.xmlAttributes != null) return false; }\r
+                       else\r
+                               if (!xmlAttributes.InternalEquals (other.xmlAttributes)) return false;\r
+                               \r
+                       return true;\r
+               }\r
 \r
                #endregion // Properties\r
        }\r
index cc3a83c1b9f9fcb6366c2223108e57fb999ced50..0a91c662d0ec3f449a8de11a57f5521181367159 100644 (file)
@@ -69,5 +69,12 @@ namespace System.Xml.Serialization
                                ns = value; \r
                        }\r
                }\r
+               \r
+               internal bool InternalEquals (XmlRootAttribute other)\r
+               {\r
+                       if (other == null) return false;\r
+                       return (dataType == other.dataType && elementName == other.elementName &&\r
+                                   isNullable == other.isNullable && ns == other.ns);\r
+               }\r
        }\r
 }\r
index af182cadb18701a78200e35b0dcc8dafccd92c61..88ecf864a19f6ca70e631f86a5a9456f4e572d2e 100644 (file)
@@ -183,7 +183,7 @@ namespace System.Xml.Serialization {
                                XmlTypeMapping tmap;\r
                                TypeData td = GetElementTypeData (typeQName, elem, out tmap);\r
                                \r
-                               mapping[n] = ImportMemberMapping (elem.Name, typeQName.Namespace, td, tmap);\r
+                               mapping[n] = ImportMemberMapping (elem.Name, typeQName.Namespace, elem.IsNillable, td, tmap);\r
                        }\r
                        BuildPendingMaps ();\r
                        return new XmlMembersMapping (mapping);\r
@@ -196,7 +196,7 @@ namespace System.Xml.Serialization {
                        {\r
                                TypeData td = GetTypeData (members[n].MemberType, null);\r
                                XmlTypeMapping tmap = GetTypeMapping (td);\r
-                               mapping[n] = ImportMemberMapping (members[n].MemberName, members[n].MemberType.Namespace, td, tmap);\r
+                               mapping[n] = ImportMemberMapping (members[n].MemberName, members[n].MemberType.Namespace, true, td, tmap);\r
                        }\r
                        BuildPendingMaps ();\r
                        return new XmlMembersMapping (name, ns, hasWrapperElement, false, mapping);\r
@@ -235,7 +235,7 @@ namespace System.Xml.Serialization {
                        return mapping;\r
                }\r
                \r
-               XmlMemberMapping ImportMemberMapping (string name, string ns, TypeData type, XmlTypeMapping emap)\r
+               XmlMemberMapping ImportMemberMapping (string name, string ns, bool isNullable, TypeData type, XmlTypeMapping emap)\r
                {\r
                        XmlTypeMapMemberElement mapMem;\r
                        \r
@@ -246,7 +246,7 @@ namespace System.Xml.Serialization {
                        \r
                        mapMem.Name = name;\r
                        mapMem.TypeData = type;\r
-                       mapMem.ElementInfo.Add (CreateElementInfo (ns, mapMem, name, type, true, XmlSchemaForm.None, emap));\r
+                       mapMem.ElementInfo.Add (CreateElementInfo (ns, mapMem, name, type, isNullable, XmlSchemaForm.None, emap));\r
                        return new XmlMemberMapping (name, ns, mapMem, encodedFormat);\r
                }\r
                \r
index d54a18fd557e2f8dcf2a8f0173da20badc686ea1..18ad6e56e3ffb3e66e37241c81823ba6053354cd 100644 (file)
@@ -55,7 +55,7 @@ namespace System.Xml.Serialization
                        throw new InvalidOperationException ("Type " + type + " not mapped");
                }
 
-               public object ReadObject ()
+               public object ReadRoot ()
                {
                        Reader.MoveToContent();
                        if (_typeMap is XmlTypeMapping)
@@ -291,7 +291,6 @@ namespace System.Xml.Serialization
                                FixupCallbackInfo info = new FixupCallbackInfo (this, map, isValueList);
                                fixup = new Fixup(ob, new XmlSerializationFixupCallback(info.FixupMembers), map.ElementMembers.Count);
                                AddFixup (fixup);
-                               if (readByOrder) maxInd = map.ElementMembers.Count;
                        }
 
                        while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && (ind < maxInd)) 
index b83f61c787e12cbe59f91c9caf09b9026c5987e8..fdaac011cb80e125d25753bee8288f2bc5225fdc 100644 (file)
@@ -70,7 +70,7 @@ namespace System.Xml.Serialization {
                #endregion // Properties
 
                #region Methods
-
+               
                protected void AddWriteCallback (Type type, string typeName, string typeNs, XmlSerializationWriteCallback callback)
                {
                        WriteCallbackInfo info = new WriteCallbackInfo ();
index c442201416b43778dcec2b8e2d7d2309661315b9..37aab46a0943490fe50ca8a443b6ab00d0d4fd09 100644 (file)
@@ -33,13 +33,13 @@ namespace System.Xml.Serialization
                        {
                                foreach (XmlTypeMapping map in maps)  {
                                        CallbackInfo info = new CallbackInfo (this, map);
-                                       if (map.TypeData.SchemaType == SchemaTypes.Enum) AddWriteCallback(map.TypeData.Type, map.XmlType, map.Namespace, new XmlSerializationWriteCallback (info.WriteObject));
-                                       else AddWriteCallback(map.TypeData.Type, map.XmlType, map.Namespace, new XmlSerializationWriteCallback (info.WriteEnum));
+                                       if (map.TypeData.SchemaType == SchemaTypes.Enum) AddWriteCallback(map.TypeData.Type, map.XmlType, map.Namespace, new XmlSerializationWriteCallback (info.WriteEnum));
+                                       else AddWriteCallback(map.TypeData.Type, map.XmlType, map.Namespace, new XmlSerializationWriteCallback (info.WriteObject));
                                }
                        }
                }
 
-               public void WriteObject (object ob)
+               public void WriteRoot (object ob)
                {
                        WriteStartDocument ();
 
@@ -488,12 +488,12 @@ namespace System.Xml.Serialization
 
                        internal void WriteObject (object ob)
                        {
-                               _swi.WriteObject (_typeMap, ob, _typeMap.ElementName, _typeMap.Namespace, false, true, false);
+                               _swi.WriteObject (_typeMap, ob, _typeMap.ElementName, _typeMap.Namespace, false, false, false);
                        }
 
                        internal void WriteEnum (object ob)
                        {
-                               _swi.WriteObject (_typeMap, ob, _typeMap.ElementName, _typeMap.Namespace, false, false, false);
+                               _swi.WriteObject (_typeMap, ob, _typeMap.ElementName, _typeMap.Namespace, false, true, false);
                        }
                }
 
index 13b7f7ce7bcfd7fe4310074aa343329e5cf1ee83..bb5b09d3d60694ed69f38d3dd307ccdb57b400e4 100644 (file)
@@ -8,12 +8,17 @@
 //
 
 using System;
+using System.Threading;
 using System.Collections;
 using System.IO;
 using System.Reflection;
 using System.Xml;
 using System.Xml.Schema;
 using System.Text;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using Microsoft.CSharp;
+using System.Configuration;
 
 namespace System.Xml.Serialization
 {
@@ -22,17 +27,67 @@ namespace System.Xml.Serialization
        {
                internal const string WsdlNamespace = "http://schemas.xmlsoap.org/wsdl/";
                internal const string EncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";
+               static int generationThreshold;
+               static bool backgroundGeneration = true;
+               static bool deleteTempFiles = true;
 
-#region Fields
-
+               bool customSerializer;
                XmlMapping typeMapping;
-
-#endregion // Fields
+               
+               SerializerData serializerData;
+               Type writerType;
+               Type readerType;
+               
+               static Hashtable serializerTypes = new Hashtable ();
+               
+               internal class SerializerData
+               {
+                       public int UsageCount;
+                       public Type ReaderType;
+                       public MethodInfo ReaderMethod;
+                       public Type WriterType;
+                       public MethodInfo WriterMethod;
+                       public GenerationBatch Batch;
+               }
+               
+               internal class GenerationBatch
+               {
+                       public bool Done;
+                       public XmlMapping[] Maps;
+                       public SerializerData[] Datas;
+               }
+               
+               static XmlSerializer ()
+               {
+                       IDictionary table = (IDictionary) ConfigurationSettings.GetConfig("system.diagnostics");
+                       if (table != null) {
+                               table = (IDictionary) table["switches"];
+                               if (table != null) {
+                                       string val = (string) table ["XmlSerialization.Compilation"];
+                                       if (val == "1") deleteTempFiles = false;
+                               }
+                       }
+                       
+                       string th = Environment.GetEnvironmentVariable ("MONO_XMLSERIALIZER_THS");
+                       
+                       if (th == null) {
+                               generationThreshold = -1;
+                               backgroundGeneration = false;
+                       }
+                       else if (th.ToLower() == "no") 
+                               generationThreshold = -1;
+                       else {
+                               generationThreshold = int.Parse (th);
+                               backgroundGeneration = (generationThreshold != 0);
+                               if (generationThreshold < 1) generationThreshold = 1;
+                       }
+               }
 
 #region Constructors
 
                protected XmlSerializer ()
                {
+                       customSerializer = true;
                }
 
                public XmlSerializer (Type type)
@@ -45,9 +100,10 @@ namespace System.Xml.Serialization
                        typeMapping = xmlTypeMapping;
                }
 
-               internal XmlSerializer (XmlMapping mapping)
+               internal XmlSerializer (XmlMapping mapping, SerializerData data)
                {
                        typeMapping = mapping;
+                       serializerData = data;
                }
 
                public XmlSerializer (Type type, string defaultNamespace)
@@ -182,10 +238,10 @@ namespace System.Xml.Serialization
                public object Deserialize (XmlReader xmlReader)
                {
                        XmlSerializationReader xsReader;
-                       if (typeMapping == null)
+                       if (customSerializer)
                                xsReader = CreateReader ();
                        else
-                               xsReader = new XmlSerializationReaderInterpreter (typeMapping);
+                               xsReader = CreateReader (typeMapping);
                                
                        xsReader.Initialize (xmlReader, this);
                        return Deserialize (xsReader);
@@ -193,24 +249,35 @@ namespace System.Xml.Serialization
 
                protected virtual object Deserialize (XmlSerializationReader reader)
                {
-                       if (typeMapping != null)
-                       {
-                               XmlSerializationReaderInterpreter rd = reader as XmlSerializationReaderInterpreter;
-                               if (rd == null) throw new InvalidOperationException ();
-                               return rd.ReadObject ();
-                       }
-                       else
+                       if (customSerializer)
                                // Must be implemented in derived class
                                throw new NotImplementedException ();
+                       
+                       if (reader is XmlSerializationReaderInterpreter)
+                               return ((XmlSerializationReaderInterpreter)reader).ReadRoot ();
+                       else
+                               return serializerData.ReaderMethod.Invoke (reader, null);
                }
 
                public static XmlSerializer [] FromMappings (XmlMapping [] mappings)
                {
-                       XmlSerializer [] sers = new XmlSerializer [mappings.Length];
+                       XmlSerializer[] sers = new XmlSerializer [mappings.Length];
+                       SerializerData[] datas = new SerializerData [mappings.Length];
+                       GenerationBatch batch = new GenerationBatch ();
+                       batch.Maps = mappings;
+                       batch.Datas = datas;
+                       
                        for (int n=0; n<mappings.Length; n++)
+                       {
                                if (mappings[n] != null)
-                                       sers[n] = new XmlSerializer (mappings[n]);
-                                       
+                               {
+                                       SerializerData data = new SerializerData ();
+                                       data.Batch = batch;
+                                       sers[n] = new XmlSerializer (mappings[n], data);
+                                       datas[n] = data;
+                               }
+                       }
+                       
                        return sers;
                }
 
@@ -224,15 +291,14 @@ namespace System.Xml.Serialization
 
                protected virtual void Serialize (object o, XmlSerializationWriter writer)
                {
-                       if (typeMapping != null)
-                       {
-                               XmlSerializationWriterInterpreter wr = writer as XmlSerializationWriterInterpreter;
-                               if (wr == null) throw new InvalidOperationException ();
-                               wr.WriteObject (o);
-                       }
-                       else
+                       if (customSerializer)
                                // Must be implemented in derived class
                                throw new NotImplementedException ();
+                               
+                       if (writer is XmlSerializationWriterInterpreter)
+                               ((XmlSerializationWriterInterpreter)writer).WriteRoot (o);
+                       else
+                               serializerData.WriterMethod.Invoke (writer, new object[] {o});
                }
 
                public void Serialize (Stream stream, object o)
@@ -273,10 +339,10 @@ namespace System.Xml.Serialization
                {
                        XmlSerializationWriter xsWriter;
                        
-                       if (typeMapping == null)
+                       if (customSerializer)
                                xsWriter = CreateWriter ();
                        else
-                               xsWriter = new XmlSerializationWriterInterpreter (typeMapping);
+                               xsWriter = CreateWriter (typeMapping);
                                
                        if (namespaces == null || namespaces.Count == 0)
                        {
@@ -289,6 +355,190 @@ namespace System.Xml.Serialization
                        Serialize (o, xsWriter);
                        writer.Flush ();
                }
+               
+               XmlSerializationWriter CreateWriter (XmlMapping typeMapping)
+               {
+                       lock (this) {
+                               if (serializerData != null && serializerData.WriterType != null)
+                                       return (XmlSerializationWriter) Activator.CreateInstance (serializerData.WriterType);
+                       }
+                       
+                       if (!typeMapping.Source.CanBeGenerated || generationThreshold == -1)
+                               return new XmlSerializationWriterInterpreter (typeMapping);
+
+                       CheckGeneratedTypes (typeMapping);
+                       
+                       lock (this) {
+                               if (serializerData.WriterType != null)
+                                       return (XmlSerializationWriter) Activator.CreateInstance (serializerData.WriterType);
+                       }
+                       
+                       return new XmlSerializationWriterInterpreter (typeMapping);
+               }
+               
+               XmlSerializationReader CreateReader (XmlMapping typeMapping)
+               {
+                       lock (this) {
+                               if (serializerData != null && serializerData.ReaderType != null)
+                                       return (XmlSerializationReader) Activator.CreateInstance (serializerData.ReaderType);
+                       }
+                       
+                       if (!typeMapping.Source.CanBeGenerated || generationThreshold == -1)
+                               return new XmlSerializationReaderInterpreter (typeMapping);
+
+                       CheckGeneratedTypes (typeMapping);
+                       
+                       lock (this) {
+                               if (serializerData.ReaderType != null)
+                                       return (XmlSerializationReader) Activator.CreateInstance (serializerData.ReaderType);
+                       }
+                       
+                       return new XmlSerializationReaderInterpreter (typeMapping);
+               }
+               
+               void CheckGeneratedTypes (XmlMapping typeMapping)
+               {
+                       lock (this)
+                       {
+                               if (serializerData == null) 
+                               {
+                                       lock (serializerTypes)
+                                       {
+                                               serializerData = (SerializerData) serializerTypes [typeMapping.Source];
+                                               if (serializerData == null) {
+                                                       serializerData = new SerializerData();
+                                                       serializerTypes [typeMapping.Source] = serializerData;
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       bool generate = false;
+                       lock (serializerData)
+                       {
+                               generate = (++serializerData.UsageCount == generationThreshold);
+                       }
+                       
+                       if (generate)
+                       {
+                               if (serializerData.Batch != null)
+                                       GenerateSerializers (serializerData.Batch);
+                               else
+                               {
+                                       GenerationBatch batch = new GenerationBatch ();
+                                       batch.Maps = new XmlMapping[] {typeMapping};
+                                       batch.Datas = new SerializerData[] {serializerData};
+                                       GenerateSerializers (batch);
+                               }
+                       }
+               }
+               
+               void GenerateSerializers (GenerationBatch batch)
+               {
+                       if (batch.Maps.Length != batch.Datas.Length)
+                               throw new ArgumentException ("batch");
+
+                       lock (batch)
+                       {
+                               if (batch.Done) return;
+                               batch.Done = true;
+                       }
+                       
+                       if (backgroundGeneration)
+                               ThreadPool.QueueUserWorkItem (new WaitCallback (RunSerializerGeneration), batch);
+                       else
+                               RunSerializerGeneration (batch);
+               }
+               
+               void RunSerializerGeneration (object obj)
+               {
+                       try
+                       {
+                               RunSerializerGenerationAux (obj);
+                       }
+                       catch (Exception ex)
+                       {
+                               Console.WriteLine (ex);
+                       }
+               }
+               
+               void RunSerializerGenerationAux (object obj)
+               {
+                       DateTime tim = DateTime.Now;
+                       
+                       GenerationBatch batch = (GenerationBatch) obj;
+                       XmlMapping[] maps = batch.Maps;
+                       
+                       string file = Path.GetTempFileName ();
+                       StreamWriter sw = new StreamWriter (file);
+//                     Console.WriteLine ("Generating " + file);
+                       
+                       SerializationCodeGenerator gen = new SerializationCodeGenerator (maps);
+                       
+                       try
+                       {
+                               gen.GenerateSerializers (sw);
+                       }
+                       catch (Exception ex)
+                       {
+                               Console.WriteLine ("Serializer could not be generated");
+                               Console.WriteLine (ex);
+                               
+                               if (deleteTempFiles)
+                                       File.Delete (file);
+                               return;
+                       }
+                       sw.Close ();
+                       
+                       CSharpCodeProvider provider = new CSharpCodeProvider();
+                       ICodeCompiler comp = provider.CreateCompiler ();
+                       
+                       CompilerParameters cp = new CompilerParameters();
+                   cp.GenerateExecutable = false;
+                       cp.IncludeDebugInformation = false;
+                   cp.GenerateInMemory = true;
+                   cp.ReferencedAssemblies.Add ("System.dll");
+                       cp.ReferencedAssemblies.Add ("System.Xml");
+                       
+                       foreach (Type rtype in gen.ReferencedTypes)
+                       {
+                               if (!cp.ReferencedAssemblies.Contains (rtype.Assembly.Location))
+                                       cp.ReferencedAssemblies.Add (rtype.Assembly.Location);
+                       }
+
+                       CompilerResults res = comp.CompileAssemblyFromFile (cp, file);
+                       if (res.Errors.Count > 0)
+                       {
+                               Console.WriteLine ("Error while compiling generated serializer");
+                               foreach (CompilerError error in res.Errors)
+                                       Console.WriteLine (error);
+                                       
+                               if (deleteTempFiles)
+                                       File.Delete (file);
+                               return;
+                       }
+                       
+                       GenerationResult[] results = gen.GenerationResults;
+                       for (int n=0; n<results.Length; n++)
+                       {
+                               GenerationResult gres = results[n];
+                               SerializerData sd = batch.Datas [n];
+                               lock (sd)
+                               {
+                                       sd.WriterType = res.CompiledAssembly.GetType (gres.Namespace + "." + gres.WriterClassName);
+                                       sd.ReaderType = res.CompiledAssembly.GetType (gres.Namespace + "." + gres.ReaderClassName);
+                                       sd.WriterMethod = sd.WriterType.GetMethod (gres.WriteMethodName);
+                                       sd.ReaderMethod = sd.ReaderType.GetMethod (gres.ReadMethodName);
+                                       sd.Batch = null;
+                               }
+                       }
+                       
+                       if (deleteTempFiles)
+                               File.Delete (file);
+
+//                     Console.WriteLine ("Generation finished - " + (DateTime.Now - tim).TotalMilliseconds + " ms");
+               }
+               
 #endregion // Methods
        }
 }
index c45c61cc2c6084867b2714679ee43cf760de7f67..4d40c1b3fe9d012d93a205cdb2f2aa1f6c577e7c 100644 (file)
@@ -20,7 +20,6 @@ namespace System.Xml.Serialization
        {\r
                private string dataType;\r
                private Type type;\r
-               private int order;\r
 \r
                public XmlTextAttribute ()\r
                {\r
@@ -48,14 +47,11 @@ namespace System.Xml.Serialization
                                type = value; \r
                        }\r
                }\r
-               /// <summary>\r
-               /// Specifies Order in which Memberswill be serialized as Elements.\r
-               /// </summary>\r
-               internal int Order\r
+               \r
+               internal bool InternalEquals (XmlTextAttribute ob)\r
                {\r
-                       get{ return  order; }\r
-                       set{ order = value; }\r
+                       if (ob == null) return false;\r
+                       return (dataType == ob.dataType && type == ob.type);\r
                }\r
-\r
        }\r
 }\r
index 9b43b7ad96466c792600b0a88897d2ab7b0b5364..df4324ce19fba0db467eb16646ac08ddc0dae48a 100644 (file)
@@ -56,5 +56,13 @@ namespace System.Xml.Serialization
                                typeName = value; \r
                        }\r
                }\r
+               \r
+               internal bool InternalEquals (XmlTypeAttribute other)\r
+               {\r
+                       if (other == null) return false;\r
+                       return (includeInSchema == other.includeInSchema && \r
+                                       typeName == other.typeName &&\r
+                                   ns != other.ns);\r
+               }\r
        }\r
 }