1 2 24 25 26 27 28 package com.lutris.util; 29 import java.io.FilterInputStream ; 30 import java.io.IOException ; 31 import java.io.InputStream ; 32 33 41 public class BMByteSearchStream extends FilterInputStream 42 { 43 46 public static final int EOF = -1; 47 48 52 public static final int AT_PATTERN = -2; 53 54 57 private BMByteSearch searcher; 58 59 63 private byte[] scanBuf; 64 65 68 private int scanBufPos; 69 70 73 private int scanBufCount; 74 75 78 private int scanBufSize; 79 80 83 private int patternLength; 84 85 90 private int patternKeep; 91 92 97 private int patternPos; 98 99 103 private byte[] readByte = new byte[1]; 104 105 116 public 117 BMByteSearchStream(InputStream inputSource, String pattern, int buflen) 118 { 119 super(inputSource); scanBuf = new byte[buflen]; 121 scanBufSize = buflen; 122 scanBufPos = 0; 123 scanBufCount = 0; 124 setPattern(pattern); 125 } 126 127 139 public 140 int read() 141 throws IOException 142 { 143 int len = read(readByte, 0, 1); 144 if (len != 1) return -1; 145 return ((int)readByte[0] + 0x100) & 0xff; 146 } 147 148 159 public 160 int read(byte[] buffer) 161 throws IOException 162 { 163 return(read(buffer, 0, buffer.length)); 164 } 165 166 178 public 179 int read(byte[] buffer, int offset, int length) 180 throws IOException 181 { 182 int count, dst, i; 183 while ((count = min(length, scanBufCount - patternKeep)) <= 0) { 184 if (loadBuf() < 0) { 185 count = min(length, scanBufCount); 190 if (count <= 0) { 191 patternPos = -1; 192 return EOF; 193 } 194 break; 195 } 196 } 197 for (dst=offset, i=count; i > 0; i--) { 198 buffer[dst++] = scanBuf[scanBufPos++]; 199 } 200 scanBufCount -= count; 201 if ((scanBufPos > patternPos) && (patternPos >= 0)) { 202 patternPos = searcher.search(scanBuf, scanBufPos, scanBufCount); 203 } 204 return count; 205 } 206 207 217 public 218 long skip(long n) 219 throws IOException 220 { 221 byte[] skipBuf = new byte[1024]; 222 long bytesLeft = n; 223 long skipped=0; 224 long r, count; 225 while (bytesLeft > 0) { 226 if (bytesLeft < 1024) count = bytesLeft; 227 else count = 1024; 228 if ((r = this.read(skipBuf, 0, (int)count))<0) { 229 patternPos = -1; 230 return(skipped); } 232 skipped += r; 233 bytesLeft -= r; 234 } 235 if ((scanBufPos > patternPos) && (patternPos >= 0)) { 236 patternPos = searcher.search(scanBuf, scanBufPos, scanBufCount); 237 } 238 return skipped; 239 } 240 241 251 public int 252 available() 253 throws IOException 254 { 255 return(scanBufCount + super.available()); 256 } 257 258 275 public int 276 availableTo() 277 throws IOException 278 { 279 return (patternPos < 0) ? scanBufCount - patternLength : patternPos - scanBufPos; 280 } 281 282 283 284 296 public 297 int readTo(byte[] buffer, int offset, int length) 298 throws IOException 299 { 300 int count, dst, i; 301 if (patternPos == scanBufPos) return AT_PATTERN; 302 if (patternPos > scanBufPos) { 303 count = min(length, patternPos - scanBufPos); 304 for (dst=offset, i=count; i > 0; i--) { 305 buffer[dst++] = scanBuf[scanBufPos++]; 306 } 307 scanBufCount -= count; 308 return count; 309 } 310 while ((count = min(length, scanBufCount - patternKeep)) <= 0) { 311 if (loadBuf() < 0) { 312 count = min(length, scanBufCount); 317 if (count <= 0) return EOF; 318 break; 319 } 320 if (patternPos == scanBufPos) return AT_PATTERN; 322 if (patternPos > scanBufPos) { 323 count = min(length, patternPos - scanBufPos); 324 for (dst=offset, i=count; i > 0; i--) { 325 buffer[dst++] = scanBuf[scanBufPos++]; 326 } 327 scanBufCount -= count; 328 return count; 329 } 330 } 331 for (dst=offset, i=count; i > 0; i--) { 332 buffer[dst++] = scanBuf[scanBufPos++]; 333 } 334 scanBufCount -= count; 335 return count; 336 } 337 338 339 349 public 350 int skipTo() 351 throws IOException 352 { 353 int count=0, skipCount = 0; 354 while (patternPos < scanBufPos) { 355 count = min(0, scanBufCount - patternKeep); 356 if (count >= 0) { 357 skipCount += count; 358 scanBufCount -= count; 359 scanBufPos += count; 360 } 361 int nread = loadBuf(); 362 if (nread < 0) { 363 boolean notFound = (patternPos < scanBufPos); 364 skipCount += scanBufCount; 365 scanBufCount = 0; 366 scanBufPos = 0; 367 patternPos = -1; 368 if (notFound) return -1; 369 return (skipCount <= 0) ? 0 : skipCount; 370 } 371 if (nread == 0) { 372 if (scanBufCount == scanBuf.length) { 374 int skip = scanBuf.length - patternKeep; 375 scanBufPos = skip; 376 scanBufCount = patternKeep; 377 skipCount += skip; 378 patternPos = -1; } 380 } 381 } 382 count = patternPos - scanBufPos; 383 skipCount += count; 384 scanBufPos += count; 385 scanBufCount -= count; 386 return skipCount; 387 } 388 389 395 public 396 int skipPattern() 397 throws IOException 398 { 399 int skipCount = skipTo(); 400 if (skipCount < 0) return -1; skipCount += patternLength; 402 scanBufCount -= patternLength; 403 scanBufPos += patternLength; 404 if (scanBufCount > 0) { 405 patternPos = searcher.search(scanBuf, scanBufPos, scanBufCount); 406 } 407 return skipCount; 408 } 409 410 417 public 418 void setPattern(String pattern) 419 { 420 searcher = new BMByteSearch(pattern); 421 patternLength = searcher.getPatternLength(); 422 patternKeep = patternLength + 2; patternPos = searcher.search(scanBuf, scanBufPos, scanBufCount); 424 } 425 426 433 public 434 void setPattern(BMByteSearch search) 435 { 436 searcher = search; 437 patternLength = searcher.getPatternLength(); 438 patternKeep = patternLength + 2; patternPos = searcher.search(scanBuf, scanBufPos, scanBufCount); 440 } 441 442 453 public 454 String peekAheadString(int length) 455 throws IOException 456 { 457 while (scanBufCount < length) { 458 if (loadBuf() < 0) break; 459 } 460 int count = min(length, scanBufCount); 461 if (count <= 0) return ""; 462 StringBuffer sb = new StringBuffer (); 463 for (int i=scanBufPos; count > 0; i++, count--) { 464 sb.append((char)(scanBuf[i] & 0xff)); 465 } 466 return sb.toString(); 467 } 468 469 482 private 483 int loadBuf() 484 throws IOException 485 { 486 if (scanBufPos > 0) { 490 for (int i=0; i<scanBufCount; i++) { 491 scanBuf[i] = scanBuf[scanBufPos + i]; 492 } 493 scanBufPos = 0; 494 } 495 496 int n, avail = super.available(); 502 if (avail == 0) { 503 n = super.read(scanBuf, scanBufCount, 1); 505 if (n <= 0) { 506 patternPos = searcher.search(scanBuf, 0, scanBufCount); 507 return EOF; 508 } 509 scanBufCount += n; 510 avail = super.available(); 511 if (avail == 0) { 512 patternPos = searcher.search(scanBuf, 0, scanBufCount); 513 return n; 514 } 515 } 516 517 int nread = scanBufSize - scanBufCount; 522 if ((avail >= 0) && (nread > avail)) nread = avail; 523 524 n = super.read(scanBuf, scanBufCount, nread); 528 529 if (n < 0) { 530 patternPos = searcher.search(scanBuf, 0, scanBufCount); 531 return EOF; 532 } 533 scanBufCount += n; 534 535 patternPos = searcher.search(scanBuf, 0, scanBufCount); 539 return n; 540 } 541 542 549 private static final 550 int min(int i1, int i2) 551 { 552 return (i1 < i2) ? i1 : i2; 553 } 554 } 555 556 | Popular Tags |