jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java

Print this page




   3  */
   4 
   5 /*
   6  * Copyright 2005 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xerces.internal.impl;
  22 
  23 import java.io.EOFException;
  24 import java.io.IOException;
  25 import java.util.Locale;
  26 import java.util.Vector;
  27 
  28 import com.sun.xml.internal.stream.Entity;
  29 import com.sun.xml.internal.stream.XMLBufferListener;
  30 import java.io.InputStream;
  31 import java.io.InputStreamReader;
  32 import java.io.Reader;
  33 
  34 
  35 import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
  36 import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
  37 import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
  38 
  39 
  40 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
  41 import com.sun.org.apache.xerces.internal.util.EncodingMap;
  42 
  43 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  44 import com.sun.org.apache.xerces.internal.util.XMLChar;
  45 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
  46 import com.sun.org.apache.xerces.internal.xni.QName;
  47 import com.sun.org.apache.xerces.internal.xni.XMLString;
  48 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  49 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  50 import com.sun.org.apache.xerces.internal.xni.*;








  51 
  52 /**
  53  * Implements the entity scanner methods.
  54  *
  55  * @author Neeraj Bajaj, Sun Microsystems
  56  * @author Andy Clark, IBM
  57  * @author Arnaud  Le Hors, IBM
  58  * @author K.Venugopal Sun Microsystems
  59  *
  60  */
  61 public class XMLEntityScanner implements XMLLocator  {
  62 
  63 
  64     protected Entity.ScannedEntity fCurrentEntity = null ;
  65     protected int fBufferSize = XMLEntityManager.DEFAULT_BUFFER_SIZE;
  66 
  67     protected XMLEntityManager fEntityManager ;
  68 
  69     /** Debug switching readers for encodings. */
  70     private static final boolean DEBUG_ENCODINGS = false;


 476         }
 477     }//getChar()
 478 
 479     /**
 480      * Returns the next character on the input.
 481      * <p>
 482      * <strong>Note:</strong> The character is <em>not</em> consumed.
 483      *
 484      * @throws IOException  Thrown if i/o error occurs.
 485      * @throws EOFException Thrown on end of file.
 486      */
 487     public int peekChar() throws IOException {
 488         if (DEBUG_BUFFER) {
 489             System.out.print("(peekChar: ");
 490             print();
 491             System.out.println();
 492         }
 493 
 494         // load more characters, if needed
 495         if (fCurrentEntity.position == fCurrentEntity.count) {
 496             invokeListeners(0);
 497             load(0, true);
 498         }
 499 
 500         // peek at character
 501         int c = fCurrentEntity.ch[fCurrentEntity.position];
 502 
 503         // return peeked character
 504         if (DEBUG_BUFFER) {
 505             System.out.print(")peekChar: ");
 506             print();
 507             if (isExternal) {
 508                 System.out.println(" -> '"+(c!='\r'?(char)c:'\n')+"'");
 509             } else {
 510                 System.out.println(" -> '"+(char)c+"'");
 511             }
 512         }
 513         if (isExternal) {
 514             return c != '\r' ? c : '\n';
 515         } else {
 516             return c;
 517         }
 518 
 519     } // peekChar():int
 520 
 521     /**
 522      * Returns the next character on the input.
 523      * <p>
 524      * <strong>Note:</strong> The character is consumed.
 525      *
 526      * @throws IOException  Thrown if i/o error occurs.
 527      * @throws EOFException Thrown on end of file.
 528      */
 529     public int scanChar() throws IOException {
 530         if (DEBUG_BUFFER) {
 531             System.out.print("(scanChar: ");
 532             print();
 533             System.out.println();
 534         }
 535 
 536         // load more characters, if needed
 537         if (fCurrentEntity.position == fCurrentEntity.count) {
 538             invokeListeners(0);
 539             load(0, true);
 540         }
 541 
 542         // scan character
 543         int c = fCurrentEntity.ch[fCurrentEntity.position++];
 544         if (c == '\n' ||
 545                 (c == '\r' && isExternal)) {
 546             fCurrentEntity.lineNumber++;
 547             fCurrentEntity.columnNumber = 1;
 548             if (fCurrentEntity.position == fCurrentEntity.count) {
 549                 invokeListeners(1);
 550                 fCurrentEntity.ch[0] = (char)c;
 551                 load(1, false);
 552             }
 553             if (c == '\r' && isExternal) {
 554                 if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') {
 555                     fCurrentEntity.position--;
 556                 }
 557                 c = '\n';
 558             }
 559         }
 560 
 561         // return character that was scanned
 562         if (DEBUG_BUFFER) {
 563             System.out.print(")scanChar: ");
 564             print();
 565             System.out.println(" -> '"+(char)c+"'");
 566         }
 567         fCurrentEntity.columnNumber++;
 568         return c;
 569 
 570     } // scanChar():int
 571 


 576      * <strong>Note:</strong> The NMTOKEN characters are consumed.
 577      * <p>
 578      * <strong>Note:</strong> The string returned must be a symbol. The
 579      * SymbolTable can be used for this purpose.
 580      *
 581      * @throws IOException  Thrown if i/o error occurs.
 582      * @throws EOFException Thrown on end of file.
 583      *
 584      * @see com.sun.org.apache.xerces.internal.util.SymbolTable
 585      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
 586      */
 587     public String scanNmtoken() throws IOException {
 588         if (DEBUG_BUFFER) {
 589             System.out.print("(scanNmtoken: ");
 590             print();
 591             System.out.println();
 592         }
 593 
 594         // load more characters, if needed
 595         if (fCurrentEntity.position == fCurrentEntity.count) {
 596             invokeListeners(0);
 597             load(0, true);
 598         }
 599 
 600         // scan nmtoken
 601         int offset = fCurrentEntity.position;
 602         boolean vc = false;
 603         char c;
 604         while (true){
 605             //while (XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) {
 606             c = fCurrentEntity.ch[fCurrentEntity.position];
 607             if(c < 127){
 608                 vc = VALID_NAMES[c];
 609             }else{
 610                 vc = XMLChar.isName(c);
 611             }
 612             if(!vc)break;
 613 
 614             if (++fCurrentEntity.position == fCurrentEntity.count) {
 615                 int length = fCurrentEntity.position - offset;
 616                 invokeListeners(length);
 617                 if (length == fCurrentEntity.fBufferSize) {
 618                     // bad luck we have to resize our buffer
 619                     char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
 620                     System.arraycopy(fCurrentEntity.ch, offset,
 621                             tmp, 0, length);
 622                     fCurrentEntity.ch = tmp;
 623                     fCurrentEntity.fBufferSize *= 2;
 624                 } else {
 625                     System.arraycopy(fCurrentEntity.ch, offset,
 626                             fCurrentEntity.ch, 0, length);
 627                 }
 628                 offset = 0;
 629                 if (load(length, false)) {
 630                     break;
 631                 }
 632             }
 633         }
 634         int length = fCurrentEntity.position - offset;
 635         fCurrentEntity.columnNumber += length;
 636 
 637         // return nmtoken
 638         String symbol = null;
 639         if (length > 0) {
 640             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
 641         }
 642         if (DEBUG_BUFFER) {
 643             System.out.print(")scanNmtoken: ");
 644             print();
 645             System.out.println(" -> "+String.valueOf(symbol));
 646         }
 647         return symbol;
 648 
 649     } // scanNmtoken():String


 656      * <p>
 657      * <strong>Note:</strong> The string returned must be a symbol. The
 658      * SymbolTable can be used for this purpose.
 659      *
 660      * @throws IOException  Thrown if i/o error occurs.
 661      * @throws EOFException Thrown on end of file.
 662      *
 663      * @see com.sun.org.apache.xerces.internal.util.SymbolTable
 664      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
 665      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart
 666      */
 667     public String scanName() throws IOException {
 668         if (DEBUG_BUFFER) {
 669             System.out.print("(scanName: ");
 670             print();
 671             System.out.println();
 672         }
 673 
 674         // load more characters, if needed
 675         if (fCurrentEntity.position == fCurrentEntity.count) {
 676             invokeListeners(0);
 677             load(0, true);
 678         }
 679 
 680         // scan name
 681         int offset = fCurrentEntity.position;
 682         if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
 683             if (++fCurrentEntity.position == fCurrentEntity.count) {
 684                 invokeListeners(1);
 685                 fCurrentEntity.ch[0] = fCurrentEntity.ch[offset];
 686                 offset = 0;
 687                 if (load(1, false)) {
 688                     fCurrentEntity.columnNumber++;
 689                     String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
 690 
 691                     if (DEBUG_BUFFER) {
 692                         System.out.print(")scanName: ");
 693                         print();
 694                         System.out.println(" -> "+String.valueOf(symbol));
 695                     }
 696                     return symbol;
 697                 }
 698             }
 699             boolean vc =false;
 700             while (true ){
 701                 //XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) ;
 702                 char c = fCurrentEntity.ch[fCurrentEntity.position];
 703                 if(c < 127){
 704                     vc = VALID_NAMES[c];
 705                 }else{
 706                     vc = XMLChar.isName(c);
 707                 }
 708                 if(!vc)break;
 709                 if (++fCurrentEntity.position == fCurrentEntity.count) {
 710                     int length = fCurrentEntity.position - offset;
 711                     invokeListeners(length);
 712                     if (length == fCurrentEntity.fBufferSize) {
 713                         // bad luck we have to resize our buffer
 714                         char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
 715                         System.arraycopy(fCurrentEntity.ch, offset,
 716                                 tmp, 0, length);
 717                         fCurrentEntity.ch = tmp;
 718                         fCurrentEntity.fBufferSize *= 2;
 719                     } else {
 720                         System.arraycopy(fCurrentEntity.ch, offset,
 721                                 fCurrentEntity.ch, 0, length);
 722                     }
 723                     offset = 0;
 724                     if (load(length, false)) {
 725                         break;
 726                     }
 727                 }
 728             }
 729         }
 730         int length = fCurrentEntity.position - offset;
 731         fCurrentEntity.columnNumber += length;
 732 
 733         // return name
 734         String symbol;
 735         if (length > 0) {
 736             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
 737         } else
 738             symbol = null;
 739         if (DEBUG_BUFFER) {
 740             System.out.print(")scanName: ");
 741             print();
 742             System.out.println(" -> "+String.valueOf(symbol));
 743         }
 744         return symbol;


 759      *
 760      * @return Returns true if a qualified name appeared immediately on
 761      *         the input and was scanned, false otherwise.
 762      *
 763      * @throws IOException  Thrown if i/o error occurs.
 764      * @throws EOFException Thrown on end of file.
 765      *
 766      * @see com.sun.org.apache.xerces.internal.util.SymbolTable
 767      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
 768      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart
 769      */
 770     public boolean scanQName(QName qname) throws IOException {
 771         if (DEBUG_BUFFER) {
 772             System.out.print("(scanQName, "+qname+": ");
 773             print();
 774             System.out.println();
 775         }
 776 
 777         // load more characters, if needed
 778         if (fCurrentEntity.position == fCurrentEntity.count) {
 779             invokeListeners(0);
 780             load(0, true);
 781         }
 782 
 783         // scan qualified name
 784         int offset = fCurrentEntity.position;
 785 
 786         //making a check if if the specified character is a valid name start character
 787         //as defined by production [5] in the XML 1.0 specification.
 788         // Name ::= (Letter | '_' | ':') (NameChar)*
 789 
 790         if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
 791             if (++fCurrentEntity.position == fCurrentEntity.count) {
 792                 invokeListeners(1);
 793                 fCurrentEntity.ch[0] = fCurrentEntity.ch[offset];
 794                 offset = 0;
 795 
 796                 if (load(1, false)) {
 797                     fCurrentEntity.columnNumber++;
 798                     //adding into symbol table.
 799                     //XXX We are trying to add single character in SymbolTable??????
 800                     String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
 801                     qname.setValues(null, name, name, null);
 802                     if (DEBUG_BUFFER) {
 803                         System.out.print(")scanQName, "+qname+": ");
 804                         print();
 805                         System.out.println(" -> true");
 806                     }
 807                     return true;
 808                 }
 809             }
 810             int index = -1;
 811             boolean vc = false;
 812             while ( true){
 813 
 814                 //XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) ;
 815                 char c = fCurrentEntity.ch[fCurrentEntity.position];
 816                 if(c < 127){


 826                     index = fCurrentEntity.position;
 827                 }
 828                 if (++fCurrentEntity.position == fCurrentEntity.count) {
 829                     int length = fCurrentEntity.position - offset;
 830                     invokeListeners(length);
 831                     if (length == fCurrentEntity.fBufferSize) {
 832                         // bad luck we have to resize our buffer
 833                         char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
 834                         System.arraycopy(fCurrentEntity.ch, offset,
 835                                 tmp, 0, length);
 836                         fCurrentEntity.ch = tmp;
 837                         fCurrentEntity.fBufferSize *= 2;
 838                     } else {
 839                         System.arraycopy(fCurrentEntity.ch, offset,
 840                                 fCurrentEntity.ch, 0, length);
 841                     }
 842                     if (index != -1) {
 843                         index = index - offset;
 844                     }
 845                     offset = 0;
 846                     if (load(length, false)) {
 847                         break;
 848                     }
 849                 }
 850             }
 851             int length = fCurrentEntity.position - offset;
 852             fCurrentEntity.columnNumber += length;
 853             if (length > 0) {
 854                 String prefix = null;
 855                 String localpart = null;
 856                 String rawname = fSymbolTable.addSymbol(fCurrentEntity.ch,
 857                         offset, length);
 858 
 859                 if (index != -1) {
 860                     int prefixLength = index - offset;
 861                     prefix = fSymbolTable.addSymbol(fCurrentEntity.ch,
 862                             offset, prefixLength);
 863                     int len = length - prefixLength - 1;
 864                     localpart = fSymbolTable.addSymbol(fCurrentEntity.ch,
 865                             index + 1, len);
 866 


 901      * <p>
 902      *
 903      * @param content The content structure to fill.
 904      *
 905      * @return Returns the next character on the input, if known. This
 906      *         value may be -1 but this does <em>note</em> designate
 907      *         end of file.
 908      *
 909      * @throws IOException  Thrown if i/o error occurs.
 910      * @throws EOFException Thrown on end of file.
 911      */
 912     public int scanContent(XMLString content) throws IOException {
 913         if (DEBUG_BUFFER) {
 914             System.out.print("(scanContent: ");
 915             print();
 916             System.out.println();
 917         }
 918 
 919         // load more characters, if needed
 920         if (fCurrentEntity.position == fCurrentEntity.count) {
 921             invokeListeners(0);
 922             load(0, true);
 923         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
 924             invokeListeners(0);
 925             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
 926             load(1, false);
 927             fCurrentEntity.position = 0;
 928         }
 929 
 930         // normalize newlines
 931         int offset = fCurrentEntity.position;
 932         int c = fCurrentEntity.ch[offset];
 933         int newlines = 0;
 934         if (c == '\n' || (c == '\r' && isExternal)) {
 935             if (DEBUG_BUFFER) {
 936                 System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
 937                 print();
 938                 System.out.println();
 939             }
 940             do {
 941                 c = fCurrentEntity.ch[fCurrentEntity.position++];
 942                 if (c == '\r' && isExternal) {
 943                     newlines++;
 944                     fCurrentEntity.lineNumber++;
 945                     fCurrentEntity.columnNumber = 1;
 946                     if (fCurrentEntity.position == fCurrentEntity.count) {
 947                         offset = 0;
 948                         invokeListeners(newlines);
 949                         fCurrentEntity.position = newlines;
 950                         if (load(newlines, false)) {
 951                             break;
 952                         }
 953                     }
 954                     if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
 955                         fCurrentEntity.position++;
 956                         offset++;
 957                     }
 958                     /*** NEWLINE NORMALIZATION ***/
 959                     else {
 960                         newlines++;
 961                     }
 962                 } else if (c == '\n') {
 963                     newlines++;
 964                     fCurrentEntity.lineNumber++;
 965                     fCurrentEntity.columnNumber = 1;
 966                     if (fCurrentEntity.position == fCurrentEntity.count) {
 967                         offset = 0;
 968                         invokeListeners(newlines);
 969                         fCurrentEntity.position = newlines;
 970                         if (load(newlines, false)) {
 971                             break;
 972                         }
 973                     }
 974                 } else {
 975                     fCurrentEntity.position--;
 976                     break;
 977                 }
 978             } while (fCurrentEntity.position < fCurrentEntity.count - 1);
 979             for (int i = offset; i < fCurrentEntity.position; i++) {
 980                 fCurrentEntity.ch[i] = '\n';
 981             }
 982             int length = fCurrentEntity.position - offset;
 983             if (fCurrentEntity.position == fCurrentEntity.count - 1) {
 984                 //CHANGED: dont replace the value.. append to the buffer. This gives control to the callee
 985                 //on buffering the data..
 986                 content.setValues(fCurrentEntity.ch, offset, length);
 987                 //content.append(fCurrentEntity.ch, offset, length);
 988                 if (DEBUG_BUFFER) {
 989                     System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
 990                     print();


1053      * @param quote   The quote character that signifies the end of the
1054      *                attribute value data.
1055      * @param content The content structure to fill.
1056      *
1057      * @return Returns the next character on the input, if known. This
1058      *         value may be -1 but this does <em>note</em> designate
1059      *         end of file.
1060      *
1061      * @throws IOException  Thrown if i/o error occurs.
1062      * @throws EOFException Thrown on end of file.
1063      */
1064     public int scanLiteral(int quote, XMLString content)
1065     throws IOException {
1066         if (DEBUG_BUFFER) {
1067             System.out.print("(scanLiteral, '"+(char)quote+"': ");
1068             print();
1069             System.out.println();
1070         }
1071         // load more characters, if needed
1072         if (fCurrentEntity.position == fCurrentEntity.count) {
1073             invokeListeners(0);
1074             load(0, true);
1075         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1076             invokeListeners(0);
1077             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
1078 
1079             load(1, false);
1080             fCurrentEntity.position = 0;
1081         }
1082 
1083         // normalize newlines
1084         int offset = fCurrentEntity.position;
1085         int c = fCurrentEntity.ch[offset];
1086         int newlines = 0;
1087         if(whiteSpaceInfoNeeded)
1088             whiteSpaceLen=0;
1089         if (c == '\n' || (c == '\r' && isExternal)) {
1090             if (DEBUG_BUFFER) {
1091                 System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
1092                 print();
1093                 System.out.println();
1094             }
1095             do {
1096                 c = fCurrentEntity.ch[fCurrentEntity.position++];
1097                 if (c == '\r' && isExternal) {
1098                     newlines++;
1099                     fCurrentEntity.lineNumber++;
1100                     fCurrentEntity.columnNumber = 1;
1101                     if (fCurrentEntity.position == fCurrentEntity.count) {
1102                         invokeListeners(newlines);
1103                         offset = 0;
1104                         fCurrentEntity.position = newlines;
1105                         if (load(newlines, false)) {
1106                             break;
1107                         }
1108                     }
1109                     if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
1110                         fCurrentEntity.position++;
1111                         offset++;
1112                     }
1113                     /*** NEWLINE NORMALIZATION ***/
1114                     else {
1115                         newlines++;
1116                     }
1117                     /***/
1118                 } else if (c == '\n') {
1119                     newlines++;
1120                     fCurrentEntity.lineNumber++;
1121                     fCurrentEntity.columnNumber = 1;
1122                     if (fCurrentEntity.position == fCurrentEntity.count) {
1123                         offset = 0;
1124                         invokeListeners(newlines);
1125                         fCurrentEntity.position = newlines;
1126                         if (load(newlines, false)) {
1127                             break;
1128                         }
1129                     }
1130                     /*** NEWLINE NORMALIZATION ***
1131                      * if (fCurrentEntity.ch[fCurrentEntity.position] == '\r'
1132                      * && external) {
1133                      * fCurrentEntity.position++;
1134                      * offset++;
1135                      * }
1136                      * /***/
1137                 } else {
1138                     fCurrentEntity.position--;
1139                     break;
1140                 }
1141             } while (fCurrentEntity.position < fCurrentEntity.count - 1);
1142             int i=0;
1143             for ( i = offset; i < fCurrentEntity.position; i++) {
1144                 fCurrentEntity.ch[i] = '\n';
1145                 storeWhiteSpace(i);
1146             }


1157             }
1158             if (DEBUG_BUFFER) {
1159                 System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
1160                 print();
1161                 System.out.println();
1162             }
1163         }
1164 
1165         // scan literal value
1166         for (; fCurrentEntity.position<fCurrentEntity.count; fCurrentEntity.position++) {
1167             c = fCurrentEntity.ch[fCurrentEntity.position];
1168             if ((c == quote &&
1169                     (!fCurrentEntity.literal || isExternal)) ||
1170                     c == '%' || !XMLChar.isContent(c)) {
1171                 break;
1172             }
1173             if (whiteSpaceInfoNeeded && c == '\t') {
1174                 storeWhiteSpace(fCurrentEntity.position);
1175             }
1176         }
1177 
1178         int length = fCurrentEntity.position - offset;
1179         fCurrentEntity.columnNumber += length - newlines;
1180         content.setValues(fCurrentEntity.ch, offset, length);
1181 
1182         // return next character
1183         if (fCurrentEntity.position != fCurrentEntity.count) {
1184             c = fCurrentEntity.ch[fCurrentEntity.position];
1185             // NOTE: We don't want to accidentally signal the
1186             //       end of the literal if we're expanding an
1187             //       entity appearing in the literal. -Ac
1188             if (c == quote && fCurrentEntity.literal) {
1189                 c = -1;
1190             }
1191         } else {
1192             c = -1;
1193         }
1194         if (DEBUG_BUFFER) {
1195             System.out.print(")scanLiteral, '"+(char)quote+"': ");
1196             print();
1197             System.out.println(" -> '"+(char)c+"'");


1241      *
1242      * @throws IOException  Thrown if i/o error occurs.
1243      * @throws EOFException Thrown on end of file.
1244      */
1245     public boolean scanData(String delimiter, XMLStringBuffer buffer)
1246     throws IOException {
1247 
1248         boolean done = false;
1249         int delimLen = delimiter.length();
1250         char charAt0 = delimiter.charAt(0);
1251         do {
1252             if (DEBUG_BUFFER) {
1253                 System.out.print("(scanData: ");
1254                 print();
1255                 System.out.println();
1256             }
1257 
1258             // load more characters, if needed
1259 
1260             if (fCurrentEntity.position == fCurrentEntity.count) {
1261                 load(0, true);
1262             }
1263 
1264             boolean bNextEntity = false;
1265 
1266             while ((fCurrentEntity.position > fCurrentEntity.count - delimLen)
1267                 && (!bNextEntity))
1268             {
1269               System.arraycopy(fCurrentEntity.ch,
1270                                fCurrentEntity.position,
1271                                fCurrentEntity.ch,
1272                                0,
1273                                fCurrentEntity.count - fCurrentEntity.position);
1274 
1275               bNextEntity = load(fCurrentEntity.count - fCurrentEntity.position, false);
1276               fCurrentEntity.position = 0;
1277               fCurrentEntity.startPosition = 0;
1278             }
1279 
1280             if (fCurrentEntity.position > fCurrentEntity.count - delimLen) {
1281                 // something must be wrong with the input:  e.g., file ends in an unterminated comment
1282                 int length = fCurrentEntity.count - fCurrentEntity.position;
1283                 buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length);
1284                 fCurrentEntity.columnNumber += fCurrentEntity.count;
1285                 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
1286                 fCurrentEntity.position = fCurrentEntity.count;
1287                 fCurrentEntity.startPosition = fCurrentEntity.count;
1288                 load(0, true);
1289                 return false;
1290             }
1291 
1292             // normalize newlines
1293             int offset = fCurrentEntity.position;
1294             int c = fCurrentEntity.ch[offset];
1295             int newlines = 0;
1296             if (c == '\n' || (c == '\r' && isExternal)) {
1297                 if (DEBUG_BUFFER) {
1298                     System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
1299                     print();
1300                     System.out.println();
1301                 }
1302                 do {
1303                     c = fCurrentEntity.ch[fCurrentEntity.position++];
1304                     if (c == '\r' && isExternal) {
1305                         newlines++;
1306                         fCurrentEntity.lineNumber++;
1307                         fCurrentEntity.columnNumber = 1;
1308                         if (fCurrentEntity.position == fCurrentEntity.count) {
1309                             offset = 0;
1310                             invokeListeners(newlines);
1311                             fCurrentEntity.position = newlines;
1312                             if (load(newlines, false)) {
1313                                 break;
1314                             }
1315                         }
1316                         if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
1317                             fCurrentEntity.position++;
1318                             offset++;
1319                         }
1320                         /*** NEWLINE NORMALIZATION ***/
1321                         else {
1322                             newlines++;
1323                         }
1324                     } else if (c == '\n') {
1325                         newlines++;
1326                         fCurrentEntity.lineNumber++;
1327                         fCurrentEntity.columnNumber = 1;
1328                         if (fCurrentEntity.position == fCurrentEntity.count) {
1329                             offset = 0;
1330                             invokeListeners(newlines);
1331                             fCurrentEntity.position = newlines;
1332                             fCurrentEntity.count = newlines;
1333                             if (load(newlines, false)) {
1334                                 break;
1335                             }
1336                         }
1337                     } else {
1338                         fCurrentEntity.position--;
1339                         break;
1340                     }
1341                 } while (fCurrentEntity.position < fCurrentEntity.count - 1);
1342                 for (int i = offset; i < fCurrentEntity.position; i++) {
1343                     fCurrentEntity.ch[i] = '\n';
1344                 }
1345                 int length = fCurrentEntity.position - offset;
1346                 if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1347                     buffer.append(fCurrentEntity.ch, offset, length);
1348                     if (DEBUG_BUFFER) {
1349                         System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
1350                         print();
1351                         System.out.println();
1352                     }
1353                     return true;


1414      * <p>
1415      * <strong>Note:</strong> The character is consumed only if it matches
1416      * the specified character.
1417      *
1418      * @param c The character to skip.
1419      *
1420      * @return Returns true if the character was skipped.
1421      *
1422      * @throws IOException  Thrown if i/o error occurs.
1423      * @throws EOFException Thrown on end of file.
1424      */
1425     public boolean skipChar(int c) throws IOException {
1426         if (DEBUG_BUFFER) {
1427             System.out.print("(skipChar, '"+(char)c+"': ");
1428             print();
1429             System.out.println();
1430         }
1431 
1432         // load more characters, if needed
1433         if (fCurrentEntity.position == fCurrentEntity.count) {
1434             invokeListeners(0);
1435             load(0, true);
1436         }
1437 
1438         // skip character
1439         int cc = fCurrentEntity.ch[fCurrentEntity.position];
1440         if (cc == c) {
1441             fCurrentEntity.position++;
1442             if (c == '\n') {
1443                 fCurrentEntity.lineNumber++;
1444                 fCurrentEntity.columnNumber = 1;
1445             } else {
1446                 fCurrentEntity.columnNumber++;
1447             }
1448             if (DEBUG_BUFFER) {
1449                 System.out.print(")skipChar, '"+(char)c+"': ");
1450                 print();
1451                 System.out.println(" -> true");
1452             }
1453             return true;
1454         } else if (c == '\n' && cc == '\r' && isExternal) {
1455             // handle newlines
1456             if (fCurrentEntity.position == fCurrentEntity.count) {
1457                 invokeListeners(1);
1458                 fCurrentEntity.ch[0] = (char)cc;
1459                 load(1, false);
1460             }
1461             fCurrentEntity.position++;
1462             if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
1463                 fCurrentEntity.position++;
1464             }
1465             fCurrentEntity.lineNumber++;
1466             fCurrentEntity.columnNumber = 1;
1467             if (DEBUG_BUFFER) {
1468                 System.out.print(")skipChar, '"+(char)c+"': ");
1469                 print();
1470                 System.out.println(" -> true");
1471             }
1472             return true;
1473         }
1474 
1475         // character was not skipped
1476         if (DEBUG_BUFFER) {
1477             System.out.print(")skipChar, '"+(char)c+"': ");
1478             print();
1479             System.out.println(" -> false");


1490      * <p>
1491      * <strong>Note:</strong> The characters are consumed only if they are
1492      * space characters.
1493      *
1494      * @return Returns true if at least one space character was skipped.
1495      *
1496      * @throws IOException  Thrown if i/o error occurs.
1497      * @throws EOFException Thrown on end of file.
1498      *
1499      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace
1500      */
1501     public boolean skipSpaces() throws IOException {
1502         if (DEBUG_BUFFER) {
1503             System.out.print("(skipSpaces: ");
1504             print();
1505             System.out.println();
1506         }
1507         //boolean entityChanged = false;
1508         // load more characters, if needed
1509         if (fCurrentEntity.position == fCurrentEntity.count) {
1510             invokeListeners(0);
1511             load(0, true);
1512         }
1513 
1514         //we are doing this check only in skipSpace() because it is called by
1515         //fMiscDispatcher and we want the parser to exit gracefully when document
1516         //is well-formed.
1517         //it is possible that end of document is reached and
1518         //fCurrentEntity becomes null
1519         //nothing was read so entity changed  'false' should be returned.
1520         if(fCurrentEntity == null){
1521             return false ;
1522         }
1523 
1524         // skip spaces
1525         int c = fCurrentEntity.ch[fCurrentEntity.position];
1526         if (XMLChar.isSpace(c)) {
1527             do {
1528                 boolean entityChanged = false;
1529                 // handle newlines
1530                 if (c == '\n' || (isExternal && c == '\r')) {
1531                     fCurrentEntity.lineNumber++;
1532                     fCurrentEntity.columnNumber = 1;
1533                     if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1534                         invokeListeners(0);
1535                         fCurrentEntity.ch[0] = (char)c;
1536                         entityChanged = load(1, true);
1537                         if (!entityChanged){
1538                             // the load change the position to be 1,
1539                             // need to restore it when entity not changed
1540                             fCurrentEntity.position = 0;
1541                         }else if(fCurrentEntity == null){
1542                             return true ;
1543                         }
1544                     }
1545                     if (c == '\r' && isExternal) {
1546                         // REVISIT: Does this need to be updated to fix the
1547                         //          #x0D ^#x0A newline normalization problem? -Ac
1548                         if (fCurrentEntity.ch[++fCurrentEntity.position] != '\n') {
1549                             fCurrentEntity.position--;
1550                         }
1551                     }
1552                 } else {
1553                     fCurrentEntity.columnNumber++;
1554                 }
1555                 // load more characters, if needed
1556                 if (!entityChanged){
1557                     fCurrentEntity.position++;
1558                 }
1559 
1560                 if (fCurrentEntity.position == fCurrentEntity.count) {
1561                     invokeListeners(0);
1562                     load(0, true);
1563 
1564                     //we are doing this check only in skipSpace() because it is called by
1565                     //fMiscDispatcher and we want the parser to exit gracefully when document
1566                     //is well-formed.
1567 
1568                     //it is possible that end of document is reached and
1569                     //fCurrentEntity becomes null
1570                     //nothing was read so entity changed  'false' should be returned.
1571                     if(fCurrentEntity == null){
1572                         return true ;
1573                     }
1574 
1575                 }
1576             } while (XMLChar.isSpace(c = fCurrentEntity.ch[fCurrentEntity.position]));
1577             if (DEBUG_BUFFER) {
1578                 System.out.print(")skipSpaces: ");
1579                 print();
1580                 System.out.println(" -> true");
1581             }
1582             return true;


1618             return true;
1619         }
1620         if(DEBUG_SKIP_STRING){
1621             System.out.println("fCurrentEntity.count = " + fCurrentEntity.count);
1622             System.out.println("fCurrentEntity.position = " + fCurrentEntity.position);
1623             System.out.println("length = " + length);
1624         }
1625         boolean entityChanged = false;
1626         //load more characters -- this function shouldn't change the entity
1627         while((fCurrentEntity.count - fCurrentEntity.position) < length){
1628             if( (fCurrentEntity.ch.length - fCurrentEntity.position) < length){
1629                 invokeListeners(0);
1630                 System.arraycopy(fCurrentEntity.ch, fCurrentEntity.position, fCurrentEntity.ch,0,fCurrentEntity.count - fCurrentEntity.position);
1631                 fCurrentEntity.count = fCurrentEntity.count - fCurrentEntity.position;
1632                 fCurrentEntity.position = 0;
1633             }
1634 
1635             if((fCurrentEntity.count - fCurrentEntity.position) < length){
1636                 int pos = fCurrentEntity.position;
1637                 invokeListeners(pos);
1638                 entityChanged = load(fCurrentEntity.count, changeEntity);
1639                 fCurrentEntity.position = pos;
1640                 if(entityChanged)break;
1641             }
1642             if(DEBUG_SKIP_STRING){
1643                 System.out.println("fCurrentEntity.count = " + fCurrentEntity.count);
1644                 System.out.println("fCurrentEntity.position = " + fCurrentEntity.position);
1645                 System.out.println("length = " + length);
1646             }
1647         }
1648         //load changes the position.. set it back to the point where we started.
1649 
1650         //after loading check again.
1651         if((fCurrentEntity.count - fCurrentEntity.position) >= length) {
1652             return true;
1653         } else {
1654             return false;
1655         }
1656     }
1657 
1658     /**


1723         return false;
1724     }
1725 
1726     //
1727     // Locator methods
1728     //
1729     //
1730     // Private methods
1731     //
1732 
1733     /**
1734      * Loads a chunk of text.
1735      *
1736      * @param offset       The offset into the character buffer to
1737      *                     read the next batch of characters.
1738      * @param changeEntity True if the load should change entities
1739      *                     at the end of the entity, otherwise leave
1740      *                     the current entity in place and the entity
1741      *                     boundary will be signaled by the return
1742      *                     value.


1743      *
1744      * @returns Returns true if the entity changed as a result of this
1745      *          load operation.
1746      */
1747     final boolean load(int offset, boolean changeEntity)
1748     throws IOException {
1749         if (DEBUG_BUFFER) {
1750             System.out.print("(load, "+offset+": ");
1751             print();
1752             System.out.println();
1753         }



1754         //maintaing the count till last load
1755         fCurrentEntity.fTotalCountTillLastLoad = fCurrentEntity.fTotalCountTillLastLoad + fCurrentEntity.fLastCount ;
1756         // read characters
1757         int length = fCurrentEntity.ch.length - offset;
1758         if (!fCurrentEntity.mayReadChunks && length > XMLEntityManager.DEFAULT_XMLDECL_BUFFER_SIZE) {
1759             length = XMLEntityManager.DEFAULT_XMLDECL_BUFFER_SIZE;
1760         }
1761         if (DEBUG_BUFFER) System.out.println("  length to try to read: "+length);
1762         int count = fCurrentEntity.reader.read(fCurrentEntity.ch, offset, length);
1763         if (DEBUG_BUFFER) System.out.println("  length actually read:  "+count);
1764 
1765         // reset count and position
1766         boolean entityChanged = false;
1767         if (count != -1) {
1768             if (count != 0) {
1769                 // record the last count
1770                 fCurrentEntity.fLastCount = count;
1771                 fCurrentEntity.count = count + offset;
1772                 fCurrentEntity.position = offset;
1773             }
1774         }
1775         // end of this entity
1776         else {
1777             fCurrentEntity.count = offset;
1778             fCurrentEntity.position = offset;
1779             entityChanged = true;
1780 
1781             if (changeEntity) {
1782                 //notify the entity manager about the end of entity
1783                 fEntityManager.endEntity();
1784                 //return if the current entity becomes null
1785                 if(fCurrentEntity == null){
1786                     throw END_OF_DOCUMENT_ENTITY;
1787                 }
1788                 // handle the trailing edges
1789                 if (fCurrentEntity.position == fCurrentEntity.count) {
1790                     load(0, true);
1791                 }
1792             }
1793 
1794         }
1795         if (DEBUG_BUFFER) {
1796             System.out.print(")load, "+offset+": ");
1797             print();
1798             System.out.println();
1799         }
1800 
1801         return entityChanged;
1802 
1803     } // load(int, boolean):boolean
1804 
1805     /**
1806      * Creates a reader capable of reading the given input stream in
1807      * the specified encoding.
1808      *
1809      * @param inputStream  The input stream.
1810      * @param encoding     The encoding name that the input stream is


2067             } else {
2068                 System.out.print("*NO CURRENT ENTITY*");
2069             }
2070         }
2071     }
2072 
2073     /**
2074      * Registers the listener object and provides callback.
2075      * @param listener listener to which call back should be provided when scanner buffer
2076      * is being changed.
2077      */
2078     public void registerListener(XMLBufferListener listener) {
2079         if(!listeners.contains(listener))
2080             listeners.add(listener);
2081     }
2082 
2083     /**
2084      *
2085      * @param loadPos Starting position from which new data is being loaded into scanner buffer.
2086      */
2087     private void invokeListeners(int loadPos){
2088         for(int i=0;i<listeners.size();i++){
2089             XMLBufferListener listener =(XMLBufferListener) listeners.get(i);
2090             listener.refresh(loadPos);
2091         }
2092     }
2093 
2094     /**
2095      * Skips space characters appearing immediately on the input that would
2096      * match non-terminal S (0x09, 0x0A, 0x0D, 0x20) before end of line
2097      * normalization is performed. This is useful when scanning structures
2098      * such as the XMLDecl and TextDecl that can only contain US-ASCII
2099      * characters.
2100      * <p>
2101      * <strong>Note:</strong> The characters are consumed only if they would
2102      * match non-terminal S before end of line normalization is performed.
2103      *
2104      * @return Returns true if at least one space character was skipped.
2105      *
2106      * @throws IOException  Thrown if i/o error occurs.
2107      * @throws EOFException Thrown on end of file.
2108      *
2109      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace
2110      */
2111     public final boolean skipDeclSpaces() throws IOException {
2112         if (DEBUG_BUFFER) {
2113             System.out.print("(skipDeclSpaces: ");
2114             //XMLEntityManager.print(fCurrentEntity);
2115             System.out.println();
2116         }
2117 
2118         // load more characters, if needed
2119         if (fCurrentEntity.position == fCurrentEntity.count) {
2120             load(0, true);
2121         }
2122 
2123         // skip spaces
2124         int c = fCurrentEntity.ch[fCurrentEntity.position];
2125         if (XMLChar.isSpace(c)) {
2126             boolean external = fCurrentEntity.isExternal();
2127             do {
2128                 boolean entityChanged = false;
2129                 // handle newlines
2130                 if (c == '\n' || (external && c == '\r')) {
2131                     fCurrentEntity.lineNumber++;
2132                     fCurrentEntity.columnNumber = 1;
2133                     if (fCurrentEntity.position == fCurrentEntity.count - 1) {
2134                         fCurrentEntity.ch[0] = (char)c;
2135                         entityChanged = load(1, true);
2136                         if (!entityChanged)
2137                             // the load change the position to be 1,
2138                             // need to restore it when entity not changed
2139                             fCurrentEntity.position = 0;
2140                     }
2141                     if (c == '\r' && external) {
2142                         // REVISIT: Does this need to be updated to fix the
2143                         //          #x0D ^#x0A newline normalization problem? -Ac
2144                         if (fCurrentEntity.ch[++fCurrentEntity.position] != '\n') {
2145                             fCurrentEntity.position--;
2146                         }
2147                     }
2148                     /*** NEWLINE NORMALIZATION ***
2149                      * else {
2150                      * if (fCurrentEntity.ch[fCurrentEntity.position + 1] == '\r'
2151                      * && external) {
2152                      * fCurrentEntity.position++;
2153                      * }
2154                      * }
2155                      * /***/
2156                 } else {
2157                     fCurrentEntity.columnNumber++;
2158                 }
2159                 // load more characters, if needed
2160                 if (!entityChanged)
2161                     fCurrentEntity.position++;
2162                 if (fCurrentEntity.position == fCurrentEntity.count) {
2163                     load(0, true);
2164                 }
2165             } while (XMLChar.isSpace(c = fCurrentEntity.ch[fCurrentEntity.position]));
2166             if (DEBUG_BUFFER) {
2167                 System.out.print(")skipDeclSpaces: ");
2168                 //  XMLEntityManager.print(fCurrentEntity);
2169                 System.out.println(" -> true");
2170             }
2171             return true;
2172         }
2173 
2174         // no spaces were found
2175         if (DEBUG_BUFFER) {
2176             System.out.print(")skipDeclSpaces: ");
2177             //XMLEntityManager.print(fCurrentEntity);
2178             System.out.println(" -> false");
2179         }
2180         return false;
2181 
2182     } // skipDeclSpaces():boolean
2183 


   3  */
   4 
   5 /*
   6  * Copyright 2005 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xerces.internal.impl;
  22 




  23 





  24 

  25 import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
  26 import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
  27 import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;


  28 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
  29 import com.sun.org.apache.xerces.internal.util.EncodingMap;

  30 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  31 import com.sun.org.apache.xerces.internal.util.XMLChar;
  32 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
  33 import com.sun.org.apache.xerces.internal.xni.*;

  34 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  35 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  36 import com.sun.xml.internal.stream.Entity;
  37 import com.sun.xml.internal.stream.XMLBufferListener;
  38 import java.io.EOFException;
  39 import java.io.IOException;
  40 import java.io.InputStream;
  41 import java.io.InputStreamReader;
  42 import java.io.Reader;
  43 import java.util.Locale;
  44 import java.util.Vector;
  45 
  46 /**
  47  * Implements the entity scanner methods.
  48  *
  49  * @author Neeraj Bajaj, Sun Microsystems
  50  * @author Andy Clark, IBM
  51  * @author Arnaud  Le Hors, IBM
  52  * @author K.Venugopal Sun Microsystems
  53  *
  54  */
  55 public class XMLEntityScanner implements XMLLocator  {
  56 
  57 
  58     protected Entity.ScannedEntity fCurrentEntity = null ;
  59     protected int fBufferSize = XMLEntityManager.DEFAULT_BUFFER_SIZE;
  60 
  61     protected XMLEntityManager fEntityManager ;
  62 
  63     /** Debug switching readers for encodings. */
  64     private static final boolean DEBUG_ENCODINGS = false;


 470         }
 471     }//getChar()
 472 
 473     /**
 474      * Returns the next character on the input.
 475      * <p>
 476      * <strong>Note:</strong> The character is <em>not</em> consumed.
 477      *
 478      * @throws IOException  Thrown if i/o error occurs.
 479      * @throws EOFException Thrown on end of file.
 480      */
 481     public int peekChar() throws IOException {
 482         if (DEBUG_BUFFER) {
 483             System.out.print("(peekChar: ");
 484             print();
 485             System.out.println();
 486         }
 487 
 488         // load more characters, if needed
 489         if (fCurrentEntity.position == fCurrentEntity.count) {
 490             load(0, true, true);

 491         }
 492 
 493         // peek at character
 494         int c = fCurrentEntity.ch[fCurrentEntity.position];
 495 
 496         // return peeked character
 497         if (DEBUG_BUFFER) {
 498             System.out.print(")peekChar: ");
 499             print();
 500             if (isExternal) {
 501                 System.out.println(" -> '"+(c!='\r'?(char)c:'\n')+"'");
 502             } else {
 503                 System.out.println(" -> '"+(char)c+"'");
 504             }
 505         }
 506         if (isExternal) {
 507             return c != '\r' ? c : '\n';
 508         } else {
 509             return c;
 510         }
 511 
 512     } // peekChar():int
 513 
 514     /**
 515      * Returns the next character on the input.
 516      * <p>
 517      * <strong>Note:</strong> The character is consumed.
 518      *
 519      * @throws IOException  Thrown if i/o error occurs.
 520      * @throws EOFException Thrown on end of file.
 521      */
 522     public int scanChar() throws IOException {
 523         if (DEBUG_BUFFER) {
 524             System.out.print("(scanChar: ");
 525             print();
 526             System.out.println();
 527         }
 528 
 529         // load more characters, if needed
 530         if (fCurrentEntity.position == fCurrentEntity.count) {
 531             load(0, true, true);

 532         }
 533 
 534         // scan character
 535         int c = fCurrentEntity.ch[fCurrentEntity.position++];
 536         if (c == '\n' ||
 537                 (c == '\r' && isExternal)) {
 538             fCurrentEntity.lineNumber++;
 539             fCurrentEntity.columnNumber = 1;
 540             if (fCurrentEntity.position == fCurrentEntity.count) {

 541                 fCurrentEntity.ch[0] = (char)c;
 542                 load(1, false, true);
 543             }
 544             if (c == '\r' && isExternal) {
 545                 if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') {
 546                     fCurrentEntity.position--;
 547                 }
 548                 c = '\n';
 549             }
 550         }
 551 
 552         // return character that was scanned
 553         if (DEBUG_BUFFER) {
 554             System.out.print(")scanChar: ");
 555             print();
 556             System.out.println(" -> '"+(char)c+"'");
 557         }
 558         fCurrentEntity.columnNumber++;
 559         return c;
 560 
 561     } // scanChar():int
 562 


 567      * <strong>Note:</strong> The NMTOKEN characters are consumed.
 568      * <p>
 569      * <strong>Note:</strong> The string returned must be a symbol. The
 570      * SymbolTable can be used for this purpose.
 571      *
 572      * @throws IOException  Thrown if i/o error occurs.
 573      * @throws EOFException Thrown on end of file.
 574      *
 575      * @see com.sun.org.apache.xerces.internal.util.SymbolTable
 576      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
 577      */
 578     public String scanNmtoken() throws IOException {
 579         if (DEBUG_BUFFER) {
 580             System.out.print("(scanNmtoken: ");
 581             print();
 582             System.out.println();
 583         }
 584 
 585         // load more characters, if needed
 586         if (fCurrentEntity.position == fCurrentEntity.count) {
 587             load(0, true, true);

 588         }
 589 
 590         // scan nmtoken
 591         int offset = fCurrentEntity.position;
 592         boolean vc = false;
 593         char c;
 594         while (true){
 595             //while (XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) {
 596             c = fCurrentEntity.ch[fCurrentEntity.position];
 597             if(c < 127){
 598                 vc = VALID_NAMES[c];
 599             }else{
 600                 vc = XMLChar.isName(c);
 601             }
 602             if(!vc)break;
 603 
 604             if (++fCurrentEntity.position == fCurrentEntity.count) {
 605                 int length = fCurrentEntity.position - offset;
 606                 invokeListeners(length);
 607                 if (length == fCurrentEntity.fBufferSize) {
 608                     // bad luck we have to resize our buffer
 609                     char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
 610                     System.arraycopy(fCurrentEntity.ch, offset,
 611                             tmp, 0, length);
 612                     fCurrentEntity.ch = tmp;
 613                     fCurrentEntity.fBufferSize *= 2;
 614                 } else {
 615                     System.arraycopy(fCurrentEntity.ch, offset,
 616                             fCurrentEntity.ch, 0, length);
 617                 }
 618                 offset = 0;
 619                 if (load(length, false, false)) {
 620                     break;
 621                 }
 622             }
 623         }
 624         int length = fCurrentEntity.position - offset;
 625         fCurrentEntity.columnNumber += length;
 626 
 627         // return nmtoken
 628         String symbol = null;
 629         if (length > 0) {
 630             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
 631         }
 632         if (DEBUG_BUFFER) {
 633             System.out.print(")scanNmtoken: ");
 634             print();
 635             System.out.println(" -> "+String.valueOf(symbol));
 636         }
 637         return symbol;
 638 
 639     } // scanNmtoken():String


 646      * <p>
 647      * <strong>Note:</strong> The string returned must be a symbol. The
 648      * SymbolTable can be used for this purpose.
 649      *
 650      * @throws IOException  Thrown if i/o error occurs.
 651      * @throws EOFException Thrown on end of file.
 652      *
 653      * @see com.sun.org.apache.xerces.internal.util.SymbolTable
 654      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
 655      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart
 656      */
 657     public String scanName() throws IOException {
 658         if (DEBUG_BUFFER) {
 659             System.out.print("(scanName: ");
 660             print();
 661             System.out.println();
 662         }
 663 
 664         // load more characters, if needed
 665         if (fCurrentEntity.position == fCurrentEntity.count) {
 666             load(0, true, true);

 667         }
 668 
 669         // scan name
 670         int offset = fCurrentEntity.position;
 671         if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
 672             if (++fCurrentEntity.position == fCurrentEntity.count) {

 673                 fCurrentEntity.ch[0] = fCurrentEntity.ch[offset];
 674                 offset = 0;
 675                 if (load(1, false, true)) {
 676                     fCurrentEntity.columnNumber++;
 677                     String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
 678 
 679                     if (DEBUG_BUFFER) {
 680                         System.out.print(")scanName: ");
 681                         print();
 682                         System.out.println(" -> "+String.valueOf(symbol));
 683                     }
 684                     return symbol;
 685                 }
 686             }
 687             boolean vc =false;
 688             while (true ){
 689                 //XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) ;
 690                 char c = fCurrentEntity.ch[fCurrentEntity.position];
 691                 if(c < 127){
 692                     vc = VALID_NAMES[c];
 693                 }else{
 694                     vc = XMLChar.isName(c);
 695                 }
 696                 if(!vc)break;
 697                 if (++fCurrentEntity.position == fCurrentEntity.count) {
 698                     int length = fCurrentEntity.position - offset;
 699                     invokeListeners(length);
 700                     if (length == fCurrentEntity.fBufferSize) {
 701                         // bad luck we have to resize our buffer
 702                         char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
 703                         System.arraycopy(fCurrentEntity.ch, offset,
 704                                 tmp, 0, length);
 705                         fCurrentEntity.ch = tmp;
 706                         fCurrentEntity.fBufferSize *= 2;
 707                     } else {
 708                         System.arraycopy(fCurrentEntity.ch, offset,
 709                                 fCurrentEntity.ch, 0, length);
 710                     }
 711                     offset = 0;
 712                     if (load(length, false, false)) {
 713                         break;
 714                     }
 715                 }
 716             }
 717         }
 718         int length = fCurrentEntity.position - offset;
 719         fCurrentEntity.columnNumber += length;
 720 
 721         // return name
 722         String symbol;
 723         if (length > 0) {
 724             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
 725         } else
 726             symbol = null;
 727         if (DEBUG_BUFFER) {
 728             System.out.print(")scanName: ");
 729             print();
 730             System.out.println(" -> "+String.valueOf(symbol));
 731         }
 732         return symbol;


 747      *
 748      * @return Returns true if a qualified name appeared immediately on
 749      *         the input and was scanned, false otherwise.
 750      *
 751      * @throws IOException  Thrown if i/o error occurs.
 752      * @throws EOFException Thrown on end of file.
 753      *
 754      * @see com.sun.org.apache.xerces.internal.util.SymbolTable
 755      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
 756      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart
 757      */
 758     public boolean scanQName(QName qname) throws IOException {
 759         if (DEBUG_BUFFER) {
 760             System.out.print("(scanQName, "+qname+": ");
 761             print();
 762             System.out.println();
 763         }
 764 
 765         // load more characters, if needed
 766         if (fCurrentEntity.position == fCurrentEntity.count) {
 767             load(0, true, true);

 768         }
 769 
 770         // scan qualified name
 771         int offset = fCurrentEntity.position;
 772 
 773         //making a check if if the specified character is a valid name start character
 774         //as defined by production [5] in the XML 1.0 specification.
 775         // Name ::= (Letter | '_' | ':') (NameChar)*
 776 
 777         if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
 778             if (++fCurrentEntity.position == fCurrentEntity.count) {

 779                 fCurrentEntity.ch[0] = fCurrentEntity.ch[offset];
 780                 offset = 0;
 781 
 782                 if (load(1, false, true)) {
 783                     fCurrentEntity.columnNumber++;
 784                     //adding into symbol table.
 785                     //XXX We are trying to add single character in SymbolTable??????
 786                     String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
 787                     qname.setValues(null, name, name, null);
 788                     if (DEBUG_BUFFER) {
 789                         System.out.print(")scanQName, "+qname+": ");
 790                         print();
 791                         System.out.println(" -> true");
 792                     }
 793                     return true;
 794                 }
 795             }
 796             int index = -1;
 797             boolean vc = false;
 798             while ( true){
 799 
 800                 //XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) ;
 801                 char c = fCurrentEntity.ch[fCurrentEntity.position];
 802                 if(c < 127){


 812                     index = fCurrentEntity.position;
 813                 }
 814                 if (++fCurrentEntity.position == fCurrentEntity.count) {
 815                     int length = fCurrentEntity.position - offset;
 816                     invokeListeners(length);
 817                     if (length == fCurrentEntity.fBufferSize) {
 818                         // bad luck we have to resize our buffer
 819                         char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
 820                         System.arraycopy(fCurrentEntity.ch, offset,
 821                                 tmp, 0, length);
 822                         fCurrentEntity.ch = tmp;
 823                         fCurrentEntity.fBufferSize *= 2;
 824                     } else {
 825                         System.arraycopy(fCurrentEntity.ch, offset,
 826                                 fCurrentEntity.ch, 0, length);
 827                     }
 828                     if (index != -1) {
 829                         index = index - offset;
 830                     }
 831                     offset = 0;
 832                     if (load(length, false, false)) {
 833                         break;
 834                     }
 835                 }
 836             }
 837             int length = fCurrentEntity.position - offset;
 838             fCurrentEntity.columnNumber += length;
 839             if (length > 0) {
 840                 String prefix = null;
 841                 String localpart = null;
 842                 String rawname = fSymbolTable.addSymbol(fCurrentEntity.ch,
 843                         offset, length);
 844 
 845                 if (index != -1) {
 846                     int prefixLength = index - offset;
 847                     prefix = fSymbolTable.addSymbol(fCurrentEntity.ch,
 848                             offset, prefixLength);
 849                     int len = length - prefixLength - 1;
 850                     localpart = fSymbolTable.addSymbol(fCurrentEntity.ch,
 851                             index + 1, len);
 852 


 887      * <p>
 888      *
 889      * @param content The content structure to fill.
 890      *
 891      * @return Returns the next character on the input, if known. This
 892      *         value may be -1 but this does <em>note</em> designate
 893      *         end of file.
 894      *
 895      * @throws IOException  Thrown if i/o error occurs.
 896      * @throws EOFException Thrown on end of file.
 897      */
 898     public int scanContent(XMLString content) throws IOException {
 899         if (DEBUG_BUFFER) {
 900             System.out.print("(scanContent: ");
 901             print();
 902             System.out.println();
 903         }
 904 
 905         // load more characters, if needed
 906         if (fCurrentEntity.position == fCurrentEntity.count) {
 907             load(0, true, true);

 908         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {

 909             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
 910             load(1, false, true);
 911             fCurrentEntity.position = 0;
 912         }
 913 
 914         // normalize newlines
 915         int offset = fCurrentEntity.position;
 916         int c = fCurrentEntity.ch[offset];
 917         int newlines = 0;
 918         if (c == '\n' || (c == '\r' && isExternal)) {
 919             if (DEBUG_BUFFER) {
 920                 System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
 921                 print();
 922                 System.out.println();
 923             }
 924             do {
 925                 c = fCurrentEntity.ch[fCurrentEntity.position++];
 926                 if (c == '\r' && isExternal) {
 927                     newlines++;
 928                     fCurrentEntity.lineNumber++;
 929                     fCurrentEntity.columnNumber = 1;
 930                     if (fCurrentEntity.position == fCurrentEntity.count) {
 931                         offset = 0;

 932                         fCurrentEntity.position = newlines;
 933                         if (load(newlines, false, true)) {
 934                             break;
 935                         }
 936                     }
 937                     if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
 938                         fCurrentEntity.position++;
 939                         offset++;
 940                     }
 941                     /*** NEWLINE NORMALIZATION ***/
 942                     else {
 943                         newlines++;
 944                     }
 945                 } else if (c == '\n') {
 946                     newlines++;
 947                     fCurrentEntity.lineNumber++;
 948                     fCurrentEntity.columnNumber = 1;
 949                     if (fCurrentEntity.position == fCurrentEntity.count) {
 950                         offset = 0;

 951                         fCurrentEntity.position = newlines;
 952                         if (load(newlines, false, true)) {
 953                             break;
 954                         }
 955                     }
 956                 } else {
 957                     fCurrentEntity.position--;
 958                     break;
 959                 }
 960             } while (fCurrentEntity.position < fCurrentEntity.count - 1);
 961             for (int i = offset; i < fCurrentEntity.position; i++) {
 962                 fCurrentEntity.ch[i] = '\n';
 963             }
 964             int length = fCurrentEntity.position - offset;
 965             if (fCurrentEntity.position == fCurrentEntity.count - 1) {
 966                 //CHANGED: dont replace the value.. append to the buffer. This gives control to the callee
 967                 //on buffering the data..
 968                 content.setValues(fCurrentEntity.ch, offset, length);
 969                 //content.append(fCurrentEntity.ch, offset, length);
 970                 if (DEBUG_BUFFER) {
 971                     System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
 972                     print();


1035      * @param quote   The quote character that signifies the end of the
1036      *                attribute value data.
1037      * @param content The content structure to fill.
1038      *
1039      * @return Returns the next character on the input, if known. This
1040      *         value may be -1 but this does <em>note</em> designate
1041      *         end of file.
1042      *
1043      * @throws IOException  Thrown if i/o error occurs.
1044      * @throws EOFException Thrown on end of file.
1045      */
1046     public int scanLiteral(int quote, XMLString content)
1047     throws IOException {
1048         if (DEBUG_BUFFER) {
1049             System.out.print("(scanLiteral, '"+(char)quote+"': ");
1050             print();
1051             System.out.println();
1052         }
1053         // load more characters, if needed
1054         if (fCurrentEntity.position == fCurrentEntity.count) {
1055             load(0, true, true);

1056         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {

1057             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
1058             load(1, false, true);

1059             fCurrentEntity.position = 0;
1060         }
1061 
1062         // normalize newlines
1063         int offset = fCurrentEntity.position;
1064         int c = fCurrentEntity.ch[offset];
1065         int newlines = 0;
1066         if(whiteSpaceInfoNeeded)
1067             whiteSpaceLen=0;
1068         if (c == '\n' || (c == '\r' && isExternal)) {
1069             if (DEBUG_BUFFER) {
1070                 System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
1071                 print();
1072                 System.out.println();
1073             }
1074             do {
1075                 c = fCurrentEntity.ch[fCurrentEntity.position++];
1076                 if (c == '\r' && isExternal) {
1077                     newlines++;
1078                     fCurrentEntity.lineNumber++;
1079                     fCurrentEntity.columnNumber = 1;
1080                     if (fCurrentEntity.position == fCurrentEntity.count) {

1081                         offset = 0;
1082                         fCurrentEntity.position = newlines;
1083                         if (load(newlines, false, true)) {
1084                             break;
1085                         }
1086                     }
1087                     if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
1088                         fCurrentEntity.position++;
1089                         offset++;
1090                     }
1091                     /*** NEWLINE NORMALIZATION ***/
1092                     else {
1093                         newlines++;
1094                     }
1095                     /***/
1096                 } else if (c == '\n') {
1097                     newlines++;
1098                     fCurrentEntity.lineNumber++;
1099                     fCurrentEntity.columnNumber = 1;
1100                     if (fCurrentEntity.position == fCurrentEntity.count) {
1101                         offset = 0;

1102                         fCurrentEntity.position = newlines;
1103                         if (load(newlines, false, true)) {
1104                             break;
1105                         }
1106                     }
1107                     /*** NEWLINE NORMALIZATION ***
1108                      * if (fCurrentEntity.ch[fCurrentEntity.position] == '\r'
1109                      * && external) {
1110                      * fCurrentEntity.position++;
1111                      * offset++;
1112                      * }
1113                      * /***/
1114                 } else {
1115                     fCurrentEntity.position--;
1116                     break;
1117                 }
1118             } while (fCurrentEntity.position < fCurrentEntity.count - 1);
1119             int i=0;
1120             for ( i = offset; i < fCurrentEntity.position; i++) {
1121                 fCurrentEntity.ch[i] = '\n';
1122                 storeWhiteSpace(i);
1123             }


1134             }
1135             if (DEBUG_BUFFER) {
1136                 System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
1137                 print();
1138                 System.out.println();
1139             }
1140         }
1141 
1142         // scan literal value
1143         for (; fCurrentEntity.position<fCurrentEntity.count; fCurrentEntity.position++) {
1144             c = fCurrentEntity.ch[fCurrentEntity.position];
1145             if ((c == quote &&
1146                     (!fCurrentEntity.literal || isExternal)) ||
1147                     c == '%' || !XMLChar.isContent(c)) {
1148                 break;
1149             }
1150             if (whiteSpaceInfoNeeded && c == '\t') {
1151                 storeWhiteSpace(fCurrentEntity.position);
1152             }
1153         } 

1154         int length = fCurrentEntity.position - offset;
1155         fCurrentEntity.columnNumber += length - newlines;
1156         content.setValues(fCurrentEntity.ch, offset, length);
1157 
1158         // return next character
1159         if (fCurrentEntity.position != fCurrentEntity.count) {
1160             c = fCurrentEntity.ch[fCurrentEntity.position];
1161             // NOTE: We don't want to accidentally signal the
1162             //       end of the literal if we're expanding an
1163             //       entity appearing in the literal. -Ac
1164             if (c == quote && fCurrentEntity.literal) {
1165                 c = -1;
1166             }
1167         } else {
1168             c = -1;
1169         }
1170         if (DEBUG_BUFFER) {
1171             System.out.print(")scanLiteral, '"+(char)quote+"': ");
1172             print();
1173             System.out.println(" -> '"+(char)c+"'");


1217      *
1218      * @throws IOException  Thrown if i/o error occurs.
1219      * @throws EOFException Thrown on end of file.
1220      */
1221     public boolean scanData(String delimiter, XMLStringBuffer buffer)
1222     throws IOException {
1223 
1224         boolean done = false;
1225         int delimLen = delimiter.length();
1226         char charAt0 = delimiter.charAt(0);
1227         do {
1228             if (DEBUG_BUFFER) {
1229                 System.out.print("(scanData: ");
1230                 print();
1231                 System.out.println();
1232             }
1233 
1234             // load more characters, if needed
1235 
1236             if (fCurrentEntity.position == fCurrentEntity.count) {
1237                 load(0, true, false);
1238             }
1239 
1240             boolean bNextEntity = false;
1241 
1242             while ((fCurrentEntity.position > fCurrentEntity.count - delimLen)
1243                 && (!bNextEntity))
1244             {
1245               System.arraycopy(fCurrentEntity.ch,
1246                                fCurrentEntity.position,
1247                                fCurrentEntity.ch,
1248                                0,
1249                                fCurrentEntity.count - fCurrentEntity.position);
1250 
1251               bNextEntity = load(fCurrentEntity.count - fCurrentEntity.position, false, false);
1252               fCurrentEntity.position = 0;
1253               fCurrentEntity.startPosition = 0;
1254             }
1255 
1256             if (fCurrentEntity.position > fCurrentEntity.count - delimLen) {
1257                 // something must be wrong with the input:  e.g., file ends in an unterminated comment
1258                 int length = fCurrentEntity.count - fCurrentEntity.position;
1259                 buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length);
1260                 fCurrentEntity.columnNumber += fCurrentEntity.count;
1261                 fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
1262                 fCurrentEntity.position = fCurrentEntity.count;
1263                 fCurrentEntity.startPosition = fCurrentEntity.count;
1264                 load(0, true, false);
1265                 return false;
1266             }
1267 
1268             // normalize newlines
1269             int offset = fCurrentEntity.position;
1270             int c = fCurrentEntity.ch[offset];
1271             int newlines = 0;
1272             if (c == '\n' || (c == '\r' && isExternal)) {
1273                 if (DEBUG_BUFFER) {
1274                     System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
1275                     print();
1276                     System.out.println();
1277                 }
1278                 do {
1279                     c = fCurrentEntity.ch[fCurrentEntity.position++];
1280                     if (c == '\r' && isExternal) {
1281                         newlines++;
1282                         fCurrentEntity.lineNumber++;
1283                         fCurrentEntity.columnNumber = 1;
1284                         if (fCurrentEntity.position == fCurrentEntity.count) {
1285                             offset = 0;

1286                             fCurrentEntity.position = newlines;
1287                             if (load(newlines, false, true)) {
1288                                 break;
1289                             }
1290                         }
1291                         if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
1292                             fCurrentEntity.position++;
1293                             offset++;
1294                         }
1295                         /*** NEWLINE NORMALIZATION ***/
1296                         else {
1297                             newlines++;
1298                         }
1299                     } else if (c == '\n') {
1300                         newlines++;
1301                         fCurrentEntity.lineNumber++;
1302                         fCurrentEntity.columnNumber = 1;
1303                         if (fCurrentEntity.position == fCurrentEntity.count) {
1304                             offset = 0;

1305                             fCurrentEntity.position = newlines;
1306                             fCurrentEntity.count = newlines;
1307                             if (load(newlines, false, true)) {
1308                                 break;
1309                             }
1310                         }
1311                     } else {
1312                         fCurrentEntity.position--;
1313                         break;
1314                     }
1315                 } while (fCurrentEntity.position < fCurrentEntity.count - 1);
1316                 for (int i = offset; i < fCurrentEntity.position; i++) {
1317                     fCurrentEntity.ch[i] = '\n';
1318                 }
1319                 int length = fCurrentEntity.position - offset;
1320                 if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1321                     buffer.append(fCurrentEntity.ch, offset, length);
1322                     if (DEBUG_BUFFER) {
1323                         System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
1324                         print();
1325                         System.out.println();
1326                     }
1327                     return true;


1388      * <p>
1389      * <strong>Note:</strong> The character is consumed only if it matches
1390      * the specified character.
1391      *
1392      * @param c The character to skip.
1393      *
1394      * @return Returns true if the character was skipped.
1395      *
1396      * @throws IOException  Thrown if i/o error occurs.
1397      * @throws EOFException Thrown on end of file.
1398      */
1399     public boolean skipChar(int c) throws IOException {
1400         if (DEBUG_BUFFER) {
1401             System.out.print("(skipChar, '"+(char)c+"': ");
1402             print();
1403             System.out.println();
1404         }
1405 
1406         // load more characters, if needed
1407         if (fCurrentEntity.position == fCurrentEntity.count) {
1408             load(0, true, true);

1409         }
1410 
1411         // skip character
1412         int cc = fCurrentEntity.ch[fCurrentEntity.position];
1413         if (cc == c) {
1414             fCurrentEntity.position++;
1415             if (c == '\n') {
1416                 fCurrentEntity.lineNumber++;
1417                 fCurrentEntity.columnNumber = 1;
1418             } else {
1419                 fCurrentEntity.columnNumber++;
1420             }
1421             if (DEBUG_BUFFER) {
1422                 System.out.print(")skipChar, '"+(char)c+"': ");
1423                 print();
1424                 System.out.println(" -> true");
1425             }
1426             return true;
1427         } else if (c == '\n' && cc == '\r' && isExternal) {
1428             // handle newlines
1429             if (fCurrentEntity.position == fCurrentEntity.count) {

1430                 fCurrentEntity.ch[0] = (char)cc;
1431                 load(1, false, true);
1432             }
1433             fCurrentEntity.position++;
1434             if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
1435                 fCurrentEntity.position++;
1436             }
1437             fCurrentEntity.lineNumber++;
1438             fCurrentEntity.columnNumber = 1;
1439             if (DEBUG_BUFFER) {
1440                 System.out.print(")skipChar, '"+(char)c+"': ");
1441                 print();
1442                 System.out.println(" -> true");
1443             }
1444             return true;
1445         }
1446 
1447         // character was not skipped
1448         if (DEBUG_BUFFER) {
1449             System.out.print(")skipChar, '"+(char)c+"': ");
1450             print();
1451             System.out.println(" -> false");


1462      * <p>
1463      * <strong>Note:</strong> The characters are consumed only if they are
1464      * space characters.
1465      *
1466      * @return Returns true if at least one space character was skipped.
1467      *
1468      * @throws IOException  Thrown if i/o error occurs.
1469      * @throws EOFException Thrown on end of file.
1470      *
1471      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace
1472      */
1473     public boolean skipSpaces() throws IOException {
1474         if (DEBUG_BUFFER) {
1475             System.out.print("(skipSpaces: ");
1476             print();
1477             System.out.println();
1478         }
1479         //boolean entityChanged = false;
1480         // load more characters, if needed
1481         if (fCurrentEntity.position == fCurrentEntity.count) {
1482             load(0, true, true);

1483         }
1484 
1485         //we are doing this check only in skipSpace() because it is called by
1486         //fMiscDispatcher and we want the parser to exit gracefully when document
1487         //is well-formed.
1488         //it is possible that end of document is reached and
1489         //fCurrentEntity becomes null
1490         //nothing was read so entity changed  'false' should be returned.
1491         if(fCurrentEntity == null){
1492             return false ;
1493         }
1494 
1495         // skip spaces
1496         int c = fCurrentEntity.ch[fCurrentEntity.position];
1497         if (XMLChar.isSpace(c)) {
1498             do {
1499                 boolean entityChanged = false;
1500                 // handle newlines
1501                 if (c == '\n' || (isExternal && c == '\r')) {
1502                     fCurrentEntity.lineNumber++;
1503                     fCurrentEntity.columnNumber = 1;
1504                     if (fCurrentEntity.position == fCurrentEntity.count - 1) {

1505                         fCurrentEntity.ch[0] = (char)c;
1506                         entityChanged = load(1, true, true);
1507                         if (!entityChanged){
1508                             // the load change the position to be 1,
1509                             // need to restore it when entity not changed
1510                             fCurrentEntity.position = 0;
1511                         }else if(fCurrentEntity == null){
1512                             return true ;
1513                         }
1514                     }
1515                     if (c == '\r' && isExternal) {
1516                         // REVISIT: Does this need to be updated to fix the
1517                         //          #x0D ^#x0A newline normalization problem? -Ac
1518                         if (fCurrentEntity.ch[++fCurrentEntity.position] != '\n') {
1519                             fCurrentEntity.position--;
1520                         }
1521                     }
1522                 } else {
1523                     fCurrentEntity.columnNumber++;
1524                 }
1525                 // load more characters, if needed
1526                 if (!entityChanged){
1527                     fCurrentEntity.position++;
1528                 }
1529 
1530                 if (fCurrentEntity.position == fCurrentEntity.count) {
1531                     load(0, true, true);

1532 
1533                     //we are doing this check only in skipSpace() because it is called by
1534                     //fMiscDispatcher and we want the parser to exit gracefully when document
1535                     //is well-formed.
1536 
1537                     //it is possible that end of document is reached and
1538                     //fCurrentEntity becomes null
1539                     //nothing was read so entity changed  'false' should be returned.
1540                     if(fCurrentEntity == null){
1541                         return true ;
1542                     }
1543 
1544                 }
1545             } while (XMLChar.isSpace(c = fCurrentEntity.ch[fCurrentEntity.position]));
1546             if (DEBUG_BUFFER) {
1547                 System.out.print(")skipSpaces: ");
1548                 print();
1549                 System.out.println(" -> true");
1550             }
1551             return true;


1587             return true;
1588         }
1589         if(DEBUG_SKIP_STRING){
1590             System.out.println("fCurrentEntity.count = " + fCurrentEntity.count);
1591             System.out.println("fCurrentEntity.position = " + fCurrentEntity.position);
1592             System.out.println("length = " + length);
1593         }
1594         boolean entityChanged = false;
1595         //load more characters -- this function shouldn't change the entity
1596         while((fCurrentEntity.count - fCurrentEntity.position) < length){
1597             if( (fCurrentEntity.ch.length - fCurrentEntity.position) < length){
1598                 invokeListeners(0);
1599                 System.arraycopy(fCurrentEntity.ch, fCurrentEntity.position, fCurrentEntity.ch,0,fCurrentEntity.count - fCurrentEntity.position);
1600                 fCurrentEntity.count = fCurrentEntity.count - fCurrentEntity.position;
1601                 fCurrentEntity.position = 0;
1602             }
1603 
1604             if((fCurrentEntity.count - fCurrentEntity.position) < length){
1605                 int pos = fCurrentEntity.position;
1606                 invokeListeners(pos);
1607                 entityChanged = load(fCurrentEntity.count, changeEntity, false);
1608                 fCurrentEntity.position = pos;
1609                 if(entityChanged)break;
1610             }
1611             if(DEBUG_SKIP_STRING){
1612                 System.out.println("fCurrentEntity.count = " + fCurrentEntity.count);
1613                 System.out.println("fCurrentEntity.position = " + fCurrentEntity.position);
1614                 System.out.println("length = " + length);
1615             }
1616         }
1617         //load changes the position.. set it back to the point where we started.
1618 
1619         //after loading check again.
1620         if((fCurrentEntity.count - fCurrentEntity.position) >= length) {
1621             return true;
1622         } else {
1623             return false;
1624         }
1625     }
1626 
1627     /**


1692         return false;
1693     }
1694 
1695     //
1696     // Locator methods
1697     //
1698     //
1699     // Private methods
1700     //
1701 
1702     /**
1703      * Loads a chunk of text.
1704      *
1705      * @param offset       The offset into the character buffer to
1706      *                     read the next batch of characters.
1707      * @param changeEntity True if the load should change entities
1708      *                     at the end of the entity, otherwise leave
1709      *                     the current entity in place and the entity
1710      *                     boundary will be signaled by the return
1711      *                     value.
1712      * @param notify       Determine whether to notify listeners of
1713      *                     the event
1714      *
1715      * @returns Returns true if the entity changed as a result of this
1716      *          load operation.
1717      */
1718     final boolean load(int offset, boolean changeEntity, boolean notify)
1719     throws IOException {
1720         if (DEBUG_BUFFER) {
1721             System.out.print("(load, "+offset+": ");
1722             print();
1723             System.out.println();
1724         }
1725         if (notify) {
1726             invokeListeners(offset);
1727         }
1728         //maintaing the count till last load
1729         fCurrentEntity.fTotalCountTillLastLoad = fCurrentEntity.fTotalCountTillLastLoad + fCurrentEntity.fLastCount ;
1730         // read characters
1731         int length = fCurrentEntity.ch.length - offset;
1732         if (!fCurrentEntity.mayReadChunks && length > XMLEntityManager.DEFAULT_XMLDECL_BUFFER_SIZE) {
1733             length = XMLEntityManager.DEFAULT_XMLDECL_BUFFER_SIZE;
1734         }
1735         if (DEBUG_BUFFER) System.out.println("  length to try to read: "+length);
1736         int count = fCurrentEntity.reader.read(fCurrentEntity.ch, offset, length);
1737         if (DEBUG_BUFFER) System.out.println("  length actually read:  "+count);
1738 
1739         // reset count and position
1740         boolean entityChanged = false;
1741         if (count != -1) {
1742             if (count != 0) {
1743                 // record the last count
1744                 fCurrentEntity.fLastCount = count;
1745                 fCurrentEntity.count = count + offset;
1746                 fCurrentEntity.position = offset;
1747             }
1748         }
1749         // end of this entity
1750         else {
1751             fCurrentEntity.count = offset;
1752             fCurrentEntity.position = offset;
1753             entityChanged = true;
1754 
1755             if (changeEntity) {
1756                 //notify the entity manager about the end of entity
1757                 fEntityManager.endEntity();
1758                 //return if the current entity becomes null
1759                 if(fCurrentEntity == null){
1760                     throw END_OF_DOCUMENT_ENTITY;
1761                 }
1762                 // handle the trailing edges
1763                 if (fCurrentEntity.position == fCurrentEntity.count) {
1764                     load(0, true, false);
1765                 }
1766             }
1767 
1768         }
1769         if (DEBUG_BUFFER) {
1770             System.out.print(")load, "+offset+": ");
1771             print();
1772             System.out.println();
1773         }
1774 
1775         return entityChanged;
1776 
1777     } // load(int, boolean):boolean
1778 
1779     /**
1780      * Creates a reader capable of reading the given input stream in
1781      * the specified encoding.
1782      *
1783      * @param inputStream  The input stream.
1784      * @param encoding     The encoding name that the input stream is


2041             } else {
2042                 System.out.print("*NO CURRENT ENTITY*");
2043             }
2044         }
2045     }
2046 
2047     /**
2048      * Registers the listener object and provides callback.
2049      * @param listener listener to which call back should be provided when scanner buffer
2050      * is being changed.
2051      */
2052     public void registerListener(XMLBufferListener listener) {
2053         if(!listeners.contains(listener))
2054             listeners.add(listener);
2055     }
2056 
2057     /**
2058      *
2059      * @param loadPos Starting position from which new data is being loaded into scanner buffer.
2060      */
2061     public void invokeListeners(int loadPos){
2062         for(int i=0;i<listeners.size();i++){
2063             XMLBufferListener listener =(XMLBufferListener) listeners.get(i);
2064             listener.refresh(loadPos);
2065         }
2066     }
2067 
2068     /**
2069      * Skips space characters appearing immediately on the input that would
2070      * match non-terminal S (0x09, 0x0A, 0x0D, 0x20) before end of line
2071      * normalization is performed. This is useful when scanning structures
2072      * such as the XMLDecl and TextDecl that can only contain US-ASCII
2073      * characters.
2074      * <p>
2075      * <strong>Note:</strong> The characters are consumed only if they would
2076      * match non-terminal S before end of line normalization is performed.
2077      *
2078      * @return Returns true if at least one space character was skipped.
2079      *
2080      * @throws IOException  Thrown if i/o error occurs.
2081      * @throws EOFException Thrown on end of file.
2082      *
2083      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace
2084      */
2085     public final boolean skipDeclSpaces() throws IOException {
2086         if (DEBUG_BUFFER) {
2087             System.out.print("(skipDeclSpaces: ");
2088             //XMLEntityManager.print(fCurrentEntity);
2089             System.out.println();
2090         }
2091 
2092         // load more characters, if needed
2093         if (fCurrentEntity.position == fCurrentEntity.count) {
2094             load(0, true, false);
2095         }
2096 
2097         // skip spaces
2098         int c = fCurrentEntity.ch[fCurrentEntity.position];
2099         if (XMLChar.isSpace(c)) {
2100             boolean external = fCurrentEntity.isExternal();
2101             do {
2102                 boolean entityChanged = false;
2103                 // handle newlines
2104                 if (c == '\n' || (external && c == '\r')) {
2105                     fCurrentEntity.lineNumber++;
2106                     fCurrentEntity.columnNumber = 1;
2107                     if (fCurrentEntity.position == fCurrentEntity.count - 1) {
2108                         fCurrentEntity.ch[0] = (char)c;
2109                         entityChanged = load(1, true, false);
2110                         if (!entityChanged)
2111                             // the load change the position to be 1,
2112                             // need to restore it when entity not changed
2113                             fCurrentEntity.position = 0;
2114                     }
2115                     if (c == '\r' && external) {
2116                         // REVISIT: Does this need to be updated to fix the
2117                         //          #x0D ^#x0A newline normalization problem? -Ac
2118                         if (fCurrentEntity.ch[++fCurrentEntity.position] != '\n') {
2119                             fCurrentEntity.position--;
2120                         }
2121                     }
2122                     /*** NEWLINE NORMALIZATION ***
2123                      * else {
2124                      * if (fCurrentEntity.ch[fCurrentEntity.position + 1] == '\r'
2125                      * && external) {
2126                      * fCurrentEntity.position++;
2127                      * }
2128                      * }
2129                      * /***/
2130                 } else {
2131                     fCurrentEntity.columnNumber++;
2132                 }
2133                 // load more characters, if needed
2134                 if (!entityChanged)
2135                     fCurrentEntity.position++;
2136                 if (fCurrentEntity.position == fCurrentEntity.count) {
2137                     load(0, true, false);
2138                 }
2139             } while (XMLChar.isSpace(c = fCurrentEntity.ch[fCurrentEntity.position]));
2140             if (DEBUG_BUFFER) {
2141                 System.out.print(")skipDeclSpaces: ");
2142                 //  XMLEntityManager.print(fCurrentEntity);
2143                 System.out.println(" -> true");
2144             }
2145             return true;
2146         }
2147 
2148         // no spaces were found
2149         if (DEBUG_BUFFER) {
2150             System.out.print(")skipDeclSpaces: ");
2151             //XMLEntityManager.print(fCurrentEntity);
2152             System.out.println(" -> false");
2153         }
2154         return false;
2155 
2156     } // skipDeclSpaces():boolean
2157