1 28 29 package org.jibx.runtime.impl; 30 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 import java.io.InputStreamReader ; 34 import java.io.Reader ; 35 36 46 47 public class InputStreamWrapper 48 { 49 50 private static final int BUFFER_SIZE = 2048; 51 52 53 private String m_encodingName; 54 55 56 private InputStream m_stream; 57 58 59 private boolean m_isEnd; 60 61 62 private byte[] m_buffer; 63 64 65 private int m_endOffset; 66 67 68 private int m_emptyOffset; 69 70 71 private int m_scanOffset; 72 73 76 77 public InputStreamWrapper() { 78 m_buffer = new byte[BUFFER_SIZE]; 79 } 80 81 88 89 public void setInput(InputStream ins) { 90 try { 91 close(); 92 } catch (IOException e) { } 93 m_stream = ins; 94 reset(); 95 } 96 97 107 108 public void setInput(InputStream ins, String enc) throws IOException { 109 setInput(ins); 110 setEncoding(enc); 111 } 112 113 121 122 public void setEncoding(String enc) throws IOException { 123 if (m_encodingName == null) { 124 m_encodingName = enc; 125 } else { 126 throw new IOException ("Encoding has already been set for stream"); 127 } 128 } 129 130 141 142 private boolean fillBuffer() throws IOException { 143 if (m_isEnd) { 144 return false; 145 } else { 146 147 int rem = m_endOffset - m_emptyOffset; 149 if (rem > 0) { 150 System.arraycopy(m_buffer, m_emptyOffset, m_buffer, 0, rem); 151 } 152 m_emptyOffset = 0; 153 154 int max = m_buffer.length - rem; 156 int actual = m_stream.read(m_buffer, rem, max); 157 if (actual >= 0) { 158 m_endOffset = rem + actual; 159 return true; 160 } else { 161 m_endOffset = rem; 162 m_isEnd = true; 163 return false; 164 } 165 } 166 } 167 168 180 181 private boolean require(int min) throws IOException { 182 while (m_endOffset - m_emptyOffset < min) { 183 if (!fillBuffer()) { 184 return false; 185 } 186 } 187 return true; 188 } 189 190 195 196 private boolean isWhite(int chr) { 197 return chr == ' ' || chr == 0x09 || chr == 0x0A || chr == 0x0D; 198 } 199 200 207 208 private String scanToken() throws IOException { 209 boolean skipping = true; 210 StringBuffer buff = new StringBuffer (); 211 while (require(m_scanOffset+1)) { 212 char chr = (char)m_buffer[m_scanOffset++]; 213 if (skipping) { 214 if (!isWhite(chr)) { 215 skipping = false; 216 buff.append(chr); 217 if (chr == '=') { 218 return buff.toString(); 219 } 220 } 221 } else if (isWhite(chr) || chr == '=') { 222 m_scanOffset--; 223 return buff.toString(); 224 } else { 225 buff.append(chr); 226 } 227 } 228 return null; 229 } 230 231 239 240 private String scanQuoted() throws IOException { 241 boolean skipping = true; 242 int quot = 0; 243 StringBuffer buff = new StringBuffer (); 244 while (require(m_scanOffset+1)) { 245 char chr = (char)m_buffer[m_scanOffset++]; 246 if (skipping) { 247 if (!isWhite(chr)) { 248 if (chr == '"' || chr == '\'') { 249 skipping = false; 250 quot = chr; 251 } else { 252 break; 253 } 254 } 255 } else if (chr == quot) { 256 return buff.toString(); 257 } else { 258 buff.append(chr); 259 } 260 } 261 return null; 262 } 263 264 273 274 public Reader getReader() throws IOException { 275 276 if (m_encodingName == null) { 278 279 m_encodingName = "UTF-8"; 281 if (require(4)) { 282 283 int bom = (((m_buffer[0] << 8) + (m_buffer[1] & 0xFF) << 8) + 285 (m_buffer[2] & 0xFF) << 8) + (m_buffer[3] & 0xFF); 286 if (bom == 0x3C3F786D) { 287 288 m_scanOffset = 2; 290 String token = scanToken(); 291 if ("xml".equals(token)) { 292 while ((token = scanToken()) != null && 293 !"?>".equals(token)) { 294 if ("encoding".equals(token)) { 295 if ("=".equals(scanToken())) { 296 token = scanQuoted(); 297 if (token != null) { 298 m_encodingName = token; 299 break; 300 } 301 } 302 } else if ("=".equals(token)) { 303 scanQuoted(); 304 } 305 } 306 } 307 308 } else if (bom == 0x0000FEFF || bom == 0xFFFE0000 || 309 bom == 0x0000FFFE || bom == 0xFEFF0000) { 310 311 m_encodingName = "UCS-4"; 313 314 } else if ((bom & 0xFFFFFF00) == 0xEFBBBF00) { 315 316 m_encodingName = "UTF-8"; 318 319 } else { 320 int upper = bom & 0xFFFF0000; 321 if (upper == 0xFEFF0000 || bom == 0x003C003F) { 322 323 m_encodingName = "UTF-16BE"; 325 326 } else if (upper == 0xFFFE0000 || bom == 0x3C003F00) { 327 328 m_encodingName = "UTF-16LE"; 330 331 } else if (bom == 0x4C6FA794){ 332 333 m_encodingName = "EBCDIC"; 335 } 336 } 337 } 338 } 339 if (m_encodingName.equalsIgnoreCase("UTF-8")) { 340 return new WrappedStreamUTF8Reader(); 341 } else if (m_encodingName.equalsIgnoreCase("ISO-8859-1") || 342 m_encodingName.equalsIgnoreCase("ASCII")) { 343 return new WrappedStreamISO88591Reader(); 344 } else { 345 return new InputStreamReader (new WrappedStream(), m_encodingName); 346 } 347 } 348 349 355 356 public String getEncoding() { 357 return m_encodingName; 358 } 359 360 366 367 public void close() throws IOException { 368 if (m_stream != null) { 369 m_stream.close(); 370 m_stream = null; 371 } 372 reset(); 373 } 374 375 378 379 public void reset() { 380 m_isEnd = false; 381 m_endOffset = 0; 382 m_emptyOffset = 0; 383 m_encodingName = null; 384 } 385 386 390 391 private class WrappedStream extends InputStream 392 { 393 396 397 public int available() throws IOException { 398 return m_endOffset - m_emptyOffset + m_stream.available(); 399 } 400 401 404 405 public void close() throws IOException { 406 InputStreamWrapper.this.close(); 407 } 408 409 412 413 public int read(byte[] b, int off, int len) throws IOException { 414 int avail; 415 int actual = 0; 416 while (len > (avail = m_endOffset - m_emptyOffset)) { 417 System.arraycopy(m_buffer, m_emptyOffset, b, off, avail); 418 off += avail; 419 len -= avail; 420 actual += avail; 421 m_emptyOffset = m_endOffset = 0; 422 if (!fillBuffer()) { 423 return actual == 0 ? -1 : actual; 424 } 425 } 426 System.arraycopy(m_buffer, m_emptyOffset, b, off, len); 427 m_emptyOffset += len; 428 return actual + len; 429 } 430 431 434 435 public int read(byte[] b) throws IOException { 436 return read(b, 0, b.length); 437 } 438 439 442 443 public long skip(long n) throws IOException { 444 int avail = m_endOffset - m_emptyOffset; 445 if (n >= (long)avail) { 446 return avail + m_stream.skip(n - avail); 447 } else { 448 m_emptyOffset += (int)n; 449 return n; 450 } 451 } 452 453 456 457 public int read() throws IOException { 458 if (m_emptyOffset >= m_endOffset && !fillBuffer()) { 459 return -1; 460 } else { 461 return m_buffer[m_emptyOffset++]; 462 } 463 } 464 } 465 466 471 472 private class WrappedStreamUTF8Reader extends Reader 473 { 474 477 478 public void close() throws IOException { 479 InputStreamWrapper.this.close(); 480 } 481 482 485 486 public int read(char[] b, int off, int len) throws IOException { 487 488 int end = off + len; 490 int empty = m_emptyOffset; 491 byte[] buff = m_buffer; 492 while (off < end) { 493 494 if (empty + 3 > m_endOffset) { 496 m_emptyOffset = empty; 497 fillBuffer(); 498 empty = m_emptyOffset; 499 if (empty == m_endOffset) { 500 int actual = len + off - end; 501 return actual > 0 ? actual : -1; 502 } 503 } 504 505 int byt = buff[empty++]; 507 if (byt >= 0) { 508 509 b[off++] = (char)byt; 511 if (byt == 0) { 512 System.err.println("Wrote null"); 513 } 514 515 } else if ((byt & 0xE0) == 0xC0) { 516 517 if (empty < m_endOffset) { 519 b[off++] = (char)(((byt & 0x1F) << 6) + 520 (buff[empty++] & 0x3F)); 521 if (b[off-1] == 0) { 522 System.err.println("Wrote null"); 523 } 524 } else { 525 throw new IOException ("UTF-8 conversion error"); 526 } 527 528 } else { 529 530 if (empty + 1 < m_endOffset) { 532 int byt2 = buff[empty++] & 0x3F; 533 b[off++] = (char)((((byt & 0x0F) << 6) + 534 byt2 << 6) + (buff[empty++] & 0x3F)); 535 if (b[off-1] == 0) { 536 System.err.println("Wrote null"); 537 } 538 } else { 539 throw new IOException ("UTF-8 conversion error"); 540 } 541 } 542 } 543 m_emptyOffset = empty; 544 return len; 545 } 546 547 550 551 public int read(char[] b) throws IOException { 552 return read(b, 0, b.length); 553 } 554 555 558 559 public int read() throws IOException { 560 561 if (m_emptyOffset + 3 > m_endOffset) { 563 fillBuffer(); 564 if (m_emptyOffset == m_endOffset) { 565 return -1; 566 } 567 } 568 569 int byt = m_buffer[m_emptyOffset++]; 571 if (byt >= 0) { 572 573 return byt & 0xFF; 575 576 } else if ((byt & 0xE0) == 0xC0) { 577 578 if (m_emptyOffset < m_endOffset) { 580 return ((byt & 0x1F) << 6) + 581 (m_buffer[m_emptyOffset++] & 0x3F); 582 } else { 583 throw new IOException ("UTF-8 conversion error"); 584 } 585 586 } else { 587 588 if (m_emptyOffset + 1 < m_endOffset) { 590 int byt2 = m_buffer[m_emptyOffset++] & 0xFF; 591 return (((byt & 0x0F) << 6) + 592 byt2 << 6) + (m_buffer[m_emptyOffset++] & 0x3F); 593 } else { 594 throw new IOException ("UTF-8 conversion error"); 595 } 596 } 597 } 598 599 602 603 public boolean ready() throws IOException { 604 return m_emptyOffset + 2 < m_endOffset; 605 } 606 } 607 608 613 614 private class WrappedStreamISO88591Reader extends Reader 615 { 616 619 620 public void close() throws IOException { 621 InputStreamWrapper.this.close(); 622 } 623 624 627 628 public int read(char[] b, int off, int len) throws IOException { 629 630 int end = off + len; 632 int empty = m_emptyOffset; 633 byte[] buff = m_buffer; 634 while (off < end) { 635 636 int avail = m_endOffset - empty; 638 if (avail == 0) { 639 m_emptyOffset = empty; 640 if (fillBuffer()) { 641 empty = m_emptyOffset; 642 avail = m_endOffset - empty; 643 } else { 644 int actual = len + off - end; 645 return actual > 0 ? actual : -1; 646 } 647 } 648 649 int use = end - off; 651 if (use > avail) { 652 use = avail; 653 } 654 655 int limit = empty + use; 657 while (empty < limit) { 658 b[off++] = (char)(buff[empty++] & 0xFF); 659 } 660 } 661 m_emptyOffset = empty; 662 return len; 663 } 664 665 668 669 public int read(char[] b) throws IOException { 670 return read(b, 0, b.length); 671 } 672 673 676 677 public int read() throws IOException { 678 if (m_emptyOffset >= m_endOffset && !fillBuffer()) { 679 return -1; 680 } else { 681 return m_buffer[m_emptyOffset++] & 0xFF; 682 } 683 } 684 685 688 689 public boolean ready() throws IOException { 690 return m_emptyOffset < m_endOffset; 691 } 692 } 693 } | Popular Tags |