| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- //------------------------------------------------------------------------------
- // <copyright file="Compilation.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- // <owner current="true" primary="true">Microsoft</owner>
- //------------------------------------------------------------------------------
- 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;
- using System.Runtime.Versioning;
- using System.Diagnostics.CodeAnalysis;
- internal class TempAssembly {
- internal 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 volatile 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) {
- bool containsSoapMapping = false;
- for (int i = 0; i < xmlMappings.Length; i++) {
- xmlMappings[i].CheckShallow();
- if (xmlMappings[i].IsSoap) {
- containsSoapMapping = true;
- }
- }
- // We will make best effort to use RefEmit for assembly generation
- bool fallbackToCSharpAssemblyGeneration = false;
- if (!containsSoapMapping && !TempAssembly.UseLegacySerializerGeneration) {
- try {
- assembly = GenerateRefEmitAssembly(xmlMappings, types, defaultNamespace, evidence);
- }
- // Only catch and handle known failures with RefEmit
- catch (CodeGeneratorConversionException) {
- fallbackToCSharpAssemblyGeneration = true;
- }
- // Add other known exceptions here...
- //
- }
- else {
- fallbackToCSharpAssemblyGeneration = true;
- }
-
- if (fallbackToCSharpAssemblyGeneration) {
- 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 static bool UseLegacySerializerGeneration {
- get {
- if (AppSettings.UseLegacySerializerGeneration.HasValue) {
- // AppSetting will always win if specified
- return (bool) AppSettings.UseLegacySerializerGeneration;
- }
- else {
- #if CONFIGURATION_DEP
- XmlSerializerSection configSection = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath) as XmlSerializerSection;
- return configSection == null ? false : configSection.UseLegacySerializerGeneration;
- #else
- return false;
- #endif
- }
- }
- }
- 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);
- }
- }
- /// <devdoc>
- /// <para>
- /// Attempts to load pre-generated serialization assembly.
- /// First check for the [XmlSerializerAssembly] attribute
- /// </para>
- /// </devdoc>
- // SxS: This method does not take any resource name and does not expose any resources to the caller.
- // It's OK to suppress the SxS warning.
- [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
- [ResourceExposure(ResourceScope.None)]
- internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract) {
- Assembly serializer = null;
- contract = null;
- string serializerName = null;
- // Packaged apps do not support loading generated serializers.
- if (Microsoft.Win32.UnsafeNativeMethods.IsPackagedProcess.Value) {
- return 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
- }
- 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;
- }
- // SxS: This method does not take any resource name and does not expose any resources to the caller.
- // It's OK to suppress the SxS warning.
- [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
- [ResourceExposure(ResourceScope.None)]
- 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();
- 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("[assembly:System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)]");
- 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();
- }
- }
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification="It is safe because the serialization assembly is generated by the framework code, not by the user.")]
- internal static Assembly GenerateRefEmitAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, Evidence evidence) {
- 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);
- string assemblyName = "Microsoft.GeneratedCode";
- AssemblyBuilder assemblyBuilder = CodeGenerator.CreateAssemblyBuilder(AppDomain.CurrentDomain, assemblyName);
- ConstructorInfo SecurityTransparentAttribute_ctor = typeof(SecurityTransparentAttribute).GetConstructor(
- CodeGenerator.InstanceBindingFlags,
- null,
- CodeGenerator.EmptyTypeArray,
- null
- );
- assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(SecurityTransparentAttribute_ctor, new Object[0]));
- ConstructorInfo AllowPartiallyTrustedCallersAttribute_ctor = typeof(AllowPartiallyTrustedCallersAttribute).GetConstructor(
- CodeGenerator.InstanceBindingFlags,
- null,
- CodeGenerator.EmptyTypeArray,
- null
- );
- assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(AllowPartiallyTrustedCallersAttribute_ctor, new Object[0]));
- ConstructorInfo SecurityRulesAttribute_ctor = typeof(SecurityRulesAttribute).GetConstructor(
- CodeGenerator.InstanceBindingFlags,
- null,
- new Type[] { typeof(SecurityRuleSet) },
- null
- );
- assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(SecurityRulesAttribute_ctor, new Object[] { SecurityRuleSet.Level1 }));
- // Add AssemblyVersion attribute to match parent accembly version
- if (types != null && types.Length > 0 && types[0] != null) {
- ConstructorInfo AssemblyVersionAttribute_ctor = typeof(AssemblyVersionAttribute).GetConstructor(
- CodeGenerator.InstanceBindingFlags,
- null,
- new Type[] { typeof(String) },
- null
- );
- FileIOPermission.Assert();
- string assemblyVersion = types[0].Assembly.GetName().Version.ToString();
- FileIOPermission.RevertAssert();
- assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(AssemblyVersionAttribute_ctor, new Object[] { assemblyVersion }));
- }
- 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";
- }
- }
- ModuleBuilder moduleBuilder = CodeGenerator.CreateModuleBuilder(assemblyBuilder, assemblyName);
- string writerClass = "XmlSerializationWriter" + suffix;
- writerClass = classes.AddUnique(writerClass, writerClass);
- XmlSerializationWriterILGen writerCodeGen = new XmlSerializationWriterILGen(scopes, "public", writerClass);
- writerCodeGen.ModuleBuilder = moduleBuilder;
- writerCodeGen.GenerateBegin();
- string[] writeMethodNames = new string[xmlMappings.Length];
- for (int i = 0; i < xmlMappings.Length; i++) {
- writeMethodNames[i] = writerCodeGen.GenerateElement(xmlMappings[i]);
- }
- Type writerType = writerCodeGen.GenerateEnd();
- string readerClass = "XmlSerializationReader" + suffix;
- readerClass = classes.AddUnique(readerClass, readerClass);
- XmlSerializationReaderILGen readerCodeGen = new XmlSerializationReaderILGen(scopes, "public", readerClass);
- readerCodeGen.ModuleBuilder = moduleBuilder;
- readerCodeGen.CreatedTypes.Add(writerType.Name, writerType);
- 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);
- if (DiagnosticsSwitches.KeepTempFiles.Enabled) {
- FileIOPermission.Assert();
- assemblyBuilder.Save(assemblyName + ".dll");
- }
- return writerType.Assembly;
- }
- // SxS: This method does not take any resource name and does not expose any resources to the caller.
- // It's OK to suppress the SxS warning.
- [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
- [ResourceExposure(ResourceScope.None)]
- 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)) {
- #if CONFIGURATION_DEP
- XmlSerializerSection configSection = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath) as XmlSerializerSection;
- location = configSection == null ? location : configSection.TempFilesLocation;
- #endif
- // 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;
- }
- }
- }
- }
|