Compilation.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Xml / System / Xml / Serialization / Compilation.cs / 4 / Compilation.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Xml.Serialization { 

    using System.Configuration; 
    using System.Reflection;
    using System.Reflection.Emit;
    using System.Collections;
    using System.IO; 
    using System;
    using System.Text; 
    using System.Xml; 
    using System.Threading;
    using System.Security; 
    using System.Security.Permissions;
    using System.Security.Policy;
    using System.Xml.Serialization.Configuration;
    using System.Diagnostics; 
    using System.CodeDom.Compiler;
    using System.Globalization; 
 
    internal class TempAssembly {
        const string GeneratedAssemblyNamespace = "Microsoft.Xml.Serialization.GeneratedAssembly"; 
        Assembly assembly;
        bool pregeneratedAssmbly = false;
        XmlSerializerImplementation contract = null;
        Hashtable writerMethods; 
        Hashtable readerMethods;
        TempMethodDictionary methods; 
        static object[] emptyObjectArray = new object[0]; 
        Hashtable assemblies = new Hashtable();
        static FileIOPermission fileIOPermission; 

        internal class TempMethod {
            internal MethodInfo writeMethod;
            internal MethodInfo readMethod; 
            internal string name;
            internal string ns; 
            internal bool isSoap; 
            internal string methodKey;
        } 

        private TempAssembly() {
        }
 
        internal TempAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, string location, Evidence evidence) {
            assembly = GenerateAssembly(xmlMappings, types, defaultNamespace, evidence, XmlSerializerCompilerParameters.Create(location), null, assemblies); 
#if DEBUG 
            // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
            if (assembly == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Failed to generate XmlSerializer assembly, but did not throw")); 
#endif
            InitAssemblyMethods(xmlMappings);
        }
 
        internal TempAssembly(XmlMapping[] xmlMappings, Assembly assembly, XmlSerializerImplementation contract) {
            this.assembly = assembly; 
            InitAssemblyMethods(xmlMappings); 
            this.contract = contract;
            pregeneratedAssmbly = true; 
        }

        internal TempAssembly(XmlSerializerImplementation contract) {
            this.contract = contract; 
            pregeneratedAssmbly = true;
        } 
 
        internal XmlSerializerImplementation Contract {
            get { 
                if (contract == null) {
                    contract = (XmlSerializerImplementation)Activator.CreateInstance(GetTypeFromAssembly(this.assembly, "XmlSerializerContract"));
                }
                return contract; 
            }
        } 
 
        internal void InitAssemblyMethods(XmlMapping[] xmlMappings) {
            methods = new TempMethodDictionary(); 
            for (int i = 0; i < xmlMappings.Length; i++) {
                TempMethod method = new TempMethod();
                method.isSoap = xmlMappings[i].IsSoap;
                method.methodKey = xmlMappings[i].Key; 
                XmlTypeMapping xmlTypeMapping = xmlMappings[i] as XmlTypeMapping;
                if (xmlTypeMapping != null) { 
                    method.name = xmlTypeMapping.ElementName; 
                    method.ns = xmlTypeMapping.Namespace;
                } 
                methods.Add(xmlMappings[i].Key, method);
            }
        }
 
        /// 
        ///     
        ///    Attempts to load pre-generated serialization assembly. 
        ///    First check for the [XmlSerializerAssembly] attribute
        ///     
        /// 
        internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract) {
            Assembly serializer = null;
            contract = null; 
            string serializerName = null;
            bool logEnabled = DiagnosticsSwitches.PregenEventLog.Enabled; 
 
            // check to see if we loading explicit pre-generated assembly
            object[] attrs = type.GetCustomAttributes(typeof(XmlSerializerAssemblyAttribute), false); 
            if (attrs.Length == 0) {
                // Guess serializer name: if parent assembly signed use strong name
                AssemblyName name = GetName(type.Assembly, true);
                serializerName = Compiler.GetTempAssemblyName(name, defaultNamespace); 
                // use strong name
                name.Name = serializerName; 
                name.CodeBase = null; 
                name.CultureInfo = CultureInfo.InvariantCulture;
                try { 
                    serializer = Assembly.Load(name);
                }
                catch (Exception e) {
                    if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                        throw;
                    } 
                    if (logEnabled) { 
                        Log(e.Message, EventLogEntryType.Information);
                    } 
                    byte[] token = name.GetPublicKeyToken();
                    if (token != null && token.Length > 0) {
                        // the parent assembly was signed, so do not try to LoadWithPartialName
                        return null; 
                    }
#pragma warning disable 618 
                    serializer = Assembly.LoadWithPartialName(serializerName, null); 
#pragma warning restore 618
                } 
                catch {
#if !FEATURE_PAL // EventLog
                    if (logEnabled) {
                        Log(Res.GetString(Res.XmlNonCLSCompliantException), EventLogEntryType.Information); 
                    }
#endif //!FEATURE_PAL // EventLog 
                    return null; 
                }
                if (serializer == null) { 
#if !FEATURE_PAL // EventLog
                    if (logEnabled) {
                        Log(Res.GetString(Res.XmlPregenCannotLoad, serializerName), EventLogEntryType.Information);
                    } 
#endif //!FEATURE_PAL // EventLog
                    return null; 
                } 
                if (!IsSerializerVersionMatch(serializer, type, defaultNamespace, null)) {
#if !FEATURE_PAL // EventLog 
                    if (logEnabled)
                        Log(Res.GetString(Res.XmlSerializerExpiredDetails, serializerName, type.FullName), EventLogEntryType.Error);
#endif //!FEATURE_PAL // EventLog
                    return null; 
                }
            } 
            else { 
                XmlSerializerAssemblyAttribute assemblyAttribute = (XmlSerializerAssemblyAttribute)attrs[0];
                if (assemblyAttribute.AssemblyName != null && assemblyAttribute.CodeBase != null) 
                    throw new InvalidOperationException(Res.GetString(Res.XmlPregenInvalidXmlSerializerAssemblyAttribute, "AssemblyName", "CodeBase"));

                // found XmlSerializerAssemblyAttribute attribute, it should have all needed information to load the pre-generated serializer
                if (assemblyAttribute.AssemblyName != null) { 
                    serializerName = assemblyAttribute.AssemblyName;
#pragma warning disable 618 
                    serializer = Assembly.LoadWithPartialName(serializerName, null); 
#pragma warning restore 618
                } 
                else if (assemblyAttribute.CodeBase != null && assemblyAttribute.CodeBase.Length > 0) {
                    serializerName = assemblyAttribute.CodeBase;
                    serializer = Assembly.LoadFrom(serializerName);
                } 
                else {
                    serializerName = type.Assembly.FullName; 
                    serializer = type.Assembly; 
                }
                if (serializer == null) { 
                    throw new FileNotFoundException(null, serializerName);
                }
            }
            Type contractType = GetTypeFromAssembly(serializer, "XmlSerializerContract"); 
            contract = (XmlSerializerImplementation)Activator.CreateInstance(contractType);
            if (contract.CanSerialize(type)) 
                return serializer; 

#if !FEATURE_PAL // EventLog 
            if (logEnabled)
                Log(Res.GetString(Res.XmlSerializerExpiredDetails, serializerName, type.FullName), EventLogEntryType.Error);
#endif //!FEATURE_PAL // EventLog
            return null; 
        }
 
#if !FEATURE_PAL // EventLog 
        static void Log(string message, EventLogEntryType type) {
            new EventLogPermission(PermissionState.Unrestricted).Assert(); 
            EventLog.WriteEntry ("XmlSerializer", message, type);
        }
#endif //!FEATURE_PAL // EventLog
 
        static AssemblyName GetName(Assembly assembly, bool copyName) {
            PermissionSet perms = new PermissionSet(PermissionState.None); 
            perms.AddPermission(new FileIOPermission(PermissionState.Unrestricted)); 
            perms.Assert();
            return assembly.GetName(copyName); 
        }


        static bool IsSerializerVersionMatch(Assembly serializer, Type type, string defaultNamespace, string location) { 
            if (serializer == null)
                return false; 
            object[] attrs = serializer.GetCustomAttributes(typeof(XmlSerializerVersionAttribute), false); 
            if (attrs.Length != 1)
                return false; 

            XmlSerializerVersionAttribute assemblyInfo = (XmlSerializerVersionAttribute)attrs[0];
            // we found out dated pre-generate assembly
            // 
            if (assemblyInfo.ParentAssemblyId == GenerateAssemblyId(type) && assemblyInfo.Namespace == defaultNamespace)
                return true; 
            return false; 
        }
        static string GenerateAssemblyId(Type type) { 
            Module[] modules = type.Assembly.GetModules();
            ArrayList list = new ArrayList();
            for (int i = 0; i < modules.Length; i++) {
                list.Add(modules[i].ModuleVersionId.ToString()); 
            }
            list.Sort(); 
            StringBuilder sb = new StringBuilder(); 
            for (int i = 0; i < list.Count; i++) {
                sb.Append(list[i].ToString()); 
                sb.Append(",");
            }
            return sb.ToString();
        } 

        internal static Assembly GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies) { 
            FileIOPermission.Assert(); 
            for (int i = 0; i < xmlMappings.Length; i++) {
                xmlMappings[i].CheckShallow(); 
            }
            Compiler compiler = new Compiler();
            try {
                Hashtable scopeTable = new Hashtable(); 
                foreach (XmlMapping mapping in xmlMappings)
                    scopeTable[mapping.Scope] = mapping; 
                TypeScope[] scopes = new TypeScope[scopeTable.Keys.Count]; 
                scopeTable.Keys.CopyTo(scopes, 0);
 
                assemblies.Clear();
                Hashtable importedTypes = new Hashtable();
                foreach (TypeScope scope in scopes) {
                    foreach (Type t in scope.Types) { 
                        compiler.AddImport(t, importedTypes);
                        Assembly a = t.Assembly; 
                        string name = a.FullName; 
                        if (assemblies[name] != null)
                            continue; 
                        if (!a.GlobalAssemblyCache) {
                            assemblies[name] = a;
                        }
                    } 
                }
                for (int i = 0; i < types.Length; i++) { 
                    compiler.AddImport(types[i], importedTypes); 
                }
                compiler.AddImport(typeof(object).Assembly); 
                compiler.AddImport(typeof(XmlSerializer).Assembly);

                IndentedWriter writer = new IndentedWriter(compiler.Source, false);
 
                writer.WriteLine("#if _DYNAMIC_XMLSERIALIZER_COMPILATION");
                writer.WriteLine("[assembly:System.Security.AllowPartiallyTrustedCallers()]"); 
                writer.WriteLine("[assembly:System.Security.SecurityTransparent()]"); 
                writer.WriteLine("#endif");
                // Add AssemblyVersion attribute to match parent accembly version 
                if (types != null && types.Length > 0 && types[0] != null) {
                    writer.WriteLine("[assembly:System.Reflection.AssemblyVersionAttribute(\"" + types[0].Assembly.GetName().Version.ToString() + "\")]");
                }
                if (assembly != null && types.Length > 0) { 
                    for (int i = 0; i < types.Length; i++) {
                        Type type = types[i]; 
                        if (type == null) 
                            continue;
                        if (DynamicAssemblies.IsTypeDynamic(type)) { 
                            throw new InvalidOperationException(Res.GetString(Res.XmlPregenTypeDynamic, types[i].FullName));
                        }
                    }
                    writer.Write("[assembly:"); 
                    writer.Write(typeof(XmlSerializerVersionAttribute).FullName);
                    writer.Write("("); 
                    writer.Write("ParentAssemblyId="); 
                    ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, GenerateAssemblyId(types[0]));
                    writer.Write(", Version="); 
                    ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, ThisAssembly.Version);
                    if (defaultNamespace != null) {
                        writer.Write(", Namespace=");
                        ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, defaultNamespace); 
                    }
                    writer.WriteLine(")]"); 
                } 
                CodeIdentifiers classes = new CodeIdentifiers();
                classes.AddUnique("XmlSerializationWriter", "XmlSerializationWriter"); 
                classes.AddUnique("XmlSerializationReader", "XmlSerializationReader");
                string suffix = null;
                if (types != null && types.Length == 1 && types[0] != null) {
                    suffix = CodeIdentifier.MakeValid(types[0].Name); 
                    if (types[0].IsArray) {
                        suffix += "Array"; 
                    } 
                }
 
                writer.WriteLine("namespace " + GeneratedAssemblyNamespace + " {");
                writer.Indent++;

                writer.WriteLine(); 

                string writerClass = "XmlSerializationWriter" + suffix; 
                writerClass = classes.AddUnique(writerClass, writerClass); 
                XmlSerializationWriterCodeGen writerCodeGen = new XmlSerializationWriterCodeGen(writer, scopes, "public", writerClass);
 
                writerCodeGen.GenerateBegin();
                string[] writeMethodNames = new string[xmlMappings.Length];

                for (int i = 0; i < xmlMappings.Length; i++) { 
                    writeMethodNames[i] = writerCodeGen.GenerateElement(xmlMappings[i]);
                } 
                writerCodeGen.GenerateEnd(); 

                writer.WriteLine(); 

                string readerClass = "XmlSerializationReader" + suffix;
                readerClass = classes.AddUnique(readerClass, readerClass);
                XmlSerializationReaderCodeGen readerCodeGen = new XmlSerializationReaderCodeGen(writer, scopes, "public", readerClass); 

                readerCodeGen.GenerateBegin(); 
                string[] readMethodNames = new string[xmlMappings.Length]; 
                for (int i = 0; i < xmlMappings.Length; i++) {
                    readMethodNames[i] = readerCodeGen.GenerateElement(xmlMappings[i]); 
                }
                readerCodeGen.GenerateEnd(readMethodNames, xmlMappings, types);

                string baseSerializer = readerCodeGen.GenerateBaseSerializer("XmlSerializer1", readerClass, writerClass, classes); 
                Hashtable serializers = new Hashtable();
                for (int i = 0; i < xmlMappings.Length; i++) { 
                    if (serializers[xmlMappings[i].Key] == null) { 
                        serializers[xmlMappings[i].Key] = readerCodeGen.GenerateTypedSerializer(readMethodNames[i], writeMethodNames[i], xmlMappings[i], classes, baseSerializer, readerClass, writerClass);
                    } 
                }
                readerCodeGen.GenerateSerializerContract("XmlSerializerContract", xmlMappings, types, readerClass, readMethodNames, writerClass, writeMethodNames, serializers);
                writer.Indent--;
                writer.WriteLine("}"); 

                return compiler.Compile(assembly, defaultNamespace, parameters, evidence); 
            } 
            finally {
                compiler.Close(); 
            }
        }

        static MethodInfo GetMethodFromType(Type type, string methodName, Assembly assembly) { 
            MethodInfo method = type.GetMethod(methodName);
            if (method != null) 
                return method; 

            MissingMethodException missingMethod = new MissingMethodException(type.FullName, methodName); 
            if (assembly != null) {
                throw new InvalidOperationException(Res.GetString(Res.XmlSerializerExpired, assembly.FullName, assembly.CodeBase), missingMethod);
            }
            throw missingMethod; 
        }
 
        internal static Type GetTypeFromAssembly(Assembly assembly, string typeName) { 
            typeName = GeneratedAssemblyNamespace + "." + typeName;
            Type type = assembly.GetType(typeName); 
            if (type == null) throw new InvalidOperationException(Res.GetString(Res.XmlMissingType, typeName, assembly.FullName));
            return type;
        }
 
        internal bool CanRead(XmlMapping mapping, XmlReader xmlReader) {
            if (mapping == null) 
                return false; 

            if (mapping.Accessor.Any) { 
                return true;
            }
            TempMethod method = methods[mapping.Key];
            return xmlReader.IsStartElement(method.name, method.ns); 
        }
 
        string ValidateEncodingStyle(string encodingStyle, string methodKey) { 
            if (encodingStyle != null && encodingStyle.Length > 0) {
                if (methods[methodKey].isSoap) { 
                    if (encodingStyle != Soap.Encoding && encodingStyle != Soap12.Encoding) {
                        throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncoding3, encodingStyle, Soap.Encoding, Soap12.Encoding));
                    }
                } 
                else {
                    throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncodingNotEncoded1, encodingStyle)); 
                } 
            }
            else { 
                if (methods[methodKey].isSoap) {
                    encodingStyle = Soap.Encoding;
                }
            } 
            return encodingStyle;
        } 
 
        internal static FileIOPermission FileIOPermission {
            get { 
                if (fileIOPermission == null)
                    fileIOPermission = new FileIOPermission(PermissionState.Unrestricted);
                return fileIOPermission;
            } 
        }
 
        internal object InvokeReader(XmlMapping mapping, XmlReader xmlReader, XmlDeserializationEvents events, string encodingStyle) { 
            XmlSerializationReader reader = null;
            try { 
                encodingStyle = ValidateEncodingStyle(encodingStyle, mapping.Key);
                reader = Contract.Reader;
                reader.Init(xmlReader, events, encodingStyle, this);
                if (methods[mapping.Key].readMethod == null) { 
                    if (readerMethods == null) {
                        readerMethods = Contract.ReadMethods; 
                    } 
                    string methodName = (string)readerMethods[mapping.Key];
                    if (methodName == null) { 
                        throw new InvalidOperationException(Res.GetString(Res.XmlNotSerializable, mapping.Accessor.Name));
                    }
                    methods[mapping.Key].readMethod = GetMethodFromType(reader.GetType(), methodName, pregeneratedAssmbly ? this.assembly : null);
                } 
                return methods[mapping.Key].readMethod.Invoke(reader, emptyObjectArray);
            } 
            catch (SecurityException e) { 
                throw new InvalidOperationException(Res.GetString(Res.XmlNoPartialTrust), e);
            } 
            finally {
                if (reader != null)
                    reader.Dispose();
            } 
        }
 
        internal void InvokeWriter(XmlMapping mapping, XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces, string encodingStyle, string id) { 
            XmlSerializationWriter writer = null;
            try { 
                encodingStyle = ValidateEncodingStyle(encodingStyle, mapping.Key);
                writer = Contract.Writer;
                writer.Init(xmlWriter, namespaces, encodingStyle, id, this);
                if (methods[mapping.Key].writeMethod == null) { 
                    if (writerMethods == null) {
                        writerMethods = Contract.WriteMethods; 
                    } 
                    string methodName = (string)writerMethods[mapping.Key];
                    if (methodName == null) { 
                        throw new InvalidOperationException(Res.GetString(Res.XmlNotSerializable, mapping.Accessor.Name));
                    }
                    methods[mapping.Key].writeMethod = GetMethodFromType(writer.GetType(), methodName, pregeneratedAssmbly ? assembly : null);
                } 
                methods[mapping.Key].writeMethod.Invoke(writer, new object[] { o });
            } 
            catch (SecurityException e) { 
                throw new InvalidOperationException(Res.GetString(Res.XmlNoPartialTrust), e);
            } 
            finally {
                if (writer != null)
                    writer.Dispose();
            } 
        }
 
        internal Assembly GetReferencedAssembly(string name) { 
            return assemblies != null && name != null ? (Assembly)assemblies[name] : null;
        } 

        internal bool NeedAssembyResolve {
            get { return assemblies != null && assemblies.Count > 0; }
        } 

        internal sealed class TempMethodDictionary : DictionaryBase { 
            internal TempMethod this[string key] { 
                get {
                    return (TempMethod) Dictionary[key]; 
                }
            }
            internal void Add(string key, TempMethod value) {
                Dictionary.Add(key, value); 
            }
        } 
    } 

    sealed class XmlSerializerCompilerParameters { 
        bool needTempDirAccess;
        CompilerParameters parameters;
        XmlSerializerCompilerParameters(CompilerParameters parameters, bool needTempDirAccess) {
            this.needTempDirAccess = needTempDirAccess; 
            this.parameters = parameters;
        } 
 
        internal bool IsNeedTempDirAccess { get { return this.needTempDirAccess; } }
        internal CompilerParameters CodeDomParameters { get { return this.parameters; } } 

        internal static XmlSerializerCompilerParameters Create(string location) {
            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateInMemory = true; 

            if (string.IsNullOrEmpty(location)) { 
                XmlSerializerSection configSection = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath) as XmlSerializerSection; 
                location = configSection == null ? location : configSection.TempFilesLocation;
                // Trim leading and trailing white spaces (VSWhidbey 229873) 
                if (!string.IsNullOrEmpty(location)) {
                    location = location.Trim();
                }
            } 
            parameters.TempFiles = new TempFileCollection(location);
            return new XmlSerializerCompilerParameters(parameters, string.IsNullOrEmpty(location)); 
        } 

        internal static XmlSerializerCompilerParameters Create(CompilerParameters parameters, bool needTempDirAccess) { 
            return new XmlSerializerCompilerParameters(parameters, needTempDirAccess);
        }
    }
 

    class TempAssemblyCacheKey { 
        string ns; 
        object type;
 
        internal TempAssemblyCacheKey(string ns, object type) {
            this.type = type;
            this.ns = ns;
        } 

        public override bool Equals(object o) { 
            TempAssemblyCacheKey key = o as TempAssemblyCacheKey; 
            if (key == null) return false;
            return (key.type == this.type && key.ns == this.ns); 
        }

        public override int GetHashCode() {
            return ((ns != null ? ns.GetHashCode() : 0) ^ (type != null ? type.GetHashCode() : 0)); 
        }
    } 
 
    internal class TempAssemblyCache {
        Hashtable cache = new Hashtable(); 

        internal TempAssembly this[string ns, object o] {
            get { return (TempAssembly)cache[new TempAssemblyCacheKey(ns, o)]; }
        } 

        internal void Add(string ns, object o, TempAssembly assembly) { 
            TempAssemblyCacheKey key = new TempAssemblyCacheKey(ns, o); 
            lock(this) {
                if (cache[key] == assembly) return; 
                Hashtable clone = new Hashtable();
                foreach (object k in cache.Keys) {
                    clone.Add(k, cache[k]);
                } 
                cache = clone;
                cache[key] = assembly; 
            } 
        }
    } 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Xml.Serialization { 

    using System.Configuration; 
    using System.Reflection;
    using System.Reflection.Emit;
    using System.Collections;
    using System.IO; 
    using System;
    using System.Text; 
    using System.Xml; 
    using System.Threading;
    using System.Security; 
    using System.Security.Permissions;
    using System.Security.Policy;
    using System.Xml.Serialization.Configuration;
    using System.Diagnostics; 
    using System.CodeDom.Compiler;
    using System.Globalization; 
 
    internal class TempAssembly {
        const string GeneratedAssemblyNamespace = "Microsoft.Xml.Serialization.GeneratedAssembly"; 
        Assembly assembly;
        bool pregeneratedAssmbly = false;
        XmlSerializerImplementation contract = null;
        Hashtable writerMethods; 
        Hashtable readerMethods;
        TempMethodDictionary methods; 
        static object[] emptyObjectArray = new object[0]; 
        Hashtable assemblies = new Hashtable();
        static FileIOPermission fileIOPermission; 

        internal class TempMethod {
            internal MethodInfo writeMethod;
            internal MethodInfo readMethod; 
            internal string name;
            internal string ns; 
            internal bool isSoap; 
            internal string methodKey;
        } 

        private TempAssembly() {
        }
 
        internal TempAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, string location, Evidence evidence) {
            assembly = GenerateAssembly(xmlMappings, types, defaultNamespace, evidence, XmlSerializerCompilerParameters.Create(location), null, assemblies); 
#if DEBUG 
            // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
            if (assembly == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Failed to generate XmlSerializer assembly, but did not throw")); 
#endif
            InitAssemblyMethods(xmlMappings);
        }
 
        internal TempAssembly(XmlMapping[] xmlMappings, Assembly assembly, XmlSerializerImplementation contract) {
            this.assembly = assembly; 
            InitAssemblyMethods(xmlMappings); 
            this.contract = contract;
            pregeneratedAssmbly = true; 
        }

        internal TempAssembly(XmlSerializerImplementation contract) {
            this.contract = contract; 
            pregeneratedAssmbly = true;
        } 
 
        internal XmlSerializerImplementation Contract {
            get { 
                if (contract == null) {
                    contract = (XmlSerializerImplementation)Activator.CreateInstance(GetTypeFromAssembly(this.assembly, "XmlSerializerContract"));
                }
                return contract; 
            }
        } 
 
        internal void InitAssemblyMethods(XmlMapping[] xmlMappings) {
            methods = new TempMethodDictionary(); 
            for (int i = 0; i < xmlMappings.Length; i++) {
                TempMethod method = new TempMethod();
                method.isSoap = xmlMappings[i].IsSoap;
                method.methodKey = xmlMappings[i].Key; 
                XmlTypeMapping xmlTypeMapping = xmlMappings[i] as XmlTypeMapping;
                if (xmlTypeMapping != null) { 
                    method.name = xmlTypeMapping.ElementName; 
                    method.ns = xmlTypeMapping.Namespace;
                } 
                methods.Add(xmlMappings[i].Key, method);
            }
        }
 
        /// 
        ///     
        ///    Attempts to load pre-generated serialization assembly. 
        ///    First check for the [XmlSerializerAssembly] attribute
        ///     
        /// 
        internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract) {
            Assembly serializer = null;
            contract = null; 
            string serializerName = null;
            bool logEnabled = DiagnosticsSwitches.PregenEventLog.Enabled; 
 
            // check to see if we loading explicit pre-generated assembly
            object[] attrs = type.GetCustomAttributes(typeof(XmlSerializerAssemblyAttribute), false); 
            if (attrs.Length == 0) {
                // Guess serializer name: if parent assembly signed use strong name
                AssemblyName name = GetName(type.Assembly, true);
                serializerName = Compiler.GetTempAssemblyName(name, defaultNamespace); 
                // use strong name
                name.Name = serializerName; 
                name.CodeBase = null; 
                name.CultureInfo = CultureInfo.InvariantCulture;
                try { 
                    serializer = Assembly.Load(name);
                }
                catch (Exception e) {
                    if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) { 
                        throw;
                    } 
                    if (logEnabled) { 
                        Log(e.Message, EventLogEntryType.Information);
                    } 
                    byte[] token = name.GetPublicKeyToken();
                    if (token != null && token.Length > 0) {
                        // the parent assembly was signed, so do not try to LoadWithPartialName
                        return null; 
                    }
#pragma warning disable 618 
                    serializer = Assembly.LoadWithPartialName(serializerName, null); 
#pragma warning restore 618
                } 
                catch {
#if !FEATURE_PAL // EventLog
                    if (logEnabled) {
                        Log(Res.GetString(Res.XmlNonCLSCompliantException), EventLogEntryType.Information); 
                    }
#endif //!FEATURE_PAL // EventLog 
                    return null; 
                }
                if (serializer == null) { 
#if !FEATURE_PAL // EventLog
                    if (logEnabled) {
                        Log(Res.GetString(Res.XmlPregenCannotLoad, serializerName), EventLogEntryType.Information);
                    } 
#endif //!FEATURE_PAL // EventLog
                    return null; 
                } 
                if (!IsSerializerVersionMatch(serializer, type, defaultNamespace, null)) {
#if !FEATURE_PAL // EventLog 
                    if (logEnabled)
                        Log(Res.GetString(Res.XmlSerializerExpiredDetails, serializerName, type.FullName), EventLogEntryType.Error);
#endif //!FEATURE_PAL // EventLog
                    return null; 
                }
            } 
            else { 
                XmlSerializerAssemblyAttribute assemblyAttribute = (XmlSerializerAssemblyAttribute)attrs[0];
                if (assemblyAttribute.AssemblyName != null && assemblyAttribute.CodeBase != null) 
                    throw new InvalidOperationException(Res.GetString(Res.XmlPregenInvalidXmlSerializerAssemblyAttribute, "AssemblyName", "CodeBase"));

                // found XmlSerializerAssemblyAttribute attribute, it should have all needed information to load the pre-generated serializer
                if (assemblyAttribute.AssemblyName != null) { 
                    serializerName = assemblyAttribute.AssemblyName;
#pragma warning disable 618 
                    serializer = Assembly.LoadWithPartialName(serializerName, null); 
#pragma warning restore 618
                } 
                else if (assemblyAttribute.CodeBase != null && assemblyAttribute.CodeBase.Length > 0) {
                    serializerName = assemblyAttribute.CodeBase;
                    serializer = Assembly.LoadFrom(serializerName);
                } 
                else {
                    serializerName = type.Assembly.FullName; 
                    serializer = type.Assembly; 
                }
                if (serializer == null) { 
                    throw new FileNotFoundException(null, serializerName);
                }
            }
            Type contractType = GetTypeFromAssembly(serializer, "XmlSerializerContract"); 
            contract = (XmlSerializerImplementation)Activator.CreateInstance(contractType);
            if (contract.CanSerialize(type)) 
                return serializer; 

#if !FEATURE_PAL // EventLog 
            if (logEnabled)
                Log(Res.GetString(Res.XmlSerializerExpiredDetails, serializerName, type.FullName), EventLogEntryType.Error);
#endif //!FEATURE_PAL // EventLog
            return null; 
        }
 
#if !FEATURE_PAL // EventLog 
        static void Log(string message, EventLogEntryType type) {
            new EventLogPermission(PermissionState.Unrestricted).Assert(); 
            EventLog.WriteEntry ("XmlSerializer", message, type);
        }
#endif //!FEATURE_PAL // EventLog
 
        static AssemblyName GetName(Assembly assembly, bool copyName) {
            PermissionSet perms = new PermissionSet(PermissionState.None); 
            perms.AddPermission(new FileIOPermission(PermissionState.Unrestricted)); 
            perms.Assert();
            return assembly.GetName(copyName); 
        }


        static bool IsSerializerVersionMatch(Assembly serializer, Type type, string defaultNamespace, string location) { 
            if (serializer == null)
                return false; 
            object[] attrs = serializer.GetCustomAttributes(typeof(XmlSerializerVersionAttribute), false); 
            if (attrs.Length != 1)
                return false; 

            XmlSerializerVersionAttribute assemblyInfo = (XmlSerializerVersionAttribute)attrs[0];
            // we found out dated pre-generate assembly
            // 
            if (assemblyInfo.ParentAssemblyId == GenerateAssemblyId(type) && assemblyInfo.Namespace == defaultNamespace)
                return true; 
            return false; 
        }
        static string GenerateAssemblyId(Type type) { 
            Module[] modules = type.Assembly.GetModules();
            ArrayList list = new ArrayList();
            for (int i = 0; i < modules.Length; i++) {
                list.Add(modules[i].ModuleVersionId.ToString()); 
            }
            list.Sort(); 
            StringBuilder sb = new StringBuilder(); 
            for (int i = 0; i < list.Count; i++) {
                sb.Append(list[i].ToString()); 
                sb.Append(",");
            }
            return sb.ToString();
        } 

        internal static Assembly GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies) { 
            FileIOPermission.Assert(); 
            for (int i = 0; i < xmlMappings.Length; i++) {
                xmlMappings[i].CheckShallow(); 
            }
            Compiler compiler = new Compiler();
            try {
                Hashtable scopeTable = new Hashtable(); 
                foreach (XmlMapping mapping in xmlMappings)
                    scopeTable[mapping.Scope] = mapping; 
                TypeScope[] scopes = new TypeScope[scopeTable.Keys.Count]; 
                scopeTable.Keys.CopyTo(scopes, 0);
 
                assemblies.Clear();
                Hashtable importedTypes = new Hashtable();
                foreach (TypeScope scope in scopes) {
                    foreach (Type t in scope.Types) { 
                        compiler.AddImport(t, importedTypes);
                        Assembly a = t.Assembly; 
                        string name = a.FullName; 
                        if (assemblies[name] != null)
                            continue; 
                        if (!a.GlobalAssemblyCache) {
                            assemblies[name] = a;
                        }
                    } 
                }
                for (int i = 0; i < types.Length; i++) { 
                    compiler.AddImport(types[i], importedTypes); 
                }
                compiler.AddImport(typeof(object).Assembly); 
                compiler.AddImport(typeof(XmlSerializer).Assembly);

                IndentedWriter writer = new IndentedWriter(compiler.Source, false);
 
                writer.WriteLine("#if _DYNAMIC_XMLSERIALIZER_COMPILATION");
                writer.WriteLine("[assembly:System.Security.AllowPartiallyTrustedCallers()]"); 
                writer.WriteLine("[assembly:System.Security.SecurityTransparent()]"); 
                writer.WriteLine("#endif");
                // Add AssemblyVersion attribute to match parent accembly version 
                if (types != null && types.Length > 0 && types[0] != null) {
                    writer.WriteLine("[assembly:System.Reflection.AssemblyVersionAttribute(\"" + types[0].Assembly.GetName().Version.ToString() + "\")]");
                }
                if (assembly != null && types.Length > 0) { 
                    for (int i = 0; i < types.Length; i++) {
                        Type type = types[i]; 
                        if (type == null) 
                            continue;
                        if (DynamicAssemblies.IsTypeDynamic(type)) { 
                            throw new InvalidOperationException(Res.GetString(Res.XmlPregenTypeDynamic, types[i].FullName));
                        }
                    }
                    writer.Write("[assembly:"); 
                    writer.Write(typeof(XmlSerializerVersionAttribute).FullName);
                    writer.Write("("); 
                    writer.Write("ParentAssemblyId="); 
                    ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, GenerateAssemblyId(types[0]));
                    writer.Write(", Version="); 
                    ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, ThisAssembly.Version);
                    if (defaultNamespace != null) {
                        writer.Write(", Namespace=");
                        ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, defaultNamespace); 
                    }
                    writer.WriteLine(")]"); 
                } 
                CodeIdentifiers classes = new CodeIdentifiers();
                classes.AddUnique("XmlSerializationWriter", "XmlSerializationWriter"); 
                classes.AddUnique("XmlSerializationReader", "XmlSerializationReader");
                string suffix = null;
                if (types != null && types.Length == 1 && types[0] != null) {
                    suffix = CodeIdentifier.MakeValid(types[0].Name); 
                    if (types[0].IsArray) {
                        suffix += "Array"; 
                    } 
                }
 
                writer.WriteLine("namespace " + GeneratedAssemblyNamespace + " {");
                writer.Indent++;

                writer.WriteLine(); 

                string writerClass = "XmlSerializationWriter" + suffix; 
                writerClass = classes.AddUnique(writerClass, writerClass); 
                XmlSerializationWriterCodeGen writerCodeGen = new XmlSerializationWriterCodeGen(writer, scopes, "public", writerClass);
 
                writerCodeGen.GenerateBegin();
                string[] writeMethodNames = new string[xmlMappings.Length];

                for (int i = 0; i < xmlMappings.Length; i++) { 
                    writeMethodNames[i] = writerCodeGen.GenerateElement(xmlMappings[i]);
                } 
                writerCodeGen.GenerateEnd(); 

                writer.WriteLine(); 

                string readerClass = "XmlSerializationReader" + suffix;
                readerClass = classes.AddUnique(readerClass, readerClass);
                XmlSerializationReaderCodeGen readerCodeGen = new XmlSerializationReaderCodeGen(writer, scopes, "public", readerClass); 

                readerCodeGen.GenerateBegin(); 
                string[] readMethodNames = new string[xmlMappings.Length]; 
                for (int i = 0; i < xmlMappings.Length; i++) {
                    readMethodNames[i] = readerCodeGen.GenerateElement(xmlMappings[i]); 
                }
                readerCodeGen.GenerateEnd(readMethodNames, xmlMappings, types);

                string baseSerializer = readerCodeGen.GenerateBaseSerializer("XmlSerializer1", readerClass, writerClass, classes); 
                Hashtable serializers = new Hashtable();
                for (int i = 0; i < xmlMappings.Length; i++) { 
                    if (serializers[xmlMappings[i].Key] == null) { 
                        serializers[xmlMappings[i].Key] = readerCodeGen.GenerateTypedSerializer(readMethodNames[i], writeMethodNames[i], xmlMappings[i], classes, baseSerializer, readerClass, writerClass);
                    } 
                }
                readerCodeGen.GenerateSerializerContract("XmlSerializerContract", xmlMappings, types, readerClass, readMethodNames, writerClass, writeMethodNames, serializers);
                writer.Indent--;
                writer.WriteLine("}"); 

                return compiler.Compile(assembly, defaultNamespace, parameters, evidence); 
            } 
            finally {
                compiler.Close(); 
            }
        }

        static MethodInfo GetMethodFromType(Type type, string methodName, Assembly assembly) { 
            MethodInfo method = type.GetMethod(methodName);
            if (method != null) 
                return method; 

            MissingMethodException missingMethod = new MissingMethodException(type.FullName, methodName); 
            if (assembly != null) {
                throw new InvalidOperationException(Res.GetString(Res.XmlSerializerExpired, assembly.FullName, assembly.CodeBase), missingMethod);
            }
            throw missingMethod; 
        }
 
        internal static Type GetTypeFromAssembly(Assembly assembly, string typeName) { 
            typeName = GeneratedAssemblyNamespace + "." + typeName;
            Type type = assembly.GetType(typeName); 
            if (type == null) throw new InvalidOperationException(Res.GetString(Res.XmlMissingType, typeName, assembly.FullName));
            return type;
        }
 
        internal bool CanRead(XmlMapping mapping, XmlReader xmlReader) {
            if (mapping == null) 
                return false; 

            if (mapping.Accessor.Any) { 
                return true;
            }
            TempMethod method = methods[mapping.Key];
            return xmlReader.IsStartElement(method.name, method.ns); 
        }
 
        string ValidateEncodingStyle(string encodingStyle, string methodKey) { 
            if (encodingStyle != null && encodingStyle.Length > 0) {
                if (methods[methodKey].isSoap) { 
                    if (encodingStyle != Soap.Encoding && encodingStyle != Soap12.Encoding) {
                        throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncoding3, encodingStyle, Soap.Encoding, Soap12.Encoding));
                    }
                } 
                else {
                    throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncodingNotEncoded1, encodingStyle)); 
                } 
            }
            else { 
                if (methods[methodKey].isSoap) {
                    encodingStyle = Soap.Encoding;
                }
            } 
            return encodingStyle;
        } 
 
        internal static FileIOPermission FileIOPermission {
            get { 
                if (fileIOPermission == null)
                    fileIOPermission = new FileIOPermission(PermissionState.Unrestricted);
                return fileIOPermission;
            } 
        }
 
        internal object InvokeReader(XmlMapping mapping, XmlReader xmlReader, XmlDeserializationEvents events, string encodingStyle) { 
            XmlSerializationReader reader = null;
            try { 
                encodingStyle = ValidateEncodingStyle(encodingStyle, mapping.Key);
                reader = Contract.Reader;
                reader.Init(xmlReader, events, encodingStyle, this);
                if (methods[mapping.Key].readMethod == null) { 
                    if (readerMethods == null) {
                        readerMethods = Contract.ReadMethods; 
                    } 
                    string methodName = (string)readerMethods[mapping.Key];
                    if (methodName == null) { 
                        throw new InvalidOperationException(Res.GetString(Res.XmlNotSerializable, mapping.Accessor.Name));
                    }
                    methods[mapping.Key].readMethod = GetMethodFromType(reader.GetType(), methodName, pregeneratedAssmbly ? this.assembly : null);
                } 
                return methods[mapping.Key].readMethod.Invoke(reader, emptyObjectArray);
            } 
            catch (SecurityException e) { 
                throw new InvalidOperationException(Res.GetString(Res.XmlNoPartialTrust), e);
            } 
            finally {
                if (reader != null)
                    reader.Dispose();
            } 
        }
 
        internal void InvokeWriter(XmlMapping mapping, XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces, string encodingStyle, string id) { 
            XmlSerializationWriter writer = null;
            try { 
                encodingStyle = ValidateEncodingStyle(encodingStyle, mapping.Key);
                writer = Contract.Writer;
                writer.Init(xmlWriter, namespaces, encodingStyle, id, this);
                if (methods[mapping.Key].writeMethod == null) { 
                    if (writerMethods == null) {
                        writerMethods = Contract.WriteMethods; 
                    } 
                    string methodName = (string)writerMethods[mapping.Key];
                    if (methodName == null) { 
                        throw new InvalidOperationException(Res.GetString(Res.XmlNotSerializable, mapping.Accessor.Name));
                    }
                    methods[mapping.Key].writeMethod = GetMethodFromType(writer.GetType(), methodName, pregeneratedAssmbly ? assembly : null);
                } 
                methods[mapping.Key].writeMethod.Invoke(writer, new object[] { o });
            } 
            catch (SecurityException e) { 
                throw new InvalidOperationException(Res.GetString(Res.XmlNoPartialTrust), e);
            } 
            finally {
                if (writer != null)
                    writer.Dispose();
            } 
        }
 
        internal Assembly GetReferencedAssembly(string name) { 
            return assemblies != null && name != null ? (Assembly)assemblies[name] : null;
        } 

        internal bool NeedAssembyResolve {
            get { return assemblies != null && assemblies.Count > 0; }
        } 

        internal sealed class TempMethodDictionary : DictionaryBase { 
            internal TempMethod this[string key] { 
                get {
                    return (TempMethod) Dictionary[key]; 
                }
            }
            internal void Add(string key, TempMethod value) {
                Dictionary.Add(key, value); 
            }
        } 
    } 

    sealed class XmlSerializerCompilerParameters { 
        bool needTempDirAccess;
        CompilerParameters parameters;
        XmlSerializerCompilerParameters(CompilerParameters parameters, bool needTempDirAccess) {
            this.needTempDirAccess = needTempDirAccess; 
            this.parameters = parameters;
        } 
 
        internal bool IsNeedTempDirAccess { get { return this.needTempDirAccess; } }
        internal CompilerParameters CodeDomParameters { get { return this.parameters; } } 

        internal static XmlSerializerCompilerParameters Create(string location) {
            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateInMemory = true; 

            if (string.IsNullOrEmpty(location)) { 
                XmlSerializerSection configSection = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath) as XmlSerializerSection; 
                location = configSection == null ? location : configSection.TempFilesLocation;
                // Trim leading and trailing white spaces (VSWhidbey 229873) 
                if (!string.IsNullOrEmpty(location)) {
                    location = location.Trim();
                }
            } 
            parameters.TempFiles = new TempFileCollection(location);
            return new XmlSerializerCompilerParameters(parameters, string.IsNullOrEmpty(location)); 
        } 

        internal static XmlSerializerCompilerParameters Create(CompilerParameters parameters, bool needTempDirAccess) { 
            return new XmlSerializerCompilerParameters(parameters, needTempDirAccess);
        }
    }
 

    class TempAssemblyCacheKey { 
        string ns; 
        object type;
 
        internal TempAssemblyCacheKey(string ns, object type) {
            this.type = type;
            this.ns = ns;
        } 

        public override bool Equals(object o) { 
            TempAssemblyCacheKey key = o as TempAssemblyCacheKey; 
            if (key == null) return false;
            return (key.type == this.type && key.ns == this.ns); 
        }

        public override int GetHashCode() {
            return ((ns != null ? ns.GetHashCode() : 0) ^ (type != null ? type.GetHashCode() : 0)); 
        }
    } 
 
    internal class TempAssemblyCache {
        Hashtable cache = new Hashtable(); 

        internal TempAssembly this[string ns, object o] {
            get { return (TempAssembly)cache[new TempAssemblyCacheKey(ns, o)]; }
        } 

        internal void Add(string ns, object o, TempAssembly assembly) { 
            TempAssemblyCacheKey key = new TempAssemblyCacheKey(ns, o); 
            lock(this) {
                if (cache[key] == assembly) return; 
                Hashtable clone = new Hashtable();
                foreach (object k in cache.Keys) {
                    clone.Add(k, cache[k]);
                } 
                cache = clone;
                cache[key] = assembly; 
            } 
        }
    } 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK