1 29 30 package com.caucho.xml.stream; 31 32 import com.caucho.util.CharBuffer; 33 import com.caucho.util.L10N; 34 import com.caucho.vfs.*; 35 36 import javax.xml.namespace.NamespaceContext ; 37 import javax.xml.namespace.QName ; 38 import javax.xml.stream.Location; 39 import javax.xml.stream.XMLStreamException; 40 import javax.xml.stream.XMLStreamReader; 41 import java.io.IOException ; 42 import java.io.InputStream ; 43 import java.io.Reader ; 44 import java.util.logging.Logger ; 45 46 49 public class XMLStreamReaderImpl implements XMLStreamReader { 50 private static final Logger log 51 = Logger.getLogger(XMLStreamReaderImpl.class.getName()); 52 private static final L10N L = new L10N(XMLStreamReaderImpl.class); 53 54 private static final boolean []IS_XML_NAME = new boolean[65536]; 55 56 private StaxIntern _intern; 57 58 private ReadStream _is; 59 60 private int _col = 1; 61 private int _row = 1; 62 private int _ofs = 1; 63 64 private NamespaceReaderContext _namespaceTracker; 65 66 private String _version; 67 private String _encoding = "UTF-8"; 68 private String _encodingScheme; 69 70 private String _publicId; 71 private String _systemId; 72 73 private boolean _seenDocumentStart = false; 74 private int _current; 75 private int _state; 76 private boolean _isShortTag; 77 private boolean _isWhitespace = false; 78 79 private boolean _eofEncountered = false; 80 81 private String _processingInstructionTarget; 82 private String _processingInstructionData; 83 84 private RawName _rawTagName = new RawName(); 85 private QName _name; 86 87 private StaxIntern.Entry []_attrRawNames = new StaxIntern.Entry[16]; 88 private QName []_attrNames = new QName [16]; 89 private String []_attrValues = new String [16]; 90 private int _attrCount; 91 private final StringBuilder _sb = new StringBuilder (); 92 93 private TempCharBuffer _tempInputBuffer; 94 private char []_inputBuf; 95 private int _inputOffset; 96 private int _inputLength; 97 98 private TempCharBuffer _tempCharBuffer; 99 private char []_cBuf; 100 private int _cBufLength; 101 102 public XMLStreamReaderImpl(InputStream is) 103 throws XMLStreamException 104 { 105 this(Vfs.openRead(is)); 106 } 107 108 public XMLStreamReaderImpl(Reader r) 109 throws XMLStreamException 110 { 111 this(Vfs.openRead(r)); 112 } 113 114 public XMLStreamReaderImpl(InputStream is, String systemId) 115 throws XMLStreamException 116 { 117 this(Vfs.openRead(is)); 118 _systemId = systemId; 119 } 120 121 public XMLStreamReaderImpl(Reader r, String systemId) 122 throws XMLStreamException 123 { 124 this(Vfs.openRead(r)); 125 _systemId = systemId; 126 } 127 128 public XMLStreamReaderImpl(ReadStream is) 129 throws XMLStreamException 130 { 131 init(is); 132 } 133 134 public void init(ReadStream is) 135 throws XMLStreamException 136 { 137 _namespaceTracker = new NamespaceReaderContext(); 138 _intern = new StaxIntern(_namespaceTracker); 139 140 _is = is; 141 142 _tempCharBuffer = TempCharBuffer.allocate(); 143 _cBuf = _tempCharBuffer.getBuffer(); 144 145 _tempInputBuffer = TempCharBuffer.allocate(); 146 _inputBuf = _tempInputBuffer.getBuffer(); 147 _inputOffset = _inputLength = 0; 148 149 readHeader(); 150 151 _current = START_DOCUMENT; 152 } 153 154 public int getAttributeCount() 155 { 156 return _attrCount; 157 } 158 159 public String getAttributeLocalName(int index) 160 { 161 if (_attrCount <= index) 162 throw new IllegalArgumentException (L.l("element only has {0} attributes, given index {1}", 163 _attrCount, index)); 164 165 return _attrNames[index].getLocalPart(); 166 } 167 168 public QName getAttributeName(int index) 169 { 170 if (_attrCount <= index) 171 throw new IllegalArgumentException (L.l("element only has {0} attributes, given index {1}", 172 _attrCount, index)); 173 174 return _attrNames[index]; 175 } 176 177 public String getAttributeNamespace(int index) 178 { 179 if (_attrCount <= index) 180 throw new IllegalArgumentException (L.l("element only has {0} attributes, given index {1}", 181 _attrCount, index)); 182 183 String ret = _attrNames[index].getNamespaceURI(); 184 185 if ("".equals(ret)) 187 return null; 188 189 return ret; 190 } 191 192 public String getAttributePrefix(int index) 193 { 194 if (_attrCount <= index) 195 throw new IllegalArgumentException (L.l("element only has {0} attributes, given index {1}", 196 _attrCount, index)); 197 198 String ret = _attrNames[index].getPrefix(); 199 200 return ret; 201 } 202 203 public String getAttributeType(int index) 204 { 205 return "CDATA"; 206 } 207 208 public String getAttributeValue(int index) 209 { 210 if (_attrCount <= index) 211 throw new IllegalArgumentException (L.l("element only has {0} attributes, given index {1}", 212 _attrCount, index)); 213 214 return _attrValues[index]; 215 } 216 217 public boolean isAttributeSpecified(int index) 218 { 219 return index < _attrCount; 220 } 221 222 public String getAttributeValue(String namespaceURI, String localName) 223 { 224 for (int i = _attrCount - 1; i >= 0; i--) { 225 QName name = _attrNames[i]; 226 227 if (name.getLocalPart().equals(localName) && 228 name.getNamespaceURI().equals(namespaceURI)) 229 return _attrValues[i]; 230 } 231 232 return null; 233 } 234 235 public String getCharacterEncodingScheme() 236 { 237 return _encodingScheme; 238 } 239 240 public String getElementText() throws XMLStreamException 241 { 242 return getText(); 243 } 244 245 public String getEncoding() 246 { 247 return _encoding; 248 } 249 250 public int getEventType() 251 { 252 return _current; 253 } 254 255 public Location getLocation() 256 { 257 return new StreamReaderLocation(_ofs, _row, _col); 258 } 259 260 public String getLocalName() 261 { 262 if (_name == null) 263 throw new IllegalStateException (); 264 265 return _name.getLocalPart(); 266 } 267 268 public String getNamespaceURI() 269 { 270 if (_name == null) 271 return null; 272 273 String uri = _name.getNamespaceURI(); 274 275 if ("".equals(uri)) 276 return null; 277 else 278 return uri; 279 } 280 281 public QName getName() 282 { 283 return _name; 284 } 285 286 public NamespaceContext getNamespaceContext() 287 { 288 return _namespaceTracker; 289 } 290 291 public int getNamespaceCount() 292 { 293 return _namespaceTracker.getNumDecls(); 294 } 295 296 public String getNamespacePrefix(int index) 297 { 298 return _namespaceTracker.getPrefix(index); 299 } 300 301 public String getNamespaceURI(int index) 302 { 303 return _namespaceTracker.getUri(index); 304 } 305 306 public String getNamespaceURI(String prefix) 307 { 308 return _namespaceTracker.getUri(prefix); 309 } 310 311 public String getPIData() 312 { 313 if (_current != PROCESSING_INSTRUCTION) 314 return null; 315 316 return _processingInstructionData; 317 } 318 319 public String getPITarget() 320 { 321 if (_current != PROCESSING_INSTRUCTION) 322 return null; 323 324 return _processingInstructionTarget; 325 } 326 327 public String getPrefix() 328 { 329 if (_name == null) 330 return null; 331 332 String prefix = _name.getPrefix(); 333 334 if ("" == prefix && "" == _name.getNamespaceURI()) 336 return null; 337 338 return prefix; 339 } 340 341 public Object getProperty(String name) throws IllegalArgumentException 342 { 343 if ("javax.xml.stream.notations".equals(name)) { 344 throw new UnsupportedOperationException (getClass().getName()); 345 } 346 else if ("javax.xml.stream.entities".equals(name)) { 347 throw new UnsupportedOperationException (getClass().getName()); 348 } 349 else { 350 throw 351 new IllegalArgumentException ("property \""+name+"+\" not supported"); 352 } 353 } 354 355 358 public String getText() 359 { 360 return new String (_cBuf, 0, _cBufLength); 361 } 362 363 366 public char[] getTextCharacters() 367 { 368 return _cBuf; 369 } 370 371 374 public int getTextCharacters(int sourceStart, char[] target, 375 int targetStart, int length) 376 throws XMLStreamException 377 { 378 int sublen = _cBufLength - sourceStart; 379 380 if (length < sublen) 381 sublen = length; 382 383 System.arraycopy(_cBuf, sourceStart, target, targetStart, sublen); 384 385 return sublen; 386 } 387 388 391 public int getTextLength() 392 { 393 return _cBufLength; 394 } 395 396 399 public int getTextStart() 400 { 401 return 0; 402 } 403 404 public String getVersion() 405 { 406 return _version; 407 } 408 409 public boolean hasName() 410 { 411 return _name != null; 412 } 413 414 public boolean hasText() 415 { 416 switch(getEventType()) { 417 case CHARACTERS: 418 case DTD: 419 case ENTITY_REFERENCE: 420 case COMMENT: 421 case SPACE: 422 return true; 423 default: 424 return false; 425 } 426 } 427 428 public boolean isCharacters() 429 { 430 return _current == CHARACTERS; 431 } 432 433 public boolean isEndElement() 434 { 435 return _current == END_ELEMENT; 436 } 437 438 public boolean isStandalone() 439 { 440 return false; 441 } 442 443 public boolean isStartElement() 444 { 445 return _current == START_ELEMENT; 446 } 447 448 public boolean isWhiteSpace() 449 { 450 return (_isWhitespace 451 && (_current == CHARACTERS || _current == SPACE)); 452 } 453 454 457 public int nextTag() throws XMLStreamException 458 { 459 while (true) { 460 int tag = next(); 461 462 if (tag < 0 463 || tag == START_ELEMENT 464 || tag == END_ELEMENT) { 465 return tag; 466 } 467 } 468 } 469 470 public void require(int type, String namespaceURI, String localName) 471 throws XMLStreamException 472 { 473 if (type != _current) 474 throw new XMLStreamException("expected " + constantToString(type) + ", "+ 475 "found " + constantToString(_current) + 476 " at " + getLocation()); 477 478 if (localName != null && !localName.equals(getLocalName())) 479 throw new XMLStreamException("expected <"+localName+">, found " + 480 "<"+getLocalName()+"> at " + getLocation()); 481 482 if (namespaceURI != null && !namespaceURI.equals(getNamespaceURI())) 483 throw new XMLStreamException("expected xmlns="+namespaceURI+ 484 ", found xmlns="+getNamespaceURI() + 485 " at " + getLocation()); 486 } 487 488 public boolean standaloneSet() 489 { 490 return isStandalone(); 491 } 492 493 public boolean hasNext() throws XMLStreamException 494 { 495 if (_is == null) 496 return false; 497 498 return _current != END_DOCUMENT; 499 } 500 501 public int next() throws XMLStreamException 502 { 503 try { 504 _current = readNext(); 505 } catch (IOException e) { 506 throw new XMLStreamException(e); 507 } 508 509 if (_current > 0) 510 return _current; 511 else { 512 if (_eofEncountered) 513 return _current = -1; 514 515 _eofEncountered = true; 516 517 return _current = END_DOCUMENT; 518 } 519 } 520 521 private int readNext() 522 throws IOException , XMLStreamException 523 { 524 if (_current == END_ELEMENT) 527 _namespaceTracker.pop(); 528 529 if (_isShortTag) { 530 _isShortTag = false; 531 return END_ELEMENT; 532 } 533 534 _name = null; 535 536 int ch = read(); 537 538 if (ch == '<') { 539 ch = read(); 540 541 switch (ch) { 542 case '/': 543 _name = readName(false).getQName(); 544 545 expect('>'); 546 547 return END_ELEMENT; 548 549 case '!': 550 expect('-'); 551 expect('-'); 552 return readComment(); 553 554 case '?': 555 readProcessingDirective(); 556 return PROCESSING_INSTRUCTION; 557 558 default: 559 unread(); 560 561 readElementBegin(); 562 563 return START_ELEMENT; 564 } 565 } 566 else if (ch < 0) { 567 close(); 568 569 return -1; 570 } 571 else { 572 unread(); 573 574 return readData(); 575 } 576 } 577 578 private void readElementBegin() 579 throws IOException , XMLStreamException 580 { 581 _namespaceTracker.push(); 582 583 StaxIntern.Entry eltName = readName(false); 584 585 int ch = readAttributes(); 586 587 if (ch == '>') { 588 } 589 else if (ch == '/') { 590 _isShortTag = true; 591 592 expect('>'); 593 } 594 else 595 throw error(L.l("Expected {0} at {1}", ">", charName(ch))); 596 597 for (int i = _attrCount - 1; i >= 0; i--) 598 _attrNames[i] = _attrRawNames[i].getQName(); 599 600 _name = eltName.getQName(); 601 } 602 603 private int readAttributes() 604 throws IOException , XMLStreamException 605 { 606 int ch; 607 int attrCount = 0; 608 609 while ((ch = skipWhitespace()) >= 0 && IS_XML_NAME[ch]) { 610 unread(); 611 612 if (_attrRawNames.length <= attrCount) 613 extendAttrs(); 614 615 StaxIntern.Entry rawName = readName(true); 616 617 ch = skipWhitespace(); 618 619 if (ch != '=') 620 throw error(L.l("attribute expects '=' at {0}", charName(ch))); 621 622 ch = skipWhitespace(); 623 624 if (ch == '\'' || ch == '"') { 625 if ("xmlns".equals(rawName.getPrefix())) { 626 _namespaceTracker.declare(rawName.getLocalName(), readValue(ch)); 627 } 628 else if ("xmlns".equals(rawName.getLocalName())) { 629 _namespaceTracker.declare(null, readValue(ch)); 630 } 631 else { 632 _attrRawNames[attrCount] = rawName; 633 _attrValues[attrCount++] = readValue(ch); 634 } 635 } 636 else 637 throw error(L.l("attribute expects value at {0}", charName(ch))); 638 } 639 640 _attrCount = attrCount; 641 642 return ch; 643 } 644 645 private String readValue(int end) 646 throws XMLStreamException 647 { 648 char []valueBuffer = _cBuf; 649 int valueIndex = 0; 650 651 while (true) { 652 int ch = read(); 653 654 switch (ch) { 655 case -1: 656 return new String (valueBuffer, 0, valueIndex); 657 658 case '"': case '\'': 659 if (ch == end) 660 return new String (valueBuffer, 0, valueIndex); 661 else 662 valueBuffer[valueIndex++] = (char) ch; 663 break; 664 665 case '&': 666 valueBuffer[valueIndex++] = (char) ch; 667 break; 668 669 default: 670 valueBuffer[valueIndex++] = (char) ch; 671 break; 672 } 673 } 674 } 675 676 private void extendAttrs() 677 { 678 int length = _attrRawNames.length; 679 680 StaxIntern.Entry []attrRawNames = new StaxIntern.Entry[length + 16]; 681 System.arraycopy(_attrRawNames, 0, attrRawNames, 0, length); 682 _attrRawNames = attrRawNames; 683 684 QName []attrNames = new QName [length + 16]; 685 System.arraycopy(_attrNames, 0, attrNames, 0, length); 686 _attrNames = attrNames; 687 688 String []attrValues = new String [length + 16]; 689 System.arraycopy(_attrValues, 0, attrValues, 0, length); 690 _attrValues = attrValues; 691 } 692 693 private int readData() 694 throws IOException , XMLStreamException 695 { 696 int ch = 0; 697 _isWhitespace = true; 698 699 int index = 0; 700 char []cBuf = _cBuf; 701 int length = cBuf.length; 702 int entity = -1; 703 704 loop: 705 for (; index < length && (ch = read()) >= 0; index++) { 706 switch (ch) { 707 case '<': 708 unread(); 709 break loop; 710 711 case '&': 712 if (cBuf.length <= index + 256) { 713 unread(); 714 break loop; 715 } 716 cBuf[index] = (char) ch; 717 entity = index; 718 break; 719 720 case '\r': 721 ch = read(); 722 if (ch != '\n') { ch = '\r'; unread(); } 723 724 case ' ': case '\t': case '\n': 725 cBuf[index] = (char) ch; 726 break; 727 728 case ';': 729 if (entity >= 0) { 730 String resolved = resolveEntity(new String (cBuf, entity + 1, index - entity - 1)); 731 index = entity + resolved.length(); 732 resolved.getChars(0, resolved.length(), cBuf, entity); 733 entity = -1; 734 break; 735 } 736 default: 737 _isWhitespace = false; 738 cBuf[index] = (char) ch; 739 break; 740 } 741 } 742 743 if (entity > 0) 744 throw new XMLStreamException("XXX: unclosed entity at end of file"); 745 746 _cBufLength = index; 747 748 if (ch < 0 && _isWhitespace) 749 return -1; 750 751 boolean isIgnorableWhitespace 753 = _isWhitespace && _namespaceTracker.getDepth() == 0; 754 755 return isIgnorableWhitespace ? SPACE : CHARACTERS; 756 } 757 758 private String resolveEntity(String s) 759 throws XMLStreamException 760 { 761 if ("amp".equals(s)) return "&"; 762 if ("apos".equals(s)) return "\'"; 763 if ("quot".equals(s)) return "\""; 764 if ("lt".equals(s)) return "<"; 765 if ("gt".equals(s)) return ">"; 766 if (s.startsWith("#x")) 767 return ""+((char)Integer.parseInt(s.substring(1), 16)); 768 if (s.startsWith("#")) 769 return ""+((char)Integer.parseInt(s.substring(1))); 770 771 throw new XMLStreamException("unknown entity: \"" + s + "\""); 772 } 773 774 private void readProcessingDirective() 775 throws XMLStreamException 776 { 777 CharBuffer target = new CharBuffer(); 778 CharBuffer data = null; 779 780 while(true) { 781 int ch = read(); 782 783 if (ch == -1) 784 return; 785 786 if (ch == '?') { 787 int next = read(); 788 if (next == '>') { 789 _processingInstructionTarget = target.toString(); 790 _processingInstructionData = data.toString(); 791 return; 792 } 793 unread(); 794 } 795 796 if (data == null && (ch == ' ' || ch == '\r' || ch == '\n')) { 797 data = new CharBuffer(); 798 continue; 799 } 800 801 if (data != null) 802 data.append((char)ch); 803 else 804 target.append((char)ch); 805 } 806 } 807 808 809 private int readComment() 810 throws XMLStreamException 811 { 812 int ch = 0; 813 int index = 0; 814 char []cBuf = _cBuf; 815 int length = cBuf.length; 816 loop: 817 for (; index < length && (ch = read()) >= 0; index++) { 818 cBuf[index] = (char) ch; 819 if (index > 3 820 && cBuf[index-2] == '-' 821 && cBuf[index-1] == '-' 822 && cBuf[index-0] == '>') { 823 index -= 2; 824 break; 825 } 826 } 827 828 _cBufLength = index; 829 830 return COMMENT; 831 } 832 833 private void readRawName(RawName name) 834 throws IOException , XMLStreamException 835 { 836 int length = 0; 837 char []nameBuffer = name._buffer; 838 int bufferLength = nameBuffer.length; 839 int prefix = -1; 840 841 int ch; 842 843 while ((ch = read()) >= 0 && IS_XML_NAME[ch]) { 844 if (bufferLength <= length) { 845 name.expandCapacity(); 846 nameBuffer = name._buffer; 847 bufferLength = nameBuffer.length; 848 } 849 850 if (ch == ':' && prefix < 0) 851 prefix = length; 852 853 nameBuffer[length++] = (char) ch; 854 } 855 unread(); 856 857 name._length = length; 858 name._prefix = prefix; 859 } 860 861 864 private StaxIntern.Entry readName(boolean isAttribute) 865 throws XMLStreamException 866 { 867 char []inputBuf = _inputBuf; 868 int inputLength = _inputLength; 869 int inputOffset = _inputOffset; 870 871 char []valueBuf = _cBuf; 872 int valueOffset = 0; 873 874 int colon = 0; 875 876 while (true) { 877 if (inputOffset < inputLength) { 878 char ch = inputBuf[inputOffset++]; 879 880 if (IS_XML_NAME[ch]) { 881 valueBuf[valueOffset++] = ch; 882 } 883 else if (ch == ':') { 884 if (colon <= 0) 885 colon = valueOffset; 886 887 valueBuf[valueOffset++] = ch; 888 } 889 else { 890 _inputOffset = inputOffset - 1; 891 892 return _intern.add(valueBuf, 0, valueOffset, colon, isAttribute); 893 } 894 } 895 else if (fillBuffer()) { 896 inputLength = _inputLength; 897 inputOffset = _inputOffset; 898 } 899 else { 900 return _intern.add(valueBuf, 0, valueOffset, colon, isAttribute); 901 } 902 } 903 } 904 905 private static boolean isXmlName(int ch) 906 { 907 return ('a' <= ch && ch <= 'z' 908 || 'A' <= ch && ch <= 'Z' 909 || '0' <= ch && ch <= '9' 910 || ch == ':' 911 || ch == '+' 912 || ch == '_' 913 || ch == '-'); 914 } 915 916 private int skipWhitespace() 917 throws XMLStreamException 918 { 919 int ch; 920 921 while ((ch = read()) >= 0 && 922 (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')) { 923 } 924 925 return ch; 926 } 927 928 931 private void readHeader() 932 throws XMLStreamException 933 { 934 937 int ch; 938 939 ch = readByte(); 940 941 if (ch == (char)0xFE) { 942 if (readByte() != (char)0xFF) { 943 throw new XMLStreamException("found unrecognized BOM"); 944 } 945 ch = readByte(); 946 } else if (ch == (char)0xFF) { 947 if (readByte() != (char)0xFE) { 948 throw new UnsupportedOperationException ("found byte-swapped BOM"); 949 } else { 950 throw new XMLStreamException("found unrecognized BOM"); 951 } 952 } 953 954 if (ch != '<') { 955 unreadByte(); 956 } 957 else if ((ch = readByte()) != '?') { 958 unreadByte(); 959 unreadByte(); 960 } 961 else if ((ch = readByte()) != 'x') { 962 unreadByte(); 963 unreadByte(); 964 unreadByte(); 965 } 966 else if ((ch = readByte()) != 'm') { 967 unreadByte(); 968 unreadByte(); 969 unreadByte(); 970 unreadByte(); 971 } 972 else if ((ch = readByte()) != 'l') { 973 unreadByte(); 974 unreadByte(); 975 unreadByte(); 976 unreadByte(); 977 unreadByte(); 978 } 979 else { 980 981 CharBuffer directive = new CharBuffer(); 982 while ((ch = readByte()) >= 0 && ch != '?') { 983 directive.append((char)ch); 984 } 985 986 String data = directive.toString().trim(); 987 if (data.startsWith("version")) { 988 data = data.substring(7).trim(); 989 data = data.substring(1).trim(); char quot = data.charAt(0); 991 _version = data.substring(1, data.indexOf(quot, 1)); 992 data = data.substring(data.indexOf(quot, 1)+1).trim(); 993 } 994 if (data.startsWith("encoding")) { 995 data = data.substring(8).trim(); 996 data = data.substring(1).trim(); char quot = data.charAt(0); 998 _encoding = data.substring(1, data.indexOf(quot, 1)); 999 data = data.substring(data.indexOf(quot, 1)+1).trim(); 1000 } 1001 1002 ch = readByte(); 1003 if (ch != '>') 1004 throw error(L.l("Expected '>' at end of '<?xml' declaration at {0}", 1005 charName(ch))); 1006 } 1007 } 1008 1009 1012 private void expect(int expect) 1013 throws XMLStreamException 1014 { 1015 int ch = read(); 1016 1017 if (ch != expect) 1018 throw error(L.l("expected {0} at {1}", charName(expect), charName(ch))); 1019 } 1020 1021 1024 private int read() 1025 throws XMLStreamException 1026 { 1027 if (_inputLength <= _inputOffset && ! fillBuffer()) 1028 return -1; 1029 1030 int ch = _inputBuf[_inputOffset++]; 1031 1032 return ch; 1033 } 1034 1035 1038 private void unread() 1039 { 1040 if (_inputOffset > 0) 1041 _inputOffset--; 1042 } 1043 1044 1047 private int readByte() 1048 throws XMLStreamException 1049 { 1050 try { 1051 if (_inputLength <= _inputOffset) { 1052 int ch = _is.read(); 1053 1054 if (ch < 0) 1055 return ch; 1056 1057 if (_inputBuf.length <= _inputLength) 1058 _inputLength = 0; 1059 1060 _inputBuf[_inputLength++] = (char) ch; 1061 _inputOffset = _inputLength; 1062 1063 return ch; 1064 } 1065 else 1066 return _inputBuf[_inputOffset++]; 1067 } catch (IOException e) { 1068 throw new XMLStreamException(e); 1069 } 1070 } 1071 1072 1075 private void unreadByte() 1076 { 1077 if (_inputOffset > 0) 1078 _inputOffset--; 1079 } 1080 1081 1084 private final boolean fillBuffer() 1085 throws XMLStreamException 1086 { 1087 try { 1088 if (_is != null) { 1089 _inputOffset = 0; 1090 _inputLength = _is.read(_inputBuf, 0, _inputBuf.length); 1091 1092 return _inputLength > 0; 1093 } 1094 else { 1095 _inputOffset = 0; 1096 _inputLength = 0; 1097 1098 return false; 1099 } 1100 } catch (IOException e) { 1101 throw new XMLStreamException(e); 1102 } 1103 } 1104 1105 private String charName(int ch) 1106 { 1107 if (ch > 0x20 && ch <= 0x7f) 1108 return "'" + (char) ch + "'"; 1109 else 1110 return "0x" + Integer.toHexString(ch); 1111 } 1112 1113 private XMLStreamException error(String s) 1114 { 1115 return new XMLStreamException(location() + s); 1116 } 1117 1118 private String location() 1119 { 1120 return ":" + _row + ":" + _col + " "; 1121 } 1122 1123 public void close() throws XMLStreamException 1124 { 1125 TempCharBuffer tempCharBuffer = _tempCharBuffer; 1126 _tempCharBuffer = null; 1127 _cBuf = null; 1128 1129 TempCharBuffer tempInputBuffer = _tempInputBuffer; 1130 _tempInputBuffer = null; 1131 _inputBuf = null; 1132 1133 _inputOffset = _inputLength = 0; 1134 1135 if (tempCharBuffer != null) 1136 TempCharBuffer.free(tempCharBuffer); 1137 1138 if (tempInputBuffer != null) 1139 TempCharBuffer.free(tempInputBuffer); 1140 1141 ReadStream is = _is; 1142 _is = null; 1143 1144 if (is != null) 1145 is.close(); 1146 } 1147 1148 static class RawName { 1149 char []_buffer = new char[64]; 1150 int _prefix; 1151 int _length; 1152 1153 public QName resolve(NamespaceContext nsc) 1154 { 1155 if (getPrefix() == null) 1156 return new QName (nsc.getNamespaceURI(null), 1157 getLocalName()); 1158 return new QName (nsc.getNamespaceURI(getPrefix()), 1159 getLocalName(), 1160 getPrefix()); 1161 } 1162 1163 public String toString() 1164 { 1165 return new String (_buffer, 0, _length); 1166 } 1167 1168 String getLocalName() 1169 { 1170 return new String (_buffer, _prefix + 1, _length - _prefix - 1); 1171 } 1172 1173 String getPrefix() 1174 { 1175 if (_prefix==-1) return null; 1176 return new String (_buffer, 0, _prefix); 1177 } 1178 1179 void expandCapacity() 1180 { 1181 char []newBuffer = new char[_buffer.length + 64]; 1182 1183 System.arraycopy(_buffer, 0, newBuffer, 0, _buffer.length); 1184 1185 _buffer = newBuffer; 1186 } 1187 } 1188 1199 static { 1200 for (int i = 0; i < IS_XML_NAME.length; i++) { 1201 if (isXmlName(i) && i != ':') 1202 IS_XML_NAME[i] = isXmlName(i); 1203 } 1204 } 1205 1206 private class StreamReaderLocation implements Location { 1207 1208 private int _ofs; 1209 private int _row; 1210 private int _col; 1211 1212 public StreamReaderLocation(int ofs, int row, int col) 1213 { 1214 this._ofs = ofs; 1215 this._row = row; 1216 this._col = col; 1217 } 1218 1219 public int getCharacterOffset() 1220 { 1221 return _ofs; 1222 } 1223 1224 public int getColumnNumber() 1225 { 1226 return _col; 1227 } 1228 1229 public int getLineNumber() 1230 { 1231 return _row; 1232 } 1233 1234 public String getPublicId() 1235 { 1236 return _publicId; 1237 } 1238 1239 public String getSystemId() 1240 { 1241 return _systemId; 1242 } 1243 1244 public String toString() { 1245 return _row+":"+_col; 1246 } 1247 1248 } 1249 1250 private static String constantToString(int constant) { 1251 1252 switch(constant) { 1253 1254 case ATTRIBUTE: return "ATTRIBUTE"; 1255 case CDATA: return "CDATA"; 1256 case CHARACTERS: return "CHARACTERS"; 1257 case COMMENT: return "COMMENT"; 1258 case DTD: return "DTD"; 1259 case END_DOCUMENT: return "END_DOCUMENT"; 1260 case END_ELEMENT: return "END_ELEMENT"; 1261 case ENTITY_DECLARATION: return "ENTITY_DECLARATION"; 1262 case ENTITY_REFERENCE: return "ENTITY_REFERENCE"; 1263 case NAMESPACE: return "NAMESPACE"; 1264 case NOTATION_DECLARATION: return "NOTATION_DECLARATION"; 1265 case PROCESSING_INSTRUCTION: return "PROCESSING_INSTRUCTION"; 1266 case SPACE: return "SPACE"; 1267 case START_DOCUMENT: return "START_DOCUMENT"; 1268 case START_ELEMENT: return "START_ELEMENT"; 1269 default: 1270 throw new RuntimeException ("constantToString("+constant+") unknown"); 1271 } 1272 1273 } 1274 1275} 1276 | Popular Tags |