merge r98447
[mono.git] / mcs / class / Mainsoft.Web / Mainsoft.Web.Hosting / OutputStreamWrapper.cs
1 //\r
2 // Mainsoft.Web.Hosting.OutputStreamWrapper\r
3 //\r
4 // Authors:\r
5 //      Vladimir Krasnov (vladimirk@mainsoft.com)\r
6 //\r
7 // (C) 2006 Mainsoft\r
8 //\r
9 //\r
10 // Permission is hereby granted, free of charge, to any person obtaining\r
11 // a copy of this software and associated documentation files (the\r
12 // "Software"), to deal in the Software without restriction, including\r
13 // without limitation the rights to use, copy, modify, merge, publish,\r
14 // distribute, sublicense, and/or sell copies of the Software, and to\r
15 // permit persons to whom the Software is furnished to do so, subject to\r
16 // the following conditions:\r
17 // \r
18 // The above copyright notice and this permission notice shall be\r
19 // included in all copies or substantial portions of the Software.\r
20 // \r
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
28 //\r
29 \r
30 using System;\r
31 using System.Web;\r
32 using System.Collections.Generic;\r
33 using System.Text;\r
34 \r
35 using java.io;\r
36 using vmw.common;\r
37 \r
38 \r
39 namespace Mainsoft.Web.Hosting\r
40 {\r
41         /// <summary>\r
42         /// \r
43         /// </summary>\r
44         public sealed class OutputStreamWrapper : java.io.Writer\r
45         {\r
46                 enum OutputMode\r
47                 {\r
48                         CharWriter,\r
49                         ByteStream,\r
50                 }\r
51 \r
52                 readonly PrintWriter _printWriter;\r
53                 readonly OutputStream _outputStream;\r
54                 readonly OutputMode _outputMode;\r
55 \r
56                 private byte [] _bytebuffer;\r
57                 private char [] _charBuffer;\r
58                 //sbyte [] _oneByte = new sbyte [1];\r
59 \r
60                 Encoding _encoding = null;\r
61 \r
62                 /// <summary>\r
63                 /// Ctor from writer\r
64                 /// </summary>\r
65                 /// <param name="writer"></param>\r
66                 public OutputStreamWrapper (PrintWriter writer)\r
67                 {\r
68                         _printWriter = writer;\r
69                         _outputMode = OutputMode.CharWriter;\r
70                 }\r
71 \r
72                 /// <summary>\r
73                 /// Ctor from stream\r
74                 /// </summary>\r
75                 /// <param name="outputStream"></param>\r
76                 public OutputStreamWrapper (OutputStream outputStream)\r
77                 {\r
78                         _outputStream = outputStream;\r
79                         _outputMode = OutputMode.ByteStream;\r
80                 }\r
81 \r
82                 /// <summary>\r
83                 /// \r
84                 /// </summary>\r
85                 public override void close ()\r
86                 {\r
87                         // BUGBUG\r
88                         // on WPS, closing the writer causes\r
89                         // any portlets rendered after us to be not shown...\r
90                         //_writer.close();\r
91                 }\r
92 \r
93                 /// <summary>\r
94                 /// Flushes servers stream\r
95                 /// </summary>\r
96                 public override void flush ()\r
97                 {\r
98                         if (_outputMode == OutputMode.CharWriter)\r
99                                 _printWriter.flush ();\r
100                         else\r
101                                 _outputStream.flush();\r
102                 }\r
103 \r
104                 /// <summary>\r
105                 /// Writes char array\r
106                 /// </summary>\r
107                 /// <param name="chars"></param>\r
108                 /// <param name="index"></param>\r
109                 /// <param name="count"></param>\r
110                 public override void write (char [] chars, int index, int count)\r
111                 {\r
112                         if (_outputMode == OutputMode.CharWriter) {\r
113                                 _printWriter.write (chars, index, count);\r
114                         }\r
115                         else {\r
116                                 int length = Encoding.GetMaxByteCount (count);\r
117                                 byte [] bytebuffer = GetByteBuffer (length);\r
118                                 int realLength = Encoding.GetBytes (chars, index, count, bytebuffer, 0);\r
119 \r
120                                 _outputStream.write (TypeUtils.ToSByteArray (bytebuffer), 0, realLength);\r
121                         }\r
122                                 \r
123                 }\r
124 \r
125                 /// <summary>\r
126                 /// Writes byte array\r
127                 /// </summary>\r
128                 /// <param name="sbytes"></param>\r
129                 /// <param name="index"></param>\r
130                 /// <param name="count"></param>\r
131                 public void write (sbyte [] sbytes, int index, int count)\r
132                 {\r
133                         if (_outputMode == OutputMode.ByteStream)\r
134                                 _outputStream.write (sbytes, index, count);\r
135                         else {\r
136                                 int length = Encoding.GetMaxCharCount (count);\r
137                                 char [] charbuffer = GetCharBuffer (length);\r
138                                 int realLength = Encoding.GetChars ((byte []) TypeUtils.ToByteArray (sbytes), index, count, charbuffer, 0);\r
139 \r
140                                 _printWriter.write (charbuffer, 0, realLength);\r
141                         }\r
142                 }\r
143 \r
144                 private char [] GetCharBuffer (int length)\r
145                 {\r
146                         // We will reuse the buffer if its size is < 32K\r
147                         if (_charBuffer != null && _charBuffer.Length >= length)\r
148                                 return _charBuffer;\r
149 \r
150                         if (length > 32 * 1024)\r
151                                 return new char [length];\r
152 \r
153                         if (length < 1024)\r
154                                 length = 1024;\r
155 \r
156                         _charBuffer = new char [length];\r
157                         return _charBuffer;\r
158                 }\r
159 \r
160                 private byte [] GetByteBuffer (int length)\r
161                 {\r
162                         // We will reuse the buffer if its size is < 32K\r
163                         if (_bytebuffer != null && _bytebuffer.Length >= length)\r
164                                 return _bytebuffer;\r
165 \r
166                         if (length > 32 * 1024)\r
167                                 return new byte [length];\r
168 \r
169                         if (length < 1024)\r
170                                 length = 1024;\r
171 \r
172                         _bytebuffer = new byte [length];\r
173                         return _bytebuffer;\r
174                 }\r
175                 \r
176                 private Encoding Encoding\r
177                 {\r
178                         get\r
179                         {\r
180                                 if (_encoding == null) {\r
181                                         HttpContext current = HttpContext.Current;\r
182                                         _encoding = (current != null) ? current.Response.ContentEncoding : Encoding.UTF8;\r
183                                 }\r
184                                 return _encoding;\r
185                         }\r
186                 }\r
187         }\r
188 }\r