[bcl] Updates referencesource to 4.7.1
[mono-project.git] / mcs / class / referencesource / System.Xml / System / Xml / Serialization / XmlSerializer.cs
blob75d99bf29244bb8a5a8cd768a312f3d370869a0e
1 //------------------------------------------------------------------------------
2 // <copyright file="XmlSerializer.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.Reflection;
11 using System.Collections;
12 using System.IO;
13 using System.Xml.Schema;
14 using System;
15 using System.Text;
16 using System.Threading;
17 using System.Globalization;
18 using System.Security;
19 using System.Security.Permissions;
20 using System.Security.Policy;
21 using System.Xml.Serialization.Configuration;
22 using System.Diagnostics;
23 using System.CodeDom.Compiler;
24 using System.Runtime.Versioning;
26 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents"]/*' />
27 /// <devdoc>
28 /// <para>[To be supplied.]</para>
29 /// </devdoc>
30 public struct XmlDeserializationEvents {
31 XmlNodeEventHandler onUnknownNode;
32 XmlAttributeEventHandler onUnknownAttribute;
33 XmlElementEventHandler onUnknownElement;
34 UnreferencedObjectEventHandler onUnreferencedObject;
35 internal object sender;
37 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents.OnUnknownNode"]/*' />
38 public XmlNodeEventHandler OnUnknownNode {
39 get {
40 return onUnknownNode;
43 set {
44 onUnknownNode = value;
48 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents.OnUnknownAttribute"]/*' />
49 public XmlAttributeEventHandler OnUnknownAttribute {
50 get {
51 return onUnknownAttribute;
53 set {
54 onUnknownAttribute = value;
58 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents.OnUnknownElement"]/*' />
59 public XmlElementEventHandler OnUnknownElement {
60 get {
61 return onUnknownElement;
63 set {
64 onUnknownElement = value;
68 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents.OnUnreferencedObject"]/*' />
69 public UnreferencedObjectEventHandler OnUnreferencedObject {
70 get {
71 return onUnreferencedObject;
73 set {
74 onUnreferencedObject = value;
79 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation"]/*' />
80 ///<internalonly/>
81 /// <devdoc>
82 /// <para>[To be supplied.]</para>
83 /// </devdoc>
84 public abstract class XmlSerializerImplementation {
85 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.Reader"]/*' />
86 public virtual XmlSerializationReader Reader{ get {throw new NotSupportedException();} }
87 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.Writer"]/*' />
88 public virtual XmlSerializationWriter Writer{ get {throw new NotSupportedException();} }
89 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.ReadMethods"]/*' />
90 public virtual Hashtable ReadMethods{ get {throw new NotSupportedException();} }
91 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.WriteMethods"]/*' />
92 public virtual Hashtable WriteMethods{ get {throw new NotSupportedException();} }
93 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.TypedSerializers"]/*' />
94 public virtual Hashtable TypedSerializers{ get {throw new NotSupportedException();} }
95 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.CanSerialize"]/*' />
96 public virtual bool CanSerialize(Type type){ throw new NotSupportedException(); }
97 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.GetSerializer"]/*' />
98 public virtual XmlSerializer GetSerializer(Type type){ throw new NotSupportedException(); }
101 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer"]/*' />
102 /// <devdoc>
103 /// <para>[To be supplied.]</para>
104 /// </devdoc>
105 public class XmlSerializer {
106 TempAssembly tempAssembly;
107 bool typedSerializer;
108 Type primitiveType;
109 XmlMapping mapping;
110 XmlDeserializationEvents events = new XmlDeserializationEvents();
112 static TempAssemblyCache cache = new TempAssemblyCache();
113 static volatile XmlSerializerNamespaces defaultNamespaces;
114 static XmlSerializerNamespaces DefaultNamespaces {
115 get {
116 if (defaultNamespaces == null) {
117 XmlSerializerNamespaces nss = new XmlSerializerNamespaces();
118 nss.AddInternal("xsi", XmlSchema.InstanceNamespace);
119 nss.AddInternal("xsd", XmlSchema.Namespace);
120 if (defaultNamespaces == null) {
121 defaultNamespaces = nss;
124 return defaultNamespaces;
128 static Hashtable xmlSerializerTable = new Hashtable();
130 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer8"]/*' />
131 ///<internalonly/>
132 protected XmlSerializer() {
135 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer"]/*' />
136 /// <devdoc>
137 /// <para>[To be supplied.]</para>
138 /// </devdoc>
139 public XmlSerializer(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, string defaultNamespace) :
140 this (type, overrides, extraTypes, root, defaultNamespace, null) {
143 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer2"]/*' />
144 /// <devdoc>
145 /// <para>[To be supplied.]</para>
146 /// </devdoc>
147 public XmlSerializer(Type type, XmlRootAttribute root) : this(type, null, new Type[0], root, null, null) {
150 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer3"]/*' />
151 /// <devdoc>
152 /// <para>[To be supplied.]</para>
153 /// </devdoc>
154 public XmlSerializer(Type type, Type[] extraTypes) : this(type, null, extraTypes, null, null, null) {
157 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer4"]/*' />
158 /// <devdoc>
159 /// <para>[To be supplied.]</para>
160 /// </devdoc>
161 public XmlSerializer(Type type, XmlAttributeOverrides overrides) : this(type, overrides, new Type[0], null, null, null) {
164 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer5"]/*' />
165 /// <devdoc>
166 /// <para>[To be supplied.]</para>
167 /// </devdoc>
168 public XmlSerializer(XmlTypeMapping xmlTypeMapping) {
169 tempAssembly = GenerateTempAssembly(xmlTypeMapping);
170 this.mapping = xmlTypeMapping;
173 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer6"]/*' />
174 /// <devdoc>
175 /// <para>[To be supplied.]</para>
176 /// </devdoc>
177 public XmlSerializer(Type type) : this(type, (string)null) {
180 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer1"]/*' />
181 /// <devdoc>
182 /// <para>[To be supplied.]</para>
183 /// </devdoc>
184 public XmlSerializer(Type type, string defaultNamespace) {
185 if (type == null)
186 throw new ArgumentNullException("type");
187 this.mapping = GetKnownMapping(type, defaultNamespace);
188 if (this.mapping != null) {
189 this.primitiveType = type;
190 return;
192 tempAssembly = cache[defaultNamespace, type];
193 if (tempAssembly == null) {
194 lock (cache) {
195 tempAssembly = cache[defaultNamespace, type];
196 if (tempAssembly == null) {
197 XmlSerializerImplementation contract;
198 Assembly assembly = TempAssembly.LoadGeneratedAssembly(type, defaultNamespace, out contract);
199 if (assembly == null) {
200 // need to reflect and generate new serialization assembly
201 XmlReflectionImporter importer = new XmlReflectionImporter(defaultNamespace);
202 this.mapping = importer.ImportTypeMapping(type, null, defaultNamespace);
203 tempAssembly = GenerateTempAssembly(this.mapping, type, defaultNamespace);
205 else {
206 // we found the pre-generated assembly, now make sure that the assembly has the right serializer
207 // try to avoid the reflection step, need to get ElementName, namespace and the Key form the type
208 this.mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace);
209 tempAssembly = new TempAssembly(new XmlMapping[] { this.mapping }, assembly, contract);
212 cache.Add(defaultNamespace, type, tempAssembly);
215 if (mapping == null) {
216 mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace);
220 public XmlSerializer(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, string defaultNamespace, string location)
221 #pragma warning disable 618 // Passing through null evidence to keep the .ctor code centralized
222 : this (type, overrides, extraTypes, root, defaultNamespace, location, null) {
223 #pragma warning restore 618
226 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer7"]/*' />
227 /// <devdoc>
228 /// <para>[To be supplied.]</para>
229 /// </devdoc>
230 [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use a XmlSerializer constructor overload which does not take an Evidence parameter. See http://go2.microsoft.com/fwlink/?LinkId=131738 for more information.")]
231 public XmlSerializer(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, string defaultNamespace, string location, Evidence evidence) {
232 if (type == null)
233 throw new ArgumentNullException("type");
234 XmlReflectionImporter importer = new XmlReflectionImporter(overrides, defaultNamespace);
235 if (extraTypes != null)
237 for (int i = 0; i < extraTypes.Length; i++)
238 importer.IncludeType(extraTypes[i]);
240 this.mapping = importer.ImportTypeMapping(type, root, defaultNamespace);
241 if (location != null || evidence != null) {
242 DemandForUserLocationOrEvidence();
244 tempAssembly = GenerateTempAssembly(this.mapping, type, defaultNamespace, location, evidence);
247 [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
248 void DemandForUserLocationOrEvidence() {
249 // Ensure full trust before asserting full file access to the user-provided location or evidence
252 internal static TempAssembly GenerateTempAssembly(XmlMapping xmlMapping) {
253 return GenerateTempAssembly(xmlMapping, null, null);
256 internal static TempAssembly GenerateTempAssembly(XmlMapping xmlMapping, Type type, string defaultNamespace) {
257 if (xmlMapping == null)
258 throw new ArgumentNullException("xmlMapping");
259 return new TempAssembly(new XmlMapping[] { xmlMapping }, new Type[] {type}, defaultNamespace, null, null);
262 internal static TempAssembly GenerateTempAssembly(XmlMapping xmlMapping, Type type, string defaultNamespace, string location, Evidence evidence) {
263 return new TempAssembly(new XmlMapping[] { xmlMapping }, new Type[] {type}, defaultNamespace, location, evidence);
266 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize"]/*' />
267 /// <devdoc>
268 /// <para>[To be supplied.]</para>
269 /// </devdoc>
270 public void Serialize(TextWriter textWriter, object o) {
271 Serialize(textWriter, o, null);
274 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize1"]/*' />
275 /// <devdoc>
276 /// <para>[To be supplied.]</para>
277 /// </devdoc>
278 public void Serialize(TextWriter textWriter, object o, XmlSerializerNamespaces namespaces) {
279 XmlTextWriter xmlWriter = new XmlTextWriter(textWriter);
280 xmlWriter.Formatting = Formatting.Indented;
281 xmlWriter.Indentation = 2;
282 Serialize(xmlWriter, o, namespaces);
285 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize2"]/*' />
286 /// <devdoc>
287 /// <para>[To be supplied.]</para>
288 /// </devdoc>
289 public void Serialize(Stream stream, object o) {
290 Serialize(stream, o, null);
293 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize3"]/*' />
294 /// <devdoc>
295 /// <para>[To be supplied.]</para>
296 /// </devdoc>
297 public void Serialize(Stream stream, object o, XmlSerializerNamespaces namespaces) {
298 XmlTextWriter xmlWriter = new XmlTextWriter(stream, null);
299 xmlWriter.Formatting = Formatting.Indented;
300 xmlWriter.Indentation = 2;
301 Serialize(xmlWriter, o, namespaces);
304 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize4"]/*' />
305 /// <devdoc>
306 /// <para>[To be supplied.]</para>
307 /// </devdoc>
308 public void Serialize(XmlWriter xmlWriter, object o) {
309 Serialize(xmlWriter, o, null);
312 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize5"]/*' />
313 /// <devdoc>
314 /// <para>[To be supplied.]</para>
315 /// </devdoc>
316 public void Serialize(XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces) {
317 Serialize(xmlWriter, o, namespaces, null);
319 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize6"]/*' />
320 public void Serialize(XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces, string encodingStyle) {
321 Serialize(xmlWriter, o, namespaces, encodingStyle, null);
324 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize6"]/*' />
325 public void Serialize(XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces, string encodingStyle, string id) {
326 try {
327 if (primitiveType != null) {
328 if (encodingStyle != null && encodingStyle.Length > 0) {
329 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncodingNotEncoded1, encodingStyle));
331 SerializePrimitive(xmlWriter, o, namespaces);
333 else if (tempAssembly == null || typedSerializer) {
334 XmlSerializationWriter writer = CreateWriter();
335 writer.Init(xmlWriter, namespaces == null || namespaces.Count == 0 ? DefaultNamespaces : namespaces, encodingStyle, id, tempAssembly);
336 try {
337 Serialize(o, writer);
339 finally {
340 writer.Dispose();
343 else
344 tempAssembly.InvokeWriter(mapping, xmlWriter, o, namespaces == null || namespaces.Count == 0 ? DefaultNamespaces : namespaces, encodingStyle, id);
346 catch (Exception e) {
347 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
348 throw;
350 if (e is TargetInvocationException)
351 e = e.InnerException;
352 throw new InvalidOperationException(Res.GetString(Res.XmlGenError), e);
354 xmlWriter.Flush();
357 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize"]/*' />
358 /// <devdoc>
359 /// <para>[To be supplied.]</para>
360 /// </devdoc>
361 public object Deserialize(Stream stream) {
362 XmlTextReader xmlReader = new XmlTextReader(stream);
363 xmlReader.WhitespaceHandling = WhitespaceHandling.Significant;
364 xmlReader.Normalization = true;
365 xmlReader.XmlResolver = null;
366 return Deserialize(xmlReader, null);
369 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize1"]/*' />
370 /// <devdoc>
371 /// <para>[To be supplied.]</para>
372 /// </devdoc>
373 public object Deserialize(TextReader textReader) {
374 XmlTextReader xmlReader = new XmlTextReader(textReader);
375 xmlReader.WhitespaceHandling = WhitespaceHandling.Significant;
376 xmlReader.Normalization = true;
377 xmlReader.XmlResolver = null;
378 return Deserialize(xmlReader, null);
381 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize2"]/*' />
382 /// <devdoc>
383 /// <para>[To be supplied.]</para>
384 /// </devdoc>
385 public object Deserialize(XmlReader xmlReader) {
386 return Deserialize(xmlReader, null);
389 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize3"]/*' />
390 public object Deserialize(XmlReader xmlReader, XmlDeserializationEvents events) {
391 return Deserialize(xmlReader, null, events);
394 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize4"]/*' />
395 public object Deserialize(XmlReader xmlReader, string encodingStyle) {
396 return Deserialize(xmlReader, encodingStyle, this.events);
399 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize5"]/*' />
400 public object Deserialize(XmlReader xmlReader, string encodingStyle, XmlDeserializationEvents events) {
401 events.sender = this;
402 try {
403 if (primitiveType != null) {
404 if (encodingStyle != null && encodingStyle.Length > 0) {
405 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidEncodingNotEncoded1, encodingStyle));
407 return DeserializePrimitive(xmlReader, events);
409 else if (tempAssembly == null || typedSerializer) {
410 XmlSerializationReader reader = CreateReader();
411 reader.Init(xmlReader, events, encodingStyle, tempAssembly);
412 try {
413 return Deserialize(reader);
415 finally {
416 reader.Dispose();
419 else {
420 return tempAssembly.InvokeReader(mapping, xmlReader, events, encodingStyle);
423 catch (Exception e) {
424 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
425 throw;
427 if (e is TargetInvocationException)
428 e = e.InnerException;
430 if (xmlReader is IXmlLineInfo) {
431 IXmlLineInfo lineInfo = (IXmlLineInfo)xmlReader;
432 throw new InvalidOperationException(Res.GetString(Res.XmlSerializeErrorDetails, lineInfo.LineNumber.ToString(CultureInfo.InvariantCulture), lineInfo.LinePosition.ToString(CultureInfo.InvariantCulture)), e);
434 else {
435 throw new InvalidOperationException(Res.GetString(Res.XmlSerializeError), e);
440 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.CanDeserialize"]/*' />
441 /// <devdoc>
442 /// <para>[To be supplied.]</para>
443 /// </devdoc>
444 public virtual bool CanDeserialize(XmlReader xmlReader) {
445 if (primitiveType != null) {
446 TypeDesc typeDesc = (TypeDesc)TypeScope.PrimtiveTypes[primitiveType];
447 return xmlReader.IsStartElement(typeDesc.DataType.Name, string.Empty);
449 else if (tempAssembly != null) {
450 return tempAssembly.CanRead(mapping, xmlReader);
452 else {
453 return false;
457 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.FromMappings"]/*' />
458 /// <devdoc>
459 /// <para>[To be supplied.]</para>
460 /// </devdoc>
461 [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
462 public static XmlSerializer[] FromMappings(XmlMapping[] mappings) {
463 return FromMappings(mappings, (Type)null);
466 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.FromMappings1"]/*' />
467 /// <devdoc>
468 /// <para>[To be supplied.]</para>
469 /// </devdoc>
470 [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
471 public static XmlSerializer[] FromMappings(XmlMapping[] mappings, Type type) {
472 if (mappings == null || mappings.Length == 0) return new XmlSerializer[0];
473 XmlSerializerImplementation contract = null;
474 Assembly assembly = type == null ? null : TempAssembly.LoadGeneratedAssembly(type, null, out contract);
475 TempAssembly tempAssembly = null;
476 if (assembly == null) {
477 if (XmlMapping.IsShallow(mappings)) {
478 return new XmlSerializer[0];
480 else {
481 if (type == null) {
482 tempAssembly = new TempAssembly(mappings, new Type[] { type }, null, null, null);
483 XmlSerializer[] serializers = new XmlSerializer[mappings.Length];
485 contract = tempAssembly.Contract;
487 for (int i = 0; i < serializers.Length; i++) {
488 serializers[i] = (XmlSerializer)contract.TypedSerializers[mappings[i].Key];
489 serializers[i].SetTempAssembly(tempAssembly, mappings[i]);
492 return serializers;
494 else {
495 // Use XmlSerializer cache when the type is not null.
496 return GetSerializersFromCache(mappings, type);
500 else {
501 XmlSerializer[] serializers = new XmlSerializer[mappings.Length];
502 for (int i = 0; i < serializers.Length; i++)
503 serializers[i] = (XmlSerializer)contract.TypedSerializers[mappings[i].Key];
504 return serializers;
508 static XmlSerializer[] GetSerializersFromCache(XmlMapping[] mappings, Type type) {
509 XmlSerializer[] serializers = new XmlSerializer[mappings.Length];
511 Hashtable typedMappingTable = null;
512 lock (xmlSerializerTable) {
513 typedMappingTable = xmlSerializerTable[type] as Hashtable;
514 if (typedMappingTable == null) {
515 typedMappingTable = new Hashtable();
516 xmlSerializerTable[type] = typedMappingTable;
520 lock (typedMappingTable) {
521 Hashtable pendingKeys = new Hashtable();
522 for (int i = 0; i < mappings.Length; i++) {
523 XmlSerializerMappingKey mappingKey = new XmlSerializerMappingKey(mappings[i]);
524 serializers[i] = typedMappingTable[mappingKey] as XmlSerializer;
525 if (serializers[i] == null) {
526 pendingKeys.Add(mappingKey, i);
530 if (pendingKeys.Count > 0) {
531 XmlMapping[] pendingMappings = new XmlMapping[pendingKeys.Count];
532 int index = 0;
533 foreach (XmlSerializerMappingKey mappingKey in pendingKeys.Keys) {
534 pendingMappings[index++] = mappingKey.Mapping;
537 TempAssembly tempAssembly = new TempAssembly(pendingMappings, new Type[] { type }, null, null, null);
538 XmlSerializerImplementation contract = tempAssembly.Contract;
540 foreach (XmlSerializerMappingKey mappingKey in pendingKeys.Keys) {
541 index = (int)pendingKeys[mappingKey];
542 serializers[index] = (XmlSerializer)contract.TypedSerializers[mappingKey.Mapping.Key];
543 serializers[index].SetTempAssembly(tempAssembly, mappingKey.Mapping);
545 typedMappingTable[mappingKey] = serializers[index];
550 return serializers;
553 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.FromMappings3"]/*' />
554 /// <devdoc>
555 /// <para>[To be supplied.]</para>
556 /// </devdoc>
557 [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
558 [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of FromMappings which does not take an Evidence parameter. See http://go2.microsoft.com/fwlink/?LinkId=131738 for more information.")]
559 public static XmlSerializer[] FromMappings(XmlMapping[] mappings, Evidence evidence) {
560 if (mappings == null || mappings.Length == 0) return new XmlSerializer[0];
561 if (XmlMapping.IsShallow(mappings)) {
562 return new XmlSerializer[0];
564 TempAssembly tempAssembly = new TempAssembly(mappings, new Type[0], null, null, evidence);
565 XmlSerializerImplementation contract = tempAssembly.Contract;
566 XmlSerializer[] serializers = new XmlSerializer[mappings.Length];
567 for (int i = 0; i < serializers.Length; i++) {
568 serializers[i] = (XmlSerializer)contract.TypedSerializers[mappings[i].Key];
570 return serializers;
573 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.GenerateSerializer"]/*' />
574 /// <devdoc>
575 /// <para>[To be supplied.]</para>
576 /// </devdoc>
577 [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
578 public static Assembly GenerateSerializer(Type[] types, XmlMapping[] mappings) {
579 CompilerParameters parameters = new CompilerParameters();
580 parameters.TempFiles = new TempFileCollection();
581 parameters.GenerateInMemory = false;
582 parameters.IncludeDebugInformation = false;
583 return GenerateSerializer(types, mappings, parameters);
586 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.GenerateSerializer1"]/*' />
587 /// <devdoc>
588 /// <para>[To be supplied.]</para>
589 /// </devdoc>
590 // SxS: This method does not take any resource name and does not expose any resources to the caller.
591 // It's OK to suppress the SxS warning.
592 [PermissionSet(SecurityAction.Demand, Name="FullTrust")]
593 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
594 [ResourceExposure(ResourceScope.None)]
595 public static Assembly GenerateSerializer(Type[] types, XmlMapping[] mappings, CompilerParameters parameters) {
596 if (types == null || types.Length == 0)
597 return null;
599 if (mappings == null)
600 throw new ArgumentNullException("mappings");
602 if (XmlMapping.IsShallow(mappings)) {
603 throw new InvalidOperationException(Res.GetString(Res.XmlMelformMapping));
606 Assembly assembly = null;
607 for (int i = 0; i < types.Length; i ++) {
608 Type type = types[i];
609 if (DynamicAssemblies.IsTypeDynamic(type)) {
610 throw new InvalidOperationException(Res.GetString(Res.XmlPregenTypeDynamic, type.FullName));
612 if (assembly == null)
613 assembly = type.Assembly;
614 else if (type.Assembly != assembly) {
615 throw new ArgumentException(Res.GetString(Res.XmlPregenOrphanType, type.FullName, assembly.Location), "types");
618 return TempAssembly.GenerateAssembly(mappings, types, null, null, XmlSerializerCompilerParameters.Create(parameters, /* needTempDirAccess = */ true), assembly, new Hashtable());
621 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.FromTypes"]/*' />
622 /// <devdoc>
623 /// <para>[To be supplied.]</para>
624 /// </devdoc>
625 public static XmlSerializer[] FromTypes(Type[] types) {
626 if (types == null)
627 return new XmlSerializer[0];
628 XmlReflectionImporter importer = new XmlReflectionImporter();
629 XmlTypeMapping[] mappings = new XmlTypeMapping[types.Length];
630 for (int i = 0; i < types.Length; i++) {
631 mappings[i] = importer.ImportTypeMapping(types[i]);
633 return FromMappings(mappings);
637 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.GetXmlSerializerAssemblyName"]/*' />
638 /// <devdoc>
639 /// <para>[To be supplied.]</para>
640 /// </devdoc>
641 [PermissionSet(SecurityAction.Demand, Name="FullTrust")]
642 public static string GetXmlSerializerAssemblyName(Type type) {
643 return GetXmlSerializerAssemblyName(type, null);
646 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.GetXmlSerializerAssemblyName"]/*' />
647 /// <devdoc>
648 /// <para>[To be supplied.]</para>
649 /// </devdoc>
650 [PermissionSet(SecurityAction.Demand, Name="FullTrust")]
651 public static string GetXmlSerializerAssemblyName(Type type, string defaultNamespace) {
652 if (type == null) {
653 throw new ArgumentNullException("type");
655 return Compiler.GetTempAssemblyName(type.Assembly.GetName(), defaultNamespace);
658 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.UnknownNode"]/*' />
659 /// <devdoc>
660 /// <para>[To be supplied.]</para>
661 /// </devdoc>
662 public event XmlNodeEventHandler UnknownNode {
663 add {
664 events.OnUnknownNode += value;
666 remove {
667 events.OnUnknownNode -= value;
671 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.UnknownAttribute"]/*' />
672 /// <devdoc>
673 /// <para>[To be supplied.]</para>
674 /// </devdoc>
675 public event XmlAttributeEventHandler UnknownAttribute {
676 add {
677 events.OnUnknownAttribute += value;
679 remove {
680 events.OnUnknownAttribute -= value;
684 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.UnknownElement"]/*' />
685 public event XmlElementEventHandler UnknownElement {
686 add {
687 events.OnUnknownElement += value;
689 remove {
690 events.OnUnknownElement -= value;
694 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.UnreferencedObject"]/*' />
695 public event UnreferencedObjectEventHandler UnreferencedObject {
696 add {
697 events.OnUnreferencedObject += value;
699 remove {
700 events.OnUnreferencedObject -= value;
704 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.CreateReader"]/*' />
705 ///<internalonly/>
706 protected virtual XmlSerializationReader CreateReader() {throw new NotImplementedException();}
707 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize4"]/*' />
708 ///<internalonly/>
709 protected virtual object Deserialize(XmlSerializationReader reader){throw new NotImplementedException();}
710 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.CreateWriter"]/*' />
711 ///<internalonly/>
712 protected virtual XmlSerializationWriter CreateWriter(){throw new NotImplementedException();}
713 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize7"]/*' />
714 ///<internalonly/>
715 protected virtual void Serialize(object o, XmlSerializationWriter writer){throw new NotImplementedException();}
717 internal void SetTempAssembly(TempAssembly tempAssembly, XmlMapping mapping) {
718 this.tempAssembly = tempAssembly;
719 this.mapping = mapping;
720 this.typedSerializer = true;
723 static XmlTypeMapping GetKnownMapping(Type type, string ns) {
724 if (ns != null && ns != string.Empty)
725 return null;
726 TypeDesc typeDesc = (TypeDesc)TypeScope.PrimtiveTypes[type];
727 if (typeDesc == null)
728 return null;
729 ElementAccessor element = new ElementAccessor();
730 element.Name = typeDesc.DataType.Name;
731 XmlTypeMapping mapping = new XmlTypeMapping(null, element);
732 mapping.SetKeyInternal(XmlMapping.GenerateKey(type, null, null));
733 return mapping;
736 void SerializePrimitive(XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces) {
737 XmlSerializationPrimitiveWriter writer = new XmlSerializationPrimitiveWriter();
738 writer.Init(xmlWriter, namespaces, null, null, null);
739 switch (Type.GetTypeCode(primitiveType)) {
740 case TypeCode.String:
741 writer.Write_string(o);
742 break;
743 case TypeCode.Int32:
744 writer.Write_int(o);
745 break;
746 case TypeCode.Boolean:
747 writer.Write_boolean(o);
748 break;
749 case TypeCode.Int16:
750 writer.Write_short(o);
751 break;
752 case TypeCode.Int64:
753 writer.Write_long(o);
754 break;
755 case TypeCode.Single:
756 writer.Write_float(o);
757 break;
758 case TypeCode.Double:
759 writer.Write_double(o);
760 break;
761 case TypeCode.Decimal:
762 writer.Write_decimal(o);
763 break;
764 case TypeCode.DateTime:
765 writer.Write_dateTime(o);
766 break;
767 case TypeCode.Char:
768 writer.Write_char(o);
769 break;
770 case TypeCode.Byte:
771 writer.Write_unsignedByte(o);
772 break;
773 case TypeCode.SByte:
774 writer.Write_byte(o);
775 break;
776 case TypeCode.UInt16:
777 writer.Write_unsignedShort(o);
778 break;
779 case TypeCode.UInt32:
780 writer.Write_unsignedInt(o);
781 break;
782 case TypeCode.UInt64:
783 writer.Write_unsignedLong(o);
784 break;
786 default:
787 if (primitiveType == typeof(XmlQualifiedName)) {
788 writer.Write_QName(o);
790 else if (primitiveType == typeof(byte[])) {
791 writer.Write_base64Binary(o);
793 else if (primitiveType == typeof(Guid)) {
794 writer.Write_guid(o);
796 else if (primitiveType == typeof(TimeSpan)) {
797 writer.Write_TimeSpan(o);
799 else {
800 throw new InvalidOperationException(Res.GetString(Res.XmlUnxpectedType, primitiveType.FullName));
802 break;
806 object DeserializePrimitive(XmlReader xmlReader, XmlDeserializationEvents events) {
807 XmlSerializationPrimitiveReader reader = new XmlSerializationPrimitiveReader();
808 reader.Init(xmlReader, events, null, null);
809 object o;
810 switch (Type.GetTypeCode(primitiveType)) {
811 case TypeCode.String:
812 o = reader.Read_string();
813 break;
814 case TypeCode.Int32:
815 o = reader.Read_int();
816 break;
817 case TypeCode.Boolean:
818 o = reader.Read_boolean();
819 break;
820 case TypeCode.Int16:
821 o = reader.Read_short();
822 break;
823 case TypeCode.Int64:
824 o = reader.Read_long();
825 break;
826 case TypeCode.Single:
827 o = reader.Read_float();
828 break;
829 case TypeCode.Double:
830 o = reader.Read_double();
831 break;
832 case TypeCode.Decimal:
833 o = reader.Read_decimal();
834 break;
835 case TypeCode.DateTime:
836 o = reader.Read_dateTime();
837 break;
838 case TypeCode.Char:
839 o = reader.Read_char();
840 break;
841 case TypeCode.Byte:
842 o = reader.Read_unsignedByte();
843 break;
844 case TypeCode.SByte:
845 o = reader.Read_byte();
846 break;
847 case TypeCode.UInt16:
848 o = reader.Read_unsignedShort();
849 break;
850 case TypeCode.UInt32:
851 o = reader.Read_unsignedInt();
852 break;
853 case TypeCode.UInt64:
854 o = reader.Read_unsignedLong();
855 break;
857 default:
858 if (primitiveType == typeof(XmlQualifiedName)) {
859 o = reader.Read_QName();
861 else if (primitiveType == typeof(byte[])) {
862 o = reader.Read_base64Binary();
864 else if (primitiveType == typeof(Guid)) {
865 o = reader.Read_guid();
867 else if (primitiveType == typeof(TimeSpan) && LocalAppContextSwitches.EnableTimeSpanSerialization) {
868 o = reader.Read_TimeSpan();
870 else {
871 throw new InvalidOperationException(Res.GetString(Res.XmlUnxpectedType, primitiveType.FullName));
873 break;
875 return o;
878 class XmlSerializerMappingKey {
879 public XmlMapping Mapping;
880 public XmlSerializerMappingKey(XmlMapping mapping) {
881 this.Mapping = mapping;
884 public override bool Equals(object obj) {
885 XmlSerializerMappingKey other = obj as XmlSerializerMappingKey;
886 if (other == null)
887 return false;
889 if (this.Mapping.Key != other.Mapping.Key)
890 return false;
892 if (this.Mapping.ElementName != other.Mapping.ElementName)
893 return false;
895 if (this.Mapping.Namespace != other.Mapping.Namespace)
896 return false;
898 if (this.Mapping.IsSoap != other.Mapping.IsSoap)
899 return false;
901 return true;
904 public override int GetHashCode() {
905 int hashCode = this.Mapping.IsSoap ? 0 : 1;
907 if (this.Mapping.Key != null)
908 hashCode ^= this.Mapping.Key.GetHashCode();
910 if (this.Mapping.ElementName != null)
911 hashCode ^= this.Mapping.ElementName.GetHashCode();
913 if (this.Mapping.Namespace != null)
914 hashCode ^= this.Mapping.Namespace.GetHashCode();
916 return hashCode;