< prev index next >

src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java

Print this page
rev 903 : 8153781: Issue in XMLScanner: EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET
   1 /*
   2  * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
   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.utils.XMLLimitAnalyzer;
  34 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
  35 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit;
  36 import com.sun.org.apache.xerces.internal.xni.*;
  37 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  38 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  39 import com.sun.xml.internal.stream.Entity;
  40 import com.sun.xml.internal.stream.Entity.ScannedEntity;
  41 import com.sun.xml.internal.stream.XMLBufferListener;
  42 import java.io.EOFException;
  43 import java.io.IOException;
  44 import java.io.InputStream;
  45 import java.io.InputStreamReader;
  46 import java.io.Reader;

  47 import java.util.Locale;
  48 import java.util.Vector;
  49 
  50 /**
  51  * Implements the entity scanner methods.
  52  *
  53  * @author Neeraj Bajaj, Sun Microsystems
  54  * @author Andy Clark, IBM
  55  * @author Arnaud  Le Hors, IBM
  56  * @author K.Venugopal Sun Microsystems
  57  *
  58  */
  59 public class XMLEntityScanner implements XMLLocator  {
  60 
  61 
  62     protected Entity.ScannedEntity fCurrentEntity = null ;
  63     protected int fBufferSize = XMLEntityManager.DEFAULT_BUFFER_SIZE;
  64 
  65     protected XMLEntityManager fEntityManager ;
  66 
  67     /** Security manager. */
  68     protected XMLSecurityManager fSecurityManager = null;
  69 
  70     /** Limit analyzer. */
  71     protected XMLLimitAnalyzer fLimitAnalyzer = null;
  72 
  73     /** Debug switching readers for encodings. */
  74     private static final boolean DEBUG_ENCODINGS = false;

  75     /** Listeners which should know when load is being called */
  76     private Vector listeners = new Vector();
  77 
  78     private static final boolean [] VALID_NAMES = new boolean[127];
  79 
  80     /**
  81      * Debug printing of buffer. This debugging flag works best when you
  82      * resize the DEFAULT_BUFFER_SIZE down to something reasonable like
  83      * 64 characters.
  84      */
  85     private static final boolean DEBUG_BUFFER = false;
  86     private static final boolean DEBUG_SKIP_STRING = false;
  87     /**
  88      * To signal the end of the document entity, this exception will be thrown.
  89      */
  90     private static final EOFException END_OF_DOCUMENT_ENTITY = new EOFException() {
  91         private static final long serialVersionUID = 980337771224675268L;
  92         public Throwable fillInStackTrace() {
  93             return this;
  94         }
  95     };
  96 


 123 
 124     protected PropertyManager fPropertyManager = null ;
 125 
 126     boolean isExternal = false;
 127     static {
 128 
 129         for(int i=0x0041;i<=0x005A ; i++){
 130             VALID_NAMES[i]=true;
 131         }
 132         for(int i=0x0061;i<=0x007A; i++){
 133             VALID_NAMES[i]=true;
 134         }
 135         for(int i=0x0030;i<=0x0039; i++){
 136             VALID_NAMES[i]=true;
 137         }
 138         VALID_NAMES[45]=true;
 139         VALID_NAMES[46]=true;
 140         VALID_NAMES[58]=true;
 141         VALID_NAMES[95]=true;
 142     }
 143     // SAPJVM: Remember, that the XML version has explicitly been set,

 144     // so that XMLStreamReader.getVersion() can find that out.
 145     boolean xmlVersionSetExplicitly = false;

 146     //
 147     // Constructors
 148     //
 149 
 150     /** Default constructor. */
 151     public XMLEntityScanner() {
 152     } // <init>()
 153 
 154 
 155     /**  private constructor, this class can only be instantiated within this class. Instance of this class should
 156      *    be obtained using getEntityScanner() or getEntityScanner(ScannedEntity scannedEntity)
 157      *    @see getEntityScanner()
 158      *    @see getEntityScanner(ScannedEntity)
 159      */
 160     public XMLEntityScanner(PropertyManager propertyManager, XMLEntityManager entityManager) {
 161         fEntityManager = entityManager ;
 162         reset(propertyManager);
 163     } // <init>()
 164 
 165 


 240      * XML 1.0 entities. In such a case the rules of XML 1.1 are applied to the entire
 241      * document. Also note that, for a given entity, this value can only be considered
 242      * final once the XML or text declaration has been read or once it has been
 243      * determined that there is no such declaration.
 244      */
 245     public final String getXMLVersion() {
 246         if (fCurrentEntity != null) {
 247             return fCurrentEntity.xmlVersion;
 248         }
 249         return null;
 250     } // getXMLVersion():String
 251 
 252     /**
 253      * Sets the XML version. This method is used by the
 254      * scanners to report the value of the version pseudo-attribute
 255      * in an XML or text declaration.
 256      *
 257      * @param xmlVersion the XML version of the current entity
 258      */
 259     public final void setXMLVersion(String xmlVersion) {
 260         xmlVersionSetExplicitly = true; // SAPJVM
 261         fCurrentEntity.xmlVersion = xmlVersion;
 262     } // setXMLVersion(String)
 263 
 264 
 265     /** set the instance of current scanned entity.
 266      *   @param ScannedEntity
 267      */
 268 
 269     public final void setCurrentEntity(Entity.ScannedEntity scannedEntity){
 270         fCurrentEntity = scannedEntity ;
 271         if(fCurrentEntity != null){
 272             isExternal = fCurrentEntity.isExternal();
 273             if(DEBUG_BUFFER)
 274                 System.out.println("Current Entity is "+scannedEntity.name);
 275         }
 276     }
 277 
 278     public  Entity.ScannedEntity getCurrentEntity(){
 279         return fCurrentEntity ;
 280     }


 529      * <p>
 530      * <strong>Note:</strong> The character is consumed.
 531      *
 532      * @throws IOException  Thrown if i/o error occurs.
 533      * @throws EOFException Thrown on end of file.
 534      */
 535     public int scanChar() throws IOException {
 536         if (DEBUG_BUFFER) {
 537             System.out.print("(scanChar: ");
 538             print();
 539             System.out.println();
 540         }
 541 
 542         // load more characters, if needed
 543         if (fCurrentEntity.position == fCurrentEntity.count) {
 544             load(0, true, true);
 545         }
 546 
 547         // scan character
 548         int c = fCurrentEntity.ch[fCurrentEntity.position++];
 549         if (c == '\n' ||
 550                 (c == '\r' && isExternal)) {
 551             fCurrentEntity.lineNumber++;
 552             fCurrentEntity.columnNumber = 1;
 553             if (fCurrentEntity.position == fCurrentEntity.count) {
 554                 invokeListeners(1);
 555                 fCurrentEntity.ch[0] = (char)c;
 556                 load(1, false, false);
 557             }
 558             if (c == '\r' && isExternal) {
 559                 if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') {
 560                     fCurrentEntity.position--;
 561                 }
 562                 c = '\n';
 563             }
 564         }
 565 
 566         // return character that was scanned
 567         if (DEBUG_BUFFER) {
 568             System.out.print(")scanChar: ");
 569             print();
 570             System.out.println(" -> '"+(char)c+"'");


 936      * @param content The content structure to fill.
 937      *
 938      * @return Returns the next character on the input, if known. This
 939      *         value may be -1 but this does <em>note</em> designate
 940      *         end of file.
 941      *
 942      * @throws IOException  Thrown if i/o error occurs.
 943      * @throws EOFException Thrown on end of file.
 944      */
 945     public int scanContent(XMLString content) throws IOException {
 946         if (DEBUG_BUFFER) {
 947             System.out.print("(scanContent: ");
 948             print();
 949             System.out.println();
 950         }
 951 
 952         // load more characters, if needed
 953         if (fCurrentEntity.position == fCurrentEntity.count) {
 954             load(0, true, true);
 955         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
 956             invokeListeners(0);
 957             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
 958             load(1, false, false);
 959             fCurrentEntity.position = 0;
 960         }
 961 
 962         // normalize newlines
 963         int offset = fCurrentEntity.position;
 964         int c = fCurrentEntity.ch[offset];
 965         int newlines = 0;
 966         if (c == '\n' || (c == '\r' && isExternal)) {
 967             if (DEBUG_BUFFER) {
 968                 System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
 969                 print();
 970                 System.out.println();
 971             }
 972             do {
 973                 c = fCurrentEntity.ch[fCurrentEntity.position++];
 974                 if (c == '\r' && isExternal) {
 975                     newlines++;
 976                     fCurrentEntity.lineNumber++;


1088      * @param content The content structure to fill.
1089      *
1090      * @return Returns the next character on the input, if known. This
1091      *         value may be -1 but this does <em>note</em> designate
1092      *         end of file.
1093      *
1094      * @throws IOException  Thrown if i/o error occurs.
1095      * @throws EOFException Thrown on end of file.
1096      */
1097     public int scanLiteral(int quote, XMLString content)
1098     throws IOException {
1099         if (DEBUG_BUFFER) {
1100             System.out.print("(scanLiteral, '"+(char)quote+"': ");
1101             print();
1102             System.out.println();
1103         }
1104         // load more characters, if needed
1105         if (fCurrentEntity.position == fCurrentEntity.count) {
1106             load(0, true, true);
1107         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1108             invokeListeners(0);
1109             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
1110             load(1, false, false);
1111             fCurrentEntity.position = 0;
1112         }
1113 
1114         // normalize newlines
1115         int offset = fCurrentEntity.position;
1116         int c = fCurrentEntity.ch[offset];
1117         int newlines = 0;
1118         if(whiteSpaceInfoNeeded)
1119             whiteSpaceLen=0;
1120         if (c == '\n' || (c == '\r' && isExternal)) {
1121             if (DEBUG_BUFFER) {
1122                 System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
1123                 print();
1124                 System.out.println();
1125             }
1126             do {
1127                 c = fCurrentEntity.ch[fCurrentEntity.position++];
1128                 if (c == '\r' && isExternal) {


1239      *
1240      * @param whiteSpacePos position of a whitespace in the scanner entity buffer
1241      */
1242     private void storeWhiteSpace(int whiteSpacePos) {
1243         if (whiteSpaceLen >= whiteSpaceLookup.length) {
1244             int [] tmp = new int[whiteSpaceLookup.length + 100];
1245             System.arraycopy(whiteSpaceLookup, 0, tmp, 0, whiteSpaceLookup.length);
1246             whiteSpaceLookup = tmp;
1247         }
1248 
1249         whiteSpaceLookup[whiteSpaceLen++] = whiteSpacePos;
1250     }
1251 
1252     //CHANGED:
1253     /**
1254      * Scans a range of character data up to the specified delimiter,
1255      * setting the fields of the XMLString structure, appropriately.
1256      * <p>
1257      * <strong>Note:</strong> The characters are consumed.
1258      * <p>
1259      * <strong>Note:</strong> This assumes that the length of the delimiter
1260      * and that the delimiter contains at least one character.
1261      * <p>
1262      * <strong>Note:</strong> This method does not guarantee to return
1263      * the longest run of character data. This method may return before
1264      * the delimiter due to reaching the end of the input buffer or any
1265      * other reason.
1266      * <p>
1267      * @param delimiter The string that signifies the end of the character
1268      *                  data to be scanned.
1269      * @param buffer    The XMLStringBuffer to fill.
1270      *
1271      * @return Returns true if there is more data to scan, false otherwise.
1272      *
1273      * @throws IOException  Thrown if i/o error occurs.
1274      * @throws EOFException Thrown on end of file.
1275      */
1276     public boolean scanData(String delimiter, XMLStringBuffer buffer)
1277     throws IOException {
1278 
1279         boolean done = false;
1280         int delimLen = delimiter.length();


1419                     buffer.append(fCurrentEntity.ch, offset, length);
1420                     return true;
1421                 }
1422             }
1423             int length = fCurrentEntity.position - offset;
1424             fCurrentEntity.columnNumber += length - newlines;
1425             if (done) {
1426                 length -= delimLen;
1427             }
1428             buffer.append(fCurrentEntity.ch, offset, length);
1429 
1430             // return true if string was skipped
1431             if (DEBUG_BUFFER) {
1432                 System.out.print(")scanData: ");
1433                 print();
1434                 System.out.println(" -> " + done);
1435             }
1436         } while (!done);
1437         return !done;
1438 
1439     } // scanData(String,XMLString)
1440 
1441     /**
1442      * Skips a character appearing immediately on the input.
1443      * <p>
1444      * <strong>Note:</strong> The character is consumed only if it matches
1445      * the specified character.
1446      *
1447      * @param c The character to skip.
1448      *
1449      * @return Returns true if the character was skipped.
1450      *
1451      * @throws IOException  Thrown if i/o error occurs.
1452      * @throws EOFException Thrown on end of file.
1453      */
1454     public boolean skipChar(int c) throws IOException {
1455         if (DEBUG_BUFFER) {
1456             System.out.print("(skipChar, '"+(char)c+"': ");
1457             print();
1458             System.out.println();
1459         }


1541         //we are doing this check only in skipSpace() because it is called by
1542         //fMiscDispatcher and we want the parser to exit gracefully when document
1543         //is well-formed.
1544         //it is possible that end of document is reached and
1545         //fCurrentEntity becomes null
1546         //nothing was read so entity changed  'false' should be returned.
1547         if(fCurrentEntity == null){
1548             return false ;
1549         }
1550 
1551         // skip spaces
1552         int c = fCurrentEntity.ch[fCurrentEntity.position];
1553         if (XMLChar.isSpace(c)) {
1554             do {
1555                 boolean entityChanged = false;
1556                 // handle newlines
1557                 if (c == '\n' || (isExternal && c == '\r')) {
1558                     fCurrentEntity.lineNumber++;
1559                     fCurrentEntity.columnNumber = 1;
1560                     if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1561                         invokeListeners(0);
1562                         fCurrentEntity.ch[0] = (char)c;
1563                         entityChanged = load(1, true, false);
1564                         if (!entityChanged){
1565                             // the load change the position to be 1,
1566                             // need to restore it when entity not changed
1567                             fCurrentEntity.position = 0;
1568                         }else if(fCurrentEntity == null){
1569                             return true ;
1570                         }
1571                     }
1572                     if (c == '\r' && isExternal) {
1573                         // REVISIT: Does this need to be updated to fix the
1574                         //          #x0D ^#x0A newline normalization problem? -Ac
1575                         if (fCurrentEntity.ch[++fCurrentEntity.position] != '\n') {
1576                             fCurrentEntity.position--;
1577                         }
1578                     }
1579                 } else {
1580                     fCurrentEntity.columnNumber++;
1581                 }


1710             //s.charAt() indexes are 0 to 'Length -1' based.
1711             int i = length - 1 ;
1712             //check from reverse
1713             while(s.charAt(i--) == fCurrentEntity.ch[afterSkip]){
1714                 if(afterSkip-- == beforeSkip){
1715                     fCurrentEntity.position = fCurrentEntity.position + length ;
1716                     fCurrentEntity.columnNumber += length;
1717                     return true;
1718                 }
1719             }
1720         }
1721 
1722         return false;
1723     } // skipString(String):boolean
1724 
1725     public boolean skipString(char [] s) throws IOException {
1726 
1727         final int length = s.length;
1728         //first make sure that required capacity is avaible
1729         if(arrangeCapacity(length, false)){
1730             int beforeSkip = fCurrentEntity.position ;
1731             int afterSkip = fCurrentEntity.position + length  ;
1732 
1733             if(DEBUG_SKIP_STRING){
1734                 System.out.println("skipString,length = " + new String(s) + "," + length);
1735                 System.out.println("skipString,length = " + new String(s) + "," + length);
1736             }
1737 
1738             for(int i=0;i<length;i++){
1739                 if(!(fCurrentEntity.ch[beforeSkip++]==s[i])){
1740                    return false;
1741                 }
1742             }
1743             fCurrentEntity.position = fCurrentEntity.position + length ;
1744             fCurrentEntity.columnNumber += length;
1745             return true;
1746 
1747         }
1748 
1749         return false;
1750     }
1751 


2090                     }
2091                     System.out.print('"');
2092                 }
2093                 System.out.print(']');
2094                 System.out.print(" @ ");
2095                 System.out.print(fCurrentEntity.lineNumber);
2096                 System.out.print(',');
2097                 System.out.print(fCurrentEntity.columnNumber);
2098             } else {
2099                 System.out.print("*NO CURRENT ENTITY*");
2100             }
2101         }
2102     }
2103 
2104     /**
2105      * Registers the listener object and provides callback.
2106      * @param listener listener to which call back should be provided when scanner buffer
2107      * is being changed.
2108      */
2109     public void registerListener(XMLBufferListener listener) {
2110         if(!listeners.contains(listener))
2111             listeners.add(listener);

2112     }
2113 
2114     /**
2115      *
2116      * @param loadPos Starting position from which new data is being loaded into scanner buffer.
2117      */
2118     public void invokeListeners(int loadPos){
2119         for(int i=0;i<listeners.size();i++){
2120             XMLBufferListener listener =(XMLBufferListener) listeners.get(i);
2121             listener.refresh(loadPos);
2122         }
2123     }
2124 
2125     /**
2126      * Skips space characters appearing immediately on the input that would
2127      * match non-terminal S (0x09, 0x0A, 0x0D, 0x20) before end of line
2128      * normalization is performed. This is useful when scanning structures
2129      * such as the XMLDecl and TextDecl that can only contain US-ASCII
2130      * characters.
2131      * <p>
2132      * <strong>Note:</strong> The characters are consumed only if they would
2133      * match non-terminal S before end of line normalization is performed.
2134      *
2135      * @return Returns true if at least one space character was skipped.
2136      *
2137      * @throws IOException  Thrown if i/o error occurs.
2138      * @throws EOFException Thrown on end of file.
2139      *
2140      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace
2141      */


   1 /*
   2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *     http://www.apache.org/licenses/LICENSE-2.0




  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xerces.internal.impl;
  23 


  24 import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
  25 import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
  26 import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
  27 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
  28 import com.sun.org.apache.xerces.internal.util.EncodingMap;
  29 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  30 import com.sun.org.apache.xerces.internal.util.XMLChar;
  31 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
  32 import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
  33 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
  34 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit;
  35 import com.sun.org.apache.xerces.internal.xni.*;
  36 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  37 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  38 import com.sun.xml.internal.stream.Entity;
  39 import com.sun.xml.internal.stream.Entity.ScannedEntity;
  40 import com.sun.xml.internal.stream.XMLBufferListener;
  41 import java.io.EOFException;
  42 import java.io.IOException;
  43 import java.io.InputStream;
  44 import java.io.InputStreamReader;
  45 import java.io.Reader;
  46 import java.util.ArrayList;
  47 import java.util.Locale;

  48 
  49 /**
  50  * Implements the entity scanner methods.
  51  *
  52  * @author Neeraj Bajaj, Sun Microsystems
  53  * @author Andy Clark, IBM
  54  * @author Arnaud  Le Hors, IBM
  55  * @author K.Venugopal Sun Microsystems
  56  *
  57  */
  58 public class XMLEntityScanner implements XMLLocator  {
  59 
  60     protected Entity.ScannedEntity fCurrentEntity = null;

  61     protected int fBufferSize = XMLEntityManager.DEFAULT_BUFFER_SIZE;
  62 
  63     protected XMLEntityManager fEntityManager;
  64 
  65     /** Security manager. */
  66     protected XMLSecurityManager fSecurityManager = null;
  67 
  68     /** Limit analyzer. */
  69     protected XMLLimitAnalyzer fLimitAnalyzer = null;
  70 
  71     /** Debug switching readers for encodings. */
  72     private static final boolean DEBUG_ENCODINGS = false;
  73 
  74     /** Listeners which should know when load is being called */
  75     private ArrayList<XMLBufferListener> listeners = new ArrayList<>();
  76 
  77     private static final boolean [] VALID_NAMES = new boolean[127];
  78 
  79     /**
  80      * Debug printing of buffer. This debugging flag works best when you
  81      * resize the DEFAULT_BUFFER_SIZE down to something reasonable like
  82      * 64 characters.
  83      */
  84     private static final boolean DEBUG_BUFFER = false;
  85     private static final boolean DEBUG_SKIP_STRING = false;
  86     /**
  87      * To signal the end of the document entity, this exception will be thrown.
  88      */
  89     private static final EOFException END_OF_DOCUMENT_ENTITY = new EOFException() {
  90         private static final long serialVersionUID = 980337771224675268L;
  91         public Throwable fillInStackTrace() {
  92             return this;
  93         }
  94     };
  95 


 122 
 123     protected PropertyManager fPropertyManager = null ;
 124 
 125     boolean isExternal = false;
 126     static {
 127 
 128         for(int i=0x0041;i<=0x005A ; i++){
 129             VALID_NAMES[i]=true;
 130         }
 131         for(int i=0x0061;i<=0x007A; i++){
 132             VALID_NAMES[i]=true;
 133         }
 134         for(int i=0x0030;i<=0x0039; i++){
 135             VALID_NAMES[i]=true;
 136         }
 137         VALID_NAMES[45]=true;
 138         VALID_NAMES[46]=true;
 139         VALID_NAMES[58]=true;
 140         VALID_NAMES[95]=true;
 141     }
 142 
 143     // Remember, that the XML version has explicitly been set,
 144     // so that XMLStreamReader.getVersion() can find that out.
 145     protected boolean xmlVersionSetExplicitly = false;
 146 
 147     //
 148     // Constructors
 149     //
 150 
 151     /** Default constructor. */
 152     public XMLEntityScanner() {
 153     } // <init>()
 154 
 155 
 156     /**  private constructor, this class can only be instantiated within this class. Instance of this class should
 157      *    be obtained using getEntityScanner() or getEntityScanner(ScannedEntity scannedEntity)
 158      *    @see getEntityScanner()
 159      *    @see getEntityScanner(ScannedEntity)
 160      */
 161     public XMLEntityScanner(PropertyManager propertyManager, XMLEntityManager entityManager) {
 162         fEntityManager = entityManager ;
 163         reset(propertyManager);
 164     } // <init>()
 165 
 166 


 241      * XML 1.0 entities. In such a case the rules of XML 1.1 are applied to the entire
 242      * document. Also note that, for a given entity, this value can only be considered
 243      * final once the XML or text declaration has been read or once it has been
 244      * determined that there is no such declaration.
 245      */
 246     public final String getXMLVersion() {
 247         if (fCurrentEntity != null) {
 248             return fCurrentEntity.xmlVersion;
 249         }
 250         return null;
 251     } // getXMLVersion():String
 252 
 253     /**
 254      * Sets the XML version. This method is used by the
 255      * scanners to report the value of the version pseudo-attribute
 256      * in an XML or text declaration.
 257      *
 258      * @param xmlVersion the XML version of the current entity
 259      */
 260     public final void setXMLVersion(String xmlVersion) {
 261         xmlVersionSetExplicitly = true;
 262         fCurrentEntity.xmlVersion = xmlVersion;
 263     } // setXMLVersion(String)
 264 
 265 
 266     /** set the instance of current scanned entity.
 267      *   @param ScannedEntity
 268      */
 269 
 270     public final void setCurrentEntity(Entity.ScannedEntity scannedEntity){
 271         fCurrentEntity = scannedEntity ;
 272         if(fCurrentEntity != null){
 273             isExternal = fCurrentEntity.isExternal();
 274             if(DEBUG_BUFFER)
 275                 System.out.println("Current Entity is "+scannedEntity.name);
 276         }
 277     }
 278 
 279     public  Entity.ScannedEntity getCurrentEntity(){
 280         return fCurrentEntity ;
 281     }


 530      * <p>
 531      * <strong>Note:</strong> The character is consumed.
 532      *
 533      * @throws IOException  Thrown if i/o error occurs.
 534      * @throws EOFException Thrown on end of file.
 535      */
 536     public int scanChar() throws IOException {
 537         if (DEBUG_BUFFER) {
 538             System.out.print("(scanChar: ");
 539             print();
 540             System.out.println();
 541         }
 542 
 543         // load more characters, if needed
 544         if (fCurrentEntity.position == fCurrentEntity.count) {
 545             load(0, true, true);
 546         }
 547 
 548         // scan character
 549         int c = fCurrentEntity.ch[fCurrentEntity.position++];
 550         if (c == '\n' || (c == '\r' && isExternal)) {

 551             fCurrentEntity.lineNumber++;
 552             fCurrentEntity.columnNumber = 1;
 553             if (fCurrentEntity.position == fCurrentEntity.count) {
 554                 invokeListeners(1);
 555                 fCurrentEntity.ch[0] = (char)c;
 556                 load(1, false, false);
 557             }
 558             if (c == '\r' && isExternal) {
 559                 if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') {
 560                     fCurrentEntity.position--;
 561                 }
 562                 c = '\n';
 563             }
 564         }
 565 
 566         // return character that was scanned
 567         if (DEBUG_BUFFER) {
 568             System.out.print(")scanChar: ");
 569             print();
 570             System.out.println(" -> '"+(char)c+"'");


 936      * @param content The content structure to fill.
 937      *
 938      * @return Returns the next character on the input, if known. This
 939      *         value may be -1 but this does <em>note</em> designate
 940      *         end of file.
 941      *
 942      * @throws IOException  Thrown if i/o error occurs.
 943      * @throws EOFException Thrown on end of file.
 944      */
 945     public int scanContent(XMLString content) throws IOException {
 946         if (DEBUG_BUFFER) {
 947             System.out.print("(scanContent: ");
 948             print();
 949             System.out.println();
 950         }
 951 
 952         // load more characters, if needed
 953         if (fCurrentEntity.position == fCurrentEntity.count) {
 954             load(0, true, true);
 955         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
 956             invokeListeners(1);
 957             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
 958             load(1, false, false);
 959             fCurrentEntity.position = 0;
 960         }
 961 
 962         // normalize newlines
 963         int offset = fCurrentEntity.position;
 964         int c = fCurrentEntity.ch[offset];
 965         int newlines = 0;
 966         if (c == '\n' || (c == '\r' && isExternal)) {
 967             if (DEBUG_BUFFER) {
 968                 System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
 969                 print();
 970                 System.out.println();
 971             }
 972             do {
 973                 c = fCurrentEntity.ch[fCurrentEntity.position++];
 974                 if (c == '\r' && isExternal) {
 975                     newlines++;
 976                     fCurrentEntity.lineNumber++;


1088      * @param content The content structure to fill.
1089      *
1090      * @return Returns the next character on the input, if known. This
1091      *         value may be -1 but this does <em>note</em> designate
1092      *         end of file.
1093      *
1094      * @throws IOException  Thrown if i/o error occurs.
1095      * @throws EOFException Thrown on end of file.
1096      */
1097     public int scanLiteral(int quote, XMLString content)
1098     throws IOException {
1099         if (DEBUG_BUFFER) {
1100             System.out.print("(scanLiteral, '"+(char)quote+"': ");
1101             print();
1102             System.out.println();
1103         }
1104         // load more characters, if needed
1105         if (fCurrentEntity.position == fCurrentEntity.count) {
1106             load(0, true, true);
1107         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1108             invokeListeners(1);
1109             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
1110             load(1, false, false);
1111             fCurrentEntity.position = 0;
1112         }
1113 
1114         // normalize newlines
1115         int offset = fCurrentEntity.position;
1116         int c = fCurrentEntity.ch[offset];
1117         int newlines = 0;
1118         if(whiteSpaceInfoNeeded)
1119             whiteSpaceLen=0;
1120         if (c == '\n' || (c == '\r' && isExternal)) {
1121             if (DEBUG_BUFFER) {
1122                 System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
1123                 print();
1124                 System.out.println();
1125             }
1126             do {
1127                 c = fCurrentEntity.ch[fCurrentEntity.position++];
1128                 if (c == '\r' && isExternal) {


1239      *
1240      * @param whiteSpacePos position of a whitespace in the scanner entity buffer
1241      */
1242     private void storeWhiteSpace(int whiteSpacePos) {
1243         if (whiteSpaceLen >= whiteSpaceLookup.length) {
1244             int [] tmp = new int[whiteSpaceLookup.length + 100];
1245             System.arraycopy(whiteSpaceLookup, 0, tmp, 0, whiteSpaceLookup.length);
1246             whiteSpaceLookup = tmp;
1247         }
1248 
1249         whiteSpaceLookup[whiteSpaceLen++] = whiteSpacePos;
1250     }
1251 
1252     //CHANGED:
1253     /**
1254      * Scans a range of character data up to the specified delimiter,
1255      * setting the fields of the XMLString structure, appropriately.
1256      * <p>
1257      * <strong>Note:</strong> The characters are consumed.
1258      * <p>
1259      * <strong>Note:</strong> This assumes that the delimiter contains at
1260      * least one character.
1261      * <p>
1262      * <strong>Note:</strong> This method does not guarantee to return
1263      * the longest run of character data. This method may return before
1264      * the delimiter due to reaching the end of the input buffer or any
1265      * other reason.
1266      * <p>
1267      * @param delimiter The string that signifies the end of the character
1268      *                  data to be scanned.
1269      * @param buffer    The XMLStringBuffer to fill.
1270      *
1271      * @return Returns true if there is more data to scan, false otherwise.
1272      *
1273      * @throws IOException  Thrown if i/o error occurs.
1274      * @throws EOFException Thrown on end of file.
1275      */
1276     public boolean scanData(String delimiter, XMLStringBuffer buffer)
1277     throws IOException {
1278 
1279         boolean done = false;
1280         int delimLen = delimiter.length();


1419                     buffer.append(fCurrentEntity.ch, offset, length);
1420                     return true;
1421                 }
1422             }
1423             int length = fCurrentEntity.position - offset;
1424             fCurrentEntity.columnNumber += length - newlines;
1425             if (done) {
1426                 length -= delimLen;
1427             }
1428             buffer.append(fCurrentEntity.ch, offset, length);
1429 
1430             // return true if string was skipped
1431             if (DEBUG_BUFFER) {
1432                 System.out.print(")scanData: ");
1433                 print();
1434                 System.out.println(" -> " + done);
1435             }
1436         } while (!done);
1437         return !done;
1438 
1439     } // scanData(String, XMLStringBuffer)
1440 
1441     /**
1442      * Skips a character appearing immediately on the input.
1443      * <p>
1444      * <strong>Note:</strong> The character is consumed only if it matches
1445      * the specified character.
1446      *
1447      * @param c The character to skip.
1448      *
1449      * @return Returns true if the character was skipped.
1450      *
1451      * @throws IOException  Thrown if i/o error occurs.
1452      * @throws EOFException Thrown on end of file.
1453      */
1454     public boolean skipChar(int c) throws IOException {
1455         if (DEBUG_BUFFER) {
1456             System.out.print("(skipChar, '"+(char)c+"': ");
1457             print();
1458             System.out.println();
1459         }


1541         //we are doing this check only in skipSpace() because it is called by
1542         //fMiscDispatcher and we want the parser to exit gracefully when document
1543         //is well-formed.
1544         //it is possible that end of document is reached and
1545         //fCurrentEntity becomes null
1546         //nothing was read so entity changed  'false' should be returned.
1547         if(fCurrentEntity == null){
1548             return false ;
1549         }
1550 
1551         // skip spaces
1552         int c = fCurrentEntity.ch[fCurrentEntity.position];
1553         if (XMLChar.isSpace(c)) {
1554             do {
1555                 boolean entityChanged = false;
1556                 // handle newlines
1557                 if (c == '\n' || (isExternal && c == '\r')) {
1558                     fCurrentEntity.lineNumber++;
1559                     fCurrentEntity.columnNumber = 1;
1560                     if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1561                         invokeListeners(1);
1562                         fCurrentEntity.ch[0] = (char)c;
1563                         entityChanged = load(1, true, false);
1564                         if (!entityChanged){
1565                             // the load change the position to be 1,
1566                             // need to restore it when entity not changed
1567                             fCurrentEntity.position = 0;
1568                         }else if(fCurrentEntity == null){
1569                             return true ;
1570                         }
1571                     }
1572                     if (c == '\r' && isExternal) {
1573                         // REVISIT: Does this need to be updated to fix the
1574                         //          #x0D ^#x0A newline normalization problem? -Ac
1575                         if (fCurrentEntity.ch[++fCurrentEntity.position] != '\n') {
1576                             fCurrentEntity.position--;
1577                         }
1578                     }
1579                 } else {
1580                     fCurrentEntity.columnNumber++;
1581                 }


1710             //s.charAt() indexes are 0 to 'Length -1' based.
1711             int i = length - 1 ;
1712             //check from reverse
1713             while(s.charAt(i--) == fCurrentEntity.ch[afterSkip]){
1714                 if(afterSkip-- == beforeSkip){
1715                     fCurrentEntity.position = fCurrentEntity.position + length ;
1716                     fCurrentEntity.columnNumber += length;
1717                     return true;
1718                 }
1719             }
1720         }
1721 
1722         return false;
1723     } // skipString(String):boolean
1724 
1725     public boolean skipString(char [] s) throws IOException {
1726 
1727         final int length = s.length;
1728         //first make sure that required capacity is avaible
1729         if(arrangeCapacity(length, false)){
1730             int beforeSkip = fCurrentEntity.position;

1731 
1732             if(DEBUG_SKIP_STRING){
1733                 System.out.println("skipString,length = " + new String(s) + "," + length);
1734                 System.out.println("skipString,length = " + new String(s) + "," + length);
1735             }
1736 
1737             for(int i=0;i<length;i++){
1738                 if(!(fCurrentEntity.ch[beforeSkip++]==s[i])){
1739                    return false;
1740                 }
1741             }
1742             fCurrentEntity.position = fCurrentEntity.position + length ;
1743             fCurrentEntity.columnNumber += length;
1744             return true;
1745 
1746         }
1747 
1748         return false;
1749     }
1750 


2089                     }
2090                     System.out.print('"');
2091                 }
2092                 System.out.print(']');
2093                 System.out.print(" @ ");
2094                 System.out.print(fCurrentEntity.lineNumber);
2095                 System.out.print(',');
2096                 System.out.print(fCurrentEntity.columnNumber);
2097             } else {
2098                 System.out.print("*NO CURRENT ENTITY*");
2099             }
2100         }
2101     }
2102 
2103     /**
2104      * Registers the listener object and provides callback.
2105      * @param listener listener to which call back should be provided when scanner buffer
2106      * is being changed.
2107      */
2108     public void registerListener(XMLBufferListener listener) {
2109         if (!listeners.contains(listener)) {
2110             listeners.add(listener);
2111         }
2112     }
2113 
2114     /**
2115      *
2116      * @param loadPos Starting position from which new data is being loaded into scanner buffer.
2117      */
2118     public void invokeListeners(int loadPos){
2119         for (int i=0; i<listeners.size(); i++) {
2120             listeners.get(i).refresh(loadPos);

2121         }
2122     }
2123 
2124     /**
2125      * Skips space characters appearing immediately on the input that would
2126      * match non-terminal S (0x09, 0x0A, 0x0D, 0x20) before end of line
2127      * normalization is performed. This is useful when scanning structures
2128      * such as the XMLDecl and TextDecl that can only contain US-ASCII
2129      * characters.
2130      * <p>
2131      * <strong>Note:</strong> The characters are consumed only if they would
2132      * match non-terminal S before end of line normalization is performed.
2133      *
2134      * @return Returns true if at least one space character was skipped.
2135      *
2136      * @throws IOException  Thrown if i/o error occurs.
2137      * @throws EOFException Thrown on end of file.
2138      *
2139      * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace
2140      */


< prev index next >