1 16 package org.jboss.axis.attachments; 17 18 import org.jboss.axis.utils.Messages; 19 import org.jboss.logging.Logger; 20 21 import java.io.FilterInputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 25 26 31 public class BoundaryDelimitedStream extends FilterInputStream 32 { 33 34 35 private static Logger log = Logger.getLogger(BoundaryDelimitedStream.class.getName()); 36 37 protected byte[] boundary = null; 38 39 40 int boundaryLen = 0; 41 42 43 int boundaryBufLen = 0; 44 45 46 InputStream is = null; 47 48 49 boolean closed = true; 50 51 52 boolean eos = false; 53 54 55 boolean theEnd = false; 56 57 58 int readbufsz = 0; 59 60 61 byte[] readbuf = null; 62 63 64 int readBufPos = 0; 65 66 67 int readBufEnd = 0; 68 69 70 protected static final int BOUNDARY_NOT_FOUND = Integer.MAX_VALUE; 71 72 74 75 int boundaryPos = BOUNDARY_NOT_FOUND; 76 77 78 static int streamCount = 0; 79 80 85 protected static synchronized int newStreamNo() 86 { 87 88 log.debug(Messages.getMessage("streamNo", "" + (streamCount + 1))); 89 90 return ++streamCount; 91 } 92 93 94 protected int streamNo = -1; 96 97 static boolean isDebugEnabled = false; 98 99 107 public synchronized BoundaryDelimitedStream getNextStream() throws IOException 108 { 109 return getNextStream(readbufsz); 110 } 111 112 120 protected synchronized BoundaryDelimitedStream getNextStream(int readbufsz) throws IOException 121 { 122 123 BoundaryDelimitedStream ret = null; 124 125 if (!theEnd) 126 { 127 128 ret = new BoundaryDelimitedStream(this, readbufsz); 130 } 131 132 return ret; 133 } 134 135 143 protected BoundaryDelimitedStream(BoundaryDelimitedStream prev, 144 int readbufsz) 145 throws IOException 146 { 147 super(null); 148 149 streamNo = newStreamNo(); 150 boundary = prev.boundary; 151 boundaryLen = prev.boundaryLen; 152 boundaryBufLen = prev.boundaryBufLen; 153 skip = prev.skip; 154 is = prev.is; 155 closed = false; eos = false; readbufsz = prev.readbufsz; 158 readbuf = prev.readbuf; 159 160 readBufPos = prev.readBufPos + boundaryBufLen; 162 readBufEnd = prev.readBufEnd; 163 164 boundaryPos = boundaryPosition(readbuf, readBufPos, readBufEnd); 166 prev.theEnd = theEnd; } 168 169 177 BoundaryDelimitedStream(InputStream is, byte[] boundary, int readbufsz) 178 { 179 180 super(null); 183 isDebugEnabled = log.isDebugEnabled(); 184 streamNo = newStreamNo(); 185 closed = false; 186 this.is = is; 187 188 this.boundary = new byte[boundary.length]; 190 191 System.arraycopy(boundary, 0, this.boundary, 0, boundary.length); 192 193 this.boundaryLen = this.boundary.length; 194 this.boundaryBufLen = boundaryLen + 2; 195 196 this.readbufsz = Math.max((boundaryBufLen) * 2, readbufsz); 199 } 200 201 private final int readFromStream(final byte[] b) 202 throws IOException 203 { 204 return readFromStream(b, 0, b.length); 205 } 206 207 private final int readFromStream(final byte[] b, final int start, final int length) 208 throws IOException 209 { 210 211 int minRead = Math.max(boundaryBufLen * 2, length); 212 213 minRead = Math.min(minRead, length - start); 214 215 int br = 0; 216 int brTotal = 0; 217 218 do 219 { 220 br = is.read(b, brTotal + start, length - brTotal); 221 222 if (br > 0) 223 { 224 brTotal += br; 225 } 226 } 227 while ((br > -1) && (brTotal < minRead)); 228 229 return (brTotal != 0) 230 ? brTotal 231 : br; 232 } 233 234 243 public synchronized int read(byte[] b, final int off, final int len) 244 throws IOException 245 { 246 247 if (closed) 248 { 249 throw new IOException (Messages.getMessage("streamClosed")); 250 } 251 252 if (eos) 253 { 254 return -1; 255 } 256 257 if (readbuf == null) 258 { readbuf = new byte[Math.max(len, readbufsz)]; 260 readBufEnd = readFromStream(readbuf); 261 262 if (readBufEnd < 0) 263 { 264 readbuf = null; 265 closed = true; 266 finalClose(); 267 268 throw new IOException (Messages.getMessage("eosBeforeMarker")); 269 } 270 271 readBufPos = 0; 272 273 boundaryPos = boundaryPosition(readbuf, 0, readBufEnd); 275 } 276 277 int bwritten = 0; 279 do 281 { int bcopy = Math.min(readBufEnd - readBufPos - boundaryBufLen, 283 len - bwritten); 284 285 bcopy = Math.min(bcopy, boundaryPos - readBufPos); 287 288 if (bcopy > 0) 289 { 290 System.arraycopy(readbuf, readBufPos, b, off + bwritten, bcopy); 291 292 bwritten += bcopy; 293 readBufPos += bcopy; 294 } 295 296 if (readBufPos == boundaryPos) 297 { 298 eos = true; 300 log.debug(Messages.getMessage("atEOS", "" + streamNo)); 301 } 302 else if (bwritten < len) 303 { byte[] dstbuf = readbuf; 305 306 if (readbuf.length < len) 307 { 308 dstbuf = new byte[len]; 309 } 310 311 int movecnt = readBufEnd - readBufPos; 312 313 System.arraycopy(readbuf, readBufPos, dstbuf, 0, movecnt); 315 316 int readcnt = readFromStream(dstbuf, movecnt, 318 dstbuf.length - movecnt); 319 320 if (readcnt < 0) 321 { 322 readbuf = null; 323 closed = true; 324 finalClose(); 325 326 throw new IOException (Messages.getMessage("eosBeforeMarker")); 327 } 328 329 readBufEnd = readcnt + movecnt; 330 readbuf = dstbuf; 331 readBufPos = 0; 333 if (BOUNDARY_NOT_FOUND != boundaryPos) 335 { 336 boundaryPos -= movecnt; 337 } 338 else 339 { 340 boundaryPos = boundaryPosition(readbuf, readBufPos, 341 readBufEnd); } 343 } 344 } 345 346 while (!eos && (bwritten < len)); 348 349 if (log.isDebugEnabled()) 350 { 351 if (bwritten > 0) 352 { 353 byte tb[] = new byte[bwritten]; 354 355 System.arraycopy(b, off, tb, 0, bwritten); 356 log.trace(Messages.getMessage("readBStream", new String []{"" + bwritten, "" + streamNo, new String (tb)})); 357 } 358 } 359 360 if (eos && theEnd) 361 { 362 readbuf = null; } 364 365 return bwritten; 366 } 367 368 376 public int read(byte[] b) throws IOException 377 { 378 return read(b, 0, b.length); 379 } 380 381 387 public int read() throws IOException 388 { 389 390 byte[] b = new byte[1]; int read = read(b); 392 393 if (read < 0) 394 { 395 return -1; 396 } 397 else 398 { 399 return b[0] & 0xff; 400 } 401 } 402 403 408 public synchronized void close() throws IOException 409 { 410 411 if (closed) 412 { 413 return; 414 } 415 416 log.debug(Messages.getMessage("bStreamClosed", "" + streamNo)); 417 418 closed = true; 420 if (!eos) 421 { 423 byte[] readrest = new byte[1024 * 16]; 425 int bread = 0; 426 427 do 428 { 429 bread = read(readrest); 430 } 431 while (bread > -1); 432 } 433 } 434 435 441 public void mark(int readlimit) 442 { 443 444 } 446 447 453 public void reset() throws IOException 454 { 455 throw new IOException (Messages.getMessage("attach.bounday.mns")); 456 } 457 458 464 public boolean markSupported() 465 { 466 return false; 467 } 468 469 public int available() throws IOException 470 { 471 472 int bcopy = readBufEnd - readBufPos - boundaryBufLen; 473 474 bcopy = Math.min(bcopy, boundaryPos - readBufPos); 476 477 return Math.max(0, bcopy); 478 } 479 480 490 protected int boundaryPosition(byte[] searchbuf, int start, int end) throws IOException 491 { 492 493 int foundAt = boundarySearch(searchbuf, start, end); 494 495 if (BOUNDARY_NOT_FOUND != foundAt) 497 { if (foundAt + boundaryLen + 2 > end) 499 { 500 foundAt = BOUNDARY_NOT_FOUND; 501 } 502 else 503 { 504 505 if ((searchbuf[foundAt + boundaryLen] == '-') 507 && (searchbuf[foundAt + boundaryLen + 1] == '-')) 508 { 509 finalClose(); 510 } 511 else if ((searchbuf[foundAt + boundaryLen] != 13) 512 || (searchbuf[foundAt + boundaryLen + 1] != 10)) 513 { 514 515 foundAt = BOUNDARY_NOT_FOUND; 517 } 518 } 519 } 520 521 return foundAt; 522 } 523 524 525 526 private int[] skip = null; 527 528 private int boundarySearch(final byte[] text, final int start, 529 final int end) 530 { 531 532 int i = 0, j = 0, k = 0; 534 535 if (boundaryLen > (end - start)) 536 { 537 return BOUNDARY_NOT_FOUND; 538 } 539 540 if (null == skip) 541 { 542 skip = new int[256]; 543 544 java.util.Arrays.fill(skip, boundaryLen); 545 546 for (k = 0; k < boundaryLen - 1; k++) 547 { 548 skip[boundary[k]] = boundaryLen - k - 1; 549 } 550 } 551 552 for (k = start + boundaryLen - 1; k < end; 553 k += skip[text[k] & (0xff)]) 554 { 555 556 try 559 { 560 for (j = boundaryLen - 1, i = k; 561 (j >= 0) && (text[i] == boundary[j]); j--) 562 { 563 i--; 564 } 565 } 566 catch (ArrayIndexOutOfBoundsException e) 567 { 568 StringBuffer sb = new StringBuffer (); 569 sb.append(">>>" 570 + e); sb.append("start=" + start); 572 sb.append("k=" + k); 573 sb.append("text.length=" + text.length); 574 sb.append("i=" + i); 575 sb.append("boundary.length=" + boundary.length); 576 sb.append("j=" + j); 577 sb.append("end=" + end); 578 log.warn(Messages.getMessage("exception01", sb.toString())); 579 throw e; 580 } 581 582 if (j == (-1)) 583 { 584 return i + 1; 585 } 586 } 587 588 return BOUNDARY_NOT_FOUND; 590 } 591 592 597 protected void finalClose() throws IOException 598 { 599 if (theEnd) return; 600 theEnd = true; 601 is.close(); 602 is = null; 603 } 604 605 612 public static void printarry(byte[] b, int start, int end) 613 { 614 615 if (log.isDebugEnabled()) 616 { 617 byte tb[] = new byte[end - start]; 618 619 System.arraycopy(b, start, tb, 0, end - start); 620 log.debug("\"" + new String (tb) + "\""); 621 } 622 } 623 } 624 | Popular Tags |