2 // XmlFormatterSerializer.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
32 using System.Reflection;
33 using System.Runtime.Serialization.Formatters.Binary;
35 using System.Xml.Schema;
37 using QName = System.Xml.XmlQualifiedName;
39 namespace System.Runtime.Serialization
41 internal class XmlFormatterSerializer
43 XmlDictionaryWriter writer;
45 KnownTypeCollection types;
49 IDataContractSurrogate surrogate;
52 ArrayList objects = new ArrayList ();
53 Hashtable references = new Hashtable (); // preserve possibly referenced objects to ids. (new in 3.5 SP1)
55 public static void Serialize (XmlDictionaryWriter writer, object graph,
56 KnownTypeCollection types,
57 bool ignoreUnknown, int maxItems, string root_ns)
59 new XmlFormatterSerializer (writer, types, ignoreUnknown, maxItems, root_ns)
60 .Serialize (graph != null ? graph.GetType () : null, graph);
63 public XmlFormatterSerializer (XmlDictionaryWriter writer,
64 KnownTypeCollection types,
65 bool ignoreUnknown, int maxItems, string root_ns)
69 ignore_unknown = ignoreUnknown;
73 public ArrayList SerializingObjects {
74 get { return objects; }
77 public IDictionary References {
78 get { return references; }
81 public XmlDictionaryWriter Writer {
82 get { return writer; }
85 public void Serialize (Type type, object graph)
88 writer.WriteAttributeString ("nil", XmlSchema.InstanceNamespace, "true");
90 Type actualType = graph.GetType ();
91 if (actualType != type) {
92 QName qname = types.GetXmlName (actualType);
93 string name = qname.Name;
94 string ns = qname.Namespace;
95 if (qname == QName.Empty) {
96 name = XmlConvert.EncodeLocalName (actualType.Name);
97 ns = KnownTypeCollection.DefaultClrNamespaceBase + actualType.Namespace;
98 } else if (qname.Namespace == KnownTypeCollection.MSSimpleNamespace)
99 ns = XmlSchema.Namespace;
100 if (writer.LookupPrefix (ns) == null) // it goes first (extraneous, but it makes att order compatible)
101 writer.WriteXmlnsAttribute (null, ns);
102 writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace);
103 writer.WriteQualifiedName (name, ns);
104 writer.WriteEndAttribute ();
106 QName predef = KnownTypeCollection.GetPredefinedTypeName (actualType);
107 if (predef != QName.Empty)
108 SerializePrimitive (type, graph, predef);
110 SerializeNonPrimitive (type, graph);
114 public void SerializePrimitive (Type type, object graph, QName qname)
116 // writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace);
117 // writer.WriteQualifiedName (qname.Name, qname.Namespace);
118 // writer.WriteEndAttribute ();
119 writer.WriteString (KnownTypeCollection.PredefinedTypeObjectToString (graph));
122 public void WriteStartElement (string rootName, string rootNamespace, string currentNamespace)
124 writer.WriteStartElement (rootName, rootNamespace);
125 if (!string.IsNullOrEmpty (currentNamespace) && currentNamespace != rootNamespace)
126 writer.WriteXmlnsAttribute (null, currentNamespace);
129 public void WriteEndElement ()
131 writer.WriteEndElement ();
134 public void SerializeNonPrimitive (Type type, object graph)
136 Type actualType = graph.GetType ();
138 SerializationMap map = types.FindUserMap (actualType);
140 /* Unknown actual type */
141 types.Add (actualType);
142 map = types.FindUserMap (actualType);
145 map.Serialize (graph, this);