2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.Web / System.Web / HttpWriter.cs
1 // 
2 // System.Web.HttpWriter
3 //
4 // Author:
5 //   Patrik Torstensson (Patrik.Torstensson@labs2.com)
6 //
7
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.IO;
30 using System.Text;
31 using System.Web.Util;
32
33 namespace System.Web
34 {
35         public sealed class HttpWriter : TextWriter
36         {
37                 internal const int MaxBufferSize = 32768;
38                 
39                 HttpResponse _Response;
40
41                 HttpResponseStream _ResponseStream;
42
43                 ReusableMemoryStream _OutputStream;
44                 StreamWriter _OutputHelper;
45                 Encoding _Encoding;     
46
47                 Stream _OutputFilter;
48                 HttpResponseStreamProxy _OutputProxy;
49
50                 internal HttpWriter (HttpResponse Response)
51                 {
52                         _Response = Response;
53
54                         _Encoding = _Response.ContentEncoding;
55                         _OutputStream = new ReusableMemoryStream (MaxBufferSize);
56                         _OutputHelper = new StreamWriter (_OutputStream, _Response.ContentEncoding);
57                         _ResponseStream = new HttpResponseStream (this);
58                 }  
59
60                 internal void Dispose ()
61                 {
62                         _OutputHelper.Close ();
63                         _OutputStream.Close ();
64                         _OutputFilter.Close ();
65                 }
66
67                 internal Stream GetActiveFilter ()
68                 {
69                         if (null == _OutputFilter) {
70                                 // Create a filter proxy to allow us to know if we have a valid filter
71                                 if (null == _OutputProxy)
72                                         _OutputProxy = new HttpResponseStreamProxy (this);
73
74                                 return _OutputProxy;
75                         }
76                         return _OutputFilter;
77                 }
78
79                 internal void ActivateFilter (Stream OutputFilter)
80                 {
81                         if (null == _OutputProxy)
82                                 throw new HttpException ("Invalid filter usage");
83
84                         _OutputFilter = OutputFilter;
85                 }
86
87                 internal void FilterData (bool CloseStream)
88                 {
89                         // Check if we have any filter at all
90                         if (null == _OutputFilter)
91                                 return;
92
93                         FlushBuffers ();
94
95                         // Save our current data
96                         byte [] arrData = _OutputStream.GetBuffer ();
97                         int size = (int) _OutputStream.Length;
98
99                         // Remove our internal data
100                         Clear ();
101
102                         // If we have a filter then we have a proxy
103                         _OutputProxy.Active = true;
104
105                         try {
106                                 // Call the filter (it does a callback into our HttpWriter again)
107                                 _OutputFilter.Write (arrData, 0, size);
108                                 _OutputFilter.Flush ();
109
110                                 if (CloseStream)
111                                         _OutputFilter.Close ();
112                         } finally {
113                                 _OutputProxy.Active = false;
114                         }
115                 }
116
117                 internal void Clear ()
118                 {
119                         _OutputHelper.Close ();
120                         _OutputStream = new ReusableMemoryStream (_OutputStream.GetBuffer ());
121                         _OutputHelper = new StreamWriter (_OutputStream, _Response.ContentEncoding);
122                 }
123
124                 internal void SendContent (HttpWorkerRequest Handler)
125                 {
126                         FlushBuffers();
127
128                         int l = (int)_OutputStream.Length;
129                         if (l > 0) {
130                                 byte [] arrContent = _OutputStream.GetBuffer ();
131                                 Handler.SendResponseFromMemory (arrContent, l);
132                         }
133                 }
134
135                 internal void Update ()
136                 {
137                         _Encoding = _Response.ContentEncoding;
138                         _OutputHelper.Flush ();
139                         _OutputHelper = new StreamWriter (_OutputStream, _Encoding);
140                 }
141
142                 internal long BufferSize
143                 {
144                         get {
145                                 FlushBuffers ();
146                                 return _OutputStream.Length;
147                         }
148                 }
149
150                 internal void FlushBuffers ()
151                 {
152                         _OutputHelper.Flush ();
153                         _OutputStream.Flush ();
154                 }
155
156                 internal byte[] GetBuffer () {
157                         return _OutputStream.GetBuffer ();
158                 }
159                 
160                 public override Encoding Encoding
161                 {
162                         get { return _Encoding; }
163                 }
164
165                 public Stream OutputStream
166                 {
167                         get { return _ResponseStream; }
168                 }
169
170                 public override void Close ()
171                 {
172                         _Response.Flush ();
173                         _Response.Close ();
174                 }
175
176                 public override void Flush ()
177                 {
178                 }
179
180                 private void CheckIfFlush ()
181                 {
182                         if (!_Response.BufferOutput) {
183                                 FlushBuffers ();
184                         }
185                 }
186
187                 public override void Write (char ch)
188                 {
189                         _OutputHelper.Write (ch);
190                         CheckIfFlush ();
191                 }
192
193                 public override void Write (object obj)
194                 {
195                         if (obj != null)
196                         {
197                                 _OutputHelper.Write (obj.ToString ());
198                                 CheckIfFlush ();
199                         }
200                 }
201
202                 public override void Write (string s)
203                 {
204                         _OutputHelper.Write (s);
205                         CheckIfFlush ();
206                 }
207
208                 public override void Write (char [] buffer, int index, int count)
209                 {
210                         _OutputHelper.Write (buffer, index, count);
211                         CheckIfFlush ();
212                 }
213
214                 public void WriteBytes (byte [] buffer, int index, int count)
215                 {
216                         _OutputStream.Write (buffer, index, count);
217                         CheckIfFlush ();
218                 }
219
220                 public override void WriteLine ()
221                 {
222                         _OutputHelper.Write ("\r\n");
223                         CheckIfFlush ();
224                 }
225
226                 public void WriteString (string s, int index, int count)
227                 {
228                         _OutputHelper.Write (s.Substring (index, count));
229                         CheckIfFlush ();
230                 }
231         }
232 }
233