package com.fasterxml.aalto.stax;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collections;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.codehaus.stax2.*;
import org.codehaus.stax2.typed.Base64Variant;
import org.codehaus.stax2.typed.Base64Variants;
import org.codehaus.stax2.typed.TypedArrayDecoder;
import org.codehaus.stax2.typed.TypedValueDecoder;
import org.codehaus.stax2.typed.TypedXMLStreamException;
import org.codehaus.stax2.validation.DTDValidationSchema;
import org.codehaus.stax2.validation.XMLValidator;
import org.codehaus.stax2.validation.XMLValidationSchema;
import org.codehaus.stax2.validation.ValidationProblemHandler;
import org.codehaus.stax2.ri.Stax2Util;
import org.codehaus.stax2.ri.typed.CharArrayBase64Decoder;
import org.codehaus.stax2.ri.typed.ValueDecoderFactory;
import com.fasterxml.aalto.UncheckedStreamException;
import com.fasterxml.aalto.WFCException;
import com.fasterxml.aalto.impl.ErrorConsts;
import com.fasterxml.aalto.impl.IoStreamException;
import com.fasterxml.aalto.in.InputBootstrapper;
import com.fasterxml.aalto.in.PName;
import com.fasterxml.aalto.in.ReaderConfig;
import com.fasterxml.aalto.in.XmlScanner;
import com.fasterxml.aalto.util.TextAccumulator;
import com.fasterxml.aalto.util.XmlNames;
public class StreamReaderImpl
implements XMLStreamReader2,
AttributeInfo, DTDInfo, LocationInfo
{
final static int STATE_PROLOG = 0;
final static int STATE_TREE = 1;
final static int STATE_EPILOG = 2;
final static int STATE_CLOSED = 3;
protected final XmlScanner _scanner;
protected final boolean _cfgCoalesceText;
protected final boolean _cfgReportTextAsChars;
protected int _currToken;
protected int _parseState;
protected PName _currName;
protected int _attrCount;
protected ValueDecoderFactory _decoderFactory;
protected CharArrayBase64Decoder _base64Decoder = null;
protected PName _dtdRootName;
public StreamReaderImpl(XmlScanner scanner)
{
_scanner = scanner;
_currToken = START_DOCUMENT;
ReaderConfig cfg = scanner.getConfig();
_cfgCoalesceText = cfg.willCoalesceText();
_cfgReportTextAsChars = !cfg.willReportCData();
}
public static StreamReaderImpl construct(InputBootstrapper bs)
throws XMLStreamException
{
return new StreamReaderImpl(bs.bootstrap());
}
public XmlScanner getScanner()
{
return _scanner;
}
final private static int MASK_GET_TEXT =
(1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
| (1 << COMMENT) | (1 << DTD) | (1 << ENTITY_REFERENCE);
final private static int MASK_GET_TEXT_XXX =
(1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE) | (1 << COMMENT);
final private static int MASK_GET_TEXT_WITH_WRITER =
(1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
| (1 << COMMENT) | (1 << DTD) | (1 << ENTITY_REFERENCE)
| (1 << PROCESSING_INSTRUCTION);
final private static int MASK_GET_ELEMENT_TEXT =
(1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
| (1 << ENTITY_REFERENCE);
final private static int MASK_TYPED_ACCESS_ARRAY =
(1 << START_ELEMENT)
| (1 << END_ELEMENT)
| (1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
;
final private static int MASK_TYPED_ACCESS_BINARY =
(1 << START_ELEMENT)
| (1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
;
@Override
public final String getCharacterEncodingScheme() {
return _scanner.getConfig().getXmlDeclEncoding();
}
@Override
public final String getEncoding() {
return _scanner.getConfig().getActualEncoding();
}
@Override
public String getVersion() {
return _scanner.getConfig().getXmlDeclVersion();
}
@Override
public final boolean isStandalone() {
return (_scanner.getConfig().getXmlDeclStandalone() == ReaderConfig.STANDALONE_YES);
}
@Override
public final boolean standaloneSet() {
return (_scanner.getConfig().getXmlDeclStandalone() != ReaderConfig.STANDALONE_UNKNOWN);
}
@Override
public Object getProperty(String name)
{
if (name.equals("javax.xml.stream.entities")) {
return Collections.EMPTY_LIST;
}
if (name.equals("javax.xml.stream.notations")) {
return Collections.EMPTY_LIST;
}
return _scanner.getConfig().getProperty(name, false);
}
public ReaderConfig getConfig() {
return _scanner.getConfig();
}
@Override
public final int getAttributeCount()
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
return _attrCount;
}
@Override
public final String getAttributeLocalName(int index)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
if (index >= _attrCount || index < 0) {
reportInvalidAttrIndex(index);
}
return _scanner.getAttrLocalName(index);
}
@Override
public final QName getAttributeName(int index)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
if (index >= _attrCount || index < 0) {
reportInvalidAttrIndex(index);
}
return _scanner.getAttrQName(index);
}
@Override
public final String getAttributeNamespace(int index)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
if (index >= _attrCount || index < 0) {
reportInvalidAttrIndex(index);
}
String p = _scanner.getAttrNsURI(index);
return (p == null) ? "" : p;
}
@Override
public final String getAttributePrefix(int index)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
if (index >= _attrCount || index < 0) {
reportInvalidAttrIndex(index);
}
String p = _scanner.getAttrPrefix(index);
return (p == null) ? "" : p;
}
@Override
public final String getAttributeType(int index)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
if (index >= _attrCount || index < 0) {
reportInvalidAttrIndex(index);
}
return _scanner.getAttrType(index);
}
@Override
public final String getAttributeValue(int index)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
if (index >= _attrCount || index < 0) {
reportInvalidAttrIndex(index);
}
return _scanner.getAttrValue(index);
}
@Override
public final String getAttributeValue(String nsURI, String localName)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
return _scanner.getAttrValue(nsURI, localName);
}
@Override
public final String getElementText() throws XMLStreamException
{
if (_currToken != START_ELEMENT) {
throwWfe(ErrorConsts.ERR_STATE_NOT_STELEM);
}
while (true) {
int type = next();
if (type == END_ELEMENT) {
return "";
}
if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
continue;
}
if (((1 << type) & MASK_GET_ELEMENT_TEXT) == 0) {
_reportNonTextEvent(type);
}
break;
}
String text = _scanner.getText();
TextAccumulator acc = null;
int type;
while ((type = next()) != END_ELEMENT) {
if (((1 << type) & MASK_GET_ELEMENT_TEXT) != 0) {
if (acc == null) {
acc = new TextAccumulator();
acc.addText(text);
}
acc.addText(getText());
continue;
}
if (type != COMMENT && type != PROCESSING_INSTRUCTION) {
_reportNonTextEvent(type);
}
}
return (acc == null) ? text : acc.getAndClear();
}
@Override
public final int getEventType()
{
if (_currToken == CDATA) {
if (_cfgCoalesceText || _cfgReportTextAsChars) {
return CHARACTERS;
}
}
return _currToken;
}
@Override
public final String getLocalName()
{
if (_currToken == START_ELEMENT || _currToken == END_ELEMENT
|| _currToken == ENTITY_REFERENCE) {
return _currName.getLocalName();
}
throw new IllegalStateException("Current state not START_ELEMENT, END_ELEMENT or ENTITY_REFERENCE");
}
@Override
public final QName getName()
{
if (_currToken != START_ELEMENT && _currToken != END_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_ELEM);
}
return _scanner.getQName();
}
@Override
public final NamespaceContext getNamespaceContext()
{
return _scanner;
}
@Override
public final int getNamespaceCount() {
if (_currToken != START_ELEMENT && _currToken != END_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_ELEM);
}
return _scanner.getNsCount();
}
@Override
public final String getNamespacePrefix(int index) {
if (_currToken != START_ELEMENT && _currToken != END_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_ELEM);
}
String p = _scanner.getNamespacePrefix(index);
return (p == null) ? "" : p;
}
@Override
public final String getNamespaceURI() {
if (_currToken != START_ELEMENT && _currToken != END_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_ELEM);
}
String uri = _scanner.getNamespaceURI();
return (uri == null) ? "" : uri;
}
@Override
public final String getNamespaceURI(int index) {
if (_currToken != START_ELEMENT && _currToken != END_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_ELEM);
}
String uri = _scanner.getNamespaceURI(index);
return (uri == null) ? "" : uri;
}
@Override
public final String getNamespaceURI(String prefix)
{
if (_currToken != START_ELEMENT && _currToken != END_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_ELEM);
}
return _scanner.getNamespaceURI(prefix);
}
@Override
public final String getPIData()
{
if (_currToken != PROCESSING_INSTRUCTION) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_PI);
}
try {
return _scanner.getText();
} catch (XMLStreamException sex) {
throw UncheckedStreamException.createFrom(sex);
}
}
@Override
public final String getPITarget() {
if (_currToken != PROCESSING_INSTRUCTION) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_PI);
}
return _currName.getLocalName();
}
@Override
public final String getPrefix() {
if (_currToken != START_ELEMENT && _currToken != END_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_ELEM);
}
String p = _currName.getPrefix();
return (p == null) ? "" : p;
}
@Override
public final String getText()
{
if (((1 << _currToken) & MASK_GET_TEXT) == 0) {
throwNotTextual(_currToken);
}
try {
return _scanner.getText();
} catch (XMLStreamException sex) {
throw UncheckedStreamException.createFrom(sex);
}
}
@Override
public final char[] getTextCharacters()
{
if (((1 << _currToken) & MASK_GET_TEXT_XXX) == 0) {
throwNotTextXxx(_currToken);
}
try {
return _scanner.getTextCharacters();
} catch (XMLStreamException sex) {
throw UncheckedStreamException.createFrom(sex);
}
}
@Override
public final int getTextCharacters(int srcStart, char[] target, int targetStart, int len)
{
if (((1 << _currToken) & MASK_GET_TEXT_XXX) == 0) {
throwNotTextXxx(_currToken);
}
try {
return _scanner.getTextCharacters(srcStart, target, targetStart, len);
} catch (XMLStreamException sex) {
throw UncheckedStreamException.createFrom(sex);
}
}
@Override
public final int getTextLength()
{
if (((1 << _currToken) & MASK_GET_TEXT_XXX) == 0) {
throwNotTextXxx(_currToken);
}
try {
return _scanner.getTextLength();
} catch (XMLStreamException sex) {
throw UncheckedStreamException.createFrom(sex);
}
}
@Override
public final int getTextStart()
{
if (((1 << _currToken) & MASK_GET_TEXT_XXX) == 0) {
throwNotTextXxx(_currToken);
}
return 0;
}
@Override
public final boolean hasName() {
return (_currToken == START_ELEMENT) || (_currToken == END_ELEMENT);
}
@Override
public final boolean hasNext() {
return (_currToken != END_DOCUMENT);
}
@Override
public final boolean hasText() {
return (((1 << _currToken) & MASK_GET_TEXT) != 0);
}
@Override
public final boolean isAttributeSpecified(int index)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
return _scanner.isAttrSpecified(index);
}
@Override
public final boolean isCharacters() {
return (getEventType() == CHARACTERS);
}
@Override
public final boolean isEndElement() {
return (_currToken == END_ELEMENT);
}
@Override
public final boolean isStartElement() {
return (_currToken == START_ELEMENT);
}
@Override
public final boolean isWhiteSpace()
{
if (_currToken == CHARACTERS || _currToken == CDATA) {
try {
return _scanner.isTextWhitespace();
} catch (XMLStreamException sex) {
throw UncheckedStreamException.createFrom(sex);
}
}
return (_currToken == SPACE);
}
@Override
public final void require(int type, String nsUri, String localName)
throws XMLStreamException
{
int curr = _currToken;
if (curr != type) {
if (curr == CDATA) {
if (_cfgCoalesceText || _cfgReportTextAsChars) {
curr = CHARACTERS;
}
} else if (curr == SPACE) {
}
}
if (type != curr) {
throwWfe("Expected type "+ErrorConsts.tokenTypeDesc(type)
+", current type "
+ErrorConsts.tokenTypeDesc(curr));
}
if (localName != null) {
if (curr != START_ELEMENT && curr != END_ELEMENT
&& curr != ENTITY_REFERENCE) {
throwWfe("Expected non-null local name, but current token not a START_ELEMENT, END_ELEMENT or ENTITY_REFERENCE (was "+ErrorConsts.tokenTypeDesc(_currToken)+")");
}
String n = getLocalName();
if (n != localName && !n.equals(localName)) {
throwWfe("Expected local name '"+localName+"'; current local name '"+n+"'.");
}
}
if (nsUri != null) {
if (curr != START_ELEMENT && curr != END_ELEMENT) {
throwWfe("Expected non-null NS URI, but current token not a START_ELEMENT or END_ELEMENT (was "+ErrorConsts.tokenTypeDesc(curr)+")");
}
String uri = getNamespaceURI();
if (nsUri.length() == 0) {
if (uri != null && uri.length() > 0) {
throwWfe("Expected empty namespace, instead have '"+uri+"'.");
}
} else {
if ((nsUri != uri) && !nsUri.equals(uri)) {
throwWfe("Expected namespace '"+nsUri+"'; have '"
+uri+"'.");
}
}
}
}
@Override
public final int next() throws XMLStreamException
{
if (_parseState == STATE_TREE) {
int type = _scanner.nextFromTree();
if (type == XmlScanner.TOKEN_EOI) {
handleTreeEoi();
}
_currToken = type;
if (type == CDATA) {
if (_cfgCoalesceText || _cfgReportTextAsChars) {
return CHARACTERS;
}
} else {
_currName = _scanner.getName();
if (type == END_ELEMENT) {
if (_scanner.hasEmptyStack()) {
_parseState = STATE_EPILOG;
}
} else if (type == START_ELEMENT) {
_attrCount = _scanner.getAttrCount();
}
}
return type;
}
int type;
if (_parseState == STATE_PROLOG) {
type = _scanner.nextFromProlog(true);
if (type == START_ELEMENT) {
_parseState = STATE_TREE;
_attrCount = _scanner.getAttrCount();
} else if (type == DTD) {
if (_dtdRootName != null) {
throwWfe("Duplicate DOCTYPE declaration");
}
_dtdRootName = _scanner.getName();
}
} else if (_parseState == STATE_EPILOG) {
type = _scanner.nextFromProlog(false);
} else {
throw new java.util.NoSuchElementException();
}
if (type < 0) {
return handlePrologEoi(_parseState == STATE_PROLOG);
}
_currName = _scanner.getName();
return (_currToken = type);
}
@Override
public final int nextTag() throws XMLStreamException
{
while (true) {
int next = next();
switch (next) {
case SPACE:
case COMMENT:
case PROCESSING_INSTRUCTION:
continue;
case CDATA:
case CHARACTERS:
if (isWhiteSpace()) {
continue;
}
throwWfe("Received non-all-whitespace CHARACTERS or CDATA event in nextTag().");
break;
case START_ELEMENT:
case END_ELEMENT:
return next;
}
throwWfe("Received event "+ErrorConsts.tokenTypeDesc(next)
+", instead of START_ELEMENT or END_ELEMENT.");
}
}
@Override
public final void close() throws XMLStreamException {
_closeScanner(false);
}
@Override
public final Location getLocation() {
return getStartLocation();
}
@Override
public final boolean getElementAsBoolean() throws XMLStreamException
{
ValueDecoderFactory.BooleanDecoder dec = _decoderFactory().getBooleanDecoder();
getElementAs(dec);
return dec.getValue();
}
@Override
public final int getElementAsInt() throws XMLStreamException
{
ValueDecoderFactory.IntDecoder dec = _decoderFactory().getIntDecoder();
getElementAs(dec);
return dec.getValue();
}
@Override
public final long getElementAsLong() throws XMLStreamException
{
ValueDecoderFactory.LongDecoder dec = _decoderFactory().getLongDecoder();
getElementAs(dec);
return dec.getValue();
}
@Override
public final float getElementAsFloat() throws XMLStreamException
{
ValueDecoderFactory.FloatDecoder dec = _decoderFactory().getFloatDecoder();
getElementAs(dec);
return dec.getValue();
}
@Override
public final double getElementAsDouble() throws XMLStreamException
{
ValueDecoderFactory.DoubleDecoder dec = _decoderFactory().getDoubleDecoder();
getElementAs(dec);
return dec.getValue();
}
@Override
public final BigInteger getElementAsInteger() throws XMLStreamException
{
ValueDecoderFactory.IntegerDecoder dec = _decoderFactory().getIntegerDecoder();
getElementAs(dec);
return dec.getValue();
}
@Override
public final BigDecimal getElementAsDecimal() throws XMLStreamException
{
ValueDecoderFactory.DecimalDecoder dec = _decoderFactory().getDecimalDecoder();
getElementAs(dec);
return dec.getValue();
}
@Override
public final QName getElementAsQName() throws XMLStreamException
{
ValueDecoderFactory.QNameDecoder dec = _decoderFactory().getQNameDecoder(getNamespaceContext());
getElementAs(dec);
return verifyQName(dec.getValue());
}
@Override
public final byte[] getElementAsBinary() throws XMLStreamException
{
return getElementAsBinary(Base64Variants.getDefaultVariant());
}
@Override
public final void getElementAs(TypedValueDecoder tvd) throws XMLStreamException
{
String value = getElementText();
value = value.trim();
if (value.length() == 0) {
_handleEmptyValue(tvd);
return;
}
try {
tvd.decode(value);
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, value);
}
}
@Override
public final byte[] getElementAsBinary(Base64Variant v) throws XMLStreamException
{
Stax2Util.ByteAggregator aggr = _base64Decoder().getByteAggregator();
byte[] buffer = aggr.startAggregation();
while (true) {
int offset = 0;
int len = buffer.length;
do {
int readCount = readElementAsBinary(buffer, offset, len, v);
if (readCount < 1) {
return aggr.aggregateAll(buffer, offset);
}
offset += readCount;
len -= readCount;
} while (len > 0);
buffer = aggr.addFullBlock(buffer);
}
}
@Override
public final int readElementAsIntArray(int[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getIntArrayDecoder(value, from, length));
}
@Override
public final int readElementAsLongArray(long[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getLongArrayDecoder(value, from, length));
}
@Override
public final int readElementAsFloatArray(float[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getFloatArrayDecoder(value, from, length));
}
@Override
public final int readElementAsDoubleArray(double[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getDoubleArrayDecoder(value, from, length));
}
@Override
public final int readElementAsArray(TypedArrayDecoder dec)
throws XMLStreamException
{
int type = _currToken;
if (((1 << type) & MASK_TYPED_ACCESS_ARRAY) == 0) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM_OR_TEXT);
}
boolean reset;
if (type == START_ELEMENT) {
if (_scanner.isEmptyTag()) {
next();
return -1;
}
while (true) {
type = next();
if (type == END_ELEMENT) {
return -1;
}
if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
continue;
}
if (type == CHARACTERS || type == CDATA) {
break;
}
throw _constructUnexpectedInTyped(type);
}
reset = true;
} else {
reset = false;
}
int count = 0;
while (type != END_ELEMENT) {
if (type == CHARACTERS || type == CDATA || type == SPACE) {
count += _scanner.decodeElements(dec, reset);
if (!dec.hasRoom()) {
break;
}
} else if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
;
} else {
throw _constructUnexpectedInTyped(type);
}
reset = true;
type = next();
}
return (count > 0) ? count : -1;
}
@Override
public final int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength)
throws XMLStreamException
{
return readElementAsBinary(resultBuffer, offset, maxLength, Base64Variants.getDefaultVariant());
}
@Override
public final int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength, Base64Variant v)
throws XMLStreamException
{
if (resultBuffer == null) {
throw new IllegalArgumentException("resultBuffer is null");
}
if (offset < 0) {
throw new IllegalArgumentException("Illegal offset ("+offset+"), must be [0, "+resultBuffer.length+"[");
}
if (maxLength < 1 || (offset + maxLength) > resultBuffer.length) {
if (maxLength == 0) {
return 0;
}
throw new IllegalArgumentException("Illegal maxLength ("+maxLength+"), has to be positive number, and offset+maxLength can not exceed"+resultBuffer.length);
}
final CharArrayBase64Decoder dec = _base64Decoder();
int type = _currToken;
if (((1 << type) & MASK_TYPED_ACCESS_BINARY) == 0) {
if (type == END_ELEMENT) {
if (!dec.hasData()) {
return -1;
}
} else {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM_OR_TEXT);
}
} else if (type == START_ELEMENT) {
if (_scanner.isEmptyTag()) {
next();
return -1;
}
while (true) {
type = next();
if (type == END_ELEMENT) {
return -1;
}
if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
continue;
}
if (type == CHARACTERS || type == CDATA) {
break;
}
throw _constructUnexpectedInTyped(type);
}
_scanner.resetForDecoding(v, dec, true);
}
int totalCount = 0;
main_loop:
while (true) {
int count;
try {
count = dec.decode(resultBuffer, offset, maxLength);
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae.getMessage(), "");
}
offset += count;
totalCount += count;
maxLength -= count;
if (maxLength < 1 || _currToken == END_ELEMENT) {
break;
}
while (true) {
type = next();
if (type == COMMENT || type == PROCESSING_INSTRUCTION
|| type == SPACE) {
continue;
}
if (type == END_ELEMENT) {
int left = dec.endOfContent();
if (left < 0) {
throw _constructTypeException("Incomplete base64 triplet at the end of decoded content", "");
} else if (left > 0) {
continue main_loop;
}
break main_loop;
}
_scanner.resetForDecoding(v, dec, false);
break;
}
}
return (totalCount > 0) ? totalCount : -1;
}
@Override
public final int getAttributeIndex(String namespaceURI, String localName)
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
return findAttributeIndex(namespaceURI, localName);
}
@Override
public final boolean getAttributeAsBoolean(int index) throws XMLStreamException
{
ValueDecoderFactory.BooleanDecoder dec = _decoderFactory().getBooleanDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
@Override
public final int getAttributeAsInt(int index) throws XMLStreamException
{
ValueDecoderFactory.IntDecoder dec = _decoderFactory().getIntDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
@Override
public final long getAttributeAsLong(int index) throws XMLStreamException
{
ValueDecoderFactory.LongDecoder dec = _decoderFactory().getLongDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
@Override
public final float getAttributeAsFloat(int index) throws XMLStreamException
{
ValueDecoderFactory.FloatDecoder dec = _decoderFactory().getFloatDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
@Override
public final double getAttributeAsDouble(int index) throws XMLStreamException
{
ValueDecoderFactory.DoubleDecoder dec = _decoderFactory().getDoubleDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
@Override
public final BigInteger getAttributeAsInteger(int index) throws XMLStreamException
{
ValueDecoderFactory.IntegerDecoder dec = _decoderFactory().getIntegerDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
@Override
public final BigDecimal getAttributeAsDecimal(int index) throws XMLStreamException
{
ValueDecoderFactory.DecimalDecoder dec = _decoderFactory().getDecimalDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
@Override
public final QName getAttributeAsQName(int index) throws XMLStreamException
{
ValueDecoderFactory.QNameDecoder dec = _decoderFactory().getQNameDecoder(getNamespaceContext());
getAttributeAs(index, dec);
return verifyQName(dec.getValue());
}
@Override
public final void getAttributeAs(int index, TypedValueDecoder tvd)
throws XMLStreamException
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
try {
_scanner.decodeAttrValue(index, tvd);
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, getAttributeValue(index));
}
}
@Override
public final int[] getAttributeAsIntArray(int index) throws XMLStreamException
{
ValueDecoderFactory.IntArrayDecoder dec = _decoderFactory().getIntArrayDecoder();
getAttributeAsArray(index, dec);
return dec.getValues();
}
@Override
public final long[] getAttributeAsLongArray(int index) throws XMLStreamException
{
ValueDecoderFactory.LongArrayDecoder dec = _decoderFactory().getLongArrayDecoder();
getAttributeAsArray(index, dec);
return dec.getValues();
}
@Override
public final float[] getAttributeAsFloatArray(int index) throws XMLStreamException
{
ValueDecoderFactory.FloatArrayDecoder dec = _decoderFactory().getFloatArrayDecoder();
getAttributeAsArray(index, dec);
return dec.getValues();
}
@Override
public final double[] getAttributeAsDoubleArray(int index) throws XMLStreamException
{
ValueDecoderFactory.DoubleArrayDecoder dec = _decoderFactory().getDoubleArrayDecoder();
getAttributeAsArray(index, dec);
return dec.getValues();
}
@Override
public final int getAttributeAsArray(int index, TypedArrayDecoder tad) throws XMLStreamException
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
return _scanner.decodeAttrValues(index, tad);
}
@Override
public final byte[] getAttributeAsBinary(int index) throws XMLStreamException
{
return getAttributeAsBinary(index, Base64Variants.getDefaultVariant());
}
@Override
public final byte[] getAttributeAsBinary(int index, Base64Variant v) throws XMLStreamException
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
return _scanner.decodeAttrBinaryValue(index, v, _base64Decoder());
}
protected QName verifyQName(QName n)
throws TypedXMLStreamException
{
String ln = n.getLocalPart();
int ix = XmlNames.findIllegalNameChar(ln, false);
if (ix >= 0) {
String prefix = n.getPrefix();
String pname = (prefix != null && prefix.length() > 0) ?
(prefix + ":" +ln) : ln;
throw _constructTypeException("Invalid local name \""+ln+"\" (character at #"+ix+" is invalid)", pname);
}
return n;
}
@Deprecated
@Override
public final Object getFeature(String name) {
return null;
}
@Deprecated
@Override
public final void setFeature(String name, Object value) {
}
@Override
public final boolean isPropertySupported(String name) {
return _scanner.getConfig().isPropertySupported(name);
}
@Override
public final boolean setProperty(String name, Object value)
{
return _scanner.getConfig().setProperty(name, value);
}
@Override
public final void skipElement() throws XMLStreamException
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
int nesting = 1;
while (true) {
int type = next();
if (type == START_ELEMENT) {
++nesting;
} else if (type == END_ELEMENT) {
if (--nesting == 0) {
break;
}
}
}
}
@Override
public final AttributeInfo getAttributeInfo() throws XMLStreamException
{
if (_currToken != START_ELEMENT) {
throw new IllegalStateException(ErrorConsts.ERR_STATE_NOT_STELEM);
}
return this;
}
@Override
public final DTDInfo getDTDInfo() throws XMLStreamException
{
if (_currToken != DTD) {
return null;
}
return this;
}
@Override
public final LocationInfo getLocationInfo() {
return this;
}
@Override
public final int getText(Writer w, boolean preserveContents)
throws XMLStreamException
{
if (((1 << _currToken) & MASK_GET_TEXT_WITH_WRITER) == 0) {
throwNotTextual(_currToken);
}
return _scanner.getText(w, preserveContents);
}
@Override
public final int getDepth()
{
int d = _scanner.getDepth();
if (_currToken == END_ELEMENT) {
++d;
}
return d;
}
@Override
public final boolean isEmptyElement() throws XMLStreamException {
return (_currToken == START_ELEMENT) ? _scanner.isEmptyTag() : false;
}
@Override
public final NamespaceContext getNonTransientNamespaceContext() {
return _scanner.getNonTransientNamespaceContext();
}
@Override
public final String getPrefixedName()
{
switch (_currToken) {
case START_ELEMENT:
case END_ELEMENT:
return _currName.getPrefixedName();
case ENTITY_REFERENCE:
return getLocalName();
case PROCESSING_INSTRUCTION:
return getPITarget();
case DTD:
return getDTDRootName();
}
throw new IllegalStateException("Current state not START_ELEMENT, END_ELEMENT, ENTITY_REFERENCE, PROCESSING_INSTRUCTION or DTD");
}
@Override
public final void closeCompletely() throws XMLStreamException {
_closeScanner(true);
}
@Override
public final Object getProcessedDTD() {
return null;
}
@Override
public final String getDTDRootName() {
if (_currToken != DTD) {
return null;
}
return (_currName == null) ? null : _currName.getPrefixedName();
}
@Override
public final String getDTDPublicId()
{
return _scanner.getDTDPublicId();
}
@Override
public final String getDTDSystemId() {
return _scanner.getDTDSystemId();
}
@Override
public final String getDTDInternalSubset()
{
if (_currToken != DTD) {
return null;
}
try {
return _scanner.getText();
} catch (XMLStreamException sex) {
throw UncheckedStreamException.createFrom(sex);
}
}
@Override
public final DTDValidationSchema getProcessedDTDSchema() {
return null;
}
@Override
public final long getStartingByteOffset() {
return _scanner.getStartingByteOffset();
}
@Override
public final long getStartingCharOffset() {
return _scanner.getStartingCharOffset();
}
@Override
public final long getEndingByteOffset() throws XMLStreamException {
return _scanner.getEndingByteOffset();
}
@Override
public final long getEndingCharOffset() throws XMLStreamException {
return _scanner.getEndingCharOffset();
}
@Override
public final XMLStreamLocation2 getStartLocation() {
return _scanner.getStartLocation();
}
@Override
public final XMLStreamLocation2 getEndLocation() throws XMLStreamException {
return _scanner.getEndLocation();
}
@Override
public final XMLStreamLocation2 getCurrentLocation() {
return _scanner.getCurrentLocation();
}
@Override
public final int findAttributeIndex(String nsURI, String localName) {
return _scanner.findAttrIndex(nsURI, localName);
}
@Override
public final int getIdAttributeIndex() {
return -1;
}
@Override
public final int getNotationAttributeIndex()
{
return -1;
}
@Override
public final XMLValidator validateAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
return null;
}
@Override
public final XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
return null;
}
@Override
public final XMLValidator stopValidatingAgainst(XMLValidator validator)
throws XMLStreamException
{
return null;
}
@Override
public final ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
{
return null;
}
protected void _reportNonTextEvent(int type) throws XMLStreamException
{
throwWfe("Expected a text token, got "+ErrorConsts.tokenTypeDesc(type)+".");
}
protected Location getLastCharLocation()
{
return _scanner.getCurrentLocation();
}
protected int handlePrologEoi(boolean isProlog)
throws XMLStreamException
{
close();
if (isProlog) {
throwUnexpectedEOI(ErrorConsts.SUFFIX_IN_PROLOG);
}
return END_DOCUMENT;
}
protected void handleTreeEoi() throws XMLStreamException
{
_currToken = END_DOCUMENT;
throwUnexpectedEOI(ErrorConsts.SUFFIX_IN_TREE);
}
protected void throwWfe(String msg) throws XMLStreamException {
throw new WFCException(msg, getLastCharLocation());
}
private void throwNotTextual(int type) {
throw new IllegalStateException("Not a textual event ("
+ErrorConsts.tokenTypeDesc(_currToken)+")");
}
private void throwNotTextXxx(int type) {
throw new IllegalStateException("getTextXxx() methods can not be called on "
+ErrorConsts.tokenTypeDesc(_currToken));
}
protected void throwFromIOE(IOException ioe) throws XMLStreamException {
throw new IoStreamException(ioe);
}
protected void throwUnexpectedEOI(String msg) throws XMLStreamException
{
throwWfe("Unexpected End-of-input"+msg);
}
protected XMLStreamException _constructUnexpectedInTyped(int nextToken)
{
if (nextToken == START_ELEMENT) {
return _constructTypeException("Element content can not contain child START_ELEMENT when using Typed Access methods", null);
}
return _constructTypeException("Expected a text token, got "+ErrorConsts.tokenTypeDesc(nextToken), null);
}
private TypedXMLStreamException _constructTypeException(IllegalArgumentException iae, String lexicalValue)
{
return new TypedXMLStreamException(lexicalValue, iae.getMessage(), getStartLocation(), iae);
}
private TypedXMLStreamException _constructTypeException(String msg, String lexicalValue)
{
return new TypedXMLStreamException(lexicalValue, msg, getStartLocation());
}
protected void reportInvalidAttrIndex(int index)
{
throw new IllegalArgumentException("Illegal attribute index, "+index+", current START_ELEMENT has "+_attrCount+" attributes");
}
protected void _closeScanner(boolean forceStreamClose)
throws XMLStreamException
{
if (_parseState != STATE_CLOSED) {
_parseState = STATE_CLOSED;
if (_currToken != END_DOCUMENT) {
_currToken = END_DOCUMENT;
}
}
_scanner.close(forceStreamClose);
}
protected final ValueDecoderFactory _decoderFactory()
{
if (_decoderFactory == null) {
_decoderFactory = new ValueDecoderFactory();
}
return _decoderFactory;
}
protected CharArrayBase64Decoder _base64Decoder()
{
if (_base64Decoder == null) {
_base64Decoder = new CharArrayBase64Decoder();
}
return _base64Decoder;
}
private void _handleEmptyValue(TypedValueDecoder dec)
throws XMLStreamException
{
try {
dec.handleEmptyValue();
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, "");
}
}
@Override
public final String toString()
{
return "[Aalto stream reader, scanner: "+_scanner+"]";
}
}