2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.Json / System.Json / JsonValue.cs
blob7b7d9a3717d30d74c66f7a701800716182f831d6
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.IO;
5 using System.Linq;
6 using System.Runtime.Serialization.Json;
7 using System.Text;
9 using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>;
12 namespace System.Json
14 public abstract class JsonValue : IEnumerable
16 public static JsonValue Load (Stream stream)
18 if (stream == null)
19 throw new ArgumentNullException ("stream");
20 return Load (new JavaScriptObjectDeserializer.BufferedStreamReader (stream));
23 public static JsonValue Load (TextReader textReader)
25 if (textReader == null)
26 throw new ArgumentNullException ("textReader");
28 var ret = new JavaScriptObjectDeserializer (textReader.ReadToEnd (), true).BasicDeserialize ();
30 return ToJsonValue (ret);
33 static IEnumerable<KeyValuePair<string,JsonValue>> ToJsonPairEnumerable (IEnumerable<KeyValuePair<string,object>> kvpc)
35 foreach (var kvp in kvpc)
36 yield return new KeyValuePair<string,JsonValue> (kvp.Key, ToJsonValue (kvp.Value));
39 static IEnumerable<JsonValue> ToJsonValueEnumerable (IEnumerable<object> arr)
41 foreach (var obj in arr)
42 yield return ToJsonValue (obj);
45 static JsonValue ToJsonValue (object ret)
47 if (ret == null)
48 return null;
49 var kvpc = ret as IEnumerable<KeyValuePair<string,object>>;
50 if (kvpc != null)
51 return new JsonObject (ToJsonPairEnumerable (kvpc));
52 var arr = ret as IEnumerable<object>;
53 if (arr != null)
54 return new JsonArray (ToJsonValueEnumerable (arr));
56 if (ret is bool)
57 return new JsonPrimitive ((bool) ret);
58 if (ret is byte)
59 return new JsonPrimitive ((byte) ret);
60 if (ret is char)
61 return new JsonPrimitive ((char) ret);
62 if (ret is decimal)
63 return new JsonPrimitive ((decimal) ret);
64 if (ret is double)
65 return new JsonPrimitive ((double) ret);
66 if (ret is float)
67 return new JsonPrimitive ((float) ret);
68 if (ret is int)
69 return new JsonPrimitive ((int) ret);
70 if (ret is long)
71 return new JsonPrimitive ((long) ret);
72 if (ret is sbyte)
73 return new JsonPrimitive ((sbyte) ret);
74 if (ret is short)
75 return new JsonPrimitive ((short) ret);
76 if (ret is string)
77 return new JsonPrimitive ((string) ret);
78 if (ret is uint)
79 return new JsonPrimitive ((uint) ret);
80 if (ret is ulong)
81 return new JsonPrimitive ((ulong) ret);
82 if (ret is ushort)
83 return new JsonPrimitive ((ushort) ret);
84 if (ret is DateTime)
85 return new JsonPrimitive ((DateTime) ret);
86 if (ret is DateTimeOffset)
87 return new JsonPrimitive ((DateTimeOffset) ret);
88 if (ret is Guid)
89 return new JsonPrimitive ((Guid) ret);
90 if (ret is TimeSpan)
91 return new JsonPrimitive ((TimeSpan) ret);
92 if (ret is Uri)
93 return new JsonPrimitive ((Uri) ret);
94 throw new NotSupportedException (String.Format ("Unexpected parser return type: {0}", ret.GetType ()));
97 public static JsonValue Parse (string jsonString)
99 if (jsonString == null)
100 throw new ArgumentNullException ("jsonString");
101 return Load (new StringReader (jsonString));
104 public virtual int Count {
105 get { throw new InvalidOperationException (); }
108 public abstract JsonType JsonType { get; }
110 public virtual JsonValue this [int index] {
111 get { throw new InvalidOperationException (); }
112 set { throw new InvalidOperationException (); }
115 public virtual JsonValue this [string key] {
116 get { throw new InvalidOperationException (); }
117 set { throw new InvalidOperationException (); }
120 public virtual bool ContainsKey (string key)
122 throw new InvalidOperationException ();
125 public virtual void Save (Stream stream)
127 if (stream == null)
128 throw new ArgumentNullException ("stream");
129 Save (new StreamWriter (stream));
132 public virtual void Save (TextWriter textWriter)
134 if (textWriter == null)
135 throw new ArgumentNullException ("textWriter");
136 SaveInternal (textWriter);
139 void SaveInternal (TextWriter w)
141 switch (JsonType) {
142 case JsonType.Object:
143 w.Write ('{');
144 bool following = false;
145 foreach (JsonPair pair in ((JsonObject) this)) {
146 if (following)
147 w.Write (", ");
148 w.Write ('\"');
149 w.Write (EscapeString (pair.Key));
150 w.Write ("\": ");
151 pair.Value.SaveInternal (w);
152 following = true;
154 w.Write ('}');
155 break;
156 case JsonType.Array:
157 w.Write ('[');
158 following = false;
159 foreach (JsonValue v in ((JsonArray) this)) {
160 if (following)
161 w.Write (", ");
162 v.SaveInternal (w);
163 following = true;
165 w.Write (']');
166 break;
167 case JsonType.Boolean:
168 w.Write ((bool) this ? "true" : "false");
169 break;
170 case JsonType.String:
171 w.Write ('"');
172 w.Write (EscapeString (((JsonPrimitive) this).GetFormattedString ()));
173 w.Write ('"');
174 break;
175 default:
176 w.Write (((JsonPrimitive) this).GetFormattedString ());
177 break;
181 public override string ToString ()
183 StringWriter sw = new StringWriter ();
184 Save (sw);
185 return sw.ToString ();
188 IEnumerator IEnumerable.GetEnumerator ()
190 throw new InvalidOperationException ();
193 internal string EscapeString (string src)
195 if (src == null)
196 return null;
198 for (int i = 0; i < src.Length; i++)
199 if (src [i] == '"' || src [i] == '\\') {
200 var sb = new StringBuilder ();
201 if (i > 0)
202 sb.Append (src, 0, i);
203 return DoEscapeString (sb, src, i);
205 return src;
208 string DoEscapeString (StringBuilder sb, string src, int cur)
210 int start = cur;
211 for (int i = cur; i < src.Length; i++)
212 if (src [i] == '"' || src [i] == '\\') {
213 sb.Append (src, start, i - start);
214 sb.Append ('\\');
215 sb.Append (src [i++]);
216 start = i;
218 sb.Append (src, start, src.Length - start);
219 return sb.ToString ();
222 // CLI -> JsonValue
224 public static implicit operator JsonValue (bool value)
226 return new JsonPrimitive (value);
229 public static implicit operator JsonValue (byte value)
231 return new JsonPrimitive (value);
234 public static implicit operator JsonValue (char value)
236 return new JsonPrimitive (value);
239 public static implicit operator JsonValue (decimal value)
241 return new JsonPrimitive (value);
244 public static implicit operator JsonValue (double value)
246 return new JsonPrimitive (value);
249 public static implicit operator JsonValue (float value)
251 return new JsonPrimitive (value);
254 public static implicit operator JsonValue (int value)
256 return new JsonPrimitive (value);
259 public static implicit operator JsonValue (long value)
261 return new JsonPrimitive (value);
264 public static implicit operator JsonValue (sbyte value)
266 return new JsonPrimitive (value);
269 public static implicit operator JsonValue (short value)
271 return new JsonPrimitive (value);
274 public static implicit operator JsonValue (string value)
276 return new JsonPrimitive (value);
279 public static implicit operator JsonValue (uint value)
281 return new JsonPrimitive (value);
284 public static implicit operator JsonValue (ulong value)
286 return new JsonPrimitive (value);
289 public static implicit operator JsonValue (ushort value)
291 return new JsonPrimitive (value);
294 public static implicit operator JsonValue (DateTime value)
296 return new JsonPrimitive (value);
299 public static implicit operator JsonValue (DateTimeOffset value)
301 return new JsonPrimitive (value);
304 public static implicit operator JsonValue (Guid value)
306 return new JsonPrimitive (value);
309 public static implicit operator JsonValue (TimeSpan value)
311 return new JsonPrimitive (value);
314 public static implicit operator JsonValue (Uri value)
316 return new JsonPrimitive (value);
319 // JsonValue -> CLI
321 public static implicit operator bool (JsonValue value)
323 if (value == null)
324 throw new ArgumentNullException ("value");
325 return Convert.ToBoolean (((JsonPrimitive) value).Value);
328 public static implicit operator byte (JsonValue value)
330 if (value == null)
331 throw new ArgumentNullException ("value");
332 return Convert.ToByte (((JsonPrimitive) value).Value);
335 public static implicit operator char (JsonValue value)
337 if (value == null)
338 throw new ArgumentNullException ("value");
339 return Convert.ToChar (((JsonPrimitive) value).Value);
342 public static implicit operator decimal (JsonValue value)
344 if (value == null)
345 throw new ArgumentNullException ("value");
346 return Convert.ToDecimal (((JsonPrimitive) value).Value);
349 public static implicit operator double (JsonValue value)
351 if (value == null)
352 throw new ArgumentNullException ("value");
353 return Convert.ToDouble (((JsonPrimitive) value).Value);
356 public static implicit operator float (JsonValue value)
358 if (value == null)
359 throw new ArgumentNullException ("value");
360 return Convert.ToSingle (((JsonPrimitive) value).Value);
363 public static implicit operator int (JsonValue value)
365 if (value == null)
366 throw new ArgumentNullException ("value");
367 return Convert.ToInt32 (((JsonPrimitive) value).Value);
370 public static implicit operator long (JsonValue value)
372 if (value == null)
373 throw new ArgumentNullException ("value");
374 return Convert.ToInt64 (((JsonPrimitive) value).Value);
377 public static implicit operator sbyte (JsonValue value)
379 if (value == null)
380 throw new ArgumentNullException ("value");
381 return Convert.ToSByte (((JsonPrimitive) value).Value);
384 public static implicit operator short (JsonValue value)
386 if (value == null)
387 throw new ArgumentNullException ("value");
388 return Convert.ToInt16 (((JsonPrimitive) value).Value);
391 public static implicit operator string (JsonValue value)
393 if (value == null)
394 return null;
395 return (string) ((JsonPrimitive) value).Value;
398 public static implicit operator uint (JsonValue value)
400 if (value == null)
401 throw new ArgumentNullException ("value");
402 return Convert.ToUInt16 (((JsonPrimitive) value).Value);
405 public static implicit operator ulong (JsonValue value)
407 if (value == null)
408 throw new ArgumentNullException ("value");
409 return Convert.ToUInt64(((JsonPrimitive) value).Value);
412 public static implicit operator ushort (JsonValue value)
414 if (value == null)
415 throw new ArgumentNullException ("value");
416 return Convert.ToUInt16 (((JsonPrimitive) value).Value);
419 public static implicit operator DateTime (JsonValue value)
421 if (value == null)
422 throw new ArgumentNullException ("value");
423 return (DateTime) ((JsonPrimitive) value).Value;
426 public static implicit operator DateTimeOffset (JsonValue value)
428 if (value == null)
429 throw new ArgumentNullException ("value");
430 return (DateTimeOffset) ((JsonPrimitive) value).Value;
433 public static implicit operator TimeSpan (JsonValue value)
435 if (value == null)
436 throw new ArgumentNullException ("value");
437 return (TimeSpan) ((JsonPrimitive) value).Value;
440 public static implicit operator Guid (JsonValue value)
442 if (value == null)
443 throw new ArgumentNullException ("value");
444 return (Guid) ((JsonPrimitive) value).Value;
447 public static implicit operator Uri (JsonValue value)
449 if (value == null)
450 throw new ArgumentNullException ("value");
451 return (Uri) ((JsonPrimitive) value).Value;