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