-//
-// System.Web.HttpWriter
//
+// System.Web.HttpWriter.cs
+//
+//
// Author:
-// Patrik Torstensson (Patrik.Torstensson@labs2.com)
+// Miguel de Icaza (miguel@novell.com)
//
-
+//
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
+
using System.IO;
using System.Text;
-using System.Web.Util;
-
-namespace System.Web
-{
- public sealed class HttpWriter : TextWriter
- {
- internal const int MaxBufferSize = 32768;
-
- HttpResponse _Response;
-
- HttpResponseStream _ResponseStream;
-
- MemoryStream _OutputStream;
- StreamWriter _OutputHelper;
- Encoding _Encoding;
+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];
- Stream _OutputFilter;
- HttpResponseStreamProxy _OutputProxy;
-
- internal HttpWriter (HttpResponse Response)
+ internal HttpWriter (HttpResponse response)
{
- _Response = Response;
-
- _Encoding = _Response.ContentEncoding;
- _OutputStream = new MemoryStream (MaxBufferSize);
- _OutputHelper = new StreamWriter (_OutputStream, _Response.ContentEncoding);
- _ResponseStream = new HttpResponseStream (this);
- }
-
- internal void Dispose ()
- {
- _OutputHelper.Close ();
- _OutputStream.Close ();
- _OutputFilter.Close ();
+ this.response = response;
+ encoding = response.ContentEncoding;
+ output_stream = response.output_stream;
}
- internal Stream GetActiveFilter ()
+ byte [] GetByteBuffer (int length)
{
- if (null == _OutputFilter) {
- // Create a filter proxy to allow us to know if we have a valid filter
- if (null == _OutputProxy)
- _OutputProxy = new HttpResponseStreamProxy (this);
+ // We will reuse the buffer if its size is < 32K
+ if (_bytebuffer.Length >= length)
+ return _bytebuffer;
- return _OutputProxy;
- }
- return _OutputFilter;
- }
-
- internal void ActivateFilter (Stream OutputFilter)
- {
- if (null == _OutputProxy)
- throw new HttpException ("Invalid filter usage");
+ if (length > 32 * 1024)
+ return new byte [length];
- _OutputFilter = OutputFilter;
+ _bytebuffer = new byte [length];
+ return _bytebuffer;
}
- internal void FilterData (bool CloseStream)
- {
- // Check if we have any filter at all
- if (null == _OutputFilter)
- return;
-
- FlushBuffers ();
-
- // Save our current data
- byte [] arrData = _OutputStream.GetBuffer ();
- int size = (int) _OutputStream.Length;
-
- // Remove our internal data
- Clear ();
-
- // If we have a filter then we have a proxy
- _OutputProxy.Active = true;
-
- try {
- // Call the filter (it does a callback into our HttpWriter again)
- _OutputFilter.Write (arrData, 0, size);
- _OutputFilter.Flush ();
-
- if (CloseStream)
- _OutputFilter.Close ();
- } finally {
- _OutputProxy.Active = false;
- }
- }
-
- internal void Clear ()
- {
- // This clears all the buffers that are around
- _OutputHelper.Flush ();
- _OutputStream.SetLength (0);
- }
-
- internal void SendContent (HttpWorkerRequest Handler)
- {
- FlushBuffers();
-
- int l = (int)_OutputStream.Length;
- if (l > 0) {
- byte [] arrContent = _OutputStream.GetBuffer ();
- Handler.SendResponseFromMemory (arrContent, l);
+ public override Encoding Encoding {
+ get {
+ return encoding;
}
}
- internal void Update ()
+ internal void SetEncoding (Encoding new_encoding)
{
- _Encoding = _Response.ContentEncoding;
- _OutputHelper.Flush ();
- _OutputHelper = new StreamWriter (_OutputStream, _Encoding);
+ encoding = new_encoding;
}
- internal long BufferSize
- {
+ public Stream OutputStream {
get {
- FlushBuffers ();
- return _OutputStream.Length;
+ return output_stream;
}
}
- internal void FlushBuffers ()
- {
- _OutputHelper.Flush ();
- _OutputStream.Flush ();
- }
-
- internal byte[] GetBuffer () {
- return _OutputStream.GetBuffer ();
- }
-
- public override Encoding Encoding
- {
- get { return _Encoding; }
- }
-
- public Stream OutputStream
- {
- get { return _ResponseStream; }
- }
-
+ //
+ // Flush data, and closes socket
+ //
public override void Close ()
{
- _Response.Flush ();
- _Response.Close ();
+ output_stream.Close ();
}
public override void Flush ()
{
+ output_stream.Flush ();
}
- private void CheckIfFlush ()
- {
- if (!_Response.BufferOutput) {
- FlushBuffers ();
- }
- }
-
+ char [] chars = new char [1];
public override void Write (char ch)
{
- _OutputHelper.Write (ch);
- CheckIfFlush ();
+ chars [0] = ch;
+ Write (chars, 0, 1);
}
public override void Write (object obj)
{
- if (obj != null)
- {
- _OutputHelper.Write (obj.ToString ());
- CheckIfFlush ();
- }
+ if (obj == null)
+ return;
+
+ Write (obj.ToString ());
}
-
+
public override void Write (string s)
{
- _OutputHelper.Write (s);
- CheckIfFlush ();
+ if (s != null)
+ WriteString (s, 0, s.Length);
}
-
+
public override void Write (char [] buffer, int index, int count)
{
- _OutputHelper.Write (buffer, index, count);
- CheckIfFlush ();
- }
+ 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;
- public void WriteBytes (byte [] buffer, int index, int count)
- {
- _OutputStream.Write (buffer, index, count);
- CheckIfFlush ();
+ response.Flush ();
}
+ static char [] newline = new char [2] { '\r', '\n' };
+
public override void WriteLine ()
{
- _OutputHelper.Write ("\r\n");
- CheckIfFlush ();
+ Write (newline, 0, 2);
}
public void WriteString (string s, int index, int count)
{
- _OutputHelper.Write (s.Substring (index, count));
- CheckIfFlush ();
+ 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 ();
+ }
+
+ public void WriteBytes (byte [] buffer, int index, int count)
+ {
+ output_stream.Write (buffer, index, count);
+
+ if (response.buffer)
+ return;
+
+ response.Flush ();
}
}
}