1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * The Apache Software License, Version 1.1 7 * 8 * 9 * Copyright (c) 1999-2002 The Apache Software Foundation. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in 21 * the documentation and/or other materials provided with the 22 * distribution. 23 * 24 * 3. The end-user documentation included with the redistribution, 25 * if any, must include the following acknowledgment: 26 * "This product includes software developed by the 27 * Apache Software Foundation (http://www.apache.org/)." 28 * Alternately, this acknowledgment may appear in the software itself, 29 * if and wherever such third-party acknowledgments normally appear. 30 * 31 * 4. The names "Xerces" and "Apache Software Foundation" must 32 * not be used to endorse or promote products derived from this 33 * software without prior written permission. For written 34 * permission, please contact apache@apache.org. 35 * 36 * 5. Products derived from this software may not be called "Apache", 37 * nor may "Apache" appear in their name, without prior written 38 * permission of the Apache Software Foundation. 39 * 40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 41 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 42 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 43 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 47 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 48 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 49 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 50 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This software consists of voluntary contributions made by many 55 * individuals on behalf of the Apache Software Foundation and was 56 * originally based on software copyright (c) 1999, International 57 * Business Machines, Inc., http://www.apache.org. For more 58 * information on the Apache Software Foundation, please see 59 * <http://www.apache.org/>. 60 */ 61 62 package com.sun.org.apache.xerces.internal.impl; 63 64 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 65 import com.sun.org.apache.xerces.internal.util.XML11Char; 66 import com.sun.org.apache.xerces.internal.util.XMLChar; 67 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; 68 import com.sun.org.apache.xerces.internal.xni.QName; 69 import com.sun.org.apache.xerces.internal.xni.XMLString; 70 import java.io.IOException; 71 72 /** 73 * Implements the entity scanner methods in 74 * the context of XML 1.1. 75 * 76 * @xerces.internal 77 * 78 * @author Michael Glavassevich, IBM 79 * @author Neil Graham, IBM 80 */ 81 82 public class XML11EntityScanner 83 extends XMLEntityScanner { 84 85 // 86 // Constructors 87 // 88 89 /** Default constructor. */ 90 public XML11EntityScanner() { 91 super(); 92 } // <init>() 93 94 // 95 // XMLEntityScanner methods 96 // 97 98 /** 99 * Returns the next character on the input. 100 * <p> 101 * <strong>Note:</strong> The character is <em>not</em> consumed. 102 * 103 * @throws IOException Thrown if i/o error occurs. 104 * @throws EOFException Thrown on end of file. 105 */ 106 public int peekChar() throws IOException { 107 108 // load more characters, if needed 109 if (fCurrentEntity.position == fCurrentEntity.count) { 110 load(0, true, true); 111 } 112 113 // peek at character 114 int c = fCurrentEntity.ch[fCurrentEntity.position]; 115 116 // return peeked character 117 if (fCurrentEntity.isExternal()) { 118 return (c != '\r' && c != 0x85 && c != 0x2028) ? c : '\n'; 119 } 120 else { 121 return c; 122 } 123 124 } // peekChar():int 125 126 /** 127 * Returns the next character on the input. 128 * <p> 129 * <strong>Note:</strong> The character is consumed. 130 * 131 * @throws IOException Thrown if i/o error occurs. 132 * @throws EOFException Thrown on end of file. 133 */ 134 public int scanChar() throws IOException { 135 136 // load more characters, if needed 137 if (fCurrentEntity.position == fCurrentEntity.count) { 138 load(0, true, true); 139 } 140 141 // scan character 142 int c = fCurrentEntity.ch[fCurrentEntity.position++]; 143 boolean external = false; 144 if (c == '\n' || 145 ((c == '\r' || c == 0x85 || c == 0x2028) && (external = fCurrentEntity.isExternal()))) { 146 fCurrentEntity.lineNumber++; 147 fCurrentEntity.columnNumber = 1; 148 if (fCurrentEntity.position == fCurrentEntity.count) { 149 invokeListeners(1); 150 fCurrentEntity.ch[0] = (char)c; 151 load(1, false, false); 152 } 153 if (c == '\r' && external) { 154 int cc = fCurrentEntity.ch[fCurrentEntity.position++]; 155 if (cc != '\n' && cc != 0x85) { 156 fCurrentEntity.position--; 157 } 158 } 159 c = '\n'; 160 } 161 162 // return character that was scanned 163 fCurrentEntity.columnNumber++; 164 return c; 165 166 } // scanChar():int 167 168 /** 169 * Returns a string matching the NMTOKEN production appearing immediately 170 * on the input as a symbol, or null if NMTOKEN Name string is present. 171 * <p> 172 * <strong>Note:</strong> The NMTOKEN characters are consumed. 173 * <p> 174 * <strong>Note:</strong> The string returned must be a symbol. The 175 * SymbolTable can be used for this purpose. 176 * 177 * @throws IOException Thrown if i/o error occurs. 178 * @throws EOFException Thrown on end of file. 179 * 180 * @see com.sun.org.apache.xerces.internal.util.SymbolTable 181 * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Name 182 */ 183 public String scanNmtoken() throws IOException { 184 // load more characters, if needed 185 if (fCurrentEntity.position == fCurrentEntity.count) { 186 load(0, true, true); 187 } 188 189 // scan nmtoken 190 int offset = fCurrentEntity.position; 191 192 do { 193 char ch = fCurrentEntity.ch[fCurrentEntity.position]; 194 if (XML11Char.isXML11Name(ch)) { 195 if (++fCurrentEntity.position == fCurrentEntity.count) { 196 int length = fCurrentEntity.position - offset; 197 invokeListeners(length); 198 if (length == fCurrentEntity.ch.length) { 199 // bad luck we have to resize our buffer 200 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 201 System.arraycopy(fCurrentEntity.ch, offset, 202 tmp, 0, length); 203 fCurrentEntity.ch = tmp; 204 } 205 else { 206 System.arraycopy(fCurrentEntity.ch, offset, 207 fCurrentEntity.ch, 0, length); 208 } 209 offset = 0; 210 if (load(length, false, false)) { 211 break; 212 } 213 } 214 } 215 else if (XML11Char.isXML11NameHighSurrogate(ch)) { 216 if (++fCurrentEntity.position == fCurrentEntity.count) { 217 int length = fCurrentEntity.position - offset; 218 invokeListeners(length); 219 if (length == fCurrentEntity.ch.length) { 220 // bad luck we have to resize our buffer 221 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 222 System.arraycopy(fCurrentEntity.ch, offset, 223 tmp, 0, length); 224 fCurrentEntity.ch = tmp; 225 } 226 else { 227 System.arraycopy(fCurrentEntity.ch, offset, 228 fCurrentEntity.ch, 0, length); 229 } 230 offset = 0; 231 if (load(length, false, false)) { 232 --fCurrentEntity.startPosition; 233 --fCurrentEntity.position; 234 break; 235 } 236 } 237 char ch2 = fCurrentEntity.ch[fCurrentEntity.position]; 238 if ( !XMLChar.isLowSurrogate(ch2) || 239 !XML11Char.isXML11Name(XMLChar.supplemental(ch, ch2)) ) { 240 --fCurrentEntity.position; 241 break; 242 } 243 if (++fCurrentEntity.position == fCurrentEntity.count) { 244 int length = fCurrentEntity.position - offset; 245 invokeListeners(length); 246 if (length == fCurrentEntity.ch.length) { 247 // bad luck we have to resize our buffer 248 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 249 System.arraycopy(fCurrentEntity.ch, offset, 250 tmp, 0, length); 251 fCurrentEntity.ch = tmp; 252 } 253 else { 254 System.arraycopy(fCurrentEntity.ch, offset, 255 fCurrentEntity.ch, 0, length); 256 } 257 offset = 0; 258 if (load(length, false, false)) { 259 break; 260 } 261 } 262 } 263 else { 264 break; 265 } 266 } 267 while (true); 268 269 int length = fCurrentEntity.position - offset; 270 fCurrentEntity.columnNumber += length; 271 272 // return nmtoken 273 String symbol = null; 274 if (length > 0) { 275 symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length); 276 } 277 return symbol; 278 279 } // scanNmtoken():String 280 281 /** 282 * Returns a string matching the Name production appearing immediately 283 * on the input as a symbol, or null if no Name string is present. 284 * <p> 285 * <strong>Note:</strong> The Name characters are consumed. 286 * <p> 287 * <strong>Note:</strong> The string returned must be a symbol. The 288 * SymbolTable can be used for this purpose. 289 * 290 * @throws IOException Thrown if i/o error occurs. 291 * @throws EOFException Thrown on end of file. 292 * 293 * @see com.sun.org.apache.xerces.internal.util.SymbolTable 294 * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Name 295 * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NameStart 296 */ 297 public String scanName() throws IOException { 298 // load more characters, if needed 299 if (fCurrentEntity.position == fCurrentEntity.count) { 300 load(0, true, true); 301 } 302 303 // scan name 304 int offset = fCurrentEntity.position; 305 char ch = fCurrentEntity.ch[offset]; 306 307 if (XML11Char.isXML11NameStart(ch)) { 308 if (++fCurrentEntity.position == fCurrentEntity.count) { 309 invokeListeners(1); 310 fCurrentEntity.ch[0] = ch; 311 offset = 0; 312 if (load(1, false, false)) { 313 fCurrentEntity.columnNumber++; 314 String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); 315 return symbol; 316 } 317 } 318 } 319 else if (XML11Char.isXML11NameHighSurrogate(ch)) { 320 if (++fCurrentEntity.position == fCurrentEntity.count) { 321 invokeListeners(1); 322 fCurrentEntity.ch[0] = ch; 323 offset = 0; 324 if (load(1, false, false)) { 325 --fCurrentEntity.position; 326 --fCurrentEntity.startPosition; 327 return null; 328 } 329 } 330 char ch2 = fCurrentEntity.ch[fCurrentEntity.position]; 331 if ( !XMLChar.isLowSurrogate(ch2) || 332 !XML11Char.isXML11NameStart(XMLChar.supplemental(ch, ch2)) ) { 333 --fCurrentEntity.position; 334 return null; 335 } 336 if (++fCurrentEntity.position == fCurrentEntity.count) { 337 invokeListeners(2); 338 fCurrentEntity.ch[0] = ch; 339 fCurrentEntity.ch[1] = ch2; 340 offset = 0; 341 if (load(2, false, false)) { 342 fCurrentEntity.columnNumber += 2; 343 String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2); 344 return symbol; 345 } 346 } 347 } 348 else { 349 return null; 350 } 351 352 do { 353 ch = fCurrentEntity.ch[fCurrentEntity.position]; 354 if (XML11Char.isXML11Name(ch)) { 355 if (++fCurrentEntity.position == fCurrentEntity.count) { 356 int length = fCurrentEntity.position - offset; 357 invokeListeners(length); 358 if (length == fCurrentEntity.ch.length) { 359 // bad luck we have to resize our buffer 360 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 361 System.arraycopy(fCurrentEntity.ch, offset, 362 tmp, 0, length); 363 fCurrentEntity.ch = tmp; 364 } 365 else { 366 System.arraycopy(fCurrentEntity.ch, offset, 367 fCurrentEntity.ch, 0, length); 368 } 369 offset = 0; 370 if (load(length, false, false)) { 371 break; 372 } 373 } 374 } 375 else if (XML11Char.isXML11NameHighSurrogate(ch)) { 376 if (++fCurrentEntity.position == fCurrentEntity.count) { 377 int length = fCurrentEntity.position - offset; 378 invokeListeners(length); 379 if (length == fCurrentEntity.ch.length) { 380 // bad luck we have to resize our buffer 381 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 382 System.arraycopy(fCurrentEntity.ch, offset, 383 tmp, 0, length); 384 fCurrentEntity.ch = tmp; 385 } 386 else { 387 System.arraycopy(fCurrentEntity.ch, offset, 388 fCurrentEntity.ch, 0, length); 389 } 390 offset = 0; 391 if (load(length, false, false)) { 392 --fCurrentEntity.position; 393 --fCurrentEntity.startPosition; 394 break; 395 } 396 } 397 char ch2 = fCurrentEntity.ch[fCurrentEntity.position]; 398 if ( !XMLChar.isLowSurrogate(ch2) || 399 !XML11Char.isXML11Name(XMLChar.supplemental(ch, ch2)) ) { 400 --fCurrentEntity.position; 401 break; 402 } 403 if (++fCurrentEntity.position == fCurrentEntity.count) { 404 int length = fCurrentEntity.position - offset; 405 invokeListeners(length); 406 if (length == fCurrentEntity.ch.length) { 407 // bad luck we have to resize our buffer 408 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 409 System.arraycopy(fCurrentEntity.ch, offset, 410 tmp, 0, length); 411 fCurrentEntity.ch = tmp; 412 } 413 else { 414 System.arraycopy(fCurrentEntity.ch, offset, 415 fCurrentEntity.ch, 0, length); 416 } 417 offset = 0; 418 if (load(length, false, false)) { 419 break; 420 } 421 } 422 } 423 else { 424 break; 425 } 426 } 427 while (true); 428 429 int length = fCurrentEntity.position - offset; 430 fCurrentEntity.columnNumber += length; 431 432 // return name 433 String symbol = null; 434 if (length > 0) { 435 symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length); 436 } 437 return symbol; 438 439 } // scanName():String 440 441 /** 442 * Returns a string matching the NCName production appearing immediately 443 * on the input as a symbol, or null if no NCName string is present. 444 * <p> 445 * <strong>Note:</strong> The NCName characters are consumed. 446 * <p> 447 * <strong>Note:</strong> The string returned must be a symbol. The 448 * SymbolTable can be used for this purpose. 449 * 450 * @throws IOException Thrown if i/o error occurs. 451 * @throws EOFException Thrown on end of file. 452 * 453 * @see com.sun.org.apache.xerces.internal.util.SymbolTable 454 * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NCName 455 * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NCNameStart 456 */ 457 public String scanNCName() throws IOException { 458 459 // load more characters, if needed 460 if (fCurrentEntity.position == fCurrentEntity.count) { 461 load(0, true, true); 462 } 463 464 // scan name 465 int offset = fCurrentEntity.position; 466 char ch = fCurrentEntity.ch[offset]; 467 468 if (XML11Char.isXML11NCNameStart(ch)) { 469 if (++fCurrentEntity.position == fCurrentEntity.count) { 470 invokeListeners(1); 471 fCurrentEntity.ch[0] = ch; 472 offset = 0; 473 if (load(1, false, false)) { 474 fCurrentEntity.columnNumber++; 475 String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); 476 return symbol; 477 } 478 } 479 } 480 else if (XML11Char.isXML11NameHighSurrogate(ch)) { 481 if (++fCurrentEntity.position == fCurrentEntity.count) { 482 invokeListeners(1); 483 fCurrentEntity.ch[0] = ch; 484 offset = 0; 485 if (load(1, false, false)) { 486 --fCurrentEntity.position; 487 --fCurrentEntity.startPosition; 488 return null; 489 } 490 } 491 char ch2 = fCurrentEntity.ch[fCurrentEntity.position]; 492 if ( !XMLChar.isLowSurrogate(ch2) || 493 !XML11Char.isXML11NCNameStart(XMLChar.supplemental(ch, ch2)) ) { 494 --fCurrentEntity.position; 495 return null; 496 } 497 if (++fCurrentEntity.position == fCurrentEntity.count) { 498 invokeListeners(2); 499 fCurrentEntity.ch[0] = ch; 500 fCurrentEntity.ch[1] = ch2; 501 offset = 0; 502 if (load(2, false, false)) { 503 fCurrentEntity.columnNumber += 2; 504 String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2); 505 return symbol; 506 } 507 } 508 } 509 else { 510 return null; 511 } 512 513 do { 514 ch = fCurrentEntity.ch[fCurrentEntity.position]; 515 if (XML11Char.isXML11NCName(ch)) { 516 if (++fCurrentEntity.position == fCurrentEntity.count) { 517 int length = fCurrentEntity.position - offset; 518 invokeListeners(length); 519 if (length == fCurrentEntity.ch.length) { 520 // bad luck we have to resize our buffer 521 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 522 System.arraycopy(fCurrentEntity.ch, offset, 523 tmp, 0, length); 524 fCurrentEntity.ch = tmp; 525 } 526 else { 527 System.arraycopy(fCurrentEntity.ch, offset, 528 fCurrentEntity.ch, 0, length); 529 } 530 offset = 0; 531 if (load(length, false, false)) { 532 break; 533 } 534 } 535 } 536 else if (XML11Char.isXML11NameHighSurrogate(ch)) { 537 if (++fCurrentEntity.position == fCurrentEntity.count) { 538 int length = fCurrentEntity.position - offset; 539 invokeListeners(length); 540 if (length == fCurrentEntity.ch.length) { 541 // bad luck we have to resize our buffer 542 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 543 System.arraycopy(fCurrentEntity.ch, offset, 544 tmp, 0, length); 545 fCurrentEntity.ch = tmp; 546 } 547 else { 548 System.arraycopy(fCurrentEntity.ch, offset, 549 fCurrentEntity.ch, 0, length); 550 } 551 offset = 0; 552 if (load(length, false, false)) { 553 --fCurrentEntity.startPosition; 554 --fCurrentEntity.position; 555 break; 556 } 557 } 558 char ch2 = fCurrentEntity.ch[fCurrentEntity.position]; 559 if ( !XMLChar.isLowSurrogate(ch2) || 560 !XML11Char.isXML11NCName(XMLChar.supplemental(ch, ch2)) ) { 561 --fCurrentEntity.position; 562 break; 563 } 564 if (++fCurrentEntity.position == fCurrentEntity.count) { 565 int length = fCurrentEntity.position - offset; 566 invokeListeners(length); 567 if (length == fCurrentEntity.ch.length) { 568 // bad luck we have to resize our buffer 569 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 570 System.arraycopy(fCurrentEntity.ch, offset, 571 tmp, 0, length); 572 fCurrentEntity.ch = tmp; 573 } 574 else { 575 System.arraycopy(fCurrentEntity.ch, offset, 576 fCurrentEntity.ch, 0, length); 577 } 578 offset = 0; 579 if (load(length, false, false)) { 580 break; 581 } 582 } 583 } 584 else { 585 break; 586 } 587 } 588 while (true); 589 590 int length = fCurrentEntity.position - offset; 591 fCurrentEntity.columnNumber += length; 592 593 // return name 594 String symbol = null; 595 if (length > 0) { 596 symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length); 597 } 598 return symbol; 599 600 } // scanNCName():String 601 602 /** 603 * Scans a qualified name from the input, setting the fields of the 604 * QName structure appropriately. 605 * <p> 606 * <strong>Note:</strong> The qualified name characters are consumed. 607 * <p> 608 * <strong>Note:</strong> The strings used to set the values of the 609 * QName structure must be symbols. The SymbolTable can be used for 610 * this purpose. 611 * 612 * @param qname The qualified name structure to fill. 613 * 614 * @return Returns true if a qualified name appeared immediately on 615 * the input and was scanned, false otherwise. 616 * 617 * @throws IOException Thrown if i/o error occurs. 618 * @throws EOFException Thrown on end of file. 619 * 620 * @see com.sun.org.apache.xerces.internal.util.SymbolTable 621 * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Name 622 * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NameStart 623 */ 624 public boolean scanQName(QName qname) throws IOException { 625 626 // load more characters, if needed 627 if (fCurrentEntity.position == fCurrentEntity.count) { 628 load(0, true, true); 629 } 630 631 // scan qualified name 632 int offset = fCurrentEntity.position; 633 char ch = fCurrentEntity.ch[offset]; 634 635 if (XML11Char.isXML11NCNameStart(ch)) { 636 if (++fCurrentEntity.position == fCurrentEntity.count) { 637 invokeListeners(1); 638 fCurrentEntity.ch[0] = ch; 639 offset = 0; 640 if (load(1, false, false)) { 641 fCurrentEntity.columnNumber++; 642 String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); 643 qname.setValues(null, name, name, null); 644 return true; 645 } 646 } 647 } 648 else if (XML11Char.isXML11NameHighSurrogate(ch)) { 649 if (++fCurrentEntity.position == fCurrentEntity.count) { 650 invokeListeners(1); 651 fCurrentEntity.ch[0] = ch; 652 offset = 0; 653 if (load(1, false, false)) { 654 --fCurrentEntity.startPosition; 655 --fCurrentEntity.position; 656 return false; 657 } 658 } 659 char ch2 = fCurrentEntity.ch[fCurrentEntity.position]; 660 if ( !XMLChar.isLowSurrogate(ch2) || 661 !XML11Char.isXML11NCNameStart(XMLChar.supplemental(ch, ch2)) ) { 662 --fCurrentEntity.position; 663 return false; 664 } 665 if (++fCurrentEntity.position == fCurrentEntity.count) { 666 invokeListeners(2); 667 fCurrentEntity.ch[0] = ch; 668 fCurrentEntity.ch[1] = ch2; 669 offset = 0; 670 if (load(2, false, false)) { 671 fCurrentEntity.columnNumber += 2; 672 String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2); 673 qname.setValues(null, name, name, null); 674 return true; 675 } 676 } 677 } 678 else { 679 return false; 680 } 681 682 int index = -1; 683 boolean sawIncompleteSurrogatePair = false; 684 do { 685 ch = fCurrentEntity.ch[fCurrentEntity.position]; 686 if (XML11Char.isXML11Name(ch)) { 687 if (ch == ':') { 688 if (index != -1) { 689 break; 690 } 691 index = fCurrentEntity.position; 692 } 693 if (++fCurrentEntity.position == fCurrentEntity.count) { 694 int length = fCurrentEntity.position - offset; 695 invokeListeners(length); 696 if (length == fCurrentEntity.ch.length) { 697 // bad luck we have to resize our buffer 698 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 699 System.arraycopy(fCurrentEntity.ch, offset, 700 tmp, 0, length); 701 fCurrentEntity.ch = tmp; 702 } 703 else { 704 System.arraycopy(fCurrentEntity.ch, offset, 705 fCurrentEntity.ch, 0, length); 706 } 707 if (index != -1) { 708 index = index - offset; 709 } 710 offset = 0; 711 if (load(length, false, false)) { 712 break; 713 } 714 } 715 } 716 else if (XML11Char.isXML11NameHighSurrogate(ch)) { 717 if (++fCurrentEntity.position == fCurrentEntity.count) { 718 int length = fCurrentEntity.position - offset; 719 invokeListeners(length); 720 if (length == fCurrentEntity.ch.length) { 721 // bad luck we have to resize our buffer 722 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 723 System.arraycopy(fCurrentEntity.ch, offset, 724 tmp, 0, length); 725 fCurrentEntity.ch = tmp; 726 } 727 else { 728 System.arraycopy(fCurrentEntity.ch, offset, 729 fCurrentEntity.ch, 0, length); 730 } 731 if (index != -1) { 732 index = index - offset; 733 } 734 offset = 0; 735 if (load(length, false, false)) { 736 sawIncompleteSurrogatePair = true; 737 --fCurrentEntity.startPosition; 738 --fCurrentEntity.position; 739 break; 740 } 741 } 742 char ch2 = fCurrentEntity.ch[fCurrentEntity.position]; 743 if ( !XMLChar.isLowSurrogate(ch2) || 744 !XML11Char.isXML11Name(XMLChar.supplemental(ch, ch2)) ) { 745 sawIncompleteSurrogatePair = true; 746 --fCurrentEntity.position; 747 break; 748 } 749 if (++fCurrentEntity.position == fCurrentEntity.count) { 750 int length = fCurrentEntity.position - offset; 751 invokeListeners(length); 752 if (length == fCurrentEntity.ch.length) { 753 // bad luck we have to resize our buffer 754 char[] tmp = new char[fCurrentEntity.ch.length << 1]; 755 System.arraycopy(fCurrentEntity.ch, offset, 756 tmp, 0, length); 757 fCurrentEntity.ch = tmp; 758 } 759 else { 760 System.arraycopy(fCurrentEntity.ch, offset, 761 fCurrentEntity.ch, 0, length); 762 } 763 if (index != -1) { 764 index = index - offset; 765 } 766 offset = 0; 767 if (load(length, false, false)) { 768 break; 769 } 770 } 771 } 772 else { 773 break; 774 } 775 } 776 while (true); 777 778 int length = fCurrentEntity.position - offset; 779 fCurrentEntity.columnNumber += length; 780 781 if (length > 0) { 782 String prefix = null; 783 String localpart = null; 784 String rawname = fSymbolTable.addSymbol(fCurrentEntity.ch, 785 offset, length); 786 if (index != -1) { 787 int prefixLength = index - offset; 788 prefix = fSymbolTable.addSymbol(fCurrentEntity.ch, 789 offset, prefixLength); 790 int len = length - prefixLength - 1; 791 int startLocal = index +1; 792 if (!XML11Char.isXML11NCNameStart(fCurrentEntity.ch[startLocal]) && 793 (!XML11Char.isXML11NameHighSurrogate(fCurrentEntity.ch[startLocal]) || 794 sawIncompleteSurrogatePair)){ 795 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 796 "IllegalQName", 797 null, 798 XMLErrorReporter.SEVERITY_FATAL_ERROR); 799 } 800 localpart = fSymbolTable.addSymbol(fCurrentEntity.ch, 801 index + 1, len); 802 803 } 804 else { 805 localpart = rawname; 806 } 807 qname.setValues(prefix, localpart, rawname, null); 808 return true; 809 } 810 return false; 811 812 } // scanQName(QName):boolean 813 814 /** 815 * Scans a range of parsed character data, setting the fields of the 816 * XMLString structure, appropriately. 817 * <p> 818 * <strong>Note:</strong> The characters are consumed. 819 * <p> 820 * <strong>Note:</strong> This method does not guarantee to return 821 * the longest run of parsed character data. This method may return 822 * before markup due to reaching the end of the input buffer or any 823 * other reason. 824 * <p> 825 * <strong>Note:</strong> The fields contained in the XMLString 826 * structure are not guaranteed to remain valid upon subsequent calls 827 * to the entity scanner. Therefore, the caller is responsible for 828 * immediately using the returned character data or making a copy of 829 * the character data. 830 * 831 * @param content The content structure to fill. 832 * 833 * @return Returns the next character on the input, if known. This 834 * value may be -1 but this does <em>note</em> designate 835 * end of file. 836 * 837 * @throws IOException Thrown if i/o error occurs. 838 * @throws EOFException Thrown on end of file. 839 */ 840 public int scanContent(XMLString content) throws IOException { 841 842 // load more characters, if needed 843 if (fCurrentEntity.position == fCurrentEntity.count) { 844 load(0, true, true); 845 } 846 else if (fCurrentEntity.position == fCurrentEntity.count - 1) { 847 invokeListeners(0); 848 fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1]; 849 load(1, false, false); 850 fCurrentEntity.position = 0; 851 fCurrentEntity.startPosition = 0; 852 } 853 854 // normalize newlines 855 int offset = fCurrentEntity.position; 856 int c = fCurrentEntity.ch[offset]; 857 int newlines = 0; 858 boolean external = fCurrentEntity.isExternal(); 859 if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) { 860 do { 861 c = fCurrentEntity.ch[fCurrentEntity.position++]; 862 if ((c == '\r' ) && external) { 863 newlines++; 864 fCurrentEntity.lineNumber++; 865 fCurrentEntity.columnNumber = 1; 866 if (fCurrentEntity.position == fCurrentEntity.count) { 867 offset = 0; 868 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); 869 fCurrentEntity.position = newlines; 870 fCurrentEntity.startPosition = newlines; 871 if (load(newlines, false, true)) { 872 break; 873 } 874 } 875 int cc = fCurrentEntity.ch[fCurrentEntity.position]; 876 if (cc == '\n' || cc == 0x85) { 877 fCurrentEntity.position++; 878 offset++; 879 } 880 /*** NEWLINE NORMALIZATION ***/ 881 else { 882 newlines++; 883 } 884 } 885 else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) { 886 newlines++; 887 fCurrentEntity.lineNumber++; 888 fCurrentEntity.columnNumber = 1; 889 if (fCurrentEntity.position == fCurrentEntity.count) { 890 offset = 0; 891 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); 892 fCurrentEntity.position = newlines; 893 fCurrentEntity.startPosition = newlines; 894 if (load(newlines, false, true)) { 895 break; 896 } 897 } 898 } 899 else { 900 fCurrentEntity.position--; 901 break; 902 } 903 } while (fCurrentEntity.position < fCurrentEntity.count - 1); 904 for (int i = offset; i < fCurrentEntity.position; i++) { 905 fCurrentEntity.ch[i] = '\n'; 906 } 907 int length = fCurrentEntity.position - offset; 908 if (fCurrentEntity.position == fCurrentEntity.count - 1) { 909 content.setValues(fCurrentEntity.ch, offset, length); 910 return -1; 911 } 912 } 913 914 // inner loop, scanning for content 915 if (external) { 916 while (fCurrentEntity.position < fCurrentEntity.count) { 917 c = fCurrentEntity.ch[fCurrentEntity.position++]; 918 if (!XML11Char.isXML11Content(c) || c == 0x85 || c == 0x2028) { 919 fCurrentEntity.position--; 920 break; 921 } 922 } 923 } 924 else { 925 while (fCurrentEntity.position < fCurrentEntity.count) { 926 c = fCurrentEntity.ch[fCurrentEntity.position++]; 927 // In internal entities control characters are allowed to appear unescaped. 928 if (!XML11Char.isXML11InternalEntityContent(c)) { 929 fCurrentEntity.position--; 930 break; 931 } 932 } 933 } 934 int length = fCurrentEntity.position - offset; 935 fCurrentEntity.columnNumber += length - newlines; 936 content.setValues(fCurrentEntity.ch, offset, length); 937 938 // return next character 939 if (fCurrentEntity.position != fCurrentEntity.count) { 940 c = fCurrentEntity.ch[fCurrentEntity.position]; 941 // REVISIT: Does this need to be updated to fix the 942 // #x0D ^#x0A newline normalization problem? -Ac 943 if ((c == '\r' || c == 0x85 || c == 0x2028) && external) { 944 c = '\n'; 945 } 946 } 947 else { 948 c = -1; 949 } 950 return c; 951 952 } // scanContent(XMLString):int 953 954 /** 955 * Scans a range of attribute value data, setting the fields of the 956 * XMLString structure, appropriately. 957 * <p> 958 * <strong>Note:</strong> The characters are consumed. 959 * <p> 960 * <strong>Note:</strong> This method does not guarantee to return 961 * the longest run of attribute value data. This method may return 962 * before the quote character due to reaching the end of the input 963 * buffer or any other reason. 964 * <p> 965 * <strong>Note:</strong> The fields contained in the XMLString 966 * structure are not guaranteed to remain valid upon subsequent calls 967 * to the entity scanner. Therefore, the caller is responsible for 968 * immediately using the returned character data or making a copy of 969 * the character data. 970 * 971 * @param quote The quote character that signifies the end of the 972 * attribute value data. 973 * @param content The content structure to fill. 974 * 975 * @return Returns the next character on the input, if known. This 976 * value may be -1 but this does <em>note</em> designate 977 * end of file. 978 * 979 * @throws IOException Thrown if i/o error occurs. 980 * @throws EOFException Thrown on end of file. 981 */ 982 public int scanLiteral(int quote, XMLString content) 983 throws IOException { 984 // load more characters, if needed 985 if (fCurrentEntity.position == fCurrentEntity.count) { 986 load(0, true, true); 987 } 988 else if (fCurrentEntity.position == fCurrentEntity.count - 1) { 989 invokeListeners(0); 990 fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1]; 991 load(1, false, false); 992 fCurrentEntity.startPosition = 0; 993 fCurrentEntity.position = 0; 994 } 995 996 // normalize newlines 997 int offset = fCurrentEntity.position; 998 int c = fCurrentEntity.ch[offset]; 999 int newlines = 0; 1000 boolean external = fCurrentEntity.isExternal(); 1001 if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) { 1002 do { 1003 c = fCurrentEntity.ch[fCurrentEntity.position++]; 1004 if ((c == '\r' ) && external) { 1005 newlines++; 1006 fCurrentEntity.lineNumber++; 1007 fCurrentEntity.columnNumber = 1; 1008 if (fCurrentEntity.position == fCurrentEntity.count) { 1009 offset = 0; 1010 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); 1011 fCurrentEntity.position = newlines; 1012 fCurrentEntity.startPosition = newlines; 1013 if (load(newlines, false, true)) { 1014 break; 1015 } 1016 } 1017 int cc = fCurrentEntity.ch[fCurrentEntity.position]; 1018 if (cc == '\n' || cc == 0x85) { 1019 fCurrentEntity.position++; 1020 offset++; 1021 } 1022 /*** NEWLINE NORMALIZATION ***/ 1023 else { 1024 newlines++; 1025 } 1026 } 1027 else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) { 1028 newlines++; 1029 fCurrentEntity.lineNumber++; 1030 fCurrentEntity.columnNumber = 1; 1031 if (fCurrentEntity.position == fCurrentEntity.count) { 1032 offset = 0; 1033 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); 1034 fCurrentEntity.position = newlines; 1035 fCurrentEntity.startPosition = newlines; 1036 if (load(newlines, false, true)) { 1037 break; 1038 } 1039 } 1040 } 1041 else { 1042 fCurrentEntity.position--; 1043 break; 1044 } 1045 } while (fCurrentEntity.position < fCurrentEntity.count - 1); 1046 for (int i = offset; i < fCurrentEntity.position; i++) { 1047 fCurrentEntity.ch[i] = '\n'; 1048 } 1049 int length = fCurrentEntity.position - offset; 1050 if (fCurrentEntity.position == fCurrentEntity.count - 1) { 1051 content.setValues(fCurrentEntity.ch, offset, length); 1052 return -1; 1053 } 1054 } 1055 1056 // scan literal value 1057 if (external) { 1058 while (fCurrentEntity.position < fCurrentEntity.count) { 1059 c = fCurrentEntity.ch[fCurrentEntity.position++]; 1060 if (c == quote || c == '%' || !XML11Char.isXML11Content(c) 1061 || c == 0x85 || c == 0x2028) { 1062 fCurrentEntity.position--; 1063 break; 1064 } 1065 } 1066 } 1067 else { 1068 while (fCurrentEntity.position < fCurrentEntity.count) { 1069 c = fCurrentEntity.ch[fCurrentEntity.position++]; 1070 // In internal entities control characters are allowed to appear unescaped. 1071 if ((c == quote && !fCurrentEntity.literal) 1072 || c == '%' || !XML11Char.isXML11InternalEntityContent(c)) { 1073 fCurrentEntity.position--; 1074 break; 1075 } 1076 } 1077 } 1078 int length = fCurrentEntity.position - offset; 1079 fCurrentEntity.columnNumber += length - newlines; 1080 content.setValues(fCurrentEntity.ch, offset, length); 1081 1082 // return next character 1083 if (fCurrentEntity.position != fCurrentEntity.count) { 1084 c = fCurrentEntity.ch[fCurrentEntity.position]; 1085 // NOTE: We don't want to accidentally signal the 1086 // end of the literal if we're expanding an 1087 // entity appearing in the literal. -Ac 1088 if (c == quote && fCurrentEntity.literal) { 1089 c = -1; 1090 } 1091 } 1092 else { 1093 c = -1; 1094 } 1095 return c; 1096 1097 } // scanLiteral(int,XMLString):int 1098 1099 /** 1100 * Scans a range of character data up to the specicied delimiter, 1101 * setting the fields of the XMLString structure, appropriately. 1102 * <p> 1103 * <strong>Note:</strong> The characters are consumed. 1104 * <p> 1105 * <strong>Note:</strong> This assumes that the internal buffer is 1106 * at least the same size, or bigger, than the length of the delimiter 1107 * and that the delimiter contains at least one character. 1108 * <p> 1109 * <strong>Note:</strong> This method does not guarantee to return 1110 * the longest run of character data. This method may return before 1111 * the delimiter due to reaching the end of the input buffer or any 1112 * other reason. 1113 * <p> 1114 * <strong>Note:</strong> The fields contained in the XMLString 1115 * structure are not guaranteed to remain valid upon subsequent calls 1116 * to the entity scanner. Therefore, the caller is responsible for 1117 * immediately using the returned character data or making a copy of 1118 * the character data. 1119 * 1120 * @param delimiter The string that signifies the end of the character 1121 * data to be scanned. 1122 * @param data The data structure to fill. 1123 * 1124 * @return Returns true if there is more data to scan, false otherwise. 1125 * 1126 * @throws IOException Thrown if i/o error occurs. 1127 * @throws EOFException Thrown on end of file. 1128 */ 1129 public boolean scanData(String delimiter, XMLStringBuffer buffer) 1130 throws IOException { 1131 1132 boolean done = false; 1133 int delimLen = delimiter.length(); 1134 char charAt0 = delimiter.charAt(0); 1135 boolean external = fCurrentEntity.isExternal(); 1136 do { 1137 // load more characters, if needed 1138 if (fCurrentEntity.position == fCurrentEntity.count) { 1139 load(0, true, false); 1140 } 1141 1142 boolean bNextEntity = false; 1143 1144 while ((fCurrentEntity.position >= fCurrentEntity.count - delimLen) 1145 && (!bNextEntity)) 1146 { 1147 System.arraycopy(fCurrentEntity.ch, 1148 fCurrentEntity.position, 1149 fCurrentEntity.ch, 1150 0, 1151 fCurrentEntity.count - fCurrentEntity.position); 1152 1153 bNextEntity = load(fCurrentEntity.count - fCurrentEntity.position, false, false); 1154 fCurrentEntity.position = 0; 1155 fCurrentEntity.startPosition = 0; 1156 } 1157 1158 if (fCurrentEntity.position >= fCurrentEntity.count - delimLen) { 1159 // something must be wrong with the input: e.g., file ends an unterminated comment 1160 int length = fCurrentEntity.count - fCurrentEntity.position; 1161 buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length); 1162 fCurrentEntity.columnNumber += fCurrentEntity.count; 1163 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); 1164 fCurrentEntity.position = fCurrentEntity.count; 1165 fCurrentEntity.startPosition = fCurrentEntity.count; 1166 load(0,true, false); 1167 return false; 1168 } 1169 1170 // normalize newlines 1171 int offset = fCurrentEntity.position; 1172 int c = fCurrentEntity.ch[offset]; 1173 int newlines = 0; 1174 if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) { 1175 do { 1176 c = fCurrentEntity.ch[fCurrentEntity.position++]; 1177 if ((c == '\r' ) && external) { 1178 newlines++; 1179 fCurrentEntity.lineNumber++; 1180 fCurrentEntity.columnNumber = 1; 1181 if (fCurrentEntity.position == fCurrentEntity.count) { 1182 offset = 0; 1183 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); 1184 fCurrentEntity.position = newlines; 1185 fCurrentEntity.startPosition = newlines; 1186 if (load(newlines, false, true)) { 1187 break; 1188 } 1189 } 1190 int cc = fCurrentEntity.ch[fCurrentEntity.position]; 1191 if (cc == '\n' || cc == 0x85) { 1192 fCurrentEntity.position++; 1193 offset++; 1194 } 1195 /*** NEWLINE NORMALIZATION ***/ 1196 else { 1197 newlines++; 1198 } 1199 } 1200 else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) { 1201 newlines++; 1202 fCurrentEntity.lineNumber++; 1203 fCurrentEntity.columnNumber = 1; 1204 if (fCurrentEntity.position == fCurrentEntity.count) { 1205 offset = 0; 1206 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); 1207 fCurrentEntity.position = newlines; 1208 fCurrentEntity.startPosition = newlines; 1209 fCurrentEntity.count = newlines; 1210 if (load(newlines, false, true)) { 1211 break; 1212 } 1213 } 1214 } 1215 else { 1216 fCurrentEntity.position--; 1217 break; 1218 } 1219 } while (fCurrentEntity.position < fCurrentEntity.count - 1); 1220 for (int i = offset; i < fCurrentEntity.position; i++) { 1221 fCurrentEntity.ch[i] = '\n'; 1222 } 1223 int length = fCurrentEntity.position - offset; 1224 if (fCurrentEntity.position == fCurrentEntity.count - 1) { 1225 buffer.append(fCurrentEntity.ch, offset, length); 1226 return true; 1227 } 1228 } 1229 1230 // iterate over buffer looking for delimiter 1231 if (external) { 1232 OUTER: while (fCurrentEntity.position < fCurrentEntity.count) { 1233 c = fCurrentEntity.ch[fCurrentEntity.position++]; 1234 if (c == charAt0) { 1235 // looks like we just hit the delimiter 1236 int delimOffset = fCurrentEntity.position - 1; 1237 for (int i = 1; i < delimLen; i++) { 1238 if (fCurrentEntity.position == fCurrentEntity.count) { 1239 fCurrentEntity.position -= i; 1240 break OUTER; 1241 } 1242 c = fCurrentEntity.ch[fCurrentEntity.position++]; 1243 if (delimiter.charAt(i) != c) { 1244 fCurrentEntity.position--; 1245 break; 1246 } 1247 } 1248 if (fCurrentEntity.position == delimOffset + delimLen) { 1249 done = true; 1250 break; 1251 } 1252 } 1253 else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) { 1254 fCurrentEntity.position--; 1255 break; 1256 } 1257 // In external entities control characters cannot appear 1258 // as literals so do not skip over them. 1259 else if (!XML11Char.isXML11ValidLiteral(c)) { 1260 fCurrentEntity.position--; 1261 int length = fCurrentEntity.position - offset; 1262 fCurrentEntity.columnNumber += length - newlines; 1263 buffer.append(fCurrentEntity.ch, offset, length); 1264 return true; 1265 } 1266 } 1267 } 1268 else { 1269 OUTER: while (fCurrentEntity.position < fCurrentEntity.count) { 1270 c = fCurrentEntity.ch[fCurrentEntity.position++]; 1271 if (c == charAt0) { 1272 // looks like we just hit the delimiter 1273 int delimOffset = fCurrentEntity.position - 1; 1274 for (int i = 1; i < delimLen; i++) { 1275 if (fCurrentEntity.position == fCurrentEntity.count) { 1276 fCurrentEntity.position -= i; 1277 break OUTER; 1278 } 1279 c = fCurrentEntity.ch[fCurrentEntity.position++]; 1280 if (delimiter.charAt(i) != c) { 1281 fCurrentEntity.position--; 1282 break; 1283 } 1284 } 1285 if (fCurrentEntity.position == delimOffset + delimLen) { 1286 done = true; 1287 break; 1288 } 1289 } 1290 else if (c == '\n') { 1291 fCurrentEntity.position--; 1292 break; 1293 } 1294 // Control characters are allowed to appear as literals 1295 // in internal entities. 1296 else if (!XML11Char.isXML11Valid(c)) { 1297 fCurrentEntity.position--; 1298 int length = fCurrentEntity.position - offset; 1299 fCurrentEntity.columnNumber += length - newlines; 1300 buffer.append(fCurrentEntity.ch, offset, length); 1301 return true; 1302 } 1303 } 1304 } 1305 int length = fCurrentEntity.position - offset; 1306 fCurrentEntity.columnNumber += length - newlines; 1307 if (done) { 1308 length -= delimLen; 1309 } 1310 buffer.append(fCurrentEntity.ch, offset, length); 1311 1312 // return true if string was skipped 1313 } while (!done); 1314 return !done; 1315 1316 } // scanData(String,XMLString) 1317 1318 /** 1319 * Skips a character appearing immediately on the input. 1320 * <p> 1321 * <strong>Note:</strong> The character is consumed only if it matches 1322 * the specified character. 1323 * 1324 * @param c The character to skip. 1325 * 1326 * @return Returns true if the character was skipped. 1327 * 1328 * @throws IOException Thrown if i/o error occurs. 1329 * @throws EOFException Thrown on end of file. 1330 */ 1331 public boolean skipChar(int c) throws IOException { 1332 1333 // load more characters, if needed 1334 if (fCurrentEntity.position == fCurrentEntity.count) { 1335 load(0, true, true); 1336 } 1337 1338 // skip character 1339 int cc = fCurrentEntity.ch[fCurrentEntity.position]; 1340 if (cc == c) { 1341 fCurrentEntity.position++; 1342 if (c == '\n') { 1343 fCurrentEntity.lineNumber++; 1344 fCurrentEntity.columnNumber = 1; 1345 } 1346 else { 1347 fCurrentEntity.columnNumber++; 1348 } 1349 return true; 1350 } 1351 else if (c == '\n' && ((cc == 0x2028 || cc == 0x85) && fCurrentEntity.isExternal())) { 1352 fCurrentEntity.position++; 1353 fCurrentEntity.lineNumber++; 1354 fCurrentEntity.columnNumber = 1; 1355 return true; 1356 } 1357 else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) { 1358 // handle newlines 1359 if (fCurrentEntity.position == fCurrentEntity.count) { 1360 invokeListeners(1); 1361 fCurrentEntity.ch[0] = (char)cc; 1362 load(1, false, false); 1363 } 1364 int ccc = fCurrentEntity.ch[++fCurrentEntity.position]; 1365 if (ccc == '\n' || ccc == 0x85) { 1366 fCurrentEntity.position++; 1367 } 1368 fCurrentEntity.lineNumber++; 1369 fCurrentEntity.columnNumber = 1; 1370 return true; 1371 } 1372 1373 // character was not skipped 1374 return false; 1375 1376 } // skipChar(int):boolean 1377 1378 /** 1379 * Skips space characters appearing immediately on the input. 1380 * <p> 1381 * <strong>Note:</strong> The characters are consumed only if they are 1382 * space characters. 1383 * 1384 * @return Returns true if at least one space character was skipped. 1385 * 1386 * @throws IOException Thrown if i/o error occurs. 1387 * @throws EOFException Thrown on end of file. 1388 * 1389 * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace 1390 * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Space 1391 */ 1392 public boolean skipSpaces() throws IOException { 1393 1394 // load more characters, if needed 1395 if (fCurrentEntity.position == fCurrentEntity.count) { 1396 load(0, true, true); 1397 } 1398 1399 1400 //we are doing this check only in skipSpace() because it is called by 1401 //fMiscDispatcher and we want the parser to exit gracefully when document 1402 //is well-formed. 1403 //it is possible that end of document is reached and 1404 //fCurrentEntity becomes null 1405 //nothing was read so entity changed 'false' should be returned. 1406 if(fCurrentEntity == null){ 1407 return false ; 1408 } 1409 1410 // skip spaces 1411 int c = fCurrentEntity.ch[fCurrentEntity.position]; 1412 1413 // External -- Match: S + 0x85 + 0x2028, and perform end of line normalization 1414 if (fCurrentEntity.isExternal()) { 1415 if (XML11Char.isXML11Space(c)) { 1416 do { 1417 boolean entityChanged = false; 1418 // handle newlines 1419 if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) { 1420 fCurrentEntity.lineNumber++; 1421 fCurrentEntity.columnNumber = 1; 1422 if (fCurrentEntity.position == fCurrentEntity.count - 1) { 1423 invokeListeners(0); 1424 fCurrentEntity.ch[0] = (char)c; 1425 entityChanged = load(1, true, false); 1426 if (!entityChanged) { 1427 // the load change the position to be 1, 1428 // need to restore it when entity not changed 1429 fCurrentEntity.startPosition = 0; 1430 fCurrentEntity.position = 0; 1431 } else if(fCurrentEntity == null){ 1432 return true ; 1433 } 1434 1435 } 1436 if (c == '\r') { 1437 // REVISIT: Does this need to be updated to fix the 1438 // #x0D ^#x0A newline normalization problem? -Ac 1439 int cc = fCurrentEntity.ch[++fCurrentEntity.position]; 1440 if (cc != '\n' && cc != 0x85 ) { 1441 fCurrentEntity.position--; 1442 } 1443 } 1444 } 1445 else { 1446 fCurrentEntity.columnNumber++; 1447 } 1448 // load more characters, if needed 1449 if (!entityChanged) 1450 fCurrentEntity.position++; 1451 if (fCurrentEntity.position == fCurrentEntity.count) { 1452 load(0, true, true); 1453 1454 if(fCurrentEntity == null){ 1455 return true ; 1456 } 1457 1458 } 1459 } while (XML11Char.isXML11Space(c = fCurrentEntity.ch[fCurrentEntity.position])); 1460 return true; 1461 } 1462 } 1463 // Internal -- Match: S (only) 1464 else if (XMLChar.isSpace(c)) { 1465 do { 1466 boolean entityChanged = false; 1467 // handle newlines 1468 if (c == '\n') { 1469 fCurrentEntity.lineNumber++; 1470 fCurrentEntity.columnNumber = 1; 1471 if (fCurrentEntity.position == fCurrentEntity.count - 1) { 1472 fCurrentEntity.ch[0] = (char)c; 1473 entityChanged = load(1, true, true); 1474 if (!entityChanged) { 1475 // the load change the position to be 1, 1476 // need to restore it when entity not changed 1477 fCurrentEntity.startPosition = 0; 1478 fCurrentEntity.position = 0; 1479 } else if(fCurrentEntity == null){ 1480 return true ; 1481 } 1482 } 1483 } 1484 else { 1485 fCurrentEntity.columnNumber++; 1486 } 1487 // load more characters, if needed 1488 if (!entityChanged) 1489 fCurrentEntity.position++; 1490 if (fCurrentEntity.position == fCurrentEntity.count) { 1491 load(0, true, true); 1492 1493 if(fCurrentEntity == null){ 1494 return true ; 1495 } 1496 1497 } 1498 } while (XMLChar.isSpace(c = fCurrentEntity.ch[fCurrentEntity.position])); 1499 return true; 1500 } 1501 1502 // no spaces were found 1503 return false; 1504 1505 } // skipSpaces():boolean 1506 1507 /** 1508 * Skips the specified string appearing immediately on the input. 1509 * <p> 1510 * <strong>Note:</strong> The characters are consumed only if they are 1511 * space characters. 1512 * 1513 * @param s The string to skip. 1514 * 1515 * @return Returns true if the string was skipped. 1516 * 1517 * @throws IOException Thrown if i/o error occurs. 1518 * @throws EOFException Thrown on end of file. 1519 */ 1520 public boolean skipString(String s) throws IOException { 1521 1522 // load more characters, if needed 1523 if (fCurrentEntity.position == fCurrentEntity.count) { 1524 load(0, true, true); 1525 } 1526 1527 // skip string 1528 final int length = s.length(); 1529 for (int i = 0; i < length; i++) { 1530 char c = fCurrentEntity.ch[fCurrentEntity.position++]; 1531 if (c != s.charAt(i)) { 1532 fCurrentEntity.position -= i + 1; 1533 return false; 1534 } 1535 if (i < length - 1 && fCurrentEntity.position == fCurrentEntity.count) { 1536 invokeListeners(0); 1537 System.arraycopy(fCurrentEntity.ch, fCurrentEntity.count - i - 1, fCurrentEntity.ch, 0, i + 1); 1538 // REVISIT: Can a string to be skipped cross an 1539 // entity boundary? -Ac 1540 if (load(i + 1, false, false)) { 1541 fCurrentEntity.startPosition -= i + 1; 1542 fCurrentEntity.position -= i + 1; 1543 return false; 1544 } 1545 } 1546 } 1547 fCurrentEntity.columnNumber += length; 1548 return true; 1549 1550 } // skipString(String):boolean 1551 1552 } // class XML11EntityScanner