This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[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                 MemoryStream _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                         _OutputStream = new MemoryStream (MaxBufferSize);
55                         _OutputHelper = new StreamWriter (_OutputStream, _Response.ContentEncoding);
56                         _ResponseStream = new HttpResponseStream (this);
57
58                         Update ();
59                 }  
60
61                 internal void Dispose ()
62                 {
63                         _OutputHelper.Close ();
64                         _OutputStream.Close ();
65                         _OutputFilter.Close ();
66                 }
67
68                 internal Stream GetActiveFilter ()
69                 {
70                         if (null == _OutputFilter) {
71                                 // Create a filter proxy to allow us to know if we have a valid filter
72                                 if (null == _OutputProxy)
73                                         _OutputProxy = new HttpResponseStreamProxy (this);
74
75                                 return _OutputProxy;
76                         }
77                         return _OutputFilter;
78                 }
79
80                 internal void ActivateFilter (Stream OutputFilter)
81                 {
82                         if (null == _OutputProxy)
83                                 throw new HttpException ("Invalid filter usage");
84
85                         _OutputFilter = OutputFilter;
86                 }
87
88                 internal void FilterData (bool CloseStream)
89                 {
90                         // Check if we have any filter at all
91                         if (null == _OutputFilter)
92                                 return;
93
94                         FlushBuffers ();
95
96                         // Save our current data
97                         byte [] arrData = _OutputStream.GetBuffer ();
98                         int size = (int) _OutputStream.Length;
99
100                         // Remove our internal data
101                         Clear ();
102
103                         // If we have a filter then we have a proxy
104                         _OutputProxy.Active = true;
105
106                         try {
107                                 // Call the filter (it does a callback into our HttpWriter again)
108                                 _OutputFilter.Write (arrData, 0, size);
109                                 _OutputFilter.Flush ();
110
111                                 if (CloseStream)
112                                         _OutputFilter.Close ();
113                         } finally {
114                                 _OutputProxy.Active = false;
115                         }
116                 }
117
118                 internal void Clear ()
119                 {
120                         _OutputHelper.Close ();
121                         _OutputStream.Close ();
122                                         
123                         _OutputStream = new MemoryStream (32768);
124                         _OutputHelper = new StreamWriter (_OutputStream, _Response.ContentEncoding);
125                 }
126
127                 internal void SendContent (HttpWorkerRequest Handler)
128                 {
129                         FlushBuffers();
130
131                         int l = (int)_OutputStream.Length;
132                         if (l > 0) {
133                                 byte [] arrContent = _OutputStream.GetBuffer ();
134                                 Handler.SendResponseFromMemory (arrContent, l);
135                         }
136                 }
137
138                 internal void Update ()
139                 {
140                         _Encoding = _Response.ContentEncoding;
141                         _OutputHelper.Flush ();
142                         _OutputHelper = new StreamWriter (_OutputStream, _Encoding);
143                 }
144
145                 internal long BufferSize
146                 {
147                         get {
148                                 FlushBuffers ();
149                                 return _OutputStream.Length;
150                         }
151                 }
152
153                 internal void FlushBuffers ()
154                 {
155                         _OutputHelper.Flush ();
156                         _OutputStream.Flush ();
157                 }
158
159                 internal byte[] GetBuffer () {
160                         return _OutputStream.GetBuffer ();
161                 }
162                 
163                 public override Encoding Encoding
164                 {
165                         get { return _Encoding; }
166                 }
167
168                 public Stream OutputStream
169                 {
170                         get { return _ResponseStream; }
171                 }
172
173                 public override void Close ()
174                 {
175                         _Response.Flush ();
176                         _Response.Close ();
177                 }
178
179                 public override void Flush ()
180                 {
181                 }
182
183                 private void CheckIfFlush ()
184                 {
185                         if (!_Response.BufferOutput) {
186                                 FlushBuffers ();
187                         }
188                 }
189
190                 public override void Write (char ch)
191                 {
192                         _OutputHelper.Write (ch);
193                         CheckIfFlush ();
194                 }
195
196                 public override void Write (object obj)
197                 {
198                         if (obj != null)
199                         {
200                                 _OutputHelper.Write (obj.ToString ());
201                                 CheckIfFlush ();
202                         }
203                 }
204
205                 public override void Write (string s)
206                 {
207                         _OutputHelper.Write (s);
208                         CheckIfFlush ();
209                 }
210
211                 public override void Write (char [] buffer, int index, int count)
212                 {
213                         _OutputHelper.Write (buffer, index, count);
214                         CheckIfFlush ();
215                 }
216
217                 public void WriteBytes (byte [] buffer, int index, int count)
218                 {
219                         _OutputStream.Write (buffer, index, count);
220                         CheckIfFlush ();
221                 }
222
223                 public override void WriteLine ()
224                 {
225                         _OutputHelper.Write ("\r\n");
226                         CheckIfFlush ();
227                 }
228
229                 public void WriteString (string s, int index, int count)
230                 {
231                         _OutputHelper.Write (s.Substring (index, count));
232                         CheckIfFlush ();
233                 }
234         }
235 }
236