2009-08-24 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web / HttpWriter.cs
index 5ffa47c7de4381860e501dd0b3426bc90db114e0..f695bccc12239b5e772567b964426698a0dfb11f 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
 using System.IO;
 using System.Text;
 using System.Globalization;
 using System.Runtime.InteropServices;
+using System.Security.Permissions;
        
 namespace System.Web {
        
+       // CAS - no InheritanceDemand here as the class is sealed
+       [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public sealed class HttpWriter : TextWriter {
                HttpResponseStream output_stream;
                HttpResponse response;
                Encoding encoding;
+               byte [] _bytebuffer = new byte [1024];
 
                internal HttpWriter (HttpResponse response)
                {
@@ -48,6 +51,19 @@ namespace System.Web {
                        output_stream = response.output_stream;
                }
 
+               byte [] GetByteBuffer (int length)
+               {
+                       // We will reuse the buffer if its size is < 32K
+                       if (_bytebuffer.Length >= length)
+                               return _bytebuffer;
+
+                       if (length > 32 * 1024)
+                               return new byte [length];
+
+                       _bytebuffer = new byte [length];
+                       return _bytebuffer;
+               }
+
                public override Encoding Encoding {
                        get {
                                return encoding;
@@ -65,6 +81,9 @@ namespace System.Web {
                        }
                }
 
+               internal HttpResponse Response {
+                       get { return response; }
+               }
                //
                // Flush data, and closes socket
                //
@@ -78,9 +97,11 @@ namespace System.Web {
                        output_stream.Flush ();
                }
 
+               char [] chars = new char [1];
                public override void Write (char ch)
                {
-                       Write (new string (ch, 1));
+                       chars [0] = ch;
+                       Write (chars, 0, 1);
                }
 
                public override void Write (object obj)
@@ -93,56 +114,61 @@ namespace System.Web {
                
                public override void Write (string s)
                {
-                       if (s == null)
-                               return;
-                       
-                       byte [] xx = encoding.GetBytes (s);
-
-                       output_stream.Write (xx, 0, xx.Length);
-                       
-                       if (response.buffer)
-                               return;
-
-                       response.Flush ();
+                       if (s != null)
+                               WriteString (s, 0, s.Length);
                }
                
                public override void Write (char [] buffer, int index, int count)
                {
-                       byte [] xx = encoding.GetBytes (buffer, index, count);
-                       output_stream.Write (xx, 0, xx.Length);
-
+                       if (buffer == null || index < 0 || count < 0 || (buffer.Length - index) < count)
+                               throw new ArgumentOutOfRangeException ();
+#if TARGET_JVM
+                       output_stream.Write (buffer, index, count);
+#else
+                       int length = encoding.GetMaxByteCount (count);
+                       byte [] bytebuffer = GetByteBuffer (length);
+                       int realLength = encoding.GetBytes (buffer, index, count, bytebuffer, 0);
+                       output_stream.Write (bytebuffer, 0, realLength);
+#endif
                        if (response.buffer)
                                return;
 
                        response.Flush ();
                }
 
-               static byte [] newline = new byte [2] { 13, 10 };
+               static char [] newline = new char [2] { '\r', '\n' };
                
                public override void WriteLine ()
                {
-                       output_stream.Write (newline, 0, 2);
-                       
-                       if (response.buffer)
-                               return;
-
-                       response.Flush ();
+                       Write (newline, 0, 2);
                }
 
                public void WriteString (string s, int index, int count)
                {
-                       char [] a = s.ToCharArray (index, count);
-
-                       byte [] xx = encoding.GetBytes (a, 0, count);
-                       
-                       output_stream.Write (xx, 0, xx.Length);
+                       if (s == null)
+                               return;
 
+                       if (index < 0 || count < 0 || ((index + count > s.Length)))
+                               throw new ArgumentOutOfRangeException ();
+#if TARGET_JVM
+                       output_stream.Write (s, index, count);
+#else
+                       int length = encoding.GetMaxByteCount (count);
+                       byte [] bytebuffer = GetByteBuffer (length);
+                       int realLength = encoding.GetBytes (s, index, count, bytebuffer, 0);
+                       output_stream.Write (bytebuffer, 0, realLength);
+#endif
                        if (response.buffer)
                                return;
 
                        response.Flush ();
                }
 
+               internal void WriteUTF8Ptr (IntPtr ptr, int length)
+               {
+                       output_stream.WritePtr (ptr, length);
+               }
+
                public void WriteBytes (byte [] buffer, int index, int count)
                {
                        output_stream.Write (buffer, index, count);