| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- //------------------------------------------------------------------------------
- // <copyright file="XmlSerializationGeneratedCode.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- // <owner current="true" primary="true">Microsoft</owner>
- //------------------------------------------------------------------------------
- namespace System.Xml.Serialization {
- using System;
- using System.IO;
- using System.Collections;
- using System.ComponentModel;
- using System.Threading;
- using System.Reflection;
- using System.Security;
- using System.Globalization;
-
- /// <include file='doc\XmlSerializationGeneratedCode.uex' path='docs/doc[@for="XmlSerializationGeneratedCode"]/*' />
- ///<internalonly/>
- public abstract class XmlSerializationGeneratedCode {
- TempAssembly tempAssembly;
- int threadCode;
- ResolveEventHandler assemblyResolver;
- internal void Init(TempAssembly tempAssembly) {
- this.tempAssembly = tempAssembly;
- // only hook the assembly resolver if we have something to help us do the resolution
- if (tempAssembly != null && tempAssembly.NeedAssembyResolve) {
- // we save the threadcode to make sure we don't handle any resolve events for any other threads
- threadCode = Thread.CurrentThread.GetHashCode();
- assemblyResolver = new ResolveEventHandler(OnAssemblyResolve);
- AppDomain.CurrentDomain.AssemblyResolve += assemblyResolver;
- }
- }
- // this method must be called at the end of serialization
- internal void Dispose() {
- if (assemblyResolver != null)
- AppDomain.CurrentDomain.AssemblyResolve -= assemblyResolver;
- assemblyResolver = null;
- }
- internal Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) {
- if (tempAssembly != null && Thread.CurrentThread.GetHashCode() == threadCode)
- return tempAssembly.GetReferencedAssembly(args.Name);
- return null;
- }
- }
- internal class XmlSerializationCodeGen {
- IndentedWriter writer;
- int nextMethodNumber = 0;
- Hashtable methodNames = new Hashtable();
- ReflectionAwareCodeGen raCodeGen;
- TypeScope[] scopes;
- TypeDesc stringTypeDesc = null;
- TypeDesc qnameTypeDesc = null;
- string access;
- string className;
- TypeMapping[] referencedMethods;
- int references = 0;
- Hashtable generatedMethods = new Hashtable();
- internal XmlSerializationCodeGen(IndentedWriter writer, TypeScope[] scopes, string access, string className) {
- this.writer = writer;
- this.scopes = scopes;
- if (scopes.Length > 0) {
- stringTypeDesc = scopes[0].GetTypeDesc(typeof(string));
- qnameTypeDesc = scopes[0].GetTypeDesc(typeof(XmlQualifiedName));
- }
- this.raCodeGen = new ReflectionAwareCodeGen(writer);
- this.className = className;
- this.access = access;
- }
- internal IndentedWriter Writer { get { return writer; } }
- internal int NextMethodNumber { get { return nextMethodNumber; } set { nextMethodNumber = value; } }
- internal ReflectionAwareCodeGen RaCodeGen { get { return raCodeGen; } }
- internal TypeDesc StringTypeDesc { get { return stringTypeDesc; } }
- internal TypeDesc QnameTypeDesc { get { return qnameTypeDesc; } }
- internal string ClassName { get { return className; } }
- internal string Access { get { return access; } }
- internal TypeScope[] Scopes { get { return scopes; } }
- internal Hashtable MethodNames { get { return methodNames; } }
- internal Hashtable GeneratedMethods { get { return generatedMethods; } }
- internal virtual void GenerateMethod(TypeMapping mapping){}
- internal void GenerateReferencedMethods() {
- while(references > 0) {
- TypeMapping mapping = referencedMethods[--references];
- GenerateMethod(mapping);
- }
- }
- internal string ReferenceMapping(TypeMapping mapping) {
- if (!mapping.IsSoap) {
- if (generatedMethods[mapping] == null) {
- referencedMethods = EnsureArrayIndex(referencedMethods, references);
- referencedMethods[references++] = mapping;
- }
- }
- return (string)methodNames[mapping];
- }
- TypeMapping[] EnsureArrayIndex(TypeMapping[] a, int index) {
- if (a == null) return new TypeMapping[32];
- if (index < a.Length) return a;
- TypeMapping[] b = new TypeMapping[a.Length + 32];
- Array.Copy(a, b, index);
- return b;
- }
- internal void WriteQuotedCSharpString(string value) {
- raCodeGen.WriteQuotedCSharpString(value);
- }
- internal void GenerateHashtableGetBegin(string privateName, string publicName) {
- writer.Write(typeof(Hashtable).FullName);
- writer.Write(" ");
- writer.Write(privateName);
- writer.WriteLine(" = null;");
- writer.Write("public override ");
- writer.Write(typeof(Hashtable).FullName);
- writer.Write(" ");
- writer.Write(publicName);
- writer.WriteLine(" {");
- writer.Indent++;
- writer.WriteLine("get {");
- writer.Indent++;
- writer.Write("if (");
- writer.Write(privateName);
- writer.WriteLine(" == null) {");
- writer.Indent++;
- writer.Write(typeof(Hashtable).FullName);
- writer.Write(" _tmp = new ");
- writer.Write(typeof(Hashtable).FullName);
- writer.WriteLine("();");
- }
- internal void GenerateHashtableGetEnd(string privateName) {
- writer.Write("if (");
- writer.Write(privateName);
- writer.Write(" == null) ");
- writer.Write(privateName);
- writer.WriteLine(" = _tmp;");
- writer.Indent--;
- writer.WriteLine("}");
- writer.Write("return ");
- writer.Write(privateName);
- writer.WriteLine(";");
- writer.Indent--;
- writer.WriteLine("}");
- writer.Indent--;
- writer.WriteLine("}");
- }
- internal void GeneratePublicMethods(string privateName, string publicName, string[] methods, XmlMapping[] xmlMappings) {
- GenerateHashtableGetBegin(privateName, publicName);
- if (methods != null && methods.Length != 0 && xmlMappings != null && xmlMappings.Length == methods.Length) {
- for (int i = 0; i < methods.Length; i++) {
- if (methods[i] == null)
- continue;
- writer.Write("_tmp[");
- WriteQuotedCSharpString(xmlMappings[i].Key);
- writer.Write("] = ");
- WriteQuotedCSharpString(methods[i]);
- writer.WriteLine(";");
- }
- }
- GenerateHashtableGetEnd(privateName);
- }
- internal void GenerateSupportedTypes(Type[] types) {
- writer.Write("public override ");
- writer.Write(typeof(bool).FullName);
- writer.Write(" CanSerialize(");
- writer.Write(typeof(Type).FullName);
- writer.WriteLine(" type) {");
- writer.Indent++;
- Hashtable uniqueTypes = new Hashtable();
- for (int i = 0; i < types.Length; i++) {
- Type type = types[i];
- if (type == null)
- continue;
- if (!type.IsPublic && !type.IsNestedPublic)
- continue;
- if (uniqueTypes[type] != null)
- continue;
- if (DynamicAssemblies.IsTypeDynamic(type))
- continue;
- if (type.IsGenericType || type.ContainsGenericParameters && DynamicAssemblies.IsTypeDynamic(type.GetGenericArguments()))
- continue;
- uniqueTypes[type] = type;
- writer.Write("if (type == typeof(");
- writer.Write(CodeIdentifier.GetCSharpName(type));
- writer.WriteLine(")) return true;");
- }
- writer.WriteLine("return false;");
- writer.Indent--;
- writer.WriteLine("}");
- }
- internal string GenerateBaseSerializer(string baseSerializer, string readerClass, string writerClass, CodeIdentifiers classes) {
- baseSerializer = CodeIdentifier.MakeValid(baseSerializer);
- baseSerializer = classes.AddUnique(baseSerializer, baseSerializer);
- writer.WriteLine();
- writer.Write("public abstract class ");
- writer.Write(CodeIdentifier.GetCSharpName(baseSerializer));
- writer.Write(" : ");
- writer.Write(typeof(XmlSerializer).FullName);
- writer.WriteLine(" {");
- writer.Indent++;
- writer.Write("protected override ");
- writer.Write(typeof(XmlSerializationReader).FullName);
- writer.WriteLine(" CreateReader() {");
- writer.Indent++;
- writer.Write("return new ");
- writer.Write(readerClass);
- writer.WriteLine("();");
- writer.Indent--;
- writer.WriteLine("}");
- writer.Write("protected override ");
- writer.Write(typeof(XmlSerializationWriter).FullName);
- writer.WriteLine(" CreateWriter() {");
- writer.Indent++;
- writer.Write("return new ");
- writer.Write(writerClass);
- writer.WriteLine("();");
- writer.Indent--;
- writer.WriteLine("}");
- writer.Indent--;
- writer.WriteLine("}");
- return baseSerializer;
- }
- internal string GenerateTypedSerializer(string readMethod, string writeMethod, XmlMapping mapping, CodeIdentifiers classes, string baseSerializer, string readerClass, string writerClass) {
- string serializerName = CodeIdentifier.MakeValid(Accessor.UnescapeName(mapping.Accessor.Mapping.TypeDesc.Name));
- serializerName = classes.AddUnique(serializerName + "Serializer", mapping);
- writer.WriteLine();
- writer.Write("public sealed class ");
- writer.Write(CodeIdentifier.GetCSharpName(serializerName));
- writer.Write(" : ");
- writer.Write(baseSerializer);
- writer.WriteLine(" {");
- writer.Indent++;
- writer.WriteLine();
- writer.Write("public override ");
- writer.Write(typeof(bool).FullName);
- writer.Write(" CanDeserialize(");
- writer.Write(typeof(XmlReader).FullName);
- writer.WriteLine(" xmlReader) {");
- writer.Indent++;
- if (mapping.Accessor.Any) {
- writer.WriteLine("return true;");
- }
- else {
- writer.Write("return xmlReader.IsStartElement(");
- WriteQuotedCSharpString(mapping.Accessor.Name);
- writer.Write(", ");
- WriteQuotedCSharpString(mapping.Accessor.Namespace);
- writer.WriteLine(");");
- }
- writer.Indent--;
- writer.WriteLine("}");
- if (writeMethod != null) {
- writer.WriteLine();
- writer.Write("protected override void Serialize(object objectToSerialize, ");
- writer.Write(typeof(XmlSerializationWriter).FullName);
- writer.WriteLine(" writer) {");
- writer.Indent++;
- writer.Write("((");
- writer.Write(writerClass);
- writer.Write(")writer).");
- writer.Write(writeMethod);
- writer.Write("(");
- if (mapping is XmlMembersMapping) {
- writer.Write("(object[])");
- }
- writer.WriteLine("objectToSerialize);");
- writer.Indent--;
- writer.WriteLine("}");
- }
- if (readMethod != null) {
- writer.WriteLine();
- writer.Write("protected override object Deserialize(");
- writer.Write(typeof(XmlSerializationReader).FullName);
- writer.WriteLine(" reader) {");
- writer.Indent++;
- writer.Write("return ((");
- writer.Write(readerClass);
- writer.Write(")reader).");
- writer.Write(readMethod);
- writer.WriteLine("();");
- writer.Indent--;
- writer.WriteLine("}");
- }
- writer.Indent--;
- writer.WriteLine("}");
- return serializerName;
- }
- void GenerateTypedSerializers(Hashtable serializers) {
- string privateName = "typedSerializers";
- GenerateHashtableGetBegin(privateName, "TypedSerializers");
- foreach (string key in serializers.Keys) {
- writer.Write("_tmp.Add(");
- WriteQuotedCSharpString(key);
- writer.Write(", new ");
- writer.Write((string)serializers[key]);
- writer.WriteLine("());");
- }
- GenerateHashtableGetEnd("typedSerializers");
- }
- //GenerateGetSerializer(serializers, xmlMappings);
- void GenerateGetSerializer(Hashtable serializers, XmlMapping[] xmlMappings) {
- writer.Write("public override ");
- writer.Write(typeof(XmlSerializer).FullName);
- writer.Write(" GetSerializer(");
- writer.Write(typeof(Type).FullName);
- writer.WriteLine(" type) {");
- writer.Indent++;
- for (int i = 0; i < xmlMappings.Length; i++) {
- if (xmlMappings[i] is XmlTypeMapping) {
- Type type = xmlMappings[i].Accessor.Mapping.TypeDesc.Type;
- if (type == null)
- continue;
- if (!type.IsPublic && !type.IsNestedPublic)
- continue;
- if (DynamicAssemblies.IsTypeDynamic(type))
- continue;
- if (type.IsGenericType || type.ContainsGenericParameters && DynamicAssemblies.IsTypeDynamic(type.GetGenericArguments()))
- continue;
- writer.Write("if (type == typeof(");
- writer.Write(CodeIdentifier.GetCSharpName(type));
- writer.Write(")) return new ");
- writer.Write((string)serializers[xmlMappings[i].Key]);
- writer.WriteLine("();");
- }
- }
- writer.WriteLine("return null;");
- writer.Indent--;
- writer.WriteLine("}");
- }
- internal void GenerateSerializerContract(string className, XmlMapping[] xmlMappings, Type[] types, string readerType, string[] readMethods, string writerType, string[] writerMethods, Hashtable serializers) {
- writer.WriteLine();
- writer.Write("public class XmlSerializerContract : global::");
- writer.Write(typeof(XmlSerializerImplementation).FullName);
- writer.WriteLine(" {");
- writer.Indent++;
- writer.Write("public override global::");
- writer.Write(typeof(XmlSerializationReader).FullName);
- writer.Write(" Reader { get { return new ");
- writer.Write(readerType);
- writer.WriteLine("(); } }");
- writer.Write("public override global::");
- writer.Write(typeof(XmlSerializationWriter).FullName);
- writer.Write(" Writer { get { return new ");
- writer.Write(writerType);
- writer.WriteLine("(); } }");
- GeneratePublicMethods("readMethods", "ReadMethods", readMethods, xmlMappings);
- GeneratePublicMethods("writeMethods", "WriteMethods", writerMethods, xmlMappings);
- GenerateTypedSerializers(serializers);
- GenerateSupportedTypes(types);
- GenerateGetSerializer(serializers, xmlMappings);
- writer.Indent--;
- writer.WriteLine("}");
- }
- internal static bool IsWildcard(SpecialMapping mapping) {
- if (mapping is SerializableMapping)
- return ((SerializableMapping)mapping).IsAny;
- return mapping.TypeDesc.CanBeElementValue;
- }
- }
- }
|