2009-09-15 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Tue, 15 Sep 2009 09:34:51 +0000 (09:34 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Tue, 15 Sep 2009 09:34:51 +0000 (09:34 -0000)
* JsonWriter.cs : use Stream as its output directly and avoid
  extraneous preamble output. Fix interop with .NET.

svn path=/trunk/mcs/; revision=141934

mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog
mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonWriter.cs

index 33da805818c7b10a31a311974f718ca92b475f1d..1c4e0003b8d3c167dc7ec242acf77c2c1f43a624 100644 (file)
@@ -1,3 +1,8 @@
+2009-09-15  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * JsonWriter.cs : use Stream as its output directly and avoid
+         extraneous preamble output. Fix interop with .NET.
+
 2009-09-07  Atsushi Enomoto  <atsushi@ximian.com>
 
        * JsonReaderWriterFactory.cs : check null stream (fix test failure).
index e56daf89ec54839c829cb568ce328f84aa896b5d..9a8191898bd34fa740df0e51c6369cf90ca43597 100644 (file)
@@ -46,12 +46,14 @@ namespace System.Runtime.Serialization.Json
                        Boolean,
                }
 
-               StreamWriter output;
+               Stream output;
                bool close_output;
                WriteState state;
                Stack<ElementType> element_kinds = new Stack<ElementType> ();
                Stack<bool> first_content_flags = new Stack<bool> ();
                string attr_name, attr_value, runtime_type;
+               Encoding encoding;
+               byte [] encbuf = new byte [1024];
 
                public JsonWriter (Stream stream, Encoding encoding, bool closeOutput)
                {
@@ -60,8 +62,13 @@ namespace System.Runtime.Serialization.Json
 
                public void SetOutput (Stream stream, Encoding encoding, bool ownsStream)
                {
-                       // null stream and encoding will be rejected by StreamWriter.ctor.
-                       output = new StreamWriter (stream, encoding);
+                       if (stream == null)
+                               throw new ArgumentNullException ("stream");
+                       if (encoding == null)
+                               throw new ArgumentNullException ("encoding");
+                       output = stream;
+                       this.encoding = encoding;
+                       close_output = ownsStream;
                }
 
                void CheckState ()
@@ -190,12 +197,13 @@ namespace System.Runtime.Serialization.Json
                                        first_content_flags.Push (false);
                                }
                                else
-                                       output.Write (',');
+                                       OutputAsciiChar (',');
 
                                if (element_kinds.Peek () != ElementType.Array) {
-                                       output.Write ('"');
-                                       output.Write (localName);
-                                       output.Write ("\":");
+                                       OutputAsciiChar ('"');
+                                       OutputString (localName);
+                                       OutputAsciiChar ('\"');
+                                       OutputAsciiChar (':');
                                }
                        }
 
@@ -217,13 +225,13 @@ namespace System.Runtime.Serialization.Json
                                throw new XmlException ("There is no open element to close");
                        switch (element_kinds.Pop ()) {
                        case ElementType.String:
-                               output.Write ('"');
+                               OutputAsciiChar ('"');
                                break;
                        case ElementType.Array:
-                               output.Write (']');
+                               OutputAsciiChar (']');
                                break;
                        case ElementType.Object:
-                               output.Write ('}');
+                               OutputAsciiChar ('}');
                                break;
                        }
 
@@ -271,12 +279,12 @@ namespace System.Runtime.Serialization.Json
                                case "object":
                                        element_kinds.Pop ();
                                        element_kinds.Push (ElementType.Object);
-                                       output.Write ('{');
+                                       OutputAsciiChar ('{');
                                        break;
                                case "array":
                                        element_kinds.Pop ();
                                        element_kinds.Push (ElementType.Array);
-                                       output.Write ('[');
+                                       OutputAsciiChar ('[');
                                        break;
                                case "number":
                                        element_kinds.Pop ();
@@ -309,14 +317,14 @@ namespace System.Runtime.Serialization.Json
                        }
 
                        if (element_kinds.Peek () == ElementType.String)
-                               output.Write ('"');
+                               OutputAsciiChar ('"');
 
                        first_content_flags.Push (true);
 
                        if (runtime_type != null) {
-                               output.Write ("\"__type\":\"");
-                               output.Write (runtime_type);
-                               output.Write ('\"');
+                               OutputString ("\"__type\":\"");
+                               OutputString (runtime_type);
+                               OutputAsciiChar ('\"');
                                runtime_type = null;
                                first_content_flags.Pop ();
                                first_content_flags.Push (false);
@@ -347,7 +355,7 @@ namespace System.Runtime.Serialization.Json
                                        throw new XmlException (String.Format ("Simple content string is allowed only for string, number and boolean types and not for {0} type", element_kinds.Peek ()));
                                }
 
-                               output.Write (EscapeStringLiteral (text));
+                               OutputString (EscapeStringLiteral (text));
                        }
                }
 
@@ -478,6 +486,20 @@ namespace System.Runtime.Serialization.Json
                        WriteString (text);
                }
 
+               void OutputAsciiChar (char c)
+               {
+                       output.WriteByte ((byte) c);
+               }
+
+               void OutputString (string s)
+               {
+                       int size = encoding.GetByteCount (s);
+                       if (encbuf.Length < size)
+                               encbuf = new byte [size];
+                       size = encoding.GetBytes (s, 0, s.Length, encbuf, 0);
+                       output.Write (encbuf, 0, size);
+               }
+
                #endregion
        }
 }