Explorar o código

* IXmlSerializerImplementation.cs: Compile as internal in NET_1_1.
* ReflectionHelper.cs: New method for generating map keys.
* SerializationCodeGenerator.cs: Added support for generating the serializer
contract class, needed for 2.0.
* SerializationSource.cs: Use Type[] instead of ArrayList for storing
extra types.
* SoapReflectionImporter.cs, XmlReflectionImporter.cs: Assign extra types
as Type[]. Added check that makes sure that enums being serialized are
public.
* XmlMapping.cs: Added internal GetKey method.
* XmlSerializer.cs: Added support for IXmlSerializerImplementation.
Added first bits to support loading of serializers from pre-generated
assemblies.
* XmlSerializerFactory.cs: Mostly implemeted.

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

Lluis Sanchez %!s(int64=21) %!d(string=hai) anos
pai
achega
a8ccb82ef3

+ 17 - 0
mcs/class/System.XML/System.Xml.Serialization/ChangeLog

@@ -1,3 +1,20 @@
+2004-07-08  Lluis Sanchez Gual  <[email protected]>
+
+	* IXmlSerializerImplementation.cs: Compile as internal in NET_1_1.
+	* ReflectionHelper.cs: New method for generating map keys.
+	* SerializationCodeGenerator.cs: Added support for generating the serializer
+	  contract class, needed for 2.0.
+	* SerializationSource.cs: Use Type[] instead of ArrayList for storing
+	  extra types.
+	* SoapReflectionImporter.cs, XmlReflectionImporter.cs: Assign extra types 
+	  as Type[]. Added check that makes sure that enums being serialized are
+	  public.
+	* XmlMapping.cs: Added internal GetKey method.
+	* XmlSerializer.cs: Added support for IXmlSerializerImplementation.
+	  Added first bits to support loading of serializers from pre-generated
+	  assemblies.
+	* XmlSerializerFactory.cs: Mostly implemeted.
+
 2004-07-02  Lluis Sanchez Gual  <[email protected]>
 
 	* CodeIdentifier.cs: Removed constructor for NET_2_0.

+ 7 - 4
mcs/class/System.XML/System.Xml.Serialization/IXmlSerializerImplementation.cs

@@ -28,14 +28,18 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
-
 using System;
 using System.Collections;
 
 namespace System.Xml.Serialization 
 {
-	public interface IXmlSerializerImplementation
+#if NET_2_0
+	public
+#else
+	internal
+#endif
+	
+	interface IXmlSerializerImplementation
 	{
 		XmlSerializationReader Reader {get;}
 		Hashtable ReadMethods {get;}
@@ -47,4 +51,3 @@ namespace System.Xml.Serialization
 	}
 }
 
-#endif

+ 24 - 0
mcs/class/System.XML/System.Xml.Serialization/ReflectionHelper.cs

@@ -89,5 +89,29 @@ namespace System.Xml.Serialization
 			}
 			while (t != null);
 		}
+		
+		public static string BuildMapKey (Type type)
+		{
+			return type.FullName + "::";
+		}
+		
+		public static string BuildMapKey (MethodInfo method, string tag)
+		{
+			string res = method.DeclaringType.FullName + ":" + method.ReturnType.FullName + " " + method.Name + "(";
+			
+			ParameterInfo[] pars = method.GetParameters ();
+			
+			for (int n=0; n<pars.Length; n++)
+			{
+				if (n > 0) res += ", ";
+				res += pars[n].ParameterType.FullName;
+			}
+			res += ")";
+			
+			if (tag != null)
+				res += ":" + tag;
+				
+			return res;
+		}
 	}
 }

+ 150 - 8
mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs

@@ -53,7 +53,7 @@ namespace System.Xml.Serialization
 		GenerationResult _result;
 		XmlMapping[] _xmlMaps;
 		
-		static CodeIdentifiers classNames = new CodeIdentifiers ();
+		CodeIdentifiers classNames = new CodeIdentifiers ();
 
 		public SerializationCodeGenerator (XmlMapping[] xmlMaps): this (xmlMaps, null)
 		{
@@ -178,11 +178,8 @@ namespace System.Xml.Serialization
 			if (writerClassName == null || writerClassName == "")
 				writerClassName = "GeneratedWriter";
 				
-			lock (classNames)
-			{
-				readerClassName = classNames.AddUnique (readerClassName, null);
-				writerClassName = classNames.AddUnique (writerClassName, null);
-			}
+			readerClassName = GetUniqueClassName (readerClassName);
+			writerClassName = GetUniqueClassName (writerClassName);
 			
 			Hashtable mapsByNamespace = new Hashtable ();
 			Hashtable generatedMaps = new Hashtable ();
@@ -230,14 +227,20 @@ namespace System.Xml.Serialization
 			
 			foreach (DictionaryEntry entry in mapsByNamespace)
 			{
+				ArrayList maps = (ArrayList) entry.Value;
+				
 				WriteLine ("namespace " + entry.Key);
 				WriteLineInd ("{");
 				
-				GenerateReader (readerClassName, (ArrayList) entry.Value);
+				GenerateReader (readerClassName, maps);
 				WriteLine ("");
-				GenerateWriter (writerClassName, (ArrayList) entry.Value);
+				GenerateWriter (writerClassName, maps);
 				WriteLine ("");
 				
+#if NET_2_0
+				GenerateContract (maps);
+#endif
+
 				WriteLineUni ("}");
 				WriteLine ("");
 			}
@@ -264,6 +267,139 @@ namespace System.Xml.Serialization
 		}
 
 		#region Writer Generation
+		
+		//*******************************************************
+		// Contract generation
+		//
+		
+#if NET_2_0
+		public void GenerateContract (ArrayList generatedMaps)
+		{
+			// Write the base serializer
+			
+			if (generatedMaps.Count == 0) return;
+			
+			GenerationResult main = (GenerationResult) generatedMaps[0];
+			
+			string baseSerializerName = GetUniqueClassName ("BaseXmlSerializer");
+			
+			WriteLine ("");
+			WriteLine ("public class " + baseSerializerName + " : System.Xml.Serialization.XmlSerializer");
+			WriteLineInd ("{");
+			WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationReader CreateReader () {");
+			WriteLine ("return new " + main.ReaderClassName + " ();");
+			WriteLineUni ("}");
+			WriteLine ("");
+			
+			WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationWriter CreateWriter () {");
+			WriteLine ("return new " + main.WriterClassName + " ();");
+			WriteLineUni ("}");
+			WriteLine ("");
+			
+			WriteLineInd ("public override bool CanDeserialize (System.Xml.XmlReader xmlReader) {");
+			WriteLine ("return true;");
+			WriteLineUni ("}");
+			
+			WriteLineUni ("}");
+			WriteLine ("");
+			
+			// Write a serializer for each imported map
+			
+			foreach (GenerationResult res in generatedMaps)
+			{
+				res.SerializerClassName = GetUniqueClassName (res.Mapping.ElementName + "Serializer");
+				
+				WriteLine ("public sealed class " + res.SerializerClassName + " : " + baseSerializerName);
+				WriteLineInd ("{");
+				WriteLineInd ("protected override void Serialize (object obj, System.Xml.Serialization.XmlSerializationWriter writer) {");
+				WriteLine ("((" + res.WriterClassName + ")writer)." + res.WriteMethodName + "(obj);");
+				WriteLineUni ("}");
+				WriteLine ("");
+				
+				WriteLineInd ("protected override object Deserialize (System.Xml.Serialization.XmlSerializationReader reader) {");
+				WriteLine ("return ((" + res.ReaderClassName + ")reader)." + res.ReadMethodName + "();");
+				WriteLineUni ("}");
+				
+				WriteLineUni ("}");
+				WriteLine ("");
+			}
+
+			WriteLine ("public class XmlSerializerContract : System.Xml.Serialization.IXmlSerializerImplementation");
+			WriteLineInd ("{");
+			
+			WriteLine ("System.Collections.Hashtable readMethods = null;");
+			WriteLine ("System.Collections.Hashtable writeMethods = null;");
+			WriteLine ("System.Collections.Hashtable typedSerializers = null;");
+			WriteLine ("");
+		
+			WriteLineInd ("public System.Xml.Serialization.XmlSerializationReader Reader {");
+			WriteLineInd ("get {");
+			WriteLine ("return new " + main.ReaderClassName + "();");
+			WriteLineUni ("}");
+			WriteLineUni ("}");
+			WriteLine ("");
+			
+			WriteLineInd ("public System.Xml.Serialization.XmlSerializationWriter Writer {");
+			WriteLineInd ("get {");
+			WriteLine ("return new " + main.WriterClassName + "();");
+			WriteLineUni ("}");
+			WriteLineUni ("}");
+			WriteLine ("");
+			
+			WriteLineInd ("public System.Collections.Hashtable ReadMethods {");
+			WriteLineInd ("get {");
+			WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
+			WriteLineInd ("if (readMethods == null) {");
+			WriteLine ("readMethods = new System.Collections.Hashtable ();");
+			foreach (GenerationResult res in generatedMaps)
+				WriteLine ("readMethods.Add (@\"" + res.Mapping.GetKey () + "\", @\"" + res.ReadMethodName + "\");");
+			WriteLineUni ("}");
+			WriteLine ("return readMethods;");
+			WriteLineUni ("}");
+			WriteLineUni ("}");
+			WriteLineUni ("}");
+			WriteLine ("");
+			
+			WriteLineInd ("public System.Collections.Hashtable WriteMethods {");
+			WriteLineInd ("get {");
+			WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
+			WriteLineInd ("if (writeMethods == null) {");
+			WriteLine ("writeMethods = new System.Collections.Hashtable ();");
+			foreach (GenerationResult res in generatedMaps)
+				WriteLine ("writeMethods.Add (@\"" + res.Mapping.GetKey () + "\", @\"" + res.WriteMethodName + "\");");
+			WriteLineUni ("}");
+			WriteLine ("return writeMethods;");
+			WriteLineUni ("}");
+			WriteLineUni ("}");
+			WriteLineUni ("}");
+			WriteLine ("");
+			
+			WriteLineInd ("public System.Collections.Hashtable TypedSerializers {");
+			WriteLineInd ("get {");
+			WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
+			WriteLineInd ("if (typedSerializers == null) {");
+			WriteLine ("typedSerializers = new System.Collections.Hashtable ();");
+			foreach (GenerationResult res in generatedMaps)
+				WriteLine ("typedSerializers.Add (@\"" + res.Mapping.GetKey () + "\", new " + res.SerializerClassName + "());");
+			WriteLineUni ("}");
+			WriteLine ("return typedSerializers;");
+			WriteLineUni ("}");
+			WriteLineUni ("}");
+			WriteLineUni ("}");
+			
+			WriteLineInd ("public bool CanSerialize (System.Type type) {");
+			foreach (GenerationResult res in generatedMaps) {
+				if (res.Mapping is XmlTypeMapping)
+					WriteLine ("if (type == typeof(" + (res.Mapping as XmlTypeMapping).TypeData.FullTypeName +  ")) return true;");
+			}
+			WriteLine ("return false;");
+			WriteLineUni ("}");
+			
+			WriteLineUni ("}");
+			WriteLine ("");
+		}
+#endif
+
 
 		//*******************************************************
 		// Writer generation
@@ -2320,6 +2456,11 @@ namespace System.Xml.Serialization
 				return GetUniqueName ("fc", typeMap, "FixupCallback__Message");
 		}
 		
+		string GetUniqueClassName (string s)
+		{
+			return classNames.AddUnique (s, null);
+		}
+		
 		string GetReadObjectCall (XmlTypeMapping typeMap, string isNullable, string checkType)
 		{
 			if (_format == SerializationFormat.Literal)
@@ -2444,6 +2585,7 @@ namespace System.Xml.Serialization
 		public string WriterClassName;
 		public string WriteMethodName;
 		public string Namespace;
+		public string SerializerClassName;
 	}
 	
 }

+ 7 - 7
mcs/class/System.XML/System.Xml.Serialization/SerializationSource.cs

@@ -36,11 +36,11 @@ namespace System.Xml.Serialization
 {
 	internal class SerializationSource 
 	{
-		ArrayList includedTypes;
+		Type[] includedTypes;
 		string namspace;
 		bool canBeGenerated = true;
 		
-		public SerializationSource (string namspace, ArrayList includedTypes)
+		public SerializationSource (string namspace, Type[] includedTypes)
 		{
 			this.namspace = namspace;
 			this.includedTypes = includedTypes;
@@ -56,8 +56,8 @@ namespace System.Xml.Serialization
 			if (includedTypes == null)
 				return other.includedTypes == null;
 			
-			if (includedTypes.Count != other.includedTypes.Count) return false;
-			for (int n=0; n<includedTypes.Count; n++)
+			if (includedTypes.Length != other.includedTypes.Length) return false;
+			for (int n=0; n<includedTypes.Length; n++)
 				if (!includedTypes[n].Equals (other.includedTypes[n])) return false;
 
 			return true;
@@ -76,7 +76,7 @@ namespace System.Xml.Serialization
 		Type type;
 		string rootHash;
 		
-		public XmlTypeSerializationSource (Type type, XmlRootAttribute root, XmlAttributeOverrides attributeOverrides, string namspace, ArrayList includedTypes)
+		public XmlTypeSerializationSource (Type type, XmlRootAttribute root, XmlAttributeOverrides attributeOverrides, string namspace, Type[] includedTypes)
 		: base (namspace, includedTypes)
 		{
 			if (attributeOverrides != null) {
@@ -117,7 +117,7 @@ namespace System.Xml.Serialization
 		string attributeOverridesHash;
 		Type type;
 		
-		public SoapTypeSerializationSource (Type type, SoapAttributeOverrides attributeOverrides, string namspace, ArrayList includedTypes)
+		public SoapTypeSerializationSource (Type type, SoapAttributeOverrides attributeOverrides, string namspace, Type[] includedTypes)
 		: base (namspace, includedTypes)
 		{
 			if (attributeOverrides != null) {
@@ -154,7 +154,7 @@ namespace System.Xml.Serialization
 		bool literalFormat;
 		
 		public MembersSerializationSource (string elementName, bool hasWrapperElement, XmlReflectionMember [] members, bool writeAccessors, 
-										   bool literalFormat, string namspace, ArrayList includedTypes)
+										   bool literalFormat, string namspace, Type[] includedTypes)
 		: base (namspace, includedTypes)
 		{
 			this.elementName = elementName;

+ 8 - 3
mcs/class/System.XML/System.Xml.Serialization/SoapReflectionImporter.cs

@@ -90,7 +90,8 @@ 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);
+			Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
+			mps.Source = new MembersSerializationSource (elementName, hasWrapperElement, members, writeAccessors, false, null, extraTypes);
 			return mps;
 		}
 
@@ -119,11 +120,12 @@ namespace System.Xml.Serialization {
 				case SchemaTypes.Primitive: map = ImportPrimitiveMapping (type, defaultNamespace); break;
 				case SchemaTypes.Enum: map = ImportEnumMapping (type, defaultNamespace); break;
 				case SchemaTypes.XmlSerializable:
-				default: throw new NotSupportedException ("Type " + type.FullName + " not supported for XML stialization");
+				default: throw new NotSupportedException ("Type " + type.FullName + " not supported for XML serialization");
 			}
 			map.RelatedMaps = relatedMaps;
 			map.Format = SerializationFormat.Encoded;
-			map.Source = new SoapTypeSerializationSource (type, attributeOverrides, defaultNamespace, includedTypes);
+			Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
+			map.Source = new SoapTypeSerializationSource (type, attributeOverrides, defaultNamespace, extraTypes);
 			return map;
 		}
 
@@ -330,6 +332,9 @@ namespace System.Xml.Serialization {
 			TypeData typeData = TypeTranslator.GetTypeData (type);
 			XmlTypeMapping map = helper.GetRegisteredClrType (type, GetTypeNamespace (typeData, defaultNamespace));
 			if (map != null) return map;
+			
+			ReflectionHelper.CheckSerializableType (type);
+				
 			map = CreateTypeMapping (typeData, null, defaultNamespace);
 			helper.RegisterClrType (map, type, map.Namespace);
 

+ 7 - 1
mcs/class/System.XML/System.Xml.Serialization/XmlMapping.cs

@@ -40,6 +40,7 @@ namespace System.Xml.Serialization
 		ArrayList relatedMaps;
 		SerializationFormat format;
 		SerializationSource source;
+		string key;
 		
 		internal string _elementName;
 		internal string _namespace;
@@ -65,9 +66,14 @@ namespace System.Xml.Serialization
 			get { return _namespace; }
 		}
 		
-		[MonoTODO]
 		public void SetKey (string key)
 		{
+			this.key = key;
+		}
+		
+		internal string GetKey ()
+		{
+			return key;
 		}
 #endif
 

+ 12 - 2
mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs

@@ -115,7 +115,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);
+			Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
+			mps.Source = new MembersSerializationSource (elementName, hasWrapperElement, members, false, true, ns, extraTypes);
 			if (allowPrivateTypes) mps.Source.CanBeGenerated = false;
 			return mps;
 		}
@@ -184,7 +185,8 @@ namespace System.Xml.Serialization {
 
 			map.RelatedMaps = relatedMaps;
 			map.Format = SerializationFormat.Literal;
-			map.Source = new XmlTypeSerializationSource (type, root, attributeOverrides, defaultNamespace, includedTypes);
+			Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
+			map.Source = new XmlTypeSerializationSource (type, root, attributeOverrides, defaultNamespace, extraTypes);
 			if (allowPrivateTypes) map.Source.CanBeGenerated = false;
 			return map;
 		}
@@ -524,6 +526,10 @@ namespace System.Xml.Serialization {
 			TypeData typeData = TypeTranslator.GetTypeData (type);
 			XmlTypeMapping map = helper.GetRegisteredClrType (type, GetTypeNamespace (typeData, root, defaultNamespace));
 			if (map != null) return map;
+			
+			if (!allowPrivateTypes)
+				ReflectionHelper.CheckSerializableType (type);
+				
 			map = CreateTypeMapping (typeData, root, null, defaultNamespace);
 			helper.RegisterClrType (map, type, map.XmlTypeNamespace);
 
@@ -552,6 +558,10 @@ namespace System.Xml.Serialization {
 			TypeData typeData = TypeTranslator.GetTypeData (type);
 			XmlTypeMapping map = helper.GetRegisteredClrType (type, GetTypeNamespace (typeData, root, defaultNamespace));
 			if (map != null) return map;
+			
+			if (!allowPrivateTypes)
+				ReflectionHelper.CheckSerializableType (type);
+				
 			map = CreateTypeMapping (typeData, root, null, defaultNamespace);
 			helper.RegisterClrType (map, type, map.XmlTypeNamespace);
 			return map;

+ 99 - 39
mcs/class/System.XML/System.Xml.Serialization/XmlSerializer.cs

@@ -71,6 +71,25 @@ namespace System.Xml.Serialization
 			public Type WriterType;
 			public MethodInfo WriterMethod;
 			public GenerationBatch Batch;
+			public IXmlSerializerImplementation Implementation;
+			
+			public XmlSerializationReader CreateReader () {
+				if (ReaderType != null)
+					return (XmlSerializationReader) Activator.CreateInstance (ReaderType);
+				else if (Implementation != null)
+					return Implementation.Reader;
+				else
+					return null;
+			}
+			
+			public XmlSerializationWriter CreateWriter () {
+				if (WriterType != null)
+					return (XmlSerializationWriter) Activator.CreateInstance (WriterType);
+				else if (Implementation != null)
+					return Implementation.Writer;
+				else
+					return null;
+			}
 		}
 		
 		internal class GenerationBatch
@@ -171,6 +190,11 @@ namespace System.Xml.Serialization
 
 			typeMapping = importer.ImportTypeMapping (type, root, defaultNamespace);
 		}
+		
+		internal XmlMapping Mapping
+		{
+			get { return typeMapping; }
+		}
 
 #if NET_2_0
 
@@ -427,16 +451,25 @@ namespace System.Xml.Serialization
 			throw new NotImplementedException ();
 		}
 
-		[MonoTODO]
 		public static Assembly GenerateSerializer (Type[] types, XmlMapping[] mappings)
 		{
-			throw new NotImplementedException ();
+			return GenerateSerializer (types, mappings, null);
 		}
 		
 		[MonoTODO]
 		public static Assembly GenerateSerializer (Type[] types, XmlMapping[] mappings, CompilerParameters parameters)
 		{
-			throw new NotImplementedException ();
+			GenerationBatch batch = new GenerationBatch ();
+			batch.Maps = mappings;
+			batch.Datas = new SerializerData [mappings.Length];
+			
+			for (int n=0; n<mappings.Length; n++) {
+				SerializerData data = new SerializerData ();
+				data.Batch = batch;
+				batch.Datas [n] = data;
+			}
+			
+			return GenerateSerializers (batch, parameters);
 		}
 		
 		[MonoTODO]
@@ -460,16 +493,14 @@ namespace System.Xml.Serialization
 			throw new NotImplementedException ();
 		}
 
-		[MonoTODO]
 		public static string GetXmlSerializerAssemblyName (Type type)
 		{
-			throw new NotImplementedException ();
+			return type.Assembly.GetName().Name + ".XmlSerializers";
 		}
 
-		[MonoTODO]
 		public static string GetXmlSerializerAssemblyName (Type type, string defaultNamespace)
 		{
-			throw new NotImplementedException ();
+			return GetXmlSerializerAssemblyName (type) + "." + defaultNamespace.GetHashCode ();
 		}
 		
 		[MonoTODO]
@@ -482,9 +513,13 @@ namespace System.Xml.Serialization
 		
 		XmlSerializationWriter CreateWriter (XmlMapping typeMapping)
 		{
+			XmlSerializationWriter writer;
+			
 			lock (this) {
-				if (serializerData != null && serializerData.WriterType != null)
-					return (XmlSerializationWriter) Activator.CreateInstance (serializerData.WriterType);
+				if (serializerData != null) {
+					writer = serializerData.CreateWriter ();
+					if (writer != null) return writer;
+				}
 			}
 			
 			if (!typeMapping.Source.CanBeGenerated || generationThreshold == -1)
@@ -493,8 +528,8 @@ namespace System.Xml.Serialization
 			CheckGeneratedTypes (typeMapping);
 			
 			lock (this) {
-				if (serializerData.WriterType != null)
-					return (XmlSerializationWriter) Activator.CreateInstance (serializerData.WriterType);
+				writer = serializerData.CreateWriter ();
+				if (writer != null) return writer;
 			}
 			
 			return new XmlSerializationWriterInterpreter (typeMapping);
@@ -502,9 +537,13 @@ namespace System.Xml.Serialization
 		
 		XmlSerializationReader CreateReader (XmlMapping typeMapping)
 		{
+			XmlSerializationReader reader;
+			
 			lock (this) {
-				if (serializerData != null && serializerData.ReaderType != null)
-					return (XmlSerializationReader) Activator.CreateInstance (serializerData.ReaderType);
+				if (serializerData != null) {
+					reader = serializerData.CreateReader ();
+					if (reader != null) return reader;
+				}
 			}
 			
 			if (!typeMapping.Source.CanBeGenerated || generationThreshold == -1)
@@ -513,8 +552,8 @@ namespace System.Xml.Serialization
 			CheckGeneratedTypes (typeMapping);
 			
 			lock (this) {
-				if (serializerData.ReaderType != null)
-					return (XmlSerializationReader) Activator.CreateInstance (serializerData.ReaderType);
+				reader = serializerData.CreateReader ();
+				if (reader != null) return reader;
 			}
 			
 			return new XmlSerializationReaderInterpreter (typeMapping);
@@ -546,18 +585,18 @@ namespace System.Xml.Serialization
 			if (generate)
 			{
 				if (serializerData.Batch != null)
-					GenerateSerializers (serializerData.Batch);
+					GenerateSerializersAsync (serializerData.Batch);
 				else
 				{
 					GenerationBatch batch = new GenerationBatch ();
 					batch.Maps = new XmlMapping[] {typeMapping};
 					batch.Datas = new SerializerData[] {serializerData};
-					GenerateSerializers (batch);
+					GenerateSerializersAsync (batch);
 				}
 			}
 		}
 		
-		void GenerateSerializers (GenerationBatch batch)
+		void GenerateSerializersAsync (GenerationBatch batch)
 		{
 			if (batch.Maps.Length != batch.Datas.Length)
 				throw new ArgumentException ("batch");
@@ -578,7 +617,11 @@ namespace System.Xml.Serialization
 		{
 			try
 			{
-				RunSerializerGenerationAux (obj);
+				GenerationBatch batch = (GenerationBatch) obj;
+				batch = LoadFromSatelliteAssembly (batch);
+				
+				if (batch != null)
+					GenerateSerializers (batch, null);
 			}
 			catch (Exception ex)
 			{
@@ -586,14 +629,20 @@ namespace System.Xml.Serialization
 			}
 		}
 		
-		void RunSerializerGenerationAux (object obj)
+		static Assembly GenerateSerializers (GenerationBatch batch, CompilerParameters cp)
 		{
 			DateTime tim = DateTime.Now;
 			
-			GenerationBatch batch = (GenerationBatch) obj;
 			XmlMapping[] maps = batch.Maps;
 			
-			string file = Path.GetTempFileName ();
+			if (cp == null) {
+				cp = new CompilerParameters();
+				cp.IncludeDebugInformation = false;
+				cp.GenerateInMemory = true;
+				cp.TempFiles.KeepFiles = !deleteTempFiles;
+			}
+			
+			string file = cp.TempFiles.AddExtension ("cs");
 			StreamWriter sw = new StreamWriter (file);
 			
 			if (!deleteTempFiles)
@@ -609,30 +658,29 @@ namespace System.Xml.Serialization
 			{
 				Console.WriteLine ("Serializer could not be generated");
 				Console.WriteLine (ex);
-				
-				if (deleteTempFiles)
-					File.Delete (file);
-				return;
+				cp.TempFiles.Delete ();
+				return null;
 			}
 			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");
-			cp.ReferencedAssemblies.Add ("System.Data");
+			cp.GenerateExecutable = false;
 			
 			foreach (Type rtype in gen.ReferencedTypes)
 			{
 				if (!cp.ReferencedAssemblies.Contains (rtype.Assembly.Location))
 					cp.ReferencedAssemblies.Add (rtype.Assembly.Location);
 			}
-
+				
+			if (!cp.ReferencedAssemblies.Contains ("System.dll"))
+				cp.ReferencedAssemblies.Add ("System.dll");
+			if (!cp.ReferencedAssemblies.Contains ("System.Xml"))
+				cp.ReferencedAssemblies.Add ("System.Xml");
+			if (!cp.ReferencedAssemblies.Contains ("System.Data"))
+				cp.ReferencedAssemblies.Add ("System.Data");
+			
 			CompilerResults res = comp.CompileAssemblyFromFile (cp, file);
 			if (res.Errors.Count > 0)
 			{
@@ -640,9 +688,8 @@ namespace System.Xml.Serialization
 				foreach (CompilerError error in res.Errors)
 					Console.WriteLine (error);
 					
-				if (deleteTempFiles)
-					File.Delete (file);
-				return;
+				cp.TempFiles.Delete ();
+				return null;
 			}
 			
 			GenerationResult[] results = gen.GenerationResults;
@@ -660,12 +707,25 @@ namespace System.Xml.Serialization
 				}
 			}
 			
-			if (deleteTempFiles)
-				File.Delete (file);
+			cp.TempFiles.Delete ();
 
 			if (!deleteTempFiles)
 				Console.WriteLine ("Generation finished - " + (DateTime.Now - tim).TotalMilliseconds + " ms");
+				
+			return res.CompiledAssembly;
+		}
+		
+#if NET_2_0
+		GenerationBatch LoadFromSatelliteAssembly (GenerationBatch batch)
+		{
+			
 		}
+#else
+		GenerationBatch LoadFromSatelliteAssembly (GenerationBatch batch)
+		{
+			return batch;
+		}
+#endif
 		
 #endregion // Methods
 	}

+ 28 - 15
mcs/class/System.XML/System.Xml.Serialization/XmlSerializerFactory.cs

@@ -31,60 +31,73 @@
 #if NET_2_0
 
 using System;
+using System.Collections;
 using System.Security.Policy;
 
 namespace System.Xml.Serialization 
 {
 	public class XmlSerializerFactory
 	{
+		static Hashtable serializersBySource = new Hashtable ();
+		
 		public XmlSerializerFactory ()
 		{
 		}
 
-		[MonoTODO]
 		public XmlSerializer CreateSerializer (Type type)
 		{
-			throw new NotImplementedException ();
+			return CreateSerializer (type, null, null, null, null);
 		}
 
-		[MonoTODO]
 		public XmlSerializer CreateSerializer (XmlTypeMapping xmlTypeMapping)
 		{
-			throw new NotImplementedException ();
+			lock (serializersBySource) 
+			{
+				XmlSerializer ser = (XmlSerializer) serializersBySource [xmlTypeMapping.Source];
+				if (ser == null) {
+					ser = new XmlSerializer (xmlTypeMapping);
+					serializersBySource [xmlTypeMapping.Source] = ser;
+				}
+				return ser;
+			}
 		}
 
-		[MonoTODO]
 		public XmlSerializer CreateSerializer (Type type, string defaultNamespace)
 		{
-			throw new NotImplementedException ();
+			return CreateSerializer (type, null, null, null, defaultNamespace);
 		}
 
-		[MonoTODO]
 		public XmlSerializer CreateSerializer (Type type, Type[] extraTypes)
 		{
-			throw new NotImplementedException ();
+			return CreateSerializer (type, null, extraTypes, null, null);
 		}
 
-		[MonoTODO]
 		public XmlSerializer CreateSerializer (Type type, XmlAttributeOverrides overrides)
 		{
-			throw new NotImplementedException ();
+			return CreateSerializer (type, overrides, null, null, null);
 		}
 
-		[MonoTODO]
 		public XmlSerializer CreateSerializer (Type type, XmlRootAttribute root)
 		{
-			throw new NotImplementedException ();
+			return CreateSerializer (type, null, null, root, null);
 		}
-
-		[MonoTODO]
+		
 		public XmlSerializer CreateSerializer (Type type, 
 			XmlAttributeOverrides overrides, 
 			Type[] extraTypes, 
 			XmlRootAttribute root, 
 			string defaultNamespace)
 		{
-			throw new NotImplementedException ();
+			XmlTypeSerializationSource source = new XmlTypeSerializationSource (type, root, overrides, defaultNamespace, extraTypes);
+			lock (serializersBySource) 
+			{
+				XmlSerializer ser = (XmlSerializer) serializersBySource [source];
+				if (ser == null) {
+					ser = new XmlSerializer (type, overrides, extraTypes, root, defaultNamespace);
+					serializersBySource [ser.Mapping.Source] = ser;
+				}
+				return ser;
+			}
 		}
 
 		[MonoTODO]