public void GenerateSerializers (TextWriter writer)
		{
			_writer = writer;
			_results = new GenerationResult [_xmlMaps.Length];
			
			WriteLine ("// It is automatically generated");
			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 != null && _config.NamespaceImports != null && _config.NamespaceImports.Length > 0) {
				foreach (string ns in _config.NamespaceImports)
					WriteLine ("using " + ns + ";");
			}
			WriteLine ("");
			
			string readerClassName = null;
			string writerClassName = null;
			string baseClassName = null;
			string implClassName = null;
			string namspace = null;
			
			if (_config != null)
			{
				readerClassName = _config.ReaderClassName;
				writerClassName = _config.WriterClassName;
				baseClassName = _config.BaseSerializerClassName;
				implClassName = _config.ImplementationClassName;
				namspace = _config.Namespace;
			}

			if (readerClassName == null || readerClassName.Length == 0)
				readerClassName = "GeneratedReader";

			if (writerClassName == null || writerClassName.Length == 0)
				writerClassName = "GeneratedWriter";
			if (baseClassName == null || baseClassName.Length == 0)
				baseClassName = "BaseXmlSerializer";
			if (implClassName == null || implClassName.Length == 0)
				implClassName = "XmlSerializerContract";
			readerClassName = GetUniqueClassName (readerClassName);
			writerClassName = GetUniqueClassName (writerClassName);
			baseClassName = GetUniqueClassName (baseClassName);
			implClassName = GetUniqueClassName (implClassName);
			Hashtable mapsByNamespace = new Hashtable ();
			Hashtable generatedMaps = new Hashtable ();
			
			for (int n=0; n<_xmlMaps.Length; n++)
			{
				_typeMap = _xmlMaps [n];
				if (_typeMap == null) continue;
				
				_result = generatedMaps [_typeMap] as GenerationResult;
				if (_result != null) {
					_results[n] = _result;
					continue;
				}
				
				_result = new GenerationResult ();
				_results[n] = _result;
				
				generatedMaps [_typeMap] = _result;
				
				string typeName;
				if (_typeMap is XmlTypeMapping) typeName = CodeIdentifier.MakeValid (((XmlTypeMapping)_typeMap).TypeData.CSharpName);
				else typeName = ((XmlMembersMapping)_typeMap).ElementName;
				
				_result.ReaderClassName = readerClassName;
				_result.WriterClassName = writerClassName;
				_result.BaseSerializerClassName = baseClassName;
				_result.ImplementationClassName = implClassName;

				if (namspace == null || namspace.Length == 0)
					_result.Namespace = "Mono.GeneratedSerializers." + _typeMap.Format;
				else
					_result.Namespace = namspace;
				
				_result.WriteMethodName = GetUniqueName ("rwo", _typeMap, "WriteRoot_" + typeName);
				_result.ReadMethodName = GetUniqueName ("rro", _typeMap, "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)
			{
				ArrayList maps = (ArrayList) entry.Value;
				
				WriteLine ("namespace " + entry.Key);
				WriteLineInd ("{");
				
				if (_config == null || !_config.NoReader)
					GenerateReader (readerClassName, maps);
				WriteLine ("");
				if (_config == null || !_config.NoWriter)
					GenerateWriter (writerClassName, maps);
				WriteLine ("");
				
#if NET_2_0
				GenerateContract (maps);
#endif

				WriteLineUni ("}");
				WriteLine ("");
			}
		}
		//*******************************************************
		// Writer generation
		//

		public void GenerateWriter (string writerClassName, ArrayList maps)
		{
			_mapsToGenerate = new ArrayList ();
			
			InitHooks ();
			
			if (_config == null || !_config.GenerateAsInternal)
				WriteLine ("public class " + writerClassName + " : XmlSerializationWriter");
			else
				WriteLine ("internal class " + writerClassName + " : XmlSerializationWriter");
			WriteLineInd ("{");
			WriteLine ("const string xmlNamespace = \"http://www.w3.org/2000/xmlns/\";");
			// ToBinHexString() is not public, so use reflection here.
			WriteLine ("static readonly System.Reflection.MethodInfo toBinHexStringMethod = typeof (XmlConvert).GetMethod (\"ToBinHexString\", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new Type [] {typeof (byte [])}, null);");
			WriteLine ("static string ToBinHexString (byte [] input)");
			WriteLineInd ("{");
			WriteLine ("return input == null ? null : (string) toBinHexStringMethod.Invoke (null, new object [] {input});");
			WriteLineUni ("}");
			
			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++)
			{
				XmlTypeMapping map = (XmlTypeMapping) _mapsToGenerate[n];
				GenerateWriteObject (map);
				if (map.TypeData.SchemaType == SchemaTypes.Enum)
					GenerateGetXmlEnumValue (map);
			}
			
			GenerateWriteInitCallbacks ();
			UpdateGeneratedTypes (_mapsToGenerate);
			
			WriteLineUni ("}");
		}
		//*******************************************************
		// Reader generation
		//
		
		public void GenerateReader (string readerClassName, ArrayList maps)
		{
			if (_config == null || !_config.GenerateAsInternal)
				WriteLine ("public class " + readerClassName + " : XmlSerializationReader");
			else
				WriteLine ("internal class " + readerClassName + " : XmlSerializationReader");
			WriteLineInd ("{");
			// FromBinHexString() is not public, so use reflection here.
			WriteLine ("static readonly System.Reflection.MethodInfo fromBinHexStringMethod = typeof (XmlConvert).GetMethod (\"FromBinHexString\", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new Type [] {typeof (string)}, null);");
			WriteLine ("static byte [] FromBinHexString (string input)");
			WriteLineInd ("{");
			WriteLine ("return input == null ? null : (byte []) fromBinHexStringMethod.Invoke (null, new object [] {input});");
			WriteLineUni ("}");

			_mapsToGenerate = new ArrayList ();
			_fixupCallbacks = new ArrayList ();
			InitHooks ();
			
			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 = _mapsToGenerate [n] as XmlTypeMapping;
				if (map == null) continue;
				
				GenerateReadObject (map);
				if (map.TypeData.SchemaType == SchemaTypes.Enum)
					GenerateGetEnumValueMethod (map);
			}
			
			GenerateReadInitCallbacks ();
			
			if (_format == SerializationFormat.Encoded)
			{
				GenerateFixupCallbacks ();
				GenerateFillerCallbacks ();
			}
			
			WriteLineUni ("}");
			UpdateGeneratedTypes (_mapsToGenerate);
		}
Esempio n. 4
0
        static Assembly GenerateSerializers(GenerationBatch batch, CompilerParameters cp)
        {
            DateTime tim = DateTime.Now;

            XmlMapping[] maps = batch.Maps;

            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)
            {
                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);
                cp.TempFiles.Delete();
                return(null);
            }
            sw.Close();

            CSharpCodeProvider provider = new CSharpCodeProvider();
            ICodeCompiler      comp     = provider.CreateCompiler();

            cp.GenerateExecutable = false;

            foreach (Type rtype in gen.ReferencedTypes)
            {
                string path = new Uri(rtype.Assembly.CodeBase).LocalPath;
                if (!cp.ReferencedAssemblies.Contains(path))
                {
                    cp.ReferencedAssemblies.Add(path);
                }
            }

            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.HasErrors || res.CompiledAssembly == null)
            {
                Console.WriteLine("Error while compiling generated serializer");
                foreach (CompilerError error in res.Errors)
                {
                    Console.WriteLine(error);
                }

                cp.TempFiles.Delete();
                return(null);
            }

            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;
                }
            }

            cp.TempFiles.Delete();

            if (!deleteTempFiles)
            {
                Console.WriteLine("Generation finished - " + (DateTime.Now - tim).TotalMilliseconds + " ms");
            }

            return(res.CompiledAssembly);
        }
		//*******************************************************
		// Writer generation
		//

		public void GenerateWriter (string writerClassName, ArrayList maps)
		{
			_mapsToGenerate = new ArrayList ();
			
			InitHooks ();
			
			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++)
			{
				XmlTypeMapping map = (XmlTypeMapping) _mapsToGenerate[n];
				GenerateWriteObject (map);
				if (map.TypeData.SchemaType == SchemaTypes.Enum)
					GenerateGetXmlEnumValue (map);
			}
			
			GenerateWriteInitCallbacks ();
			UpdateGeneratedTypes (_mapsToGenerate);
			
			WriteLineUni ("}");
		}
		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 != null && _config.NamespaceImports != null && _config.NamespaceImports.Length > 0) {
				foreach (string ns in _config.NamespaceImports)
					WriteLine ("using " + ns + ";");
			}
			WriteLine ("");
			
			string readerClassName = null;
			string writerClassName = null;
			string namspace = null;
			
			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 ();
			Hashtable generatedMaps = new Hashtable ();
			
			for (int n=0; n<_xmlMaps.Length; n++)
			{
				_typeMap = _xmlMaps [n];
				if (_typeMap == null) continue;
				
				_result = generatedMaps [_typeMap] as GenerationResult;
				if (_result != null) {
					_results[n] = _result;
					continue;
				}
				
				_result = new GenerationResult ();
				_results[n] = _result;
				
				generatedMaps [_typeMap] = _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 = GetUniqueName ("rwo", _typeMap, "WriteRoot_" + typeName);
				_result.ReadMethodName = GetUniqueName ("rro", _typeMap, "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 ("");
			}
		}
		//*******************************************************
		// Reader generation
		//
		
		public void GenerateReader (string readerClassName, ArrayList maps)
		{
			WriteLine ("public class " + readerClassName + " : XmlSerializationReader");
			WriteLineInd ("{");

			_mapsToGenerate = new ArrayList ();
			_fixupCallbacks = new ArrayList ();
			InitHooks ();
			
			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 = _mapsToGenerate [n] as XmlTypeMapping;
				if (map == null) continue;
				
				GenerateReadObject (map);
				if (map.TypeData.SchemaType == SchemaTypes.Enum)
					GenerateGetEnumValue (map);
			}
			
			GenerateReadInitCallbacks ();
			
			if (_format == SerializationFormat.Encoded)
			{
				GenerateFixupCallbacks ();
				GenerateFillerCallbacks ();
			}
			
			WriteLineUni ("}");
			UpdateGeneratedTypes (_mapsToGenerate);
		}