1 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 ; 38 import java.io.InputStream ; 39 import java.io.Reader ; 40 import java.util.logging.Level ; 41 import java.util.logging.Logger ; 42 43 abstract public class ToCharResponseStream extends AbstractResponseStream { 44 static final Logger 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 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 _encodingReader; 64 65 public ToCharResponseStream() 66 { 67 } 68 69 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 89 90 } 92 93 96 public boolean isCauchoResponseStream() 97 { 98 return true; 99 } 100 101 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 116 public int getBufferSize() 117 { 118 return _bufferCapacity; 119 } 120 121 124 public int getRemaining() 125 { 126 return _bufferCapacity - _bufferSize - _charLength; 127 } 128 129 132 public char []getCharBuffer() 133 { 134 return _charBuffer; 135 } 136 137 140 public int getCharOffset() 141 { 142 return _charLength; 143 } 144 145 148 public void setCharOffset(int offset) 149 throws IOException 150 { 151 _charLength = offset; 152 153 if (SIZE <= _charLength) 154 expandCharBuffer(); 155 } 156 157 160 public char []nextCharBuffer(int offset) 161 throws IOException 162 { 163 _charLength = offset; 164 165 if (SIZE <= _charLength) 166 expandCharBuffer(); 167 168 return _charBuffer; 169 } 170 171 174 public void print(int ch) 175 throws IOException 176 { 177 181 182 _charBuffer[_charLength++] = (char) ch; 183 184 if (SIZE <= _charLength) 185 expandCharBuffer(); 186 } 187 188 191 public void print(char []buffer, int offset, int length) 192 throws IOException 193 { 194 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 227 public int getBufferOffset() 228 { 229 return 0; 230 } 231 232 235 public void setBufferOffset(int offset) 236 { 237 if (offset > 0) { 238 try { 239 write(_byteBuffer, 0, offset); 240 } catch (IOException e) { 241 log.log(Level.FINE, e.toString(), e); 242 } 243 } 244 } 245 246 249 public byte []getBuffer() 250 { 251 return _byteBuffer; 252 } 253 254 257 public byte []nextBuffer(int offset) 258 throws IOException 259 { 260 if (offset > 0) 261 write(_byteBuffer, 0, offset); 262 263 return _byteBuffer; 264 } 265 266 273 public void write(byte []buf, int offset, int length) 274 throws IOException 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 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 int ch; 297 while ((ch = _encodingReader.read()) >= 0) { 298 print(ch); 299 } 300 } 301 302 309 public void write(int ch) 310 throws IOException 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 334 public void flushBuffer() 335 throws IOException 336 { 337 flushCharBuffer(); 338 } 339 340 343 public void flushChar() 344 throws IOException 345 { 346 flushCharBuffer(); 347 } 348 349 352 private void expandCharBuffer() 353 throws IOException 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 374 private void flushCharBuffer() 375 throws IOException 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 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 431 public void close() 432 throws IOException 433 { 434 super.close(); 435 436 _encodingReader = null; 437 } 438 439 442 abstract protected String getEncoding(); 443 444 447 abstract protected void writeNext(char []buffer, int offset, int length) 448 throws IOException ; 449 450 static class BufferInputStream extends InputStream { 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 |