2009-02-20 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mcs / class / System.Web / System.Web / HttpWriter.cs
1 //
2 // System.Web.HttpWriter.cs 
3 //
4 // 
5 // Author:
6 //      Miguel de Icaza (miguel@novell.com)
7 //
8 //
9 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.IO;
32 using System.Text;
33 using System.Globalization;
34 using System.Runtime.InteropServices;
35 using System.Security.Permissions;
36         
37 namespace System.Web {
38         
39         // CAS - no InheritanceDemand here as the class is sealed
40         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
41         public sealed class HttpWriter : TextWriter {
42                 HttpResponseStream output_stream;
43                 HttpResponse response;
44                 Encoding encoding;
45                 byte [] _bytebuffer = new byte [1024];
46
47                 internal HttpWriter (HttpResponse response)
48                 {
49                         this.response = response;
50                         encoding = response.ContentEncoding;
51                         output_stream = response.output_stream;
52                 }
53
54                 byte [] GetByteBuffer (int length)
55                 {
56                         // We will reuse the buffer if its size is < 32K
57                         if (_bytebuffer.Length >= length)
58                                 return _bytebuffer;
59
60                         if (length > 32 * 1024)
61                                 return new byte [length];
62
63                         _bytebuffer = new byte [length];
64                         return _bytebuffer;
65                 }
66
67                 public override Encoding Encoding {
68                         get {
69                                 return encoding;
70                         }
71                 }
72
73                 internal void SetEncoding (Encoding new_encoding)
74                 {
75                         encoding = new_encoding;
76                 }
77
78                 public Stream OutputStream {
79                         get {
80                                 return output_stream;
81                         }
82                 }
83
84                 internal HttpResponse Response {
85                         get { return response; }
86                 }
87                 //
88                 // Flush data, and closes socket
89                 //
90                 public override void Close ()
91                 {
92                         output_stream.Close ();
93                 }
94
95                 public override void Flush ()
96                 {
97                         output_stream.Flush ();
98                 }
99
100                 char [] chars = new char [1];
101                 public override void Write (char ch)
102                 {
103                         chars [0] = ch;
104                         Write (chars, 0, 1);
105                 }
106
107                 public override void Write (object obj)
108                 {
109                         if (obj == null)
110                                 return;
111                         
112                         Write (obj.ToString ());
113                 }
114                 
115                 public override void Write (string s)
116                 {
117                         if (s != null)
118                                 WriteString (s, 0, s.Length);
119                 }
120                 
121                 public override void Write (char [] buffer, int index, int count)
122                 {
123                         if (buffer == null || index < 0 || count < 0 || (buffer.Length - index) < count)
124                                 throw new ArgumentOutOfRangeException ();
125 #if TARGET_JVM
126                         output_stream.Write (buffer, index, count);
127 #else
128                         int length = encoding.GetMaxByteCount (count);
129                         byte [] bytebuffer = GetByteBuffer (length);
130                         int realLength = encoding.GetBytes (buffer, index, count, bytebuffer, 0);
131                         output_stream.Write (bytebuffer, 0, realLength);
132 #endif
133                         if (response.buffer)
134                                 return;
135
136                         response.Flush ();
137                 }
138
139                 static char [] newline = new char [2] { '\r', '\n' };
140                 
141                 public override void WriteLine ()
142                 {
143                         Write (newline, 0, 2);
144                 }
145
146                 public void WriteString (string s, int index, int count)
147                 {
148                         if (s == null)
149                                 return;
150
151                         if (index < 0 || count < 0 || ((index + count > s.Length)))
152                                 throw new ArgumentOutOfRangeException ();
153 #if TARGET_JVM
154                         output_stream.Write (s, index, count);
155 #else
156                         int length = encoding.GetMaxByteCount (count);
157                         byte [] bytebuffer = GetByteBuffer (length);
158                         int realLength = encoding.GetBytes (s, index, count, bytebuffer, 0);
159                         output_stream.Write (bytebuffer, 0, realLength);
160 #endif
161                         if (response.buffer)
162                                 return;
163
164                         response.Flush ();
165                 }
166
167                 internal void WriteUTF8Ptr (IntPtr ptr, int length)
168                 {
169                         output_stream.WritePtr (ptr, length);
170                 }
171
172                 public void WriteBytes (byte [] buffer, int index, int count)
173                 {
174                         output_stream.Write (buffer, index, count);
175
176                         if (response.buffer)
177                                 return;
178
179                         response.Flush ();
180                 }
181         }
182 }
183