1 16 package org.mortbay.http; 17 18 import java.io.IOException ; 19 import java.io.OutputStream ; 20 21 22 26 public class ChunkingOutputStream 27 extends BufferedOutputStream 28 implements HttpMessage.HeaderWriter 29 { 30 31 final static byte[] 32 __CRLF = {(byte)'\015',(byte)'\012'}; 33 final static byte[] 34 __CHUNK_EOF ={(byte)'0',(byte)'\015',(byte)'\012',(byte)'\015',(byte)'\012'}; 35 36 final static int __CHUNK_RESERVE=8; 37 final static int __EOF_RESERVE=8; 38 39 40 private boolean _chunking; 41 private boolean _complete; 42 private boolean _completed; 43 44 45 48 public ChunkingOutputStream(OutputStream outputStream, 49 int bufferSize, 50 int headerReserve) 51 { 52 this(outputStream,bufferSize,headerReserve,true); 53 } 54 55 58 public ChunkingOutputStream(OutputStream outputStream, 59 int bufferSize, 60 int headerReserve, 61 boolean chunking) 62 { 63 super(outputStream, 64 bufferSize, 65 headerReserve, 66 __CHUNK_RESERVE, 67 __EOF_RESERVE); 68 _chunking=chunking; 69 setBypassBuffer(true); 70 setFixed(true); 71 } 72 73 74 public boolean isChunking() 75 { 76 return _chunking; 77 } 78 79 80 public void setChunking(boolean chunking) 81 { 82 _chunking=chunking; 83 } 84 85 86 public void close() 87 throws IOException 88 { 89 _complete=true; 90 flush(); 91 } 92 93 94 public void resetStream() 95 { 96 _complete=false; 97 _completed=false; 98 _chunking=true; 99 super.resetStream(); 100 } 101 102 103 protected void wrapBuffer() 104 throws IOException 105 { 106 int size=size(); 108 if (_chunking && size()>0) 109 { 110 prewrite(__CRLF,0,__CRLF.length); 111 while (size>0) 112 { 113 int d=size%16; 114 if (d<=9) 115 prewrite('0'+d); 116 else 117 prewrite('a'-10+d); 118 size=size/16; 119 } 120 postwrite(__CRLF,0,__CRLF.length); 121 } 122 123 if (_complete && !_completed) 125 { 126 _completed=true; 127 if (_chunking) 128 postwrite(__CHUNK_EOF,0,__CHUNK_EOF.length); 129 } 130 } 131 132 133 protected void bypassWrite(byte[] b, int offset, int length) 134 throws IOException 135 { 136 int i=9; 137 int chunk=length; 138 _buf[10]=(byte)'\012'; 139 _buf[9]=(byte)'\015'; 140 while (chunk>0) 141 { 142 int d=chunk%16; 143 if (d<=9) 144 _buf[--i]=(byte)('0'+d); 145 else 146 _buf[--i]=(byte)('a'-10+d); 147 chunk=chunk/16; 148 } 149 if (_chunking) 150 _out.write(_buf,i,10-i+1); 151 _out.write(b,offset,length); 152 if (_chunking) 153 _out.write(__CRLF,0,__CRLF.length); 154 _out.flush(); 155 } 156 157 } 158 159 160 | Popular Tags |