Merge pull request #2819 from BrzVlad/fix-major-log
[mono.git] / mcs / class / System.Web.Extensions / System.Web.Script.Serialization / JsonDeserializer.cs
index 634d6e867e642f6afd7dc430bedd73184f3da46e..29e6cfb92b86bd69a4e665ccb7ab5a94d7cb4732 100644 (file)
@@ -2,9 +2,10 @@
 // JsonDeserializer.cs
 //
 // Author:
-//   Marek Habersack <mhabersack@novell.com>
+//   Marek Habersack <grendel@twistedcode.net>
 //
 // (C) 2008 Novell, Inc.  http://novell.com/
+// Copyright 2011, Xamarin, Inc (http://xamarin.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 // Code is based on JSON_checker (http://www.json.org/JSON_checker/) and JSON_parser
-// (http://fara.cs.uni-potsdam.de/~jsg/json_parser/) C sources. License for the original code
-// follows:
-
-#region Original License
-/*
-Copyright (c) 2005 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-#endregion
+// (http://fara.cs.uni-potsdam.de/~jsg/json_parser/) C sources.
 
 using System;
 using System.Collections;
@@ -248,11 +222,11 @@ namespace System.Web.Script.Serialization
                        /*start    GO*/ {GO,GO,OS,__,AB,__,__,__,SB,__,__,PX,MX,__,ZX,IX,__,__,__,__,__,FA,__,__,__,__,TR,__,__,__,__,__,I1,__,__,V1},
                        /*ok       OK*/ {OK,OK,__,OE,__,AE,__,CM,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                        /*object   OB*/ {OB,OB,__,EO,__,__,__,__,SB,__,__,__,KB,__,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,__,KB,KB,KB,KB},
-                       /*key      KE*/ {KE,KE,__,__,__,__,__,__,SB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
+                       /*key      KE*/ {KE,KE,__,__,__,__,__,__,SB,__,__,__,KB,__,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,KB,__,KB,KB,KB,KB},
                        /*colon    CO*/ {CO,CO,__,__,__,__,CA,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                        /*value    VA*/ {VA,VA,OS,__,AB,__,__,__,SB,__,__,PX,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__,I1,__,__,V1},
                        /*array    AR*/ {AR,AR,OS,__,AB,AE,__,__,SB,__,__,PX,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__,I1,__,__,V1},
-                       /*string   ST*/ {ST,__,ST,ST,ST,ST,ST,ST,SE,EX,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST},
+                       /*string   ST*/ {ST,ST,ST,ST,ST,ST,ST,ST,SE,EX,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST},
                        /*escape   ES*/ {__,__,__,__,__,__,__,__,ST,ST,ST,__,__,__,__,__,__,ST,__,__,__,ST,__,ST,ST,__,ST,U1,__,__,__,__,__,__,__,__},
                        /*u1       U1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__,__,__,__,__,__},
                        /*u2       U2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__,__,__,__,__,__},
@@ -277,8 +251,8 @@ namespace System.Web.Script.Serialization
                        /*null     N3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__,__,__},
                        /*_.       FX*/ {OK,OK,__,OE,__,AE,__,CM,__,__,__,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__,__,__,__,__},
                        /*inval.   IV*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
-                       /*unq.key  UK*/ {__,UI,__,__,__,__,UE,__,__,__,__,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,__,UK,UK,UK,UK},
-                       /*unq.ign. UI*/ {__,UI,__,__,__,__,UE,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
+                       /*unq.key  UK*/ {UI,UI,__,__,__,__,UE,__,__,__,__,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,UK,__,UK,UK,UK,UK},
+                       /*unq.ign. UI*/ {UI,UI,__,__,__,__,UE,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                        /*i1       I1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,I2,__,__,__,__,__,__,__,__,__,__,__,__},
                        /*i2       I2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,I3,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                        /*i3       I3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,I4,__,__},
@@ -302,7 +276,6 @@ namespace System.Web.Script.Serialization
                JsonType jsonType;
                
                bool escaped;
-               bool negated;
                int state;
                Stack <string> currentKey;
                StringBuilder buffer;
@@ -326,7 +299,7 @@ namespace System.Web.Script.Serialization
                {
                        if (input == null)
                                throw new ArgumentNullException ("input");
-                       
+
                        return Deserialize (new StringReader (input));
                }
                
@@ -367,11 +340,10 @@ namespace System.Web.Script.Serialization
                                throw new InvalidOperationException ("JSON syntax error.");
 
                        object ret = PopObject ();
-//                     Console.WriteLine ("Returning: {0}", ret);
-//                     DumpObject (String.Empty, ret);
                        return ret;
                }
 
+#if DEBUG
                void DumpObject (string indent, object obj)
                {
                        if (obj is Dictionary <string, object>) {
@@ -391,6 +363,7 @@ namespace System.Web.Script.Serialization
                        else
                                Console.WriteLine ("null");
                }
+#endif
                
                void DecodeUnicodeChar ()
                {
@@ -405,7 +378,6 @@ namespace System.Web.Script.Serialization
 
                string GetModeMessage (JsonMode expectedMode)
                {
-//                     Console.WriteLine ("{0}.GetModeMessage ({1})", this, expectedMode);
                        switch (expectedMode) {
                                case JsonMode.ARRAY:
                                        return "Invalid array passed in, ',' or ']' expected (" + currentPosition + ")";
@@ -483,8 +455,6 @@ namespace System.Web.Script.Serialization
 
                bool ParseBuffer (out object result)
                {
-//                     Console.WriteLine ("{0}.ParseBuffer ()", this);
-//                     Console.WriteLine ("\ttype: {0}", jsonType);
                        result = null;
                        
                        if (jsonType == JsonType.NONE) {
@@ -503,43 +473,43 @@ namespace System.Web.Script.Serialization
                                case JsonType.INTEGER:
                                        /* MS AJAX.NET JSON parser promotes big integers to double */
                                        
-                                       if (Int32.TryParse (s, out intValue))
+                                       if (Int32.TryParse (s, NumberStyles.Integer, CultureInfo.InvariantCulture, out intValue))
                                                result = intValue;
-                                       else if (Int64.TryParse (s, out longValue))
+                                       else if (Int64.TryParse (s, NumberStyles.Integer, CultureInfo.InvariantCulture, out longValue))
                                                result = longValue;
-                                       else if (Decimal.TryParse (s, out decimalValue))
+                                       else if (Decimal.TryParse (s, NumberStyles.Integer, CultureInfo.InvariantCulture, out decimalValue))
                                                result = decimalValue;
-                                       else if (Double.TryParse (s, out doubleValue))
+                                       else if (Double.TryParse (s, NumberStyles.Integer, CultureInfo.InvariantCulture, out doubleValue))
                                                result = doubleValue;
                                        else
                                                converted = false;
                                        break;
 
                                case JsonType.FLOAT:
-                                       if (Decimal.TryParse (s, out decimalValue))
+                                       if (Decimal.TryParse (s, NumberStyles.Float, CultureInfo.InvariantCulture, out decimalValue))
                                                result = decimalValue;
-                                       else if (Double.TryParse (s, out doubleValue))
+                                       else if (Double.TryParse (s, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue))
                                                result = doubleValue;
                                        else
                                                converted = false;
                                        break;
 
                                case JsonType.TRUE:
-                                       if (String.Compare (s, "true", StringComparison.Ordinal) == 0)
+                                       if (String.Compare (s.Trim (), "true", StringComparison.Ordinal) == 0)
                                                result = true;
                                        else
                                                converted = false;
                                        break;
 
                                case JsonType.FALSE:
-                                       if (String.Compare (s, "false", StringComparison.Ordinal) == 0)
+                                       if (String.Compare (s.Trim (), "false", StringComparison.Ordinal) == 0)
                                                result = false;
                                        else
                                                converted = false;
                                        break;
 
                                case JsonType.NULL:
-                                       if (String.Compare (s, "null", StringComparison.Ordinal) != 0)
+                                       if (String.Compare (s.Trim (), "null", StringComparison.Ordinal) != 0)
                                                converted = false;
                                        break;
 
@@ -565,7 +535,6 @@ namespace System.Web.Script.Serialization
                
                bool ProcessCharacter (char ch)
                {
-//                     Console.WriteLine ("{0}.ProcessCharacter ('{1}')", this, ch);
                        int next_class, next_state;
 
                        if (ch >= 128)
@@ -576,7 +545,6 @@ namespace System.Web.Script.Serialization
                                        return false;
                        }
 
-//                     Console.WriteLine ("\tnext_class == {0:x} ({0})", next_class);
                        if (escaped) {
                                escaped = false;
                                RemoveLastCharFromBuffer ();
@@ -611,9 +579,7 @@ namespace System.Web.Script.Serialization
                        } else if (jsonType != JsonType.NONE || !(next_class == C_SPACE || next_class == C_WHITE))
                                buffer.Append (ch);
 
-//                     Console.WriteLine ("\tstate == {0:x} ({0})", state);
                        next_state = state_transition_table [state, next_class];
-//                     Console.WriteLine ("\tnext_state == {0:x} ({0})", next_state);
                        if (next_state >= 0) {
                                state = next_state;
                                return true;
@@ -731,10 +697,8 @@ namespace System.Web.Script.Serialization
                                                StoreValue (result);
                                        PopMode (JsonMode.ARRAY);
                                        result = PopObject (true);
-                                       if (result != null) {
-//                                             Console.WriteLine ("result: {0}", result);
+                                       if (result != null)
                                                StoreValue (result);
-                                       }
                                        
                                        jsonType = JsonType.NONE;
                                        state = OK;
@@ -797,7 +761,7 @@ namespace System.Web.Script.Serialization
 
                                        // With MS.AJAX, a comma resets the recursion depth
                                        recursionDepth = 0;
-                                       
+
                                        bool doStore = ParseBuffer (out result);
                                        switch (PeekMode ()) {
                                                case JsonMode.OBJECT:
@@ -881,7 +845,6 @@ namespace System.Web.Script.Serialization
 
                void StoreKey (object o)
                {
-//                     Console.WriteLine ("{0}.StoreKey ({1})", this, o);
                        string key = o as string;
                        if (key != null)
                                key = key.Trim ();
@@ -900,7 +863,6 @@ namespace System.Web.Script.Serialization
 
                void StoreValue (object o)
                {
-//                     Console.WriteLine ("{0}.StoreValue ({1})", this, o);
                        Dictionary <string, object> dict = PeekObject () as Dictionary <string, object>;
                        if (dict == null) {
                                ArrayList arr = PeekObject () as ArrayList;
@@ -916,7 +878,6 @@ namespace System.Web.Script.Serialization
                        else
                                key = currentKey.Pop ();
 
-//                     Console.WriteLine ("\tkey == {0}", key);
                        if (String.IsNullOrEmpty (key))
                                throw new InvalidOperationException ("Internal error: object is a dictionary, but no key present.");