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.TempBuffer; 36 import com.caucho.vfs.i18n.EncodingWriter; 37 38 import java.io.IOException ; 39 import java.io.UnsupportedEncodingException ; 40 import java.util.Locale ; 41 import java.util.logging.Logger ; 42 43 46 public abstract class ToByteResponseStream extends AbstractResponseStream { 47 private static final Logger log = Log.open(ToByteResponseStream.class); 48 private static final L10N L = new L10N(ToByteResponseStream.class); 49 50 protected static final int SIZE = TempBuffer.SIZE; 51 52 private final char []_charBuffer = new char[SIZE]; 53 private int _charLength; 54 55 private TempBuffer _head = TempBuffer.allocate(); 57 private TempBuffer _tail; 58 59 private byte []_byteBuffer; 60 private int _byteLength; 61 62 private int _bufferCapacity; 63 private int _bufferSize; 64 65 private boolean _isHead; 66 private boolean _isClosed; 67 protected boolean _isFinished; 68 69 private EncodingWriter _toByte = Encoding.getLatin1Writer(); 70 71 protected ToByteResponseStream() 72 { 73 } 74 75 78 public void start() 79 { 80 _bufferCapacity = SIZE; 81 82 _charLength = 0; 83 84 _head.clear(); 85 _tail = _head; 86 _byteBuffer = _tail.getBuffer(); 87 _byteLength = 0; 88 89 _bufferSize = 0; 90 91 _isHead = false; 92 _isClosed = false; 93 _isFinished = false; 94 95 _toByte = Encoding.getLatin1Writer(); 96 } 97 98 101 public boolean isCauchoResponseStream() 102 { 103 return true; 104 } 105 106 109 public void setHead() 110 { 111 _isHead = true; 112 } 113 114 117 public void setEncoding(String encoding) 118 throws UnsupportedEncodingException 119 { 120 EncodingWriter toByte; 121 122 if (encoding == null) 123 toByte = Encoding.getLatin1Writer(); 124 else 125 toByte = Encoding.getWriteEncoding(encoding); 126 127 if (toByte != null) 128 _toByte = toByte; 129 else { 130 _toByte = Encoding.getLatin1Writer(); 131 132 throw new UnsupportedEncodingException (encoding); 133 } 134 } 135 136 139 public void setLocale(Locale locale) 140 throws UnsupportedEncodingException 141 { 142 } 143 144 147 public char []getCharBuffer() 148 { 149 return _charBuffer; 150 } 151 152 155 public int getCharOffset() 156 throws IOException 157 { 158 return _charLength; 159 } 160 161 164 public void setCharOffset(int offset) 165 throws IOException 166 { 167 _charLength = offset; 168 169 if (_charLength == SIZE) 170 flushCharBuffer(); 171 } 172 173 176 public byte []getBuffer() 177 throws IOException 178 { 179 return _byteBuffer; 180 } 181 182 185 public int getBufferOffset() 186 throws IOException 187 { 188 return _byteLength; 189 } 190 191 194 public void setBufferOffset(int offset) 195 throws IOException 196 { 197 if (_charLength > 0) 198 flushCharBuffer(); 199 200 _byteLength = offset; 201 } 202 203 206 public int getBufferSize() 207 { 208 return _bufferCapacity; 209 } 210 211 214 220 221 224 public void setBufferSize(int size) 225 { 226 _bufferCapacity = SIZE * ((size + SIZE - 1) / SIZE); 227 228 if (_bufferCapacity <= 0) 229 _bufferCapacity = 0; 230 } 231 232 235 public int getRemaining() 236 { 237 return _bufferCapacity - getBufferLength(); 238 } 239 240 243 protected int getBufferLength() 244 { 245 return _bufferSize + _byteLength + _charLength; 246 } 247 248 251 public void clearBuffer() 252 { 253 TempBuffer next = _head.getNext(); 254 if (next != null) { 255 _head.setNext(null); 256 TempBuffer.freeAll(next); 257 } 258 _head.clear(); 259 _tail = _head; 260 _byteBuffer = _tail.getBuffer(); 261 _byteLength = 0; 262 263 _charLength = 0; 264 265 _bufferSize = 0; 266 } 267 268 271 public void write(int ch) 272 throws IOException 273 { 274 if (_isClosed) 275 return; 276 else if (_isHead) { 277 return; 278 } 279 280 if (_charLength > 0) 281 flushCharBuffer(); 282 283 if (_bufferCapacity <= _bufferSize + _byteLength + 1) { 284 flushByteBuffer(); 285 } 286 else if (_byteLength == SIZE) { 287 _tail.setLength(_byteLength); 288 _bufferSize += _byteLength; 289 290 TempBuffer tempBuf = TempBuffer.allocate(); 291 _tail.setNext(tempBuf); 292 _tail = tempBuf; 293 294 _byteBuffer = _tail.getBuffer(); 295 _byteLength = 0; 296 } 297 298 _byteBuffer[_byteLength++] = (byte) ch; 299 } 300 301 304 public void write(byte []buffer, int offset, int length) 305 throws IOException 306 { 307 boolean isFinished = false; 308 309 if (_isClosed) 310 return; 311 else if (_isHead) { 312 return; 313 } 314 315 if (_charLength > 0) 316 flushCharBuffer(); 317 318 if (_bufferCapacity <= _bufferSize + _byteLength + length) { 319 if (_bufferSize + _byteLength > 0) 320 flushByteBuffer(); 321 322 if (_bufferCapacity <= length) { 323 _bufferSize = length; 324 writeNext(buffer, offset, length, isFinished); 325 _bufferSize = 0; 326 return; 327 } 328 } 329 330 int byteLength = _byteLength; 331 while (length > 0) { 332 if (SIZE <= byteLength) { 333 _tail.setLength(byteLength); 334 _bufferSize += byteLength; 335 336 TempBuffer tempBuf = TempBuffer.allocate(); 337 _tail.setNext(tempBuf); 338 _tail = tempBuf; 339 340 _byteBuffer = _tail.getBuffer(); 341 byteLength = 0; 342 } 343 344 int sublen = length; 345 if (SIZE - byteLength < sublen) 346 sublen = SIZE - byteLength; 347 348 System.arraycopy(buffer, offset, _byteBuffer, byteLength, sublen); 349 350 offset += sublen; 351 length -= sublen; 352 byteLength += sublen; 353 } 354 355 _byteLength = byteLength; 356 } 357 358 361 public void print(int ch) 362 throws IOException 363 { 364 if (_isClosed) 365 return; 366 else if (_isHead) 367 return; 368 369 _charBuffer[_charLength++] = (char) ch; 370 371 if (_charLength == SIZE) 372 flushCharBuffer(); 373 } 374 375 378 public void print(char []buffer, int offset, int length) 379 throws IOException 380 { 381 if (_isClosed) 382 return; 383 else if (_isHead) 384 return; 385 386 int charLength = _charLength; 387 388 while (length > 0) { 389 int sublen = SIZE - charLength; 390 391 if (length < sublen) 392 sublen = length; 393 394 System.arraycopy(buffer, offset, _charBuffer, charLength, sublen); 395 396 offset += sublen; 397 length -= sublen; 398 charLength += sublen; 399 400 if (charLength == SIZE) { 401 _charLength = charLength; 402 charLength = 0; 403 flushCharBuffer(); 404 } 405 } 406 407 _charLength = charLength; 408 } 409 410 413 public void flushBuffer() 414 throws IOException 415 { 416 if (_charLength > 0) 417 flushCharBuffer(); 418 419 flushByteBuffer(); 420 } 421 422 425 public void flush() 426 throws IOException 427 { 428 flushBuffer(); 429 } 430 431 434 public void close() 435 throws IOException 436 { 437 flushBuffer(); 438 439 _isClosed = true; 440 } 441 442 445 public char []nextCharBuffer(int offset) 446 throws IOException 447 { 448 _charLength = offset; 449 flushCharBuffer(); 450 451 return _charBuffer; 452 } 453 454 457 protected void flushCharBuffer() 458 throws IOException 459 { 460 int charLength = _charLength; 461 _charLength = 0; 462 463 if (charLength > 0) { 464 _toByte.write(this, _charBuffer, 0, charLength); 465 466 if (_bufferCapacity <= _byteLength + _bufferSize) 467 flushByteBuffer(); 468 } 469 } 470 471 474 public byte []nextBuffer(int offset) 475 throws IOException 476 { 477 if (_byteLength + _bufferSize < _bufferCapacity) { 478 _tail.setLength(offset); 479 _bufferSize += offset; 480 481 TempBuffer tempBuf = TempBuffer.allocate(); 482 _tail.setNext(tempBuf); 483 _tail = tempBuf; 484 485 _byteBuffer = _tail.getBuffer(); 486 _byteLength = 0; 487 } 488 else { 489 _byteLength = offset; 490 flushByteBuffer(); 491 } 492 493 return _byteBuffer; 494 } 495 496 499 protected void flushByteBuffer() 500 throws IOException 501 { 502 _tail.setLength(_byteLength); 503 _bufferSize += _byteLength; 504 _byteLength = 0; 505 506 TempBuffer ptr = _head; 507 do { 508 _head = ptr; 509 510 TempBuffer next = ptr.getNext(); 511 ptr.setNext(null); 512 513 writeNext(ptr.getBuffer(), 0, ptr.getLength(), _isFinished); 514 515 if (next != null) 516 TempBuffer.free(ptr); 517 518 ptr = next; 519 } while (ptr != null); 520 521 _tail = _head; 522 _byteBuffer = _tail.getBuffer(); 523 _bufferSize = 0; 524 } 525 526 529 abstract protected void writeNext(byte []buffer, int offset, 530 int length, boolean isEnd) 531 throws IOException ; 532 533 536 public void clearClose() 537 { 538 _isClosed = false; 539 } 540 } 541 | Popular Tags |