New tests.
[mono.git] / mcs / class / System.ServiceModel.Web / System.Runtime.Serialization.Json / JsonSerializationReader.cs
index 257206ef873957c79bf57275e4ed371fc7168037..87cb0dc1e2648706b139b82b21b369c47bda0bb3 100644 (file)
@@ -71,6 +71,8 @@ namespace System.Runtime.Serialization.Json
                        if (serialized_object_count ++ == serializer.MaxItemsInObjectGraph)
                                throw SerializationError (String.Format ("The object graph exceeded the maximum object count '{0}' specified in the serializer", serializer.MaxItemsInObjectGraph));
 
+                       bool isNull = reader.GetAttribute ("type") == "null";
+
                        switch (Type.GetTypeCode (type)) {
                        case TypeCode.DBNull:
                                string dbn = reader.ReadElementContentAsString ();
@@ -78,7 +80,12 @@ namespace System.Runtime.Serialization.Json
                                        throw new SerializationException (String.Format ("The only expected DBNull value string is '{{}}'. Tha actual input was '{0}'.", dbn));
                                return DBNull.Value;
                        case TypeCode.String:
-                               return reader.ReadElementContentAsString ();
+                               if (isNull) {
+                                       reader.ReadElementContentAsString ();
+                                       return null;
+                               }
+                               else
+                                       return reader.ReadElementContentAsString ();
                        case TypeCode.Single:
                                return reader.ReadElementContentAsFloat ();
                        case TypeCode.Double:
@@ -105,13 +112,24 @@ namespace System.Runtime.Serialization.Json
                                        return Convert.ChangeType (l, type, null);
                        case TypeCode.Boolean:
                                return reader.ReadElementContentAsBoolean ();
+                       case TypeCode.DateTime:
+                               // it does not use ReadElementContentAsDateTime(). Different string format.
+                               var s = reader.ReadElementContentAsString ();
+                               if (s.Length < 2 || !s.StartsWith ("/Date(", StringComparison.Ordinal) || !s.EndsWith (")/", StringComparison.Ordinal))
+                                       throw new XmlException ("Invalid JSON DateTime format. The value format should be '/Date(UnixTime)/'");
+                               return new DateTime (1970, 1, 1).AddMilliseconds (long.Parse (s.Substring (6, s.Length - 8)));
                        default:
                                if (type == typeof (Guid)) {
                                        return new Guid (reader.ReadElementContentAsString ());
                                } else if (type == typeof (Uri)) {
-                                       return new Uri (reader.ReadElementContentAsString ());
+                                       if (isNull) {
+                                               reader.ReadElementContentAsString ();
+                                               return null;
+                                       }
+                                       else
+                                               return new Uri (reader.ReadElementContentAsString ());
                                } else if (type == typeof (XmlQualifiedName)) {
-                                       string s = reader.ReadElementContentAsString ();
+                                       s = reader.ReadElementContentAsString ();
                                        int idx = s.IndexOf (':');
                                        return idx < 0 ? new XmlQualifiedName (s) : new XmlQualifiedName (s.Substring (0, idx), s.Substring (idx + 1));
                                } else if (type != typeof (object)) {
@@ -241,6 +259,8 @@ namespace System.Runtime.Serialization.Json
                {
                        reader.ReadStartElement ();
                        object ret;
+                       if (collectionType.IsInterface)
+                               collectionType = typeof (List<>).MakeGenericType (elementType);
                        if (typeof (IList).IsAssignableFrom (collectionType)) {
 #if NET_2_1
                                Type listType = collectionType.IsArray ? typeof (List<>).MakeGenericType (elementType) : null;
@@ -256,13 +276,25 @@ namespace System.Runtime.Serialization.Json
                                        c.Add (elem);
                                }
 #if NET_2_1
-                               ret = c;
+                               if (collectionType.IsArray) {
+                                       Array array = Array.CreateInstance (elementType, c.Count);
+                                       c.CopyTo (array, 0);
+                                       ret = array;
+                               }
+                               else
+                                       ret = c;
 #else
                                ret = collectionType.IsArray ? ((ArrayList) c).ToArray (elementType) : c;
 #endif
                        } else {
                                object c = Activator.CreateInstance (collectionType);
                                MethodInfo add = collectionType.GetMethod ("Add", new Type [] {elementType});
+                               if (add == null) {
+                                       var icoll = typeof (ICollection<>).MakeGenericType (elementType);
+                                       if (icoll.IsAssignableFrom (c.GetType ()))
+                                               add = icoll.GetMethod ("Add");
+                               }
+                               
                                for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) {
                                        if (!reader.IsStartElement ("item"))
                                                throw SerializationError (String.Format ("Expected element 'item', but found '{0}' in namespace '{1}'", reader.LocalName, reader.NamespaceURI));