Bring back 2.10 based System.Json and move aspnet stack version to System.Json.Microsoft
[mono.git] / mcs / class / System.Json / System.Json / JsonValue.cs
index bfbcc91ee3b7306aff5f2d14482e9cc6d69e8da7..1d16b88e3f40407f1994efc04735c38bc269fada 100644 (file)
@@ -2,6 +2,8 @@ using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.IO;
+using System.Linq;
+using System.Runtime.Serialization.Json;
 using System.Text;
 
 using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>;
@@ -9,20 +11,87 @@ using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.Jso
 
 namespace System.Json
 {
-       public abstract class JsonValue
+       public abstract class JsonValue : IEnumerable
        {
                public static JsonValue Load (Stream stream)
                {
                        if (stream == null)
                                throw new ArgumentNullException ("stream");
-                       return Load (new StreamReader (stream));
+                       return Load (new StreamReader (stream, true));
                }
 
                public static JsonValue Load (TextReader textReader)
                {
                        if (textReader == null)
                                throw new ArgumentNullException ("textReader");
-                       return new JsonReader (textReader).Read ();
+
+                       var ret = new JavaScriptReader (textReader, true).Read ();
+
+                       return ToJsonValue (ret);
+               }
+
+               static IEnumerable<KeyValuePair<string,JsonValue>> ToJsonPairEnumerable (IEnumerable<KeyValuePair<string,object>> kvpc)
+               {
+                       foreach (var kvp in kvpc)
+                               yield return new KeyValuePair<string,JsonValue> (kvp.Key, ToJsonValue (kvp.Value));
+               }
+
+               static IEnumerable<JsonValue> ToJsonValueEnumerable (IEnumerable<object> arr)
+               {
+                       foreach (var obj in arr)
+                               yield return ToJsonValue (obj);
+               }
+
+               static JsonValue ToJsonValue (object ret)
+               {
+                       if (ret == null)
+                               return null;
+                       var kvpc = ret as IEnumerable<KeyValuePair<string,object>>;
+                       if (kvpc != null)
+                               return new JsonObject (ToJsonPairEnumerable (kvpc));
+                       var arr = ret as IEnumerable<object>;
+                       if (arr != null)
+                               return new JsonArray (ToJsonValueEnumerable (arr));
+
+                       if (ret is bool)
+                               return new JsonPrimitive ((bool) ret);
+                       if (ret is byte)
+                               return new JsonPrimitive ((byte) ret);
+                       if (ret is char)
+                               return new JsonPrimitive ((char) ret);
+                       if (ret is decimal)
+                               return new JsonPrimitive ((decimal) ret);
+                       if (ret is double)
+                               return new JsonPrimitive ((double) ret);
+                       if (ret is float)
+                               return new JsonPrimitive ((float) ret);
+                       if (ret is int)
+                               return new JsonPrimitive ((int) ret);
+                       if (ret is long)
+                               return new JsonPrimitive ((long) ret);
+                       if (ret is sbyte)
+                               return new JsonPrimitive ((sbyte) ret);
+                       if (ret is short)
+                               return new JsonPrimitive ((short) ret);
+                       if (ret is string)
+                               return new JsonPrimitive ((string) ret);
+                       if (ret is uint)
+                               return new JsonPrimitive ((uint) ret);
+                       if (ret is ulong)
+                               return new JsonPrimitive ((ulong) ret);
+                       if (ret is ushort)
+                               return new JsonPrimitive ((ushort) ret);
+                       if (ret is DateTime)
+                               return new JsonPrimitive ((DateTime) ret);
+                       if (ret is DateTimeOffset)
+                               return new JsonPrimitive ((DateTimeOffset) ret);
+                       if (ret is Guid)
+                               return new JsonPrimitive ((Guid) ret);
+                       if (ret is TimeSpan)
+                               return new JsonPrimitive ((TimeSpan) ret);
+                       if (ret is Uri)
+                               return new JsonPrimitive ((Uri) ret);
+                       throw new NotSupportedException (String.Format ("Unexpected parser return type: {0}", ret.GetType ()));
                }
 
                public static JsonValue Parse (string jsonString)
@@ -79,15 +148,26 @@ namespace System.Json
                                        w.Write ('\"');
                                        w.Write (EscapeString (pair.Key));
                                        w.Write ("\": ");
-                                       pair.Value.SaveInternal (w);
+                                       if (pair.Value == null)
+                                               w.Write ("null");
+                                       else
+                                               pair.Value.SaveInternal (w);
                                        following = true;
                                }
                                w.Write ('}');
                                break;
                        case JsonType.Array:
                                w.Write ('[');
-                               foreach (JsonValue v in ((JsonArray) this))
-                                       v.SaveInternal (w);
+                               following = false;
+                               foreach (JsonValue v in ((JsonArray) this)) {
+                                       if (following)
+                                               w.Write (", ");
+                                       if (v != null) 
+                                               v.SaveInternal (w);
+                                       else
+                                               w.Write ("null");
+                                       following = true;
+                               }
                                w.Write (']');
                                break;
                        case JsonType.Boolean:
@@ -111,25 +191,37 @@ namespace System.Json
                        return sw.ToString ();
                }
 
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       throw new InvalidOperationException ();
+               }
+
                internal string EscapeString (string src)
                {
+                       if (src == null)
+                               return null;
+
                        for (int i = 0; i < src.Length; i++)
                                if (src [i] == '"' || src [i] == '\\') {
-                                       var sb = new StringBuilder ().Append (src, 0, i - 1);
+                                       var sb = new StringBuilder ();
+                                       if (i > 0)
+                                               sb.Append (src, 0, i);
                                        return DoEscapeString (sb, src, i);
-                       }
+                               }
                        return src;
                }
 
                string DoEscapeString (StringBuilder sb, string src, int cur)
                {
+                       int start = cur;
                        for (int i = cur; i < src.Length; i++)
                                if (src [i] == '"' || src [i] == '\\') {
+                                       sb.Append (src, start, i - start);
                                        sb.Append ('\\');
                                        sb.Append (src [i++]);
-                                       return DoEscapeString (sb, src, i);
+                                       start = i;
                                }
-                       sb.Append (src, cur, src.Length - cur);
+                       sb.Append (src, start, src.Length - start);
                        return sb.ToString ();
                }
 
@@ -236,76 +328,76 @@ namespace System.Json
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (bool) ((JsonPrimitive) value).Value;
+                       return Convert.ToBoolean (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator byte (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (byte) ((JsonPrimitive) value).Value;
+                       return Convert.ToByte (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator char (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (char) ((JsonPrimitive) value).Value;
+                       return Convert.ToChar (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator decimal (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (decimal) ((JsonPrimitive) value).Value;
+                       return Convert.ToDecimal (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator double (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (double) ((JsonPrimitive) value).Value;
+                       return Convert.ToDouble (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator float (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (float) ((JsonPrimitive) value).Value;
+                       return Convert.ToSingle (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator int (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (int) ((JsonPrimitive) value).Value;
+                       return Convert.ToInt32 (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator long (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (long) ((JsonPrimitive) value).Value;
+                       return Convert.ToInt64 (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator sbyte (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (sbyte) ((JsonPrimitive) value).Value;
+                       return Convert.ToSByte (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator short (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (short) ((JsonPrimitive) value).Value;
+                       return Convert.ToInt16 (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator string (JsonValue value)
                {
                        if (value == null)
-                               throw new ArgumentNullException ("value");
+                               return null;
                        return (string) ((JsonPrimitive) value).Value;
                }
 
@@ -313,21 +405,21 @@ namespace System.Json
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (uint) ((JsonPrimitive) value).Value;
+                       return Convert.ToUInt16 (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator ulong (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (ulong) ((JsonPrimitive) value).Value;
+                       return Convert.ToUInt64(((JsonPrimitive) value).Value);
                }
 
                public static implicit operator ushort (JsonValue value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       return (ushort) ((JsonPrimitive) value).Value;
+                       return Convert.ToUInt16 (((JsonPrimitive) value).Value);
                }
 
                public static implicit operator DateTime (JsonValue value)