|
|
|
package com.fr.third.javax.xml.stream;
|
|
|
|
|
|
|
|
import com.fr.third.javax.xml.stream.xerces.xni.parser.*;
|
|
|
|
import java.util.*;
|
|
|
|
import com.fr.third.javax.xml.stream.xerces.xni.*;
|
|
|
|
import com.fr.third.javax.xml.stream.xerces.impl.io.*;
|
|
|
|
import com.fr.third.javax.xml.stream.xerces.util.*;
|
|
|
|
import java.io.*;
|
|
|
|
|
|
|
|
import static com.fr.third.javax.xml.stream.xerces.util.XMLChar.isInvalid;
|
|
|
|
|
|
|
|
public class XMLEntityReaderImpl extends XMLEntityReader
|
|
|
|
{
|
|
|
|
protected Entity.ScannedEntity fCurrentEntity;
|
|
|
|
protected XMLEntityManager fEntityManager;
|
|
|
|
private static final boolean DEBUG_ENCODINGS = false;
|
|
|
|
private Vector listeners;
|
|
|
|
public static final boolean[] validContent;
|
|
|
|
public static final boolean[] validNames;
|
|
|
|
private static final boolean DEBUG_BUFFER = false;
|
|
|
|
private static final boolean DEBUG_SKIP_STRING = false;
|
|
|
|
protected SymbolTable fSymbolTable;
|
|
|
|
protected XMLErrorReporter fErrorReporter;
|
|
|
|
int[] whiteSpaceLookup;
|
|
|
|
int whiteSpaceLen;
|
|
|
|
boolean whiteSpaceInfoNeeded;
|
|
|
|
char[] scannedName;
|
|
|
|
protected boolean fAllowJavaEncodings;
|
|
|
|
protected static final String SYMBOL_TABLE = "http://apache.org/xml/properties/internal/symbol-table";
|
|
|
|
protected static final String ERROR_REPORTER = "http://apache.org/xml/properties/internal/error-reporter";
|
|
|
|
protected static final String ALLOW_JAVA_ENCODINGS = "http://apache.org/xml/features/allow-java-encodings";
|
|
|
|
protected PropertyManager fPropertyManager;
|
|
|
|
boolean isExternal;
|
|
|
|
|
|
|
|
static {
|
|
|
|
validContent = new boolean[127];
|
|
|
|
validNames = new boolean[127];
|
|
|
|
for (char i = ' '; i < '\u007f'; ++i) {
|
|
|
|
XMLEntityReaderImpl.validContent[i] = true;
|
|
|
|
}
|
|
|
|
XMLEntityReaderImpl.validContent[9] = true;
|
|
|
|
XMLEntityReaderImpl.validContent[10] = true;
|
|
|
|
XMLEntityReaderImpl.validContent[38] = false;
|
|
|
|
XMLEntityReaderImpl.validContent[60] = false;
|
|
|
|
for (int j = 65; j <= 90; ++j) {
|
|
|
|
XMLEntityReaderImpl.validNames[j] = true;
|
|
|
|
}
|
|
|
|
for (int j = 97; j <= 122; ++j) {
|
|
|
|
XMLEntityReaderImpl.validNames[j] = true;
|
|
|
|
}
|
|
|
|
for (int j = 48; j <= 57; ++j) {
|
|
|
|
XMLEntityReaderImpl.validNames[j] = true;
|
|
|
|
}
|
|
|
|
XMLEntityReaderImpl.validNames[45] = true;
|
|
|
|
XMLEntityReaderImpl.validNames[46] = true;
|
|
|
|
XMLEntityReaderImpl.validNames[58] = true;
|
|
|
|
XMLEntityReaderImpl.validNames[95] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public XMLEntityReaderImpl(final XMLEntityManager entityManager) {
|
|
|
|
this.fCurrentEntity = null;
|
|
|
|
this.listeners = new Vector();
|
|
|
|
this.fSymbolTable = null;
|
|
|
|
this.fErrorReporter = null;
|
|
|
|
this.whiteSpaceLookup = new int[100];
|
|
|
|
this.whiteSpaceLen = 0;
|
|
|
|
this.whiteSpaceInfoNeeded = true;
|
|
|
|
this.scannedName = null;
|
|
|
|
this.fPropertyManager = null;
|
|
|
|
this.isExternal = false;
|
|
|
|
this.fEntityManager = entityManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
public XMLEntityReaderImpl(final PropertyManager propertyManager, final XMLEntityManager entityManager) {
|
|
|
|
this.fCurrentEntity = null;
|
|
|
|
this.listeners = new Vector();
|
|
|
|
this.fSymbolTable = null;
|
|
|
|
this.fErrorReporter = null;
|
|
|
|
this.whiteSpaceLookup = new int[100];
|
|
|
|
this.whiteSpaceLen = 0;
|
|
|
|
this.whiteSpaceInfoNeeded = true;
|
|
|
|
this.scannedName = null;
|
|
|
|
this.fPropertyManager = null;
|
|
|
|
this.isExternal = false;
|
|
|
|
this.fEntityManager = entityManager;
|
|
|
|
this.reset(propertyManager);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void reset(final PropertyManager propertyManager) {
|
|
|
|
this.fSymbolTable = (SymbolTable)propertyManager.getProperty("http://apache.org/xml/properties/internal/symbol-table");
|
|
|
|
this.fErrorReporter = (XMLErrorReporter)propertyManager.getProperty("http://apache.org/xml/properties/internal/error-reporter");
|
|
|
|
this.fCurrentEntity = null;
|
|
|
|
this.whiteSpaceLen = 0;
|
|
|
|
this.whiteSpaceInfoNeeded = true;
|
|
|
|
this.scannedName = null;
|
|
|
|
this.listeners.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void reset(final XMLComponentManager componentManager) throws XMLConfigurationException {
|
|
|
|
try {
|
|
|
|
this.fAllowJavaEncodings = componentManager.getFeature("http://apache.org/xml/features/allow-java-encodings");
|
|
|
|
}
|
|
|
|
catch (XMLConfigurationException e) {
|
|
|
|
this.fAllowJavaEncodings = false;
|
|
|
|
}
|
|
|
|
this.fSymbolTable = (SymbolTable)componentManager.getProperty("http://apache.org/xml/properties/internal/symbol-table");
|
|
|
|
this.fErrorReporter = (XMLErrorReporter)componentManager.getProperty("http://apache.org/xml/properties/internal/error-reporter");
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setCurrentEntity(final Entity.ScannedEntity scannedEntity) {
|
|
|
|
this.fCurrentEntity = scannedEntity;
|
|
|
|
if (this.fCurrentEntity != null) {
|
|
|
|
this.isExternal = this.fCurrentEntity.isExternal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Entity.ScannedEntity getCurrentEntity() {
|
|
|
|
return this.fCurrentEntity;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getBaseSystemId() {
|
|
|
|
return (this.fCurrentEntity != null && this.fCurrentEntity.entityLocation != null) ? this.fCurrentEntity.entityLocation.getExpandedSystemId() : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getLineNumber() {
|
|
|
|
return (this.fCurrentEntity != null) ? this.fCurrentEntity.lineNumber : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getColumnNumber() {
|
|
|
|
return (this.fCurrentEntity != null) ? this.fCurrentEntity.columnNumber : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getCharacterOffset() {
|
|
|
|
return (this.fCurrentEntity != null) ? (this.fCurrentEntity.fTotalCountTillLastLoad + this.fCurrentEntity.position) : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getExpandedSystemId() {
|
|
|
|
return (this.fCurrentEntity != null && this.fCurrentEntity.entityLocation != null) ? this.fCurrentEntity.entityLocation.getExpandedSystemId() : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getLiteralSystemId() {
|
|
|
|
return (this.fCurrentEntity != null && this.fCurrentEntity.entityLocation != null) ? this.fCurrentEntity.entityLocation.getLiteralSystemId() : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getPublicId() {
|
|
|
|
return (this.fCurrentEntity != null && this.fCurrentEntity.entityLocation != null) ? this.fCurrentEntity.entityLocation.getPublicId() : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setVersion(final String version) {
|
|
|
|
this.fCurrentEntity.version = version;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getVersion() {
|
|
|
|
return this.fCurrentEntity.version;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getEncoding() {
|
|
|
|
return this.fCurrentEntity.encoding;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEncoding(final String encoding) throws IOException {
|
|
|
|
if (this.fCurrentEntity.stream != null && (this.fCurrentEntity.encoding == null || !this.fCurrentEntity.encoding.equals(encoding))) {
|
|
|
|
if (this.fCurrentEntity.encoding != null && this.fCurrentEntity.encoding.startsWith("UTF-16")) {
|
|
|
|
final String ENCODING = encoding.toUpperCase(Locale.ENGLISH);
|
|
|
|
if (ENCODING.equals("UTF-16")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (ENCODING.equals("ISO-10646-UCS-4")) {
|
|
|
|
if (this.fCurrentEntity.encoding.equals("UTF-16BE")) {
|
|
|
|
this.fCurrentEntity.reader = new UCSReader(this.fCurrentEntity.stream, (short)8);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.fCurrentEntity.reader = new UCSReader(this.fCurrentEntity.stream, (short)4);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (ENCODING.equals("ISO-10646-UCS-2")) {
|
|
|
|
if (this.fCurrentEntity.encoding.equals("UTF-16BE")) {
|
|
|
|
this.fCurrentEntity.reader = new UCSReader(this.fCurrentEntity.stream, (short)2);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.fCurrentEntity.reader = new UCSReader(this.fCurrentEntity.stream, (short)1);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.fCurrentEntity.reader = this.createReader(this.fCurrentEntity.stream, encoding, null);
|
|
|
|
this.fCurrentEntity.encoding = encoding;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isExternal() {
|
|
|
|
return this.fCurrentEntity.isExternal();
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getChar(final int relative) throws IOException {
|
|
|
|
if (this.arrangeCapacity(relative + 1, false)) {
|
|
|
|
return this.fCurrentEntity.ch[this.fCurrentEntity.position + relative];
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int peekChar() throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
final int c = this.fCurrentEntity.ch[this.fCurrentEntity.position];
|
|
|
|
if (this.isExternal) {
|
|
|
|
return (c != 13) ? c : 10;
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int scanChar() throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
int c = this.fCurrentEntity.ch[this.fCurrentEntity.position++];
|
|
|
|
if (c == 10 || (c == 13 && this.isExternal)) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(1);
|
|
|
|
this.fCurrentEntity.ch[0] = (char)c;
|
|
|
|
this.load(1, false);
|
|
|
|
}
|
|
|
|
if (c == 13 && this.isExternal) {
|
|
|
|
if (this.fCurrentEntity.ch[this.fCurrentEntity.position++] != '\n') {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity2.position;
|
|
|
|
}
|
|
|
|
c = 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final Entity.ScannedEntity fCurrentEntity3 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity3.columnNumber;
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String scanNmtoken() throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
int offset = this.fCurrentEntity.position;
|
|
|
|
boolean vc = false;
|
|
|
|
while (true) {
|
|
|
|
final char c = this.fCurrentEntity.ch[this.fCurrentEntity.position];
|
|
|
|
if (c < '\u007f') {
|
|
|
|
vc = XMLEntityReaderImpl.validNames[c];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vc = XMLChar.isName(c);
|
|
|
|
}
|
|
|
|
if (!vc) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (++this.fCurrentEntity.position != this.fCurrentEntity.count) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
final int length = this.fCurrentEntity.position - offset;
|
|
|
|
this.invokeListeners(length);
|
|
|
|
if (length == this.fCurrentEntity.fBufferSize) {
|
|
|
|
final char[] tmp = new char[this.fCurrentEntity.fBufferSize * 2];
|
|
|
|
System.arraycopy(this.fCurrentEntity.ch, offset, tmp, 0, length);
|
|
|
|
this.fCurrentEntity.ch = tmp;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
fCurrentEntity.fBufferSize *= 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
System.arraycopy(this.fCurrentEntity.ch, offset, this.fCurrentEntity.ch, 0, length);
|
|
|
|
}
|
|
|
|
offset = 0;
|
|
|
|
if (this.load(length, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final int length = this.fCurrentEntity.position - offset;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity2.columnNumber += length;
|
|
|
|
String symbol = null;
|
|
|
|
if (length > 0) {
|
|
|
|
symbol = this.fSymbolTable.addSymbol(this.fCurrentEntity.ch, offset, length);
|
|
|
|
}
|
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String scanName() throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
int offset = this.fCurrentEntity.position;
|
|
|
|
if (XMLChar.isNameStart(this.fCurrentEntity.ch[offset])) {
|
|
|
|
if (++this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(1);
|
|
|
|
this.fCurrentEntity.ch[0] = this.fCurrentEntity.ch[offset];
|
|
|
|
offset = 0;
|
|
|
|
if (this.load(1, false)) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity.columnNumber;
|
|
|
|
final String symbol = this.fSymbolTable.addSymbol(this.fCurrentEntity.ch, 0, 1);
|
|
|
|
this.scannedName = this.fSymbolTable.getCharArray();
|
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
boolean vc = false;
|
|
|
|
while (true) {
|
|
|
|
final char c = this.fCurrentEntity.ch[this.fCurrentEntity.position];
|
|
|
|
if (c < '\u007f') {
|
|
|
|
vc = XMLEntityReaderImpl.validNames[c];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vc = XMLChar.isName(c);
|
|
|
|
}
|
|
|
|
if (!vc) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (++this.fCurrentEntity.position != this.fCurrentEntity.count) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
final int length = this.fCurrentEntity.position - offset;
|
|
|
|
this.invokeListeners(length);
|
|
|
|
if (length == this.fCurrentEntity.fBufferSize) {
|
|
|
|
final char[] tmp = new char[this.fCurrentEntity.fBufferSize * 2];
|
|
|
|
System.arraycopy(this.fCurrentEntity.ch, offset, tmp, 0, length);
|
|
|
|
this.fCurrentEntity.ch = tmp;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity2.fBufferSize *= 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
System.arraycopy(this.fCurrentEntity.ch, offset, this.fCurrentEntity.ch, 0, length);
|
|
|
|
}
|
|
|
|
offset = 0;
|
|
|
|
if (this.load(length, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final int length2 = this.fCurrentEntity.position - offset;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity3 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity3.columnNumber += length2;
|
|
|
|
String symbol2 = null;
|
|
|
|
if (length2 > 0) {
|
|
|
|
symbol2 = this.fSymbolTable.addSymbol(this.fCurrentEntity.ch, offset, length2);
|
|
|
|
this.scannedName = this.fSymbolTable.getCharArray();
|
|
|
|
}
|
|
|
|
return symbol2;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean scanQName(final QName qname) throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
int offset = this.fCurrentEntity.position;
|
|
|
|
if (XMLChar.isNameStart(this.fCurrentEntity.ch[offset])) {
|
|
|
|
if (++this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(1);
|
|
|
|
this.fCurrentEntity.ch[0] = this.fCurrentEntity.ch[offset];
|
|
|
|
offset = 0;
|
|
|
|
if (this.load(1, false)) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity.columnNumber;
|
|
|
|
final String name = this.fSymbolTable.addSymbol(this.fCurrentEntity.ch, 0, 1);
|
|
|
|
qname.setValues(null, name, name, null);
|
|
|
|
qname.characters = this.fSymbolTable.getCharArray();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int index = -1;
|
|
|
|
boolean vc = false;
|
|
|
|
while (true) {
|
|
|
|
final char c = this.fCurrentEntity.ch[this.fCurrentEntity.position];
|
|
|
|
if (c < '\u007f') {
|
|
|
|
vc = XMLEntityReaderImpl.validNames[c];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vc = XMLChar.isName(c);
|
|
|
|
}
|
|
|
|
if (!vc) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (c == ':') {
|
|
|
|
if (index != -1) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
index = this.fCurrentEntity.position;
|
|
|
|
}
|
|
|
|
if (++this.fCurrentEntity.position != this.fCurrentEntity.count) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
final int length = this.fCurrentEntity.position - offset;
|
|
|
|
this.invokeListeners(length);
|
|
|
|
if (length == this.fCurrentEntity.fBufferSize) {
|
|
|
|
final char[] tmp = new char[this.fCurrentEntity.fBufferSize * 2];
|
|
|
|
System.arraycopy(this.fCurrentEntity.ch, offset, tmp, 0, length);
|
|
|
|
this.fCurrentEntity.ch = tmp;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity2.fBufferSize *= 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
System.arraycopy(this.fCurrentEntity.ch, offset, this.fCurrentEntity.ch, 0, length);
|
|
|
|
}
|
|
|
|
if (index != -1) {
|
|
|
|
index -= offset;
|
|
|
|
}
|
|
|
|
offset = 0;
|
|
|
|
if (this.load(length, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final int length2 = this.fCurrentEntity.position - offset;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity3 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity3.columnNumber += length2;
|
|
|
|
if (length2 > 0) {
|
|
|
|
String prefix = null;
|
|
|
|
String localpart = null;
|
|
|
|
final String rawname = this.fSymbolTable.addSymbol(this.fCurrentEntity.ch, offset, length2);
|
|
|
|
qname.characters = this.fSymbolTable.getCharArray();
|
|
|
|
if (index != -1) {
|
|
|
|
final int prefixLength = index - offset;
|
|
|
|
prefix = this.fSymbolTable.addSymbol(this.fCurrentEntity.ch, offset, prefixLength);
|
|
|
|
final int len = length2 - prefixLength - 1;
|
|
|
|
localpart = this.fSymbolTable.addSymbol(this.fCurrentEntity.ch, index + 1, len);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
localpart = rawname;
|
|
|
|
}
|
|
|
|
qname.setValues(prefix, localpart, rawname, null);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int scanContent(final XMLString content) throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
else if (this.fCurrentEntity.position == this.fCurrentEntity.count - 1) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.fCurrentEntity.ch[0] = this.fCurrentEntity.ch[this.fCurrentEntity.count - 1];
|
|
|
|
this.load(1, false);
|
|
|
|
this.fCurrentEntity.position = 0;
|
|
|
|
}
|
|
|
|
int offset = this.fCurrentEntity.position;
|
|
|
|
int c = this.fCurrentEntity.ch[offset];
|
|
|
|
int newlines = 0;
|
|
|
|
if (c == 10 || (c == 13 && this.isExternal)) {
|
|
|
|
do {
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position++];
|
|
|
|
if (c == 13 && this.isExternal) {
|
|
|
|
++newlines;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
offset = 0;
|
|
|
|
this.invokeListeners(newlines);
|
|
|
|
this.fCurrentEntity.position = newlines;
|
|
|
|
if (this.load(newlines, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity.ch[this.fCurrentEntity.position] == '\n') {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity2.position;
|
|
|
|
++offset;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
++newlines;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (c != 10) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity3 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity3.position;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++newlines;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity4 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity4.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
if (this.fCurrentEntity.position != this.fCurrentEntity.count) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
offset = 0;
|
|
|
|
this.invokeListeners(newlines);
|
|
|
|
this.fCurrentEntity.position = newlines;
|
|
|
|
if (this.load(newlines, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} while (this.fCurrentEntity.position < this.fCurrentEntity.count - 1);
|
|
|
|
for (int i = offset; i < this.fCurrentEntity.position; ++i) {
|
|
|
|
this.fCurrentEntity.ch[i] = '\n';
|
|
|
|
}
|
|
|
|
final int length = this.fCurrentEntity.position - offset;
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count - 1) {
|
|
|
|
content.setValues(this.fCurrentEntity.ch, offset, length);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
boolean vc = false;
|
|
|
|
while (this.fCurrentEntity.position < this.fCurrentEntity.count) {
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position++];
|
|
|
|
if (c < 127) {
|
|
|
|
vc = XMLEntityReaderImpl.validContent[c];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vc = XMLChar.isContent(c);
|
|
|
|
}
|
|
|
|
if (!vc) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity5 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity5.position;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final int length2 = this.fCurrentEntity.position - offset;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity6 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity6.columnNumber += length2 - newlines;
|
|
|
|
content.setValues(this.fCurrentEntity.ch, offset, length2);
|
|
|
|
if (this.fCurrentEntity.position != this.fCurrentEntity.count) {
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position];
|
|
|
|
if (c == 13 && this.isExternal) {
|
|
|
|
c = 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
c = -1;
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int scanLiteral(final int quote, final XMLString content) throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
else if (this.fCurrentEntity.position == this.fCurrentEntity.count - 1) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.fCurrentEntity.ch[0] = this.fCurrentEntity.ch[this.fCurrentEntity.count - 1];
|
|
|
|
this.load(1, false);
|
|
|
|
this.fCurrentEntity.position = 0;
|
|
|
|
}
|
|
|
|
int offset = this.fCurrentEntity.position;
|
|
|
|
int c = this.fCurrentEntity.ch[offset];
|
|
|
|
int newlines = 0;
|
|
|
|
if (this.whiteSpaceInfoNeeded) {
|
|
|
|
this.whiteSpaceLen = 0;
|
|
|
|
}
|
|
|
|
if (c == 10 || (c == 13 && this.isExternal)) {
|
|
|
|
do {
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position++];
|
|
|
|
if (c == 13 && this.isExternal) {
|
|
|
|
++newlines;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(newlines);
|
|
|
|
offset = 0;
|
|
|
|
this.fCurrentEntity.position = newlines;
|
|
|
|
if (this.load(newlines, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity.ch[this.fCurrentEntity.position] == '\n') {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity2.position;
|
|
|
|
++offset;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
++newlines;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (c != 10) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity3 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity3.position;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++newlines;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity4 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity4.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
if (this.fCurrentEntity.position != this.fCurrentEntity.count) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
offset = 0;
|
|
|
|
this.invokeListeners(newlines);
|
|
|
|
this.fCurrentEntity.position = newlines;
|
|
|
|
if (this.load(newlines, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} while (this.fCurrentEntity.position < this.fCurrentEntity.count - 1);
|
|
|
|
int i;
|
|
|
|
for (i = 0, i = offset; i < this.fCurrentEntity.position; ++i) {
|
|
|
|
this.fCurrentEntity.ch[i] = '\n';
|
|
|
|
this.whiteSpaceLookup[this.whiteSpaceLen++] = i;
|
|
|
|
}
|
|
|
|
final int length = this.fCurrentEntity.position - offset;
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count - 1) {
|
|
|
|
content.setValues(this.fCurrentEntity.ch, offset, length);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
boolean vc = true;
|
|
|
|
while (this.fCurrentEntity.position < this.fCurrentEntity.count) {
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position++];
|
|
|
|
if ((c == quote && (!this.fCurrentEntity.literal || this.isExternal)) || c == 37) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity5 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity5.position;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (c < 127) {
|
|
|
|
vc = XMLEntityReaderImpl.validContent[c];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vc = XMLChar.isContent(c);
|
|
|
|
}
|
|
|
|
if (!vc) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity6 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity6.position;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!this.whiteSpaceInfoNeeded || (c != 32 && c != 9)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (this.whiteSpaceLen < this.whiteSpaceLookup.length) {
|
|
|
|
this.whiteSpaceLookup[this.whiteSpaceLen++] = this.fCurrentEntity.position - 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
final int[] tmp = new int[this.whiteSpaceLookup.length + 20];
|
|
|
|
System.arraycopy(this.whiteSpaceLookup, 0, tmp, 0, this.whiteSpaceLookup.length);
|
|
|
|
(this.whiteSpaceLookup = tmp)[this.whiteSpaceLen++] = this.fCurrentEntity.position - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final int length = this.fCurrentEntity.position - offset;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity7 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity7.columnNumber += length - newlines;
|
|
|
|
content.setValues(this.fCurrentEntity.ch, offset, length);
|
|
|
|
if (this.fCurrentEntity.position != this.fCurrentEntity.count) {
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position];
|
|
|
|
if (c == quote && this.fCurrentEntity.literal) {
|
|
|
|
c = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
c = -1;
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean scanData(final String delimiter, final XMLStringBuffer buffer) throws IOException {
|
|
|
|
boolean done = false;
|
|
|
|
final int delimLen = delimiter.length();
|
|
|
|
final char charAt0 = delimiter.charAt(0);
|
|
|
|
do {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
else if (this.fCurrentEntity.position >= this.fCurrentEntity.count - delimLen) {
|
|
|
|
this.invokeListeners(this.fCurrentEntity.count - this.fCurrentEntity.position);
|
|
|
|
System.arraycopy(this.fCurrentEntity.ch, this.fCurrentEntity.position, this.fCurrentEntity.ch, 0, this.fCurrentEntity.count - this.fCurrentEntity.position);
|
|
|
|
this.load(this.fCurrentEntity.count - this.fCurrentEntity.position, false);
|
|
|
|
this.fCurrentEntity.position = 0;
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity.position >= this.fCurrentEntity.count - delimLen) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
final int length = this.fCurrentEntity.count - this.fCurrentEntity.position;
|
|
|
|
buffer.append(this.fCurrentEntity.ch, this.fCurrentEntity.position, length);
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
fCurrentEntity.columnNumber += this.fCurrentEntity.count;
|
|
|
|
this.fCurrentEntity.position = this.fCurrentEntity.count;
|
|
|
|
this.load(0, true);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
int offset = this.fCurrentEntity.position;
|
|
|
|
int c = this.fCurrentEntity.ch[offset];
|
|
|
|
int newlines = 0;
|
|
|
|
if (c == 10 || (c == 13 && this.isExternal)) {
|
|
|
|
do {
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position++];
|
|
|
|
if (c == 13 && this.isExternal) {
|
|
|
|
++newlines;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity2.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
offset = 0;
|
|
|
|
this.invokeListeners(newlines);
|
|
|
|
this.fCurrentEntity.position = newlines;
|
|
|
|
if (this.load(newlines, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity.ch[this.fCurrentEntity.position] == '\n') {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity3 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity3.position;
|
|
|
|
++offset;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
++newlines;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (c != 10) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity4 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity4.position;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++newlines;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity5 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity5.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
if (this.fCurrentEntity.position != this.fCurrentEntity.count) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
offset = 0;
|
|
|
|
this.invokeListeners(newlines);
|
|
|
|
this.fCurrentEntity.position = newlines;
|
|
|
|
this.fCurrentEntity.count = newlines;
|
|
|
|
if (this.load(newlines, false)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} while (this.fCurrentEntity.position < this.fCurrentEntity.count - 1);
|
|
|
|
for (int i = offset; i < this.fCurrentEntity.position; ++i) {
|
|
|
|
this.fCurrentEntity.ch[i] = '\n';
|
|
|
|
}
|
|
|
|
final int length2 = this.fCurrentEntity.position - offset;
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count - 1) {
|
|
|
|
buffer.append(this.fCurrentEntity.ch, offset, length2);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Label_0949:
|
|
|
|
while (this.fCurrentEntity.position < this.fCurrentEntity.count) {
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position++];
|
|
|
|
if (c == charAt0) {
|
|
|
|
final int delimOffset = this.fCurrentEntity.position - 1;
|
|
|
|
for (int j = 1; j < delimLen; ++j) {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity6 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity6.position -= j;
|
|
|
|
break Label_0949;
|
|
|
|
}
|
|
|
|
c = this.fCurrentEntity.ch[this.fCurrentEntity.position++];
|
|
|
|
if (delimiter.charAt(j) != c) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity7 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity7.position -= j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity.position == delimOffset + delimLen) {
|
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (c == 10 || (this.isExternal && c == 13)) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity8 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity8.position;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (isInvalid(c)) {
|
|
|
|
if(XMLChar.isHighSurrogate(c)){
|
|
|
|
this.fCurrentEntity.position--;
|
|
|
|
if (this.fCurrentEntity.position - offset > 0){
|
|
|
|
int length2 = this.fCurrentEntity.position - offset;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity10 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity10.columnNumber += length2 - newlines;
|
|
|
|
buffer.append(this.fCurrentEntity.ch, offset, length2);
|
|
|
|
}
|
|
|
|
final int high = this.scanChar();
|
|
|
|
final int low = this.peekChar();
|
|
|
|
if (!XMLChar.isLowSurrogate(low)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
int x = XMLChar.supplemental((char)high, (char)low);
|
|
|
|
if (isInvalid(x)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
buffer.append((char)high);
|
|
|
|
buffer.append((char)low);
|
|
|
|
offset = ++this.fCurrentEntity.position;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
final Entity.ScannedEntity fCurrentEntity9 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity9.position;
|
|
|
|
final int length2 = this.fCurrentEntity.position - offset;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity10 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity10.columnNumber += length2 - newlines;
|
|
|
|
buffer.append(this.fCurrentEntity.ch, offset, length2);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int length2 = this.fCurrentEntity.position - offset;
|
|
|
|
if (length2 != 0){
|
|
|
|
final Entity.ScannedEntity fCurrentEntity11 = this.fCurrentEntity;
|
|
|
|
fCurrentEntity11.columnNumber += length2 - newlines;
|
|
|
|
if (done) {
|
|
|
|
length2 -= delimLen;
|
|
|
|
}
|
|
|
|
buffer.append(this.fCurrentEntity.ch, offset, length2);
|
|
|
|
}
|
|
|
|
} while (!done);
|
|
|
|
return !done;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean skipChar(final int c) throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
final int cc = this.fCurrentEntity.ch[this.fCurrentEntity.position];
|
|
|
|
if (cc == c) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity.position;
|
|
|
|
if (c == 10) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity2.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity3 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity3.columnNumber;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (c == 10 && cc == 13 && this.isExternal) {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(1);
|
|
|
|
this.fCurrentEntity.ch[0] = (char)cc;
|
|
|
|
this.load(1, false);
|
|
|
|
}
|
|
|
|
final Entity.ScannedEntity fCurrentEntity4 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity4.position;
|
|
|
|
if (this.fCurrentEntity.ch[this.fCurrentEntity.position] == '\n') {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity5 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity5.position;
|
|
|
|
}
|
|
|
|
final Entity.ScannedEntity fCurrentEntity6 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity6.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isSpace(final char ch) {
|
|
|
|
return ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r';
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean skipSpaces() throws IOException {
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity == null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
int c = this.fCurrentEntity.ch[this.fCurrentEntity.position];
|
|
|
|
if (XMLChar.isSpace(c)) {
|
|
|
|
do {
|
|
|
|
boolean entityChanged = false;
|
|
|
|
if (c == 10 || (this.isExternal && c == 13)) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity.lineNumber;
|
|
|
|
this.fCurrentEntity.columnNumber = 1;
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count - 1) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.fCurrentEntity.ch[0] = (char)c;
|
|
|
|
entityChanged = this.load(1, true);
|
|
|
|
if (!entityChanged) {
|
|
|
|
this.fCurrentEntity.position = 0;
|
|
|
|
}
|
|
|
|
else if (this.fCurrentEntity == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (c == 13 && this.isExternal && this.fCurrentEntity.ch[++this.fCurrentEntity.position] != '\n') {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity2 = this.fCurrentEntity;
|
|
|
|
--fCurrentEntity2.position;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity3 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity3.columnNumber;
|
|
|
|
}
|
|
|
|
if (!entityChanged) {
|
|
|
|
final Entity.ScannedEntity fCurrentEntity4 = this.fCurrentEntity;
|
|
|
|
++fCurrentEntity4.position;
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
this.load(0, true);
|
|
|
|
if (this.fCurrentEntity == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} while (XMLChar.isSpace(c = this.fCurrentEntity.ch[this.fCurrentEntity.position]));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean arrangeCapacity(final int length) throws IOException {
|
|
|
|
return this.arrangeCapacity(length, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean arrangeCapacity(final int length, final boolean changeEntity) throws IOException {
|
|
|
|
if (this.fCurrentEntity.count - this.fCurrentEntity.position >= length) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
boolean entityChanged = false;
|
|
|
|
while (this.fCurrentEntity.count - this.fCurrentEntity.position < length) {
|
|
|
|
if (this.fCurrentEntity.ch.length - this.fCurrentEntity.position < length) {
|
|
|
|
this.invokeListeners(0);
|
|
|
|
System.arraycopy(this.fCurrentEntity.ch, this.fCurrentEntity.position, this.fCurrentEntity.ch, 0, this.fCurrentEntity.count - this.fCurrentEntity.position);
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
fCurrentEntity.count -= this.fCurrentEntity.position;
|
|
|
|
this.fCurrentEntity.position = 0;
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity.count - this.fCurrentEntity.position < length) {
|
|
|
|
final int pos = this.fCurrentEntity.position;
|
|
|
|
this.invokeListeners(pos);
|
|
|
|
entityChanged = this.load(this.fCurrentEntity.count, changeEntity);
|
|
|
|
this.fCurrentEntity.position = pos;
|
|
|
|
if (entityChanged) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this.fCurrentEntity.count - this.fCurrentEntity.position >= length;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean skipString(final String s) throws IOException {
|
|
|
|
final int length = s.length();
|
|
|
|
if (this.arrangeCapacity(length, false)) {
|
|
|
|
final int beforeSkip = this.fCurrentEntity.position;
|
|
|
|
int afterSkip = this.fCurrentEntity.position + length - 1;
|
|
|
|
int i = length - 1;
|
|
|
|
while (s.charAt(i--) == this.fCurrentEntity.ch[afterSkip]) {
|
|
|
|
if (afterSkip-- == beforeSkip) {
|
|
|
|
this.fCurrentEntity.position += length;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
fCurrentEntity.columnNumber += length;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean skipString(final char[] s) throws IOException {
|
|
|
|
final int length = s.length;
|
|
|
|
if (this.arrangeCapacity(length, false)) {
|
|
|
|
int beforeSkip = this.fCurrentEntity.position;
|
|
|
|
final int afterSkip = this.fCurrentEntity.position + length;
|
|
|
|
for (int i = 0; i < length; ++i) {
|
|
|
|
if (this.fCurrentEntity.ch[beforeSkip++] != s[i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.fCurrentEntity.position += length;
|
|
|
|
final Entity.ScannedEntity fCurrentEntity = this.fCurrentEntity;
|
|
|
|
fCurrentEntity.columnNumber += length;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
final boolean load(final int offset, final boolean changeEntity) throws IOException {
|
|
|
|
this.fCurrentEntity.fTotalCountTillLastLoad += this.fCurrentEntity.fLastCount;
|
|
|
|
final int length = this.fCurrentEntity.mayReadChunks ? (this.fCurrentEntity.ch.length - offset) : 64;
|
|
|
|
final int count = this.fCurrentEntity.reader.read(this.fCurrentEntity.ch, offset, length);
|
|
|
|
boolean entityChanged = false;
|
|
|
|
if (count != -1) {
|
|
|
|
if (count != 0) {
|
|
|
|
this.fCurrentEntity.fLastCount = count;
|
|
|
|
this.fCurrentEntity.count = count + offset;
|
|
|
|
this.fCurrentEntity.position = offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.fCurrentEntity.count = offset;
|
|
|
|
this.fCurrentEntity.position = offset;
|
|
|
|
entityChanged = true;
|
|
|
|
if (changeEntity) {
|
|
|
|
this.fEntityManager.endEntity();
|
|
|
|
if (this.fCurrentEntity == null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (this.fCurrentEntity.position == this.fCurrentEntity.count) {
|
|
|
|
this.load(0, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return entityChanged;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Reader createReader(final InputStream inputStream, String encoding, final Boolean isBigEndian) throws IOException {
|
|
|
|
if (encoding == null) {
|
|
|
|
encoding = "UTF-8";
|
|
|
|
}
|
|
|
|
final String ENCODING = encoding.toUpperCase(Locale.ENGLISH);
|
|
|
|
if (ENCODING.equals("UTF-8")) {
|
|
|
|
return new UTF8Reader(inputStream, this.fCurrentEntity.fBufferSize, this.fErrorReporter.getMessageFormatter("http://www.w3.org/TR/1998/REC-xml-19980210"), this.fErrorReporter.getLocale());
|
|
|
|
}
|
|
|
|
if (ENCODING.equals("US-ASCII")) {
|
|
|
|
return new ASCIIReader(inputStream, this.fCurrentEntity.fBufferSize, this.fErrorReporter.getMessageFormatter("http://www.w3.org/TR/1998/REC-xml-19980210"), this.fErrorReporter.getLocale());
|
|
|
|
}
|
|
|
|
if (ENCODING.equals("ISO-10646-UCS-4")) {
|
|
|
|
if (isBigEndian != null) {
|
|
|
|
final boolean isBE = isBigEndian;
|
|
|
|
if (isBE) {
|
|
|
|
return new UCSReader(inputStream, (short)8);
|
|
|
|
}
|
|
|
|
return new UCSReader(inputStream, (short)4);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.fErrorReporter.reportError("http://www.w3.org/TR/1998/REC-xml-19980210", "EncodingByteOrderUnsupported", new Object[] { encoding }, (short)2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ENCODING.equals("ISO-10646-UCS-2")) {
|
|
|
|
if (isBigEndian != null) {
|
|
|
|
final boolean isBE = isBigEndian;
|
|
|
|
if (isBE) {
|
|
|
|
return new UCSReader(inputStream, (short)2);
|
|
|
|
}
|
|
|
|
return new UCSReader(inputStream, (short)1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.fErrorReporter.reportError("http://www.w3.org/TR/1998/REC-xml-19980210", "EncodingByteOrderUnsupported", new Object[] { encoding }, (short)2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final boolean validIANA = XMLChar.isValidIANAEncoding(encoding);
|
|
|
|
final boolean validJava = XMLChar.isValidJavaEncoding(encoding);
|
|
|
|
if (!validIANA || (this.fAllowJavaEncodings && !validJava)) {
|
|
|
|
this.fErrorReporter.reportError("http://www.w3.org/TR/1998/REC-xml-19980210", "EncodingDeclInvalid", new Object[] { encoding }, (short)2);
|
|
|
|
encoding = "ISO-8859-1";
|
|
|
|
}
|
|
|
|
String javaEncoding = EncodingMap.getIANA2JavaMapping(ENCODING);
|
|
|
|
if (javaEncoding == null) {
|
|
|
|
if (this.fAllowJavaEncodings) {
|
|
|
|
javaEncoding = encoding;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.fErrorReporter.reportError("http://www.w3.org/TR/1998/REC-xml-19980210", "EncodingDeclInvalid", new Object[] { encoding }, (short)2);
|
|
|
|
javaEncoding = "ISO8859_1";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return new InputStreamReader(inputStream, javaEncoding);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Object[] getEncodingName(final byte[] b4, final int count) {
|
|
|
|
if (count < 2) {
|
|
|
|
return new Object[] { "UTF-8", null };
|
|
|
|
}
|
|
|
|
final int b5 = b4[0] & 0xFF;
|
|
|
|
final int b6 = b4[1] & 0xFF;
|
|
|
|
if (b5 == 254 && b6 == 255) {
|
|
|
|
return new Object[] { "UTF-16BE", new Boolean(true) };
|
|
|
|
}
|
|
|
|
if (b5 == 255 && b6 == 254) {
|
|
|
|
return new Object[] { "UTF-16LE", new Boolean(false) };
|
|
|
|
}
|
|
|
|
if (count < 3) {
|
|
|
|
return new Object[] { "UTF-8", null };
|
|
|
|
}
|
|
|
|
final int b7 = b4[2] & 0xFF;
|
|
|
|
if (b5 == 239 && b6 == 187 && b7 == 191) {
|
|
|
|
return new Object[] { "UTF-8", null };
|
|
|
|
}
|
|
|
|
if (count < 4) {
|
|
|
|
return new Object[] { "UTF-8", null };
|
|
|
|
}
|
|
|
|
final int b8 = b4[3] & 0xFF;
|
|
|
|
if (b5 == 0 && b6 == 0 && b7 == 0 && b8 == 60) {
|
|
|
|
return new Object[] { "ISO-10646-UCS-4", new Boolean(true) };
|
|
|
|
}
|
|
|
|
if (b5 == 60 && b6 == 0 && b7 == 0 && b8 == 0) {
|
|
|
|
return new Object[] { "ISO-10646-UCS-4", new Boolean(false) };
|
|
|
|
}
|
|
|
|
if (b5 == 0 && b6 == 0 && b7 == 60 && b8 == 0) {
|
|
|
|
return new Object[] { "ISO-10646-UCS-4", null };
|
|
|
|
}
|
|
|
|
if (b5 == 0 && b6 == 60 && b7 == 0 && b8 == 0) {
|
|
|
|
return new Object[] { "ISO-10646-UCS-4", null };
|
|
|
|
}
|
|
|
|
if (b5 == 0 && b6 == 60 && b7 == 0 && b8 == 63) {
|
|
|
|
return new Object[] { "UTF-16BE", new Boolean(true) };
|
|
|
|
}
|
|
|
|
if (b5 == 60 && b6 == 0 && b7 == 63 && b8 == 0) {
|
|
|
|
return new Object[] { "UTF-16LE", new Boolean(false) };
|
|
|
|
}
|
|
|
|
if (b5 == 76 && b6 == 111 && b7 == 167 && b8 == 148) {
|
|
|
|
return new Object[] { "CP037", null };
|
|
|
|
}
|
|
|
|
return new Object[] { "UTF-8", null };
|
|
|
|
}
|
|
|
|
|
|
|
|
final void print() {
|
|
|
|
}
|
|
|
|
|
|
|
|
public void registerListener(final XMLBufferListener listener) {
|
|
|
|
if (!this.listeners.contains(listener)) {
|
|
|
|
this.listeners.add(listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void invokeListeners(final int loadPos) {
|
|
|
|
for (int i = 0; i < this.listeners.size(); ++i) {
|
|
|
|
final XMLBufferListener listener = (XMLBufferListener) this.listeners.get(i);
|
|
|
|
listener.refresh(loadPos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|