1 16 package org.apache.axis.attachments; 17 18 import org.apache.axis.components.logger.LogFactory; 19 import org.apache.axis.utils.Messages; 20 import org.apache.commons.logging.Log; 21 22 23 28 public class BoundaryDelimitedStream extends java.io.FilterInputStream { 29 30 31 protected static Log log = 32 LogFactory.getLog(BoundaryDelimitedStream.class.getName()); 33 34 protected byte[] boundary = null; 35 36 37 int boundaryLen = 0; 38 39 40 int boundaryBufLen = 0; 41 42 43 java.io.InputStream is = null; 44 45 46 boolean closed = true; 47 48 49 boolean eos = false; 50 51 52 boolean theEnd = false; 53 54 55 int readbufsz = 0; 56 57 58 byte[] readbuf = null; 59 60 61 int readBufPos = 0; 62 63 64 int readBufEnd = 0; 65 66 67 protected static final int BOUNDARY_NOT_FOUND = Integer.MAX_VALUE; 68 69 71 72 int boundaryPos = BOUNDARY_NOT_FOUND; 73 74 75 static int streamCount = 0; 76 77 82 protected static synchronized int newStreamNo() { 83 84 log.debug(Messages.getMessage("streamNo", "" + (streamCount + 1))); 85 86 return ++streamCount; 87 } 88 89 90 protected int streamNo = -1; 92 93 static boolean isDebugEnabled = false; 94 95 103 public synchronized BoundaryDelimitedStream getNextStream() throws java.io.IOException { 104 return getNextStream(readbufsz); 105 } 106 107 115 protected synchronized BoundaryDelimitedStream getNextStream( 116 int readbufsz) throws java.io.IOException { 117 118 BoundaryDelimitedStream ret = null; 119 120 if (!theEnd) { 121 122 ret = new BoundaryDelimitedStream(this, readbufsz); 124 } 125 126 return ret; 127 } 128 129 137 protected BoundaryDelimitedStream(BoundaryDelimitedStream prev, 138 int readbufsz) 139 throws java.io.IOException 140 { 141 super(null); 142 143 streamNo = newStreamNo(); 144 boundary = prev.boundary; 145 boundaryLen = prev.boundaryLen; 146 boundaryBufLen = prev.boundaryBufLen; 147 skip = prev.skip; 148 is = prev.is; 149 closed = false; eos = false; readbufsz = prev.readbufsz; 152 readbuf = prev.readbuf; 153 154 readBufPos = prev.readBufPos + boundaryBufLen; 156 readBufEnd = prev.readBufEnd; 157 158 boundaryPos = boundaryPosition(readbuf, readBufPos, readBufEnd); 160 prev.theEnd = theEnd; } 162 163 173 BoundaryDelimitedStream( 174 java.io.InputStream is, byte[] boundary, int readbufsz) 175 throws org.apache.axis.AxisFault { 176 177 super(null); 180 isDebugEnabled = log.isDebugEnabled(); 181 streamNo = newStreamNo(); 182 closed = false; 183 this.is = is; 184 185 this.boundary = new byte[boundary.length]; 187 188 System.arraycopy(boundary, 0, this.boundary, 0, boundary.length); 189 190 this.boundaryLen = this.boundary.length; 191 this.boundaryBufLen = boundaryLen + 2; 192 193 this.readbufsz = Math.max((boundaryBufLen) * 2, readbufsz); 196 } 197 198 private final int readFromStream(final byte[] b) 199 throws java.io.IOException { 200 return readFromStream(b, 0, b.length); 201 } 202 203 private final int readFromStream( 204 final byte[] b, final int start, final int length) 205 throws java.io.IOException { 206 207 int minRead = Math.max(boundaryBufLen * 2, length); 208 209 minRead = Math.min(minRead, length - start); 210 211 int br = 0; 212 int brTotal = 0; 213 214 do { 215 br = is.read(b, brTotal + start, length - brTotal); 216 217 if (br > 0) { 218 brTotal += br; 219 } 220 } while ((br > -1) && (brTotal < minRead)); 221 222 return (brTotal != 0) 223 ? brTotal 224 : br; 225 } 226 227 236 public synchronized int read(byte[] b, final int off, final int len) 237 throws java.io.IOException { 238 239 if (closed) { 240 throw new java.io.IOException (Messages.getMessage("streamClosed")); 241 } 242 243 if (eos) { 244 return -1; 245 } 246 247 if (readbuf == null) { readbuf = new byte[Math.max(len, readbufsz)]; 249 readBufEnd = readFromStream(readbuf); 250 251 if (readBufEnd < 0) { 252 readbuf = null; 253 closed = true; 254 finalClose(); 255 256 throw new java.io.IOException ( 257 Messages.getMessage("eosBeforeMarker")); 258 } 259 260 readBufPos = 0; 261 262 boundaryPos = boundaryPosition(readbuf, 0, readBufEnd); 264 } 265 266 int bwritten = 0; 268 do { int bcopy = Math.min(readBufEnd - readBufPos - boundaryBufLen, 271 len - bwritten); 272 273 bcopy = Math.min(bcopy, boundaryPos - readBufPos); 275 276 if (bcopy > 0) { 277 System.arraycopy(readbuf, readBufPos, b, off + bwritten, bcopy); 278 279 bwritten += bcopy; 280 readBufPos += bcopy; 281 } 282 283 if (readBufPos == boundaryPos) { 284 eos = true; 286 log.debug(Messages.getMessage("atEOS", "" + streamNo)); 287 } else if (bwritten < len) { byte[] dstbuf = readbuf; 289 290 if (readbuf.length < len) { 291 dstbuf = new byte[len]; 292 } 293 294 int movecnt = readBufEnd - readBufPos; 295 296 System.arraycopy(readbuf, readBufPos, dstbuf, 0, movecnt); 298 299 int readcnt = readFromStream(dstbuf, movecnt, 301 dstbuf.length - movecnt); 302 303 if (readcnt < 0) { 304 readbuf = null; 305 closed = true; 306 finalClose(); 307 308 throw new java.io.IOException ( 309 Messages.getMessage("eosBeforeMarker")); 310 } 311 312 readBufEnd = readcnt + movecnt; 313 readbuf = dstbuf; 314 readBufPos = 0; 316 if (BOUNDARY_NOT_FOUND != boundaryPos) { 318 boundaryPos -= movecnt; 319 } else { 320 boundaryPos = boundaryPosition( 321 readbuf, readBufPos, 322 readBufEnd); } 324 } 325 } 326 327 while (!eos && (bwritten < len)); 329 330 if (log.isDebugEnabled()) { 331 if (bwritten > 0) { 332 byte tb[] = new byte[bwritten]; 333 334 System.arraycopy(b, off, tb, 0, bwritten); 335 log.debug(Messages.getMessage("readBStream", 336 new String []{"" + bwritten, 337 "" + streamNo, 338 new String (tb)})); 339 } 340 } 341 342 if (eos && theEnd) { 343 readbuf = null; } 345 346 return bwritten; 347 } 348 349 357 public int read(byte[] b) throws java.io.IOException { 358 return read(b, 0, b.length); 359 } 360 361 367 public int read() throws java.io.IOException { 368 369 byte[] b = new byte[1]; int read = read(b); 371 372 if (read < 0) { 373 return -1; 374 } else { 375 return b[0]&0xff; 376 } 377 } 378 379 384 public synchronized void close() throws java.io.IOException { 385 386 if (closed) { 387 return; 388 } 389 390 log.debug(Messages.getMessage("bStreamClosed", "" + streamNo)); 391 392 closed = true; 394 if (!eos) { 396 byte[] readrest = new byte[1024 * 16]; 398 int bread = 0; 399 400 do { 401 bread = read(readrest); 402 } while (bread > -1); 403 } 404 } 405 406 412 public void mark(int readlimit) { 413 414 } 416 417 423 public void reset() throws java.io.IOException { 424 throw new java.io.IOException ( 425 Messages.getMessage("attach.bounday.mns")); 426 } 427 428 434 public boolean markSupported() { 435 return false; 436 } 437 438 public int available() throws java.io.IOException { 439 440 int bcopy = readBufEnd - readBufPos - boundaryBufLen; 441 442 bcopy = Math.min(bcopy, boundaryPos - readBufPos); 444 445 return Math.max(0, bcopy); 446 } 447 448 458 protected int boundaryPosition(byte[] searchbuf, int start, int end) throws java.io.IOException { 459 460 int foundAt = boundarySearch(searchbuf, start, end); 461 462 if (BOUNDARY_NOT_FOUND != foundAt) { if (foundAt + boundaryLen + 2 > end) { 465 foundAt = BOUNDARY_NOT_FOUND; 466 } else { 467 468 if ((searchbuf[foundAt + boundaryLen] == '-') 470 && (searchbuf[foundAt + boundaryLen + 1] == '-')) { 471 finalClose(); 472 } else if ((searchbuf[foundAt + boundaryLen] != 13) 473 || (searchbuf[foundAt + boundaryLen + 1] != 10)) { 474 475 foundAt = BOUNDARY_NOT_FOUND; 477 } 478 } 479 } 480 481 return foundAt; 482 } 483 484 485 486 private int[] skip = null; 487 488 private int boundarySearch(final byte[] text, final int start, 489 final int end) { 490 491 int i = 0, j = 0, k = 0; 493 494 if (boundaryLen > (end - start)) { 495 return BOUNDARY_NOT_FOUND; 496 } 497 498 if (null == skip) { 499 skip = new int[256]; 500 501 java.util.Arrays.fill(skip, boundaryLen); 502 503 for (k = 0; k < boundaryLen - 1; k++) { 504 skip[boundary[k]] = boundaryLen - k - 1; 505 } 506 } 507 508 for (k = start + boundaryLen - 1; k < end; 509 k += skip[text[k] & (0xff)]) { 510 511 try { 514 for (j = boundaryLen - 1, i = k; 515 (j >= 0) && (text[i] == boundary[j]); j--) { 516 i--; 517 } 518 } catch (ArrayIndexOutOfBoundsException e) { 519 StringBuffer sb = new StringBuffer (); 520 sb.append( 521 ">>>" 522 + e); sb.append("start=" + start); 524 sb.append("k=" + k); 525 sb.append("text.length=" + text.length); 526 sb.append("i=" + i); 527 sb.append("boundary.length=" + boundary.length); 528 sb.append("j=" + j); 529 sb.append("end=" + end); 530 log.warn(Messages.getMessage("exception01",sb.toString())); 531 throw e; 532 } 533 534 if (j == (-1)) { 535 return i + 1; 536 } 537 } 538 539 return BOUNDARY_NOT_FOUND; 541 } 542 543 548 protected void finalClose() throws java.io.IOException { 549 if(theEnd) return; 550 theEnd= true; 551 is.close(); 552 is= null; 553 } 554 555 562 public static void printarry(byte[] b, int start, int end) { 563 564 if (log.isDebugEnabled()) { 565 byte tb[] = new byte[end - start]; 566 567 System.arraycopy(b, start, tb, 0, end - start); 568 log.debug("\"" + new String (tb) + "\""); 569 } 570 } 571 } 572 | Popular Tags |