Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Xml / System / Xml / Serialization / Compilation.cs
blobb34385a1dff2fa46db125c00533c132012df7fff
1 //------------------------------------------------------------------------------
2 // <copyright file="Compilation.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
8 namespace System.Xml.Serialization {
10 using System.Configuration;
11 using System.Reflection;
12 using System.Reflection.Emit;
13 using System.Collections;
14 using System.IO;
15 using System;
16 using System.Text;
17 using System.Xml;
18 using System.Threading;
19 using System.Security;
20 using System.Security.Permissions;
21 using System.Security.Policy;
22 using System.Xml.Serialization.Configuration;
23 using System.Diagnostics;
24 using System.CodeDom.Compiler;
25 using System.Globalization;
26 using System.Runtime.Versioning;
27 using System.Diagnostics.CodeAnalysis;
29 internal class TempAssembly {
30 internal const string GeneratedAssemblyNamespace = "Microsoft.Xml.Serialization.GeneratedAssembly";
31 Assembly assembly;
32 bool pregeneratedAssmbly = false;
33 XmlSerializerImplementation contract = null;
34 Hashtable writerMethods;
35 Hashtable readerMethods;
36 TempMethodDictionary methods;
37 static object[] emptyObjectArray = new object[0];
38 Hashtable assemblies = new Hashtable();
39 static volatile FileIOPermission fileIOPermission;
41 internal class TempMethod {
42 internal MethodInfo writeMethod;
43 internal MethodInfo readMethod;
44 internal string name;
45 internal string ns;
46 internal bool isSoap;
47 internal string methodKey;
50 private TempAssembly() {
53 internal TempAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, string location, Evidence evidence) {
54 bool containsSoapMapping = false;
55 for (int i = 0; i < xmlMappings.Length; i++) {
56 xmlMappings[i].CheckShallow();
57 if (xmlMappings[i].IsSoap) {
58 containsSoapMapping = true;
62 // We will make best effort to use RefEmit for assembly generation
63 bool fallbackToCSharpAssemblyGeneration = false;
65 if (!containsSoapMapping && !TempAssembly.UseLegacySerializerGeneration) {
66 try {
67 assembly = GenerateRefEmitAssembly(xmlMappings, types, defaultNamespace, evidence);
69 // Only catch and handle known failures with RefEmit
70 catch (CodeGeneratorConversionException) {
71 fallbackToCSharpAssemblyGeneration = true;
73 // Add other known exceptions here...
76 else {
77 fallbackToCSharpAssemblyGeneration = true;
80 if (fallbackToCSharpAssemblyGeneration) {
81 assembly = GenerateAssembly(xmlMappings, types, defaultNamespace, evidence, XmlSerializerCompilerParameters.Create(location), null, assemblies);
84 #if DEBUG
85 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
86 if (assembly == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Failed to generate XmlSerializer assembly, but did not throw"));
87 #endif
88 InitAssemblyMethods(xmlMappings);
91 internal TempAssembly(XmlMapping[] xmlMappings, Assembly assembly, XmlSerializerImplementation contract) {
92 this.assembly = assembly;
93 InitAssemblyMethods(xmlMappings);
94 this.contract = contract;
95 pregeneratedAssmbly = true;
98 internal static bool UseLegacySerializerGeneration {
99 get {
100 if (AppSettings.UseLegacySerializerGeneration.HasValue) {
101 // AppSetting will always win if specified
102 return (bool) AppSettings.UseLegacySerializerGeneration;
104 else {
105 #if CONFIGURATION_DEP
106 XmlSerializerSection configSection = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath) as XmlSerializerSection;
107 return configSection == null ? false : configSection.UseLegacySerializerGeneration;
108 #else
109 return false;
110 #endif
115 internal TempAssembly(XmlSerializerImplementation contract) {
116 this.contract = contract;
117 pregeneratedAssmbly = true;
120 internal XmlSerializerImplementation Contract {
121 get {
122 if (contract == null) {
123 contract = (XmlSerializerImplementation)Activator.CreateInstance(GetTypeFromAssembly(this.assembly, "XmlSerializerContract"));
125 return contract;
129 internal void InitAssemblyMethods(XmlMapping[] xmlMappings) {
130 methods = new TempMethodDictionary();
131 for (int i = 0; i < xmlMappings.Length; i++) {
132 TempMethod method = new TempMethod();
133 method.isSoap = xmlMappings[i].IsSoap;
134 method.methodKey = xmlMappings[i].Key;
135 XmlTypeMapping xmlTypeMapping = xmlMappings[i] as XmlTypeMapping;
136 if (xmlTypeMapping != null) {
137 method.name = xmlTypeMapping.ElementName;
138 method.ns = xmlTypeMapping.Namespace;
140 methods.Add(xmlMappings[i].Key, method);
144 /// <devdoc>
145 /// <para>
146 /// Attempts to load pre-generated serialization assembly.
147 /// First check for the [XmlSerializerAssembly] attribute
148 /// </para>
149 /// </devdoc>
150 // SxS: This method does not take any resource name and does not expose any resources to the caller.
151 // It's OK to suppress the SxS warning.
152 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
153 [ResourceExposure(ResourceScope.None)]
154 internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract) {
155 Assembly serializer = null;
156 contract = null;
157 string serializerName = null;
159 // Packaged apps do not support loading generated serializers.
160 if (Microsoft.Win32.UnsafeNativeMethods.IsPackagedProcess.Value) {
161 return null;
164 bool logEnabled = DiagnosticsSwitches.PregenEventLog.Enabled;
166 // check to see if we loading explicit pre-generated assembly
167 object[] attrs = type.GetCustomAttributes(typeof(XmlSerializerAssemblyAttribute), false);
168 if (attrs.Length == 0) {
169 // Guess serializer name: if parent assembly signed use strong name
170 AssemblyName name = GetName(type.Assembly, true);
171 serializerName = Compiler.GetTempAssemblyName(name, defaultNamespace);
172 // use strong name
173 name.Name = serializerName;
174 name.CodeBase = null;
175 name.CultureInfo = CultureInfo.InvariantCulture;
176 try {
177 serializer = Assembly.Load(name);
179 catch (Exception e) {
180 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
181 throw;
183 if (logEnabled) {
184 Log(e.Message, EventLogEntryType.Information);
186 byte[] token = name.GetPublicKeyToken();
187 if (token != null && token.Length > 0) {
188 // the parent assembly was signed, so do not try to LoadWithPartialName
189 return null;
191 #pragma warning disable 618
192 serializer = Assembly.LoadWithPartialName(serializerName, null);
193 #pragma warning restore 618
195 if (serializer == null) {
196 #if !FEATURE_PAL // EventLog
197 if (logEnabled) {
198 Log(Res.GetString(Res.XmlPregenCannotLoad, serializerName), EventLogEntryType.Information);
200 #endif //!FEATURE_PAL // EventLog
201 return null;
203 if (!IsSerializerVersionMatch(serializer, type, defaultNamespace, null)) {
204 #if !FEATURE_PAL // EventLog
205 if (logEnabled)
206 Log(Res.GetString(Res.XmlSerializerExpiredDetails, serializerName, type.FullName), EventLogEntryType.Error);
207 #endif //!FEATURE_PAL // EventLog
208 return null;
211 else {
212 XmlSerializerAssemblyAttribute assemblyAttribute = (XmlSerializerAssemblyAttribute)attrs[0];
213 if (assemblyAttribute.AssemblyName != null && assemblyAttribute.CodeBase != null)
214 throw new InvalidOperationException(Res.GetString(Res.XmlPregenInvalidXmlSerializerAssemblyAttribute, "AssemblyName", "CodeBase"));
216 // found XmlSerializerAssemblyAttribute attribute, it should have all needed information to load the pre-generated serializer
217 if (assemblyAttribute.AssemblyName != null) {
218 serializerName = assemblyAttribute.AssemblyName;
219 #pragma warning disable 618
220 serializer = Assembly.LoadWithPartialName(serializerName, null);
221 #pragma warning restore 618
223 else if (assemblyAttribute.CodeBase != null && assemblyAttribute.CodeBase.Length > 0) {
224 serializerName = assemblyAttribute.CodeBase;
225 serializer = Assembly.LoadFrom(serializerName);
227 else {
228 serializerName = type.Assembly.FullName;
229 serializer = type.Assembly;
231 if (serializer == null) {
232 throw new FileNotFoundException(null, serializerName);
235 Type contractType = GetTypeFromAssembly(serializer, "XmlSerializerContract");
236 contract = (XmlSerializerImplementation)Activator.CreateInstance(contractType);
237 if (contract.CanSerialize(type))
238 return serializer;
240 #if !FEATURE_PAL // EventLog
241 if (logEnabled)
242 Log(Res.GetString(Res.XmlSerializerExpiredDetails, serializerName, type.FullName), EventLogEntryType.Error);
243 #endif //!FEATURE_PAL // EventLog
244 return null;
247 #if !FEATURE_PAL // EventLog
248 static void Log(string message, EventLogEntryType type) {
249 new EventLogPermission(PermissionState.Unrestricted).Assert();
250 EventLog.WriteEntry("XmlSerializer", message, type);
252 #endif //!FEATURE_PAL // EventLog
254 static AssemblyName GetName(Assembly assembly, bool copyName) {
255 PermissionSet perms = new PermissionSet(PermissionState.None);
256 perms.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
257 perms.Assert();
258 return assembly.GetName(copyName);
262 static bool IsSerializerVersionMatch(Assembly serializer, Type type, string defaultNamespace, string location) {
263 if (serializer == null)
264 return false;
265 object[] attrs = serializer.GetCustomAttributes(typeof(XmlSerializerVersionAttribute), false);
266 if (attrs.Length != 1)
267 return false;
269 XmlSerializerVersionAttribute assemblyInfo = (XmlSerializerVersionAttribute)attrs[0];
270 // we found out dated pre-generate assembly
272 if (assemblyInfo.ParentAssemblyId == GenerateAssemblyId(type) && assemblyInfo.Namespace == defaultNamespace)
273 return true;
274 return false;
277 // SxS: This method does not take any resource name and does not expose any resources to the caller.
278 // It's OK to suppress the SxS warning.
279 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
280 [ResourceExposure(ResourceScope.None)]
281 static string GenerateAssemblyId(Type type) {
282 Module[] modules = type.Assembly.GetModules();
283 ArrayList list = new ArrayList();
284 for (int i = 0; i < modules.Length; i++) {
285 list.Add(modules[i].ModuleVersionId.ToString());
287 list.Sort();
288 StringBuilder sb = new StringBuilder();
289 for (int i = 0; i < list.Count; i++) {
290 sb.Append(list[i].ToString());
291 sb.Append(",");
293 return sb.ToString();
296 internal static Assembly GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies) {
297 FileIOPermission.Assert();
298 Compiler compiler = new Compiler();
299 try {
300 Hashtable scopeTable = new Hashtable();
301 foreach (XmlMapping mapping in xmlMappings)
302 scopeTable[mapping.Scope] = mapping;
303 TypeScope[] scopes = new TypeScope[scopeTable.Keys.Count];
304 scopeTable.Keys.CopyTo(scopes, 0);
306 assemblies.Clear();
307 Hashtable importedTypes = new Hashtable();
308 foreach (TypeScope scope in scopes) {
309 foreach (Type t in scope.Types) {
310 compiler.AddImport(t, importedTypes);
311 Assembly a = t.Assembly;
312 string name = a.FullName;
313 if (assemblies[name] != null)
314 continue;
315 if (!a.GlobalAssemblyCache) {
316 assemblies[name] = a;
320 for (int i = 0; i < types.Length; i++) {
321 compiler.AddImport(types[i], importedTypes);
323 compiler.AddImport(typeof(object).Assembly);
324 compiler.AddImport(typeof(XmlSerializer).Assembly);
326 IndentedWriter writer = new IndentedWriter(compiler.Source, false);
328 writer.WriteLine("#if _DYNAMIC_XMLSERIALIZER_COMPILATION");
329 writer.WriteLine("[assembly:System.Security.AllowPartiallyTrustedCallers()]");
330 writer.WriteLine("[assembly:System.Security.SecurityTransparent()]");
331 writer.WriteLine("[assembly:System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)]");
332 writer.WriteLine("#endif");
333 // Add AssemblyVersion attribute to match parent accembly version
334 if (types != null && types.Length > 0 && types[0] != null) {
335 writer.WriteLine("[assembly:System.Reflection.AssemblyVersionAttribute(\"" + types[0].Assembly.GetName().Version.ToString() + "\")]");
337 if (assembly != null && types.Length > 0) {
338 for (int i = 0; i < types.Length; i++) {
339 Type type = types[i];
340 if (type == null)
341 continue;
342 if (DynamicAssemblies.IsTypeDynamic(type)) {
343 throw new InvalidOperationException(Res.GetString(Res.XmlPregenTypeDynamic, types[i].FullName));
346 writer.Write("[assembly:");
347 writer.Write(typeof(XmlSerializerVersionAttribute).FullName);
348 writer.Write("(");
349 writer.Write("ParentAssemblyId=");
350 ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, GenerateAssemblyId(types[0]));
351 writer.Write(", Version=");
352 ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, ThisAssembly.Version);
353 if (defaultNamespace != null) {
354 writer.Write(", Namespace=");
355 ReflectionAwareCodeGen.WriteQuotedCSharpString(writer, defaultNamespace);
357 writer.WriteLine(")]");
359 CodeIdentifiers classes = new CodeIdentifiers();
360 classes.AddUnique("XmlSerializationWriter", "XmlSerializationWriter");
361 classes.AddUnique("XmlSerializationReader", "XmlSerializationReader");
362 string suffix = null;
363 if (types != null && types.Length == 1 && types[0] != null) {
364 suffix = CodeIdentifier.MakeValid(types[0].Name);
365 if (types[0].IsArray) {
366 suffix += "Array";
370 writer.WriteLine("namespace " + GeneratedAssemblyNamespace + " {");
371 writer.Indent++;
373 writer.WriteLine();
375 string writerClass = "XmlSerializationWriter" + suffix;
376 writerClass = classes.AddUnique(writerClass, writerClass);
377 XmlSerializationWriterCodeGen writerCodeGen = new XmlSerializationWriterCodeGen(writer, scopes, "public", writerClass);
379 writerCodeGen.GenerateBegin();
380 string[] writeMethodNames = new string[xmlMappings.Length];
382 for (int i = 0; i < xmlMappings.Length; i++) {
383 writeMethodNames[i] = writerCodeGen.GenerateElement(xmlMappings[i]);
385 writerCodeGen.GenerateEnd();
387 writer.WriteLine();
389 string readerClass = "XmlSerializationReader" + suffix;
390 readerClass = classes.AddUnique(readerClass, readerClass);
391 XmlSerializationReaderCodeGen readerCodeGen = new XmlSerializationReaderCodeGen(writer, scopes, "public", readerClass);
393 readerCodeGen.GenerateBegin();
394 string[] readMethodNames = new string[xmlMappings.Length];
395 for (int i = 0; i < xmlMappings.Length; i++) {
396 readMethodNames[i] = readerCodeGen.GenerateElement(xmlMappings[i]);
398 readerCodeGen.GenerateEnd(readMethodNames, xmlMappings, types);
400 string baseSerializer = readerCodeGen.GenerateBaseSerializer("XmlSerializer1", readerClass, writerClass, classes);
401 Hashtable serializers = new Hashtable();
402 for (int i = 0; i < xmlMappings.Length; i++) {
403 if (serializers[xmlMappings[i].Key] == null) {
404 serializers[xmlMappings[i].Key] = readerCodeGen.GenerateTypedSerializer(readMethodNames[i], writeMethodNames[i], xmlMappings[i], classes, baseSerializer, readerClass, writerClass);
407 readerCodeGen.GenerateSerializerContract("XmlSerializerContract", xmlMappings, types, readerClass, readMethodNames, writerClass, writeMethodNames, serializers);
408 writer.Indent--;
409 writer.WriteLine("}");
411 return compiler.Compile(assembly, defaultNamespace, parameters, evidence);
413 finally {
414 compiler.Close();
418 [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.")]
419 internal static Assembly GenerateRefEmitAssembly(XmlMapping[] xmlMappings, Type[] types, string defaultNamespace, Evidence evidence) {
420 Hashtable scopeTable = new Hashtable();
421 foreach (XmlMapping mapping in xmlMappings)
422 scopeTable[mapping.Scope] = mapping;
423 TypeScope[] scopes = new TypeScope[scopeTable.Keys.Count];
424 scopeTable.Keys.CopyTo(scopes, 0);
426 string assemblyName = "Microsoft.GeneratedCode";
427 AssemblyBuilder assemblyBuilder = CodeGenerator.CreateAssemblyBuilder(AppDomain.CurrentDomain, assemblyName);
428 ConstructorInfo SecurityTransparentAttribute_ctor = typeof(SecurityTransparentAttribute).GetConstructor(
429 CodeGenerator.InstanceBindingFlags,
430 null,
431 CodeGenerator.EmptyTypeArray,
432 null
434 assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(SecurityTransparentAttribute_ctor, new Object[0]));
435 ConstructorInfo AllowPartiallyTrustedCallersAttribute_ctor = typeof(AllowPartiallyTrustedCallersAttribute).GetConstructor(
436 CodeGenerator.InstanceBindingFlags,
437 null,
438 CodeGenerator.EmptyTypeArray,
439 null
441 assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(AllowPartiallyTrustedCallersAttribute_ctor, new Object[0]));
442 ConstructorInfo SecurityRulesAttribute_ctor = typeof(SecurityRulesAttribute).GetConstructor(
443 CodeGenerator.InstanceBindingFlags,
444 null,
445 new Type[] { typeof(SecurityRuleSet) },
446 null
448 assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(SecurityRulesAttribute_ctor, new Object[] { SecurityRuleSet.Level1 }));
449 // Add AssemblyVersion attribute to match parent accembly version
450 if (types != null && types.Length > 0 && types[0] != null) {
452 ConstructorInfo AssemblyVersionAttribute_ctor = typeof(AssemblyVersionAttribute).GetConstructor(
453 CodeGenerator.InstanceBindingFlags,
454 null,
455 new Type[] { typeof(String) },
456 null
458 FileIOPermission.Assert();
459 string assemblyVersion = types[0].Assembly.GetName().Version.ToString();
460 FileIOPermission.RevertAssert();
461 assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(AssemblyVersionAttribute_ctor, new Object[] { assemblyVersion }));
463 CodeIdentifiers classes = new CodeIdentifiers();
464 classes.AddUnique("XmlSerializationWriter", "XmlSerializationWriter");
465 classes.AddUnique("XmlSerializationReader", "XmlSerializationReader");
466 string suffix = null;
467 if (types != null && types.Length == 1 && types[0] != null) {
468 suffix = CodeIdentifier.MakeValid(types[0].Name);
469 if (types[0].IsArray) {
470 suffix += "Array";
474 ModuleBuilder moduleBuilder = CodeGenerator.CreateModuleBuilder(assemblyBuilder, assemblyName);
476 string writerClass = "XmlSerializationWriter" + suffix;
477 writerClass = classes.AddUnique(writerClass, writerClass);
478 XmlSerializationWriterILGen writerCodeGen = new XmlSerializationWriterILGen(scopes, "public", writerClass);
479 writerCodeGen.ModuleBuilder = moduleBuilder;
481 writerCodeGen.GenerateBegin();
482 string[] writeMethodNames = new string[xmlMappings.Length];
484 for (int i = 0; i < xmlMappings.Length; i++) {
485 writeMethodNames[i] = writerCodeGen.GenerateElement(xmlMappings[i]);
487 Type writerType = writerCodeGen.GenerateEnd();
489 string readerClass = "XmlSerializationReader" + suffix;
490 readerClass = classes.AddUnique(readerClass, readerClass);
491 XmlSerializationReaderILGen readerCodeGen = new XmlSerializationReaderILGen(scopes, "public", readerClass);
493 readerCodeGen.ModuleBuilder = moduleBuilder;
494 readerCodeGen.CreatedTypes.Add(writerType.Name, writerType);
496 readerCodeGen.GenerateBegin();
497 string[] readMethodNames = new string[xmlMappings.Length];
498 for (int i = 0; i < xmlMappings.Length; i++) {
499 readMethodNames[i] = readerCodeGen.GenerateElement(xmlMappings[i]);
501 readerCodeGen.GenerateEnd(readMethodNames, xmlMappings, types);
503 string baseSerializer = readerCodeGen.GenerateBaseSerializer("XmlSerializer1", readerClass, writerClass, classes);
504 Hashtable serializers = new Hashtable();
505 for (int i = 0; i < xmlMappings.Length; i++) {
506 if (serializers[xmlMappings[i].Key] == null) {
507 serializers[xmlMappings[i].Key] = readerCodeGen.GenerateTypedSerializer(readMethodNames[i], writeMethodNames[i], xmlMappings[i], classes, baseSerializer, readerClass, writerClass);
510 readerCodeGen.GenerateSerializerContract("XmlSerializerContract", xmlMappings, types, readerClass, readMethodNames, writerClass, writeMethodNames, serializers);
512 if (DiagnosticsSwitches.KeepTempFiles.Enabled) {
513 FileIOPermission.Assert();
514 assemblyBuilder.Save(assemblyName + ".dll");
516 return writerType.Assembly;
519 // SxS: This method does not take any resource name and does not expose any resources to the caller.
520 // It's OK to suppress the SxS warning.
521 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
522 [ResourceExposure(ResourceScope.None)]
523 static MethodInfo GetMethodFromType(Type type, string methodName, Assembly assembly) {
524 MethodInfo method = type.GetMethod(methodName);
525 if (method != null)
526 return method;
528 MissingMethodException missingMethod = new MissingMethodException(type.FullName, methodName);
529 if (assembly != null) {
530 throw new InvalidOperationException(Res.GetString(Res.XmlSerializerExpired, assembly.FullName, assembly.CodeBase), missingMethod);
532 throw missingMethod;
535 internal static Type GetTypeFromAssembly(Assembly assembly, string typeName) {
536 typeName = GeneratedAssemblyNamespace + "." + typeName;
537 Type type = assembly.GetType(typeName);
538 if (type == null) throw new InvalidOperationException(Res.GetString(Res.XmlMissingType, typeName, assembly.FullName));
539 return type;
542 internal bool CanRead(XmlMapping mapping, XmlReader xmlReader) {
543 if (mapping == null)
544 return false;
546 if (mapping.Accessor.Any) {
547 return true;
549 TempMethod method = methods[mapping.Key];
550 return xmlReader.IsStartElement(method.name, method.ns);
553 string ValidateEncodingStyle(string encodingStyle, string methodKey) {
554 if (encodingStyle != null && encodingStyle.Length > 0) {
555 if (methods[methodKey].isSoap) {
556 if (encodingStyle != Soap.Encoding && encodingStyle != Soap12.Encoding) {
557 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncoding3, encodingStyle, Soap.Encoding, Soap12.Encoding));
560 else {
561 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncodingNotEncoded1, encodingStyle));
564 else {
565 if (methods[methodKey].isSoap) {
566 encodingStyle = Soap.Encoding;
569 return encodingStyle;
572 internal static FileIOPermission FileIOPermission {
573 get {
574 if (fileIOPermission == null)
575 fileIOPermission = new FileIOPermission(PermissionState.Unrestricted);
576 return fileIOPermission;
580 internal object InvokeReader(XmlMapping mapping, XmlReader xmlReader, XmlDeserializationEvents events, string encodingStyle) {
581 XmlSerializationReader reader = null;
582 try {
583 encodingStyle = ValidateEncodingStyle(encodingStyle, mapping.Key);
584 reader = Contract.Reader;
585 reader.Init(xmlReader, events, encodingStyle, this);
586 if (methods[mapping.Key].readMethod == null) {
587 if (readerMethods == null) {
588 readerMethods = Contract.ReadMethods;
590 string methodName = (string)readerMethods[mapping.Key];
591 if (methodName == null) {
592 throw new InvalidOperationException(Res.GetString(Res.XmlNotSerializable, mapping.Accessor.Name));
594 methods[mapping.Key].readMethod = GetMethodFromType(reader.GetType(), methodName, pregeneratedAssmbly ? this.assembly : null);
596 return methods[mapping.Key].readMethod.Invoke(reader, emptyObjectArray);
598 catch (SecurityException e) {
599 throw new InvalidOperationException(Res.GetString(Res.XmlNoPartialTrust), e);
601 finally {
602 if (reader != null)
603 reader.Dispose();
607 internal void InvokeWriter(XmlMapping mapping, XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces, string encodingStyle, string id) {
608 XmlSerializationWriter writer = null;
609 try {
610 encodingStyle = ValidateEncodingStyle(encodingStyle, mapping.Key);
611 writer = Contract.Writer;
612 writer.Init(xmlWriter, namespaces, encodingStyle, id, this);
613 if (methods[mapping.Key].writeMethod == null) {
614 if (writerMethods == null) {
615 writerMethods = Contract.WriteMethods;
617 string methodName = (string)writerMethods[mapping.Key];
618 if (methodName == null) {
619 throw new InvalidOperationException(Res.GetString(Res.XmlNotSerializable, mapping.Accessor.Name));
621 methods[mapping.Key].writeMethod = GetMethodFromType(writer.GetType(), methodName, pregeneratedAssmbly ? assembly : null);
623 methods[mapping.Key].writeMethod.Invoke(writer, new object[] { o });
625 catch (SecurityException e) {
626 throw new InvalidOperationException(Res.GetString(Res.XmlNoPartialTrust), e);
628 finally {
629 if (writer != null)
630 writer.Dispose();
634 internal Assembly GetReferencedAssembly(string name) {
635 return assemblies != null && name != null ? (Assembly)assemblies[name] : null;
638 internal bool NeedAssembyResolve {
639 get { return assemblies != null && assemblies.Count > 0; }
642 internal sealed class TempMethodDictionary : DictionaryBase {
643 internal TempMethod this[string key] {
644 get {
645 return (TempMethod)Dictionary[key];
648 internal void Add(string key, TempMethod value) {
649 Dictionary.Add(key, value);
654 sealed class XmlSerializerCompilerParameters {
655 bool needTempDirAccess;
656 CompilerParameters parameters;
657 XmlSerializerCompilerParameters(CompilerParameters parameters, bool needTempDirAccess) {
658 this.needTempDirAccess = needTempDirAccess;
659 this.parameters = parameters;
662 internal bool IsNeedTempDirAccess { get { return this.needTempDirAccess; } }
663 internal CompilerParameters CodeDomParameters { get { return this.parameters; } }
665 internal static XmlSerializerCompilerParameters Create(string location) {
666 CompilerParameters parameters = new CompilerParameters();
667 parameters.GenerateInMemory = true;
669 if (string.IsNullOrEmpty(location)) {
670 #if CONFIGURATION_DEP
671 XmlSerializerSection configSection = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath) as XmlSerializerSection;
672 location = configSection == null ? location : configSection.TempFilesLocation;
673 #endif
674 // Trim leading and trailing white spaces (VSWhidbey 229873)
675 if (!string.IsNullOrEmpty(location)) {
676 location = location.Trim();
679 parameters.TempFiles = new TempFileCollection(location);
680 return new XmlSerializerCompilerParameters(parameters, string.IsNullOrEmpty(location));
683 internal static XmlSerializerCompilerParameters Create(CompilerParameters parameters, bool needTempDirAccess) {
684 return new XmlSerializerCompilerParameters(parameters, needTempDirAccess);
689 class TempAssemblyCacheKey {
690 string ns;
691 object type;
693 internal TempAssemblyCacheKey(string ns, object type) {
694 this.type = type;
695 this.ns = ns;
698 public override bool Equals(object o) {
699 TempAssemblyCacheKey key = o as TempAssemblyCacheKey;
700 if (key == null) return false;
701 return (key.type == this.type && key.ns == this.ns);
704 public override int GetHashCode() {
705 return ((ns != null ? ns.GetHashCode() : 0) ^ (type != null ? type.GetHashCode() : 0));
709 internal class TempAssemblyCache {
710 Hashtable cache = new Hashtable();
712 internal TempAssembly this[string ns, object o] {
713 get { return (TempAssembly)cache[new TempAssemblyCacheKey(ns, o)]; }
716 internal void Add(string ns, object o, TempAssembly assembly) {
717 TempAssemblyCacheKey key = new TempAssemblyCacheKey(ns, o);
718 lock (this) {
719 if (cache[key] == assembly) return;
720 Hashtable clone = new Hashtable();
721 foreach (object k in cache.Keys) {
722 clone.Add(k, cache[k]);
724 cache = clone;
725 cache[key] = assembly;