Merge pull request #268 from pcc/menudeactivate
[mono.git] / mcs / class / System.ServiceModel.Web / System.Runtime.Serialization.Json / DataContractJsonSerializer.cs
1 //
2 // DataContractJsonSerializer.cs
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //
7 // Copyright (C) 2007-2008 Novell, Inc (http://www.novell.com)
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Collections.ObjectModel;
32 using System.Globalization;
33 using System.IO;
34 using System.Linq;
35 using System.Reflection;
36 using System.Text;
37 using System.Xml;
38
39 namespace System.Runtime.Serialization.Json
40 {
41         public sealed class DataContractJsonSerializer : XmlObjectSerializer
42         {
43                 const string default_root_name = "root";
44
45                 #region lengthy constructor list
46
47                 public DataContractJsonSerializer (Type type)
48                         : this (type, Type.EmptyTypes)
49                 {
50                 }
51
52                 public DataContractJsonSerializer (Type type, IEnumerable<Type> knownTypes)
53                         : this (type, default_root_name, knownTypes)
54                 {
55                 }
56
57                 public DataContractJsonSerializer (Type type, string rootName)
58                         : this (type, rootName, Type.EmptyTypes)
59                 {
60                 }
61
62                 public DataContractJsonSerializer (Type type, XmlDictionaryString rootName)
63                         : this (type, rootName != null ? rootName.Value : default_root_name, Type.EmptyTypes)
64                 {
65                 }
66
67                 public DataContractJsonSerializer (Type type, string rootName, IEnumerable<Type> knownTypes)
68                         : this (type, rootName, knownTypes, int.MaxValue, false, false)
69                 {
70                 }
71
72                 public DataContractJsonSerializer (Type type, XmlDictionaryString rootName, IEnumerable<Type> knownTypes)
73                         : this (type, rootName != null ? rootName.Value : default_root_name, knownTypes)
74                 {
75                 }
76
77                 DataContractJsonSerializer(Type type, string rootName, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool alwaysEmitTypeInformation)
78                 {
79                         if (type == null)
80                                 throw new ArgumentNullException ("type");
81                         if (rootName == null)
82                                 throw new ArgumentNullException ("rootName");
83                         if (maxItemsInObjectGraph < 0)
84                                 throw new ArgumentOutOfRangeException ("maxItemsInObjectGraph");
85
86                         this.type = type;
87                         known_types = new ReadOnlyCollection<Type> (knownTypes != null ? knownTypes.ToArray () : Type.EmptyTypes);
88                         root = rootName;
89                         max_items = maxItemsInObjectGraph;
90                         ignore_extension = ignoreExtensionDataObject;
91                         always_emit_type = alwaysEmitTypeInformation;
92                 }
93
94                 public DataContractJsonSerializer (Type type, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation)
95             : this (type, default_root_name, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, alwaysEmitTypeInformation)
96                 {
97         }
98
99                 public DataContractJsonSerializer (Type type, string rootName, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation)
100                         : this (type, rootName, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, alwaysEmitTypeInformation)
101                 {
102                         surrogate = dataContractSurrogate;
103                 }
104
105                 public DataContractJsonSerializer (Type type, XmlDictionaryString rootName, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation)
106                         : this (type, rootName != null ? rootName.Value : default_root_name, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, dataContractSurrogate, alwaysEmitTypeInformation)
107                 {
108                 }
109
110 #if NET_4_5
111                 public DataContractJsonSerializer (Type type, DataContractJsonSerializerSettings settings)
112                         : this (type, settings.RootName, settings.KnownTypes, settings.MaxItemsInObjectGraph, settings.IgnoreExtensionDataObject,
113                                 settings.DataContractSurrogate, false)
114                 {
115                 }
116 #endif
117
118         #endregion
119
120         Type type;
121                 string root;
122                 ReadOnlyCollection<Type> known_types;
123                 int max_items;
124                 bool ignore_extension;
125                 bool always_emit_type;
126                 IDataContractSurrogate surrogate;
127
128                 [MonoTODO]
129                 public IDataContractSurrogate DataContractSurrogate {
130                         get { return surrogate; }
131                 }
132
133                 [MonoTODO]
134                 public bool IgnoreExtensionDataObject {
135                         get { return ignore_extension; }
136                 }
137
138                 [MonoTODO]
139                 public ReadOnlyCollection<Type> KnownTypes {
140                         get { return known_types; }
141                 }
142
143                 public int MaxItemsInObjectGraph {
144                         get { return max_items; }
145                 }
146
147                 public override bool IsStartObject (XmlReader reader)
148                 {
149                         if (reader == null)
150                                 throw new ArgumentNullException ("reader");
151                         reader.MoveToContent ();
152                         return reader.IsStartElement (root, String.Empty);
153                 }
154
155                 public override bool IsStartObject (XmlDictionaryReader reader)
156                 {
157                         return IsStartObject ((XmlReader) reader);
158                 }
159
160                 public override object ReadObject (Stream stream)
161                 {
162 #if NET_2_1
163                         var r = (JsonReader) JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max);
164                         r.LameSilverlightLiteralParser = true;
165                         return ReadObject(r);
166 #else
167                         return ReadObject (JsonReaderWriterFactory.CreateJsonReader (stream, new XmlDictionaryReaderQuotas ()));
168 #endif
169                 }
170
171                 public override object ReadObject (XmlDictionaryReader reader)
172                 {
173                         return ReadObject (reader, true);
174                 }
175
176                 public override object ReadObject (XmlReader reader)
177                 {
178                         return ReadObject (reader, true);
179                 }
180
181                 public override object ReadObject (XmlDictionaryReader reader, bool verifyObjectName)
182                 {
183                         return ReadObject ((XmlReader) reader, verifyObjectName);
184                 }
185
186                 public override object ReadObject (XmlReader reader, bool verifyObjectName)
187                 {
188                         if (reader == null)
189                                 throw new ArgumentNullException ("reader");
190                         try {
191                                 if (verifyObjectName && !IsStartObject (reader))
192                                         throw new SerializationException (String.Format ("Expected element was '{0}', but the actual input element was '{1}' in namespace '{2}'", root, reader.LocalName, reader.NamespaceURI));
193
194                                 return new JsonSerializationReader (this, reader, type, verifyObjectName).ReadRoot ();
195                         } catch (SerializationException) {
196                                 throw;
197                         } catch (Exception ex) {
198                                 throw new SerializationException ("Deserialization has failed", ex);
199                         }
200                 }
201
202                 public override void WriteObject (Stream stream, object graph)
203                 {
204                         using (var xw = JsonReaderWriterFactory.CreateJsonWriter (stream))
205                                 WriteObject (xw, graph);
206                 }
207
208                 public override void WriteObject (XmlWriter writer, object graph)
209                 {
210                         try {
211                                 WriteStartObject (writer, graph);
212                                 WriteObjectContent (writer, graph);
213                                 WriteEndObject (writer);
214                         } catch (NotImplementedException) {
215                                 throw;
216                         } catch (InvalidDataContractException) {
217                                 throw;
218                         } catch (Exception ex) {
219                                 throw new SerializationException (String.Format ("There was an error during serialization for object of type {0}", graph != null ? graph.GetType () : null), ex);
220                         }
221                 }
222
223                 public override void WriteObject (XmlDictionaryWriter writer, object graph)
224                 {
225                         WriteObject ((XmlWriter) writer, graph);
226                 }
227
228                 public override void WriteStartObject (XmlDictionaryWriter writer, object graph)
229                 {
230                         WriteStartObject ((XmlWriter) writer, graph);
231                 }
232
233                 public override void WriteStartObject (XmlWriter writer, object graph)
234                 {
235                         if (writer == null)
236                                 throw new ArgumentNullException ("writer");
237                         writer.WriteStartElement (root);
238                 }
239
240                 public override void WriteObjectContent (XmlDictionaryWriter writer, object graph)
241                 {
242                         WriteObjectContent ((XmlWriter) writer, graph);
243                 }
244
245                 public override void WriteObjectContent (XmlWriter writer, object graph)
246                 {
247                         new JsonSerializationWriter (this, writer, type, always_emit_type).WriteObjectContent (graph, true, false);
248                 }
249
250                 public override void WriteEndObject (XmlDictionaryWriter writer)
251                 {
252                         WriteEndObject ((XmlWriter) writer);
253                 }
254
255                 public override void WriteEndObject (XmlWriter writer)
256                 {
257                         if (writer == null)
258                                 throw new ArgumentNullException ("writer");
259                         writer.WriteEndElement ();
260                 }
261
262 #if NET_4_5
263                 [MonoTODO]
264                 public DateTimeFormat DateTimeFormat {
265                         get { throw new NotImplementedException (); }
266                 }
267
268                 [MonoTODO]
269                 public EmitTypeInformation EmitTypeInformation {
270                         get { throw new NotImplementedException (); }
271                 }
272
273                 [MonoTODO]
274                 public bool SerializeReadOnlyTypes {
275                         get { throw new NotImplementedException (); }
276                 }
277
278                 [MonoTODO]
279                 public bool UseSimpleDictionaryFormat {
280                         get { throw new NotImplementedException (); }
281                 }
282 #endif
283
284         }
285 }