1 16 package org.mortbay.util; 17 import java.io.IOException ; 18 import java.io.OutputStream ; 19 20 import org.apache.commons.logging.Log; 21 import org.mortbay.log.LogFactory; 22 23 24 32 public class ByteBufferOutputStream extends OutputStream 33 { 34 private static Log log = LogFactory.getLog(ByteBufferOutputStream.class); 35 36 protected byte[] _buf; 37 38 40 private int _start; 41 42 44 private int _end; 45 46 49 private int _pos; 50 51 private int _preReserve; 52 private int _postReserve; 53 private boolean _resized; 54 private boolean _fixed ; 55 56 57 59 public ByteBufferOutputStream(){this(4096,0,0);} 60 61 62 65 public ByteBufferOutputStream(int capacity) 66 { 67 this(capacity,0,0); 68 } 69 70 71 75 public ByteBufferOutputStream(int capacity,int preReserve) 76 { 77 this(capacity,preReserve,0); 78 } 79 80 81 86 public ByteBufferOutputStream(int bufferSize,int preReserve,int postReserve) 87 { 88 _buf=ByteArrayPool.getByteArray(bufferSize); 89 _end=_buf.length-postReserve; 90 _preReserve=preReserve; 91 _start=preReserve; 92 _pos=preReserve; 93 _postReserve=postReserve; 94 } 95 96 97 100 public boolean isFixed() 101 { 102 return _fixed; 103 } 104 105 106 109 public void setFixed(boolean fixed) 110 { 111 _fixed = fixed; 112 } 113 114 115 118 public int size() 119 { 120 return _pos-_start; 121 } 122 123 124 127 public int bufferSize() 128 { 129 return _buf.length; 130 } 131 132 133 136 public int capacity() 137 { 138 return _end-_start; 139 } 140 141 142 146 public int spareCapacity() 147 { 148 return _end-_pos; 149 } 150 151 152 155 public int preReserve() 156 { 157 return _start; 158 } 159 160 161 164 public int postReserve() 165 { 166 return _buf.length-_end; 167 } 168 169 170 public void writeTo(OutputStream out) 171 throws IOException 172 { 173 out.write(_buf,_start,_pos-_start); 174 } 175 176 177 public void write(int b) 178 throws IOException 179 { 180 ensureSpareCapacity(1); 181 _buf[_pos++]=(byte)b; 182 } 183 184 185 public void write(byte[] b) 186 throws IOException 187 { 188 ensureSpareCapacity(b.length); 189 System.arraycopy(b,0,_buf,_pos,b.length); 190 _pos+=b.length; 191 } 192 193 194 public void write(byte[] b,int offset, int length) 195 throws IOException 196 { 197 ensureSpareCapacity(length); 198 System.arraycopy(b,offset,_buf,_pos,length); 199 _pos+=length; 200 } 201 202 203 206 public void prewrite(int b) 207 { 208 ensureReserve(1); 209 _buf[--_start]=(byte)b; 210 } 211 212 213 216 public void prewrite(byte[] b) 217 { 218 ensureReserve(b.length); 219 System.arraycopy(b,0,_buf,_start-b.length,b.length); 220 _start-=b.length; 221 } 222 223 224 229 public void prewrite(byte[] b,int offset, int length) 230 { 231 ensureReserve(length); 232 System.arraycopy(b,offset,_buf,_start-length,length); 233 _start-=length; 234 } 235 236 237 244 public void postwrite(byte b) 245 throws IOException 246 { 247 _buf[_pos++]=b; 248 } 249 250 251 258 public void postwrite(byte[] b,int offset, int length) 259 throws IOException 260 { 261 System.arraycopy(b,offset,_buf,_pos,length); 262 _pos+=length; 263 } 264 265 266 public void flush() 267 throws IOException 268 { 269 } 270 271 272 public void resetStream() 273 { 274 _pos=_preReserve; 275 _start=_preReserve; 276 } 277 278 279 public void reset(int reserve) 280 { 281 _preReserve=reserve; 282 _pos=_preReserve; 283 _start=_preReserve; 284 } 285 286 287 public void close() 288 throws IOException 289 { 290 flush(); 291 } 292 293 294 public void destroy() 295 { 296 if (!_resized) 297 ByteArrayPool.returnByteArray(_buf); 298 _buf=null; 299 } 300 301 302 public void ensureReserve(int n) 303 { 304 if (n>_start) 305 { 306 if (log.isDebugEnabled())log.debug("Reserve: "+n+">"+_start); 307 if ((_pos+n)<_end) 308 { 309 if (log.isDebugEnabled())log.debug("Shift reserve: "+_pos+"+"+n+"<"+_end); 310 System.arraycopy(_buf,_start,_buf,n,_pos-_start); 311 _pos=_pos+n-_start; 312 _start=n; 313 } 314 else 315 { 316 if (log.isDebugEnabled())log.debug("New reserve: "+_pos+"+"+n+">="+_end); 317 byte[] buf = new byte[_buf.length+n-_start]; 318 System.arraycopy(_buf,_start,buf,n,_pos-_start); 319 _pos=n+_pos-_start; 320 _start=n; 321 _buf=buf; 322 _end=_buf.length-_postReserve; 323 } 324 } 325 } 326 327 328 329 public void ensureSize(int bufSize) 330 throws IOException 331 { 332 ensureSize(bufSize,_preReserve,_postReserve); 333 } 334 335 336 public void ensureSize(int bufSize, int pre, int post) 337 throws IOException 338 { 339 if (bufSize>_buf.length || pre>_preReserve || post>_postReserve) 341 { 342 if (_fixed) 344 throw new IllegalStateException ("Fixed"); 345 346 byte[] old=_buf; 347 _buf=ByteArrayPool.getByteArray(bufSize); 348 349 if (_pos>_start) 350 System.arraycopy(old,_start,_buf,pre,_pos-_start); 351 if (!_resized) 352 ByteArrayPool.returnByteArray(old); 353 354 _end=_buf.length-post; 355 _preReserve=pre; 356 _start=pre; 357 _pos=pre; 358 _postReserve=post; 359 } 360 } 361 362 363 public void ensureSpareCapacity(int n) 364 throws IOException 365 { 366 if (n>spareCapacity()) 368 { 369 if (_pos>_start ) 371 flush(); 372 373 ensureCapacity(n); 374 } 375 } 376 377 378 public void ensureCapacity(int n) 379 throws IOException 380 { 381 if (n>capacity()) 383 { 384 if (_fixed) 386 throw new IllegalStateException ("Fixed"); 387 388 int new_size = ((n+_preReserve+_postReserve+4095)/4096)*4096; 389 390 byte[] old = _buf; 391 _buf = new byte[new_size]; 392 if (_pos>_start) 393 System.arraycopy(old,_start,_buf,_start,_pos-_start); 394 if (!_resized) 395 ByteArrayPool.returnByteArray(old); 396 397 _end=_buf.length-_postReserve; 398 _resized=true; 399 } 400 } 401 } 402 403 404 | Popular Tags |