1 //------------------------------------------------------------------------------
2 // <copyright file="Compilation.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
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
;
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";
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
;
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
) {
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...
77 fallbackToCSharpAssemblyGeneration
= true;
80 if (fallbackToCSharpAssemblyGeneration
) {
81 assembly
= GenerateAssembly(xmlMappings
, types
, defaultNamespace
, evidence
, XmlSerializerCompilerParameters
.Create(location
), null, assemblies
);
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"));
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
{
100 if (AppSettings
.UseLegacySerializerGeneration
.HasValue
) {
101 // AppSetting will always win if specified
102 return (bool) AppSettings
.UseLegacySerializerGeneration
;
105 #if CONFIGURATION_DEP
106 XmlSerializerSection configSection
= ConfigurationManager
.GetSection(ConfigurationStrings
.XmlSerializerSectionPath
) as XmlSerializerSection
;
107 return configSection
== null ? false : configSection
.UseLegacySerializerGeneration
;
115 internal TempAssembly(XmlSerializerImplementation contract
) {
116 this.contract
= contract
;
117 pregeneratedAssmbly
= true;
120 internal XmlSerializerImplementation Contract
{
122 if (contract
== null) {
123 contract
= (XmlSerializerImplementation
)Activator
.CreateInstance(GetTypeFromAssembly(this.assembly
, "XmlSerializerContract"));
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
);
146 /// Attempts to load pre-generated serialization assembly.
147 /// First check for the [XmlSerializerAssembly] attribute
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;
157 string serializerName
= null;
159 // Packaged apps do not support loading generated serializers.
160 if (Microsoft
.Win32
.UnsafeNativeMethods
.IsPackagedProcess
.Value
) {
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
);
173 name
.Name
= serializerName
;
174 name
.CodeBase
= null;
175 name
.CultureInfo
= CultureInfo
.InvariantCulture
;
177 serializer
= Assembly
.Load(name
);
179 catch (Exception e
) {
180 if (e
is ThreadAbortException
|| e
is StackOverflowException
|| e
is OutOfMemoryException
) {
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
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
198 Log(Res
.GetString(Res
.XmlPregenCannotLoad
, serializerName
), EventLogEntryType
.Information
);
200 #endif //!FEATURE_PAL // EventLog
203 if (!IsSerializerVersionMatch(serializer
, type
, defaultNamespace
, null)) {
204 #if !FEATURE_PAL // EventLog
206 Log(Res
.GetString(Res
.XmlSerializerExpiredDetails
, serializerName
, type
.FullName
), EventLogEntryType
.Error
);
207 #endif //!FEATURE_PAL // EventLog
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
);
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
))
240 #if !FEATURE_PAL // EventLog
242 Log(Res
.GetString(Res
.XmlSerializerExpiredDetails
, serializerName
, type
.FullName
), EventLogEntryType
.Error
);
243 #endif //!FEATURE_PAL // EventLog
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
));
258 return assembly
.GetName(copyName
);
262 static bool IsSerializerVersionMatch(Assembly serializer
, Type type
, string defaultNamespace
, string location
) {
263 if (serializer
== null)
265 object[] attrs
= serializer
.GetCustomAttributes(typeof(XmlSerializerVersionAttribute
), false);
266 if (attrs
.Length
!= 1)
269 XmlSerializerVersionAttribute assemblyInfo
= (XmlSerializerVersionAttribute
)attrs
[0];
270 // we found out dated pre-generate assembly
272 if (assemblyInfo
.ParentAssemblyId
== GenerateAssemblyId(type
) && assemblyInfo
.Namespace
== defaultNamespace
)
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());
288 StringBuilder sb
= new StringBuilder();
289 for (int i
= 0; i
< list
.Count
; i
++) {
290 sb
.Append(list
[i
].ToString());
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();
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);
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)
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
];
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
);
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
) {
370 writer
.WriteLine("namespace " + GeneratedAssemblyNamespace
+ " {");
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();
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
);
409 writer
.WriteLine("}");
411 return compiler
.Compile(assembly
, defaultNamespace
, parameters
, evidence
);
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
,
431 CodeGenerator
.EmptyTypeArray
,
434 assemblyBuilder
.SetCustomAttribute(new CustomAttributeBuilder(SecurityTransparentAttribute_ctor
, new Object
[0]));
435 ConstructorInfo AllowPartiallyTrustedCallersAttribute_ctor
= typeof(AllowPartiallyTrustedCallersAttribute
).GetConstructor(
436 CodeGenerator
.InstanceBindingFlags
,
438 CodeGenerator
.EmptyTypeArray
,
441 assemblyBuilder
.SetCustomAttribute(new CustomAttributeBuilder(AllowPartiallyTrustedCallersAttribute_ctor
, new Object
[0]));
442 ConstructorInfo SecurityRulesAttribute_ctor
= typeof(SecurityRulesAttribute
).GetConstructor(
443 CodeGenerator
.InstanceBindingFlags
,
445 new Type
[] { typeof(SecurityRuleSet) }
,
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
,
455 new Type
[] { typeof(String) }
,
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
) {
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
);
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
);
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
));
542 internal bool CanRead(XmlMapping mapping
, XmlReader xmlReader
) {
546 if (mapping
.Accessor
.Any
) {
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
));
561 throw new InvalidOperationException(Res
.GetString(Res
.XmlInvalidEncodingNotEncoded1
, encodingStyle
));
565 if (methods
[methodKey
].isSoap
) {
566 encodingStyle
= Soap
.Encoding
;
569 return encodingStyle
;
572 internal static FileIOPermission FileIOPermission
{
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;
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
);
607 internal void InvokeWriter(XmlMapping mapping
, XmlWriter xmlWriter
, object o
, XmlSerializerNamespaces namespaces
, string encodingStyle
, string id
) {
608 XmlSerializationWriter writer
= null;
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
);
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
] {
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
;
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
{
693 internal TempAssemblyCacheKey(string ns
, object type
) {
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
);
719 if (cache
[key
] == assembly
) return;
720 Hashtable clone
= new Hashtable();
721 foreach (object k
in cache
.Keys
) {
722 clone
.Add(k
, cache
[k
]);
725 cache
[key
] = assembly
;