KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > server > connection > ToCharResponseStream


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.server.connection;
31
32 import com.caucho.log.Log;
33 import com.caucho.util.L10N;
34 import com.caucho.vfs.Encoding;
35 import com.caucho.vfs.TempCharBuffer;
36
37 import java.io.IOException JavaDoc;
38 import java.io.InputStream JavaDoc;
39 import java.io.Reader JavaDoc;
40 import java.util.logging.Level JavaDoc;
41 import java.util.logging.Logger JavaDoc;
42
43 abstract public class ToCharResponseStream extends AbstractResponseStream {
44   static final Logger JavaDoc log = Log.open(ToCharResponseStream.class);
45   
46   static final L10N L = new L10N(ToCharResponseStream.class);
47
48   private static final int SIZE = TempCharBuffer.SIZE;
49   
50   private final byte []_byteBuffer = new byte[SIZE];
51   
52   // head of the expandable buffer
53
private TempCharBuffer _head = TempCharBuffer.allocate();
54   private TempCharBuffer _tail;
55   
56   private char []_charBuffer;
57   private int _charLength;
58
59   private int _bufferCapacity;
60   private int _bufferSize;
61   
62   private BufferInputStream _in;
63   private Reader JavaDoc _encodingReader;
64
65   public ToCharResponseStream()
66   {
67   }
68   
69   /**
70    * Initializes the Buffered Response stream at the beginning of a request.
71    */

72   public void start()
73   {
74     super.start();
75     
76     _head.clear();
77     _head.setNext(null);
78     _tail = _head;
79
80     _charBuffer = _tail.getBuffer();
81     _charLength = 0;
82     
83     _bufferCapacity = SIZE;
84     _bufferSize = 0;
85     /*
86     _autoFlush = true;
87     _isClosed = false;
88     */

89
90     // _toChar = Encoding.getReadEncoding("ISO-8859-1");
91
}
92
93   /**
94    * Returns true for a caucho response stream.
95    */

96   public boolean isCauchoResponseStream()
97   {
98     return true;
99   }
100
101   /**
102    * Sets the buffer size.
103    */

104   public void setBufferSize(int size)
105   {
106     size = (size + SIZE - 1);
107     size -= size % SIZE;
108
109     if (_bufferCapacity < size)
110       _bufferCapacity = size;
111   }
112
113   /**
114    * Gets the buffer size.
115    */

116   public int getBufferSize()
117   {
118     return _bufferCapacity;
119   }
120
121   /**
122    * Returns the remaining buffer entries.
123    */

124   public int getRemaining()
125   {
126     return _bufferCapacity - _bufferSize - _charLength;
127   }
128
129   /**
130    * Returns the char buffer.
131    */

132   public char []getCharBuffer()
133   {
134     return _charBuffer;
135   }
136
137   /**
138    * Returns the char offset.
139    */

140   public int getCharOffset()
141   {
142     return _charLength;
143   }
144
145   /**
146    * Sets the char offset.
147    */

148   public void setCharOffset(int offset)
149     throws IOException JavaDoc
150   {
151     _charLength = offset;
152
153     if (SIZE <= _charLength)
154       expandCharBuffer();
155   }
156
157   /**
158    * Converts the char buffer.
159    */

160   public char []nextCharBuffer(int offset)
161     throws IOException JavaDoc
162   {
163     _charLength = offset;
164
165     if (SIZE <= _charLength)
166       expandCharBuffer();
167
168     return _charBuffer;
169   }
170
171   /**
172    * Writes a character to the output.
173    */

174   public void print(int ch)
175     throws IOException JavaDoc
176   {
177     /*
178     if (_isClosed)
179       return;
180     */

181
182     _charBuffer[_charLength++] = (char) ch;
183
184     if (SIZE <= _charLength)
185       expandCharBuffer();
186   }
187
188   /**
189    * Writes a char array to the output.
190    */

191   public void print(char []buffer, int offset, int length)
192     throws IOException JavaDoc
193   {
194     /*
195     if (_isHead || _isClosed)
196       return;
197
198     if (_byteLength > 0)
199       flushByteBuffer();
200     */

201
202     int charLength = _charLength;
203     while (length > 0) {
204       int sublen = length;
205       if (SIZE - charLength < sublen)
206     sublen = SIZE - charLength;
207
208       System.arraycopy(buffer, offset, _charBuffer, charLength, sublen);
209
210       offset += sublen;
211       length -= sublen;
212       charLength += sublen;
213
214       if (SIZE <= charLength) {
215     _charLength = charLength;
216     expandCharBuffer();
217     charLength = _charLength;
218       }
219     }
220
221     _charLength = charLength;
222   }
223
224   /**
225    * Returns the buffer offset.
226    */

227   public int getBufferOffset()
228   {
229     return 0;
230   }
231
232   /**
233    * Sets the byte buffer offset.
234    */

235   public void setBufferOffset(int offset)
236   {
237     if (offset > 0) {
238       try {
239     write(_byteBuffer, 0, offset);
240       } catch (IOException JavaDoc e) {
241     log.log(Level.FINE, e.toString(), e);
242       }
243     }
244   }
245
246   /**
247    * Gets the byte buffer
248    */

249   public byte []getBuffer()
250   {
251     return _byteBuffer;
252   }
253
254   /**
255    * Returns the next buffer.
256    */

257   public byte []nextBuffer(int offset)
258     throws IOException JavaDoc
259   {
260     if (offset > 0)
261       write(_byteBuffer, 0, offset);
262
263     return _byteBuffer;
264   }
265
266   /**
267    * Writes the next chunk of data to the response stream.
268    *
269    * @param buf the buffer containing the data
270    * @param offset start offset into the buffer
271    * @param length length of the data in the buffer
272    */

273   public void write(byte []buf, int offset, int length)
274     throws IOException JavaDoc
275   {
276     if (length == 0)
277       return;
278     
279     if (_encodingReader == null) {
280       if (_in == null)
281     _in = new BufferInputStream();
282       _encodingReader = Encoding.getReadEncoding(_in, getEncoding());
283     }
284
285     // XXX: performance issues
286
if (_encodingReader == null) {
287       for (; length > 0; length--) {
288     print((char) buf[offset++]);
289       }
290       return;
291     }
292     
293     _in.init(buf, offset, length);
294
295     // XXX: performance issues
296
int ch;
297     while ((ch = _encodingReader.read()) >= 0) {
298       print(ch);
299     }
300   }
301
302   /**
303    * Writes the next chunk of data to the response stream.
304    *
305    * @param buf the buffer containing the data
306    * @param offset start offset into the buffer
307    * @param length length of the data in the buffer
308    */

309   public void write(int ch)
310     throws IOException JavaDoc
311   {
312     if (_encodingReader == null) {
313       if (_in == null)
314     _in = new BufferInputStream();
315       _byteBuffer[0] = (byte) ch;
316       _encodingReader = Encoding.getReadEncoding(_in, getEncoding());
317     }
318
319     if (_encodingReader == null) {
320       print((char) ch);
321       return;
322     }
323     
324     _in.init(_byteBuffer, 0, 1);
325
326     while ((ch = _encodingReader.read()) >= 0) {
327       print(ch);
328     }
329   }
330
331   /**
332    * Flushes the buffer.
333    */

334   public void flushBuffer()
335     throws IOException JavaDoc
336   {
337     flushCharBuffer();
338   }
339
340   /**
341    * Flushes the buffer.
342    */

343   public void flushChar()
344     throws IOException JavaDoc
345   {
346     flushCharBuffer();
347   }
348
349   /**
350    * Flushes or writes to the buffer.
351    */

352   private void expandCharBuffer()
353     throws IOException JavaDoc
354   {
355     if (_bufferCapacity <= _bufferSize + _charLength) {
356       flushCharBuffer();
357     }
358     else if (_charLength == SIZE) {
359       _tail.setLength(_charLength);
360       _bufferSize += _charLength;
361     
362       TempCharBuffer tempBuf = TempCharBuffer.allocate();
363       _tail.setNext(tempBuf);
364       _tail = tempBuf;
365
366       _charBuffer = _tail.getBuffer();
367       _charLength = 0;
368     }
369   }
370
371   /**
372    * Flushes the buffered response to the output stream.
373    */

374   private void flushCharBuffer()
375     throws IOException JavaDoc
376   {
377     _tail.setLength(_charLength);
378     _bufferSize += _charLength;
379     _charLength = 0;
380
381     TempCharBuffer ptr = _head;
382     do {
383       _head = ptr;
384       
385       TempCharBuffer next = ptr.getNext();
386       ptr.setNext(null);
387
388       writeNext(ptr.getBuffer(), 0, ptr.getLength());
389
390       if (next != null)
391     TempCharBuffer.free(ptr);
392
393       ptr = next;
394     } while (ptr != null);
395
396     _tail = _head;
397     _tail.setLength(0);
398     _charBuffer = _tail.getBuffer();
399     _bufferSize = 0;
400   }
401
402   /**
403    * Flushes the buffer.
404    */

405   public void clearBuffer()
406   {
407     _charLength = 0;
408
409     TempCharBuffer ptr = _head;
410     do {
411       _head = ptr;
412       
413       TempCharBuffer next = ptr.getNext();
414       ptr.setNext(null);
415
416       if (next != null)
417     TempCharBuffer.free(ptr);
418
419       ptr = next;
420     } while (ptr != null);
421
422     _tail = _head;
423     _tail.setLength(0);
424     _charBuffer = _head.getBuffer();
425     _bufferSize = 0;
426   }
427
428   /**
429    * Closes the stream.
430    */

431   public void close()
432     throws IOException JavaDoc
433   {
434     super.close();
435     
436     _encodingReader = null;
437   }
438
439   /**
440    * Returns the encoding.
441    */

442   abstract protected String JavaDoc getEncoding();
443   
444   /**
445    * Writes to the next.
446    */

447   abstract protected void writeNext(char []buffer, int offset, int length)
448     throws IOException JavaDoc;
449
450   static class BufferInputStream extends InputStream JavaDoc {
451     private byte []_buffer;
452     private int _offset;
453     private int _length;
454
455     void init(byte []buffer, int offset, int length)
456     {
457       _buffer = buffer;
458       _offset = offset;
459       _length = length;
460     }
461
462     public int read()
463     {
464       if (_offset < _length)
465     return _buffer[_offset++] & 0xff;
466       else
467     return -1;
468     }
469   }
470 }
471
Popular Tags