0001: /*
0002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: *
0025: * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
0026: */
0027:
0028: /*
0029: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
0030: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0031: *
0032: * This code is free software; you can redistribute it and/or modify it
0033: * under the terms of the GNU General Public License version 2 only, as
0034: * published by the Free Software Foundation. Sun designates this
0035: * particular file as subject to the "Classpath" exception as provided
0036: * by Sun in the LICENSE file that accompanied this code.
0037: *
0038: * This code is distributed in the hope that it will be useful, but WITHOUT
0039: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0040: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0041: * version 2 for more details (a copy is included in the LICENSE file that
0042: * accompanied this code).
0043: *
0044: * You should have received a copy of the GNU General Public License version
0045: * 2 along with this work; if not, write to the Free Software Foundation,
0046: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0047: *
0048: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0049: * CA 95054 USA or visit www.sun.com if you need additional information or
0050: * have any questions.
0051: *
0052: * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
0053: *
0054: */
0055:
0056: package com.sun.xml.internal.fastinfoset.sax;
0057:
0058: import com.sun.xml.internal.fastinfoset.Decoder;
0059: import com.sun.xml.internal.fastinfoset.DecoderStateTables;
0060: import com.sun.xml.internal.fastinfoset.EncodingConstants;
0061: import com.sun.xml.internal.fastinfoset.QualifiedName;
0062: import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
0063: import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmState;
0064: import com.sun.xml.internal.org.jvnet.fastinfoset.sax.EncodingAlgorithmContentHandler;
0065: import com.sun.xml.internal.org.jvnet.fastinfoset.sax.FastInfosetReader;
0066: import com.sun.xml.internal.org.jvnet.fastinfoset.sax.PrimitiveTypeContentHandler;
0067: import com.sun.xml.internal.fastinfoset.util.CharArray;
0068: import com.sun.xml.internal.fastinfoset.util.CharArrayString;
0069: import java.io.IOException;
0070: import java.io.InputStream;
0071: import java.net.URL;
0072: import java.util.Map;
0073: import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithm;
0074: import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException;
0075: import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
0076: import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
0077: import org.xml.sax.ContentHandler;
0078: import org.xml.sax.DTDHandler;
0079: import org.xml.sax.EntityResolver;
0080: import org.xml.sax.ErrorHandler;
0081: import org.xml.sax.InputSource;
0082: import org.xml.sax.SAXException;
0083: import org.xml.sax.SAXNotRecognizedException;
0084: import org.xml.sax.SAXNotSupportedException;
0085: import org.xml.sax.SAXParseException;
0086: import org.xml.sax.ext.LexicalHandler;
0087: import org.xml.sax.helpers.DefaultHandler;
0088: import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
0089: import org.xml.sax.ext.DeclHandler;
0090:
0091: /**
0092: * The Fast Infoset SAX parser.
0093: * <p>
0094: * Instantiate this parser to parse a fast infoset document in accordance
0095: * with the SAX API.
0096: *
0097: * <p>
0098: * More than one fast infoset document may be decoded from the
0099: * {@link java.io.InputStream}.
0100: */
0101: public class SAXDocumentParser extends Decoder implements
0102: FastInfosetReader {
0103:
0104: /*
0105: * Empty lexical handler used by default to report
0106: * lexical-based events
0107: */
0108: private static final class LexicalHandlerImpl implements
0109: LexicalHandler {
0110: public void comment(char[] ch, int start, int end) {
0111: }
0112:
0113: public void startDTD(String name, String publicId,
0114: String systemId) {
0115: }
0116:
0117: public void endDTD() {
0118: }
0119:
0120: public void startEntity(String name) {
0121: }
0122:
0123: public void endEntity(String name) {
0124: }
0125:
0126: public void startCDATA() {
0127: }
0128:
0129: public void endCDATA() {
0130: }
0131: };
0132:
0133: /*
0134: * Empty DTD declaration handler used by default to report
0135: * DTD declaration-based events
0136: */
0137: private static final class DeclHandlerImpl implements DeclHandler {
0138: public void elementDecl(String name, String model)
0139: throws SAXException {
0140: }
0141:
0142: public void attributeDecl(String eName, String aName,
0143: String type, String mode, String value)
0144: throws SAXException {
0145: }
0146:
0147: public void internalEntityDecl(String name, String value)
0148: throws SAXException {
0149: }
0150:
0151: public void externalEntityDecl(String name, String publicId,
0152: String systemId) throws SAXException {
0153: }
0154: }
0155:
0156: /**
0157: * SAX Namespace attributes features
0158: */
0159: protected boolean _namespacePrefixesFeature = false;
0160:
0161: /**
0162: * Reference to entity resolver.
0163: */
0164: protected EntityResolver _entityResolver;
0165:
0166: /**
0167: * Reference to dtd handler.
0168: */
0169: protected DTDHandler _dtdHandler;
0170:
0171: /**
0172: * Reference to content handler.
0173: */
0174: protected ContentHandler _contentHandler;
0175:
0176: /**
0177: * Reference to error handler.
0178: */
0179: protected ErrorHandler _errorHandler;
0180:
0181: /**
0182: * Reference to lexical handler.
0183: */
0184: protected LexicalHandler _lexicalHandler;
0185:
0186: /**
0187: * Reference to DTD declaration handler.
0188: */
0189: protected DeclHandler _declHandler;
0190:
0191: protected EncodingAlgorithmContentHandler _algorithmHandler;
0192:
0193: protected PrimitiveTypeContentHandler _primitiveHandler;
0194:
0195: protected BuiltInEncodingAlgorithmState builtInAlgorithmState = new BuiltInEncodingAlgorithmState();
0196:
0197: protected AttributesHolder _attributes;
0198:
0199: protected int[] _namespacePrefixes = new int[16];
0200:
0201: protected int _namespacePrefixesIndex;
0202:
0203: protected boolean _clearAttributes = false;
0204:
0205: /** Creates a new instance of DocumetParser2 */
0206: public SAXDocumentParser() {
0207: DefaultHandler handler = new DefaultHandler();
0208: _attributes = new AttributesHolder(
0209: _registeredEncodingAlgorithms);
0210:
0211: _entityResolver = handler;
0212: _dtdHandler = handler;
0213: _contentHandler = handler;
0214: _errorHandler = handler;
0215: _lexicalHandler = new LexicalHandlerImpl();
0216: _declHandler = new DeclHandlerImpl();
0217: }
0218:
0219: protected void resetOnError() {
0220: _clearAttributes = false;
0221: _attributes.clear();
0222: _namespacePrefixesIndex = 0;
0223:
0224: if (_v != null) {
0225: _v.prefix.clearCompletely();
0226: }
0227: _duplicateAttributeVerifier.clear();
0228: }
0229:
0230: // XMLReader interface
0231:
0232: public boolean getFeature(String name)
0233: throws SAXNotRecognizedException, SAXNotSupportedException {
0234: if (name.equals(Features.NAMESPACES_FEATURE)) {
0235: return true;
0236: } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
0237: return _namespacePrefixesFeature;
0238: } else if (name.equals(Features.STRING_INTERNING_FEATURE)
0239: || name
0240: .equals(FastInfosetReader.STRING_INTERNING_PROPERTY)) {
0241: return getStringInterning();
0242: } else {
0243: throw new SAXNotRecognizedException(CommonResourceBundle
0244: .getInstance().getString(
0245: "message.featureNotSupported")
0246: + name);
0247: }
0248: }
0249:
0250: public void setFeature(String name, boolean value)
0251: throws SAXNotRecognizedException, SAXNotSupportedException {
0252: if (name.equals(Features.NAMESPACES_FEATURE)) {
0253: if (value == false) {
0254: throw new SAXNotSupportedException(name + ":" + value);
0255: }
0256: } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
0257: _namespacePrefixesFeature = value;
0258: } else if (name.equals(Features.STRING_INTERNING_FEATURE)
0259: || name
0260: .equals(FastInfosetReader.STRING_INTERNING_PROPERTY)) {
0261: setStringInterning(value);
0262: } else {
0263: throw new SAXNotRecognizedException(CommonResourceBundle
0264: .getInstance().getString(
0265: "message.featureNotSupported")
0266: + name);
0267: }
0268: }
0269:
0270: public Object getProperty(String name)
0271: throws SAXNotRecognizedException, SAXNotSupportedException {
0272: if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
0273: return getLexicalHandler();
0274: } else if (name
0275: .equals(Properties.DTD_DECLARATION_HANDLER_PROPERTY)) {
0276: return getDeclHandler();
0277: } else if (name
0278: .equals(FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY)) {
0279: return getExternalVocabularies();
0280: } else if (name
0281: .equals(FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY)) {
0282: return getRegisteredEncodingAlgorithms();
0283: } else if (name
0284: .equals(FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY)) {
0285: return getEncodingAlgorithmContentHandler();
0286: } else if (name
0287: .equals(FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY)) {
0288: return getPrimitiveTypeContentHandler();
0289: } else {
0290: throw new SAXNotRecognizedException(CommonResourceBundle
0291: .getInstance().getString(
0292: "message.propertyNotRecognized",
0293: new Object[] { name }));
0294: }
0295: }
0296:
0297: public void setProperty(String name, Object value)
0298: throws SAXNotRecognizedException, SAXNotSupportedException {
0299: if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
0300: if (value instanceof LexicalHandler) {
0301: setLexicalHandler((LexicalHandler) value);
0302: } else {
0303: throw new SAXNotSupportedException(
0304: Properties.LEXICAL_HANDLER_PROPERTY);
0305: }
0306: } else if (name
0307: .equals(Properties.DTD_DECLARATION_HANDLER_PROPERTY)) {
0308: if (value instanceof DeclHandler) {
0309: setDeclHandler((DeclHandler) value);
0310: } else {
0311: throw new SAXNotSupportedException(
0312: Properties.LEXICAL_HANDLER_PROPERTY);
0313: }
0314: } else if (name
0315: .equals(FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY)) {
0316: if (value instanceof Map) {
0317: setExternalVocabularies((Map) value);
0318: } else {
0319: throw new SAXNotSupportedException(
0320: FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY);
0321: }
0322: } else if (name
0323: .equals(FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY)) {
0324: if (value instanceof Map) {
0325: setRegisteredEncodingAlgorithms((Map) value);
0326: } else {
0327: throw new SAXNotSupportedException(
0328: FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY);
0329: }
0330: } else if (name
0331: .equals(FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY)) {
0332: if (value instanceof EncodingAlgorithmContentHandler) {
0333: setEncodingAlgorithmContentHandler((EncodingAlgorithmContentHandler) value);
0334: } else {
0335: throw new SAXNotSupportedException(
0336: FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY);
0337: }
0338: } else if (name
0339: .equals(FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY)) {
0340: if (value instanceof PrimitiveTypeContentHandler) {
0341: setPrimitiveTypeContentHandler((PrimitiveTypeContentHandler) value);
0342: } else {
0343: throw new SAXNotSupportedException(
0344: FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY);
0345: }
0346: } else if (name.equals(FastInfosetReader.BUFFER_SIZE_PROPERTY)) {
0347: if (value instanceof Integer) {
0348: setBufferSize(((Integer) value).intValue());
0349: } else {
0350: throw new SAXNotSupportedException(
0351: FastInfosetReader.BUFFER_SIZE_PROPERTY);
0352: }
0353: } else {
0354: throw new SAXNotRecognizedException(CommonResourceBundle
0355: .getInstance().getString(
0356: "message.propertyNotRecognized",
0357: new Object[] { name }));
0358: }
0359: }
0360:
0361: public void setEntityResolver(EntityResolver resolver) {
0362: _entityResolver = resolver;
0363: }
0364:
0365: public EntityResolver getEntityResolver() {
0366: return _entityResolver;
0367: }
0368:
0369: public void setDTDHandler(DTDHandler handler) {
0370: _dtdHandler = handler;
0371: }
0372:
0373: public DTDHandler getDTDHandler() {
0374: return _dtdHandler;
0375: }
0376:
0377: public void setContentHandler(ContentHandler handler) {
0378: _contentHandler = handler;
0379: }
0380:
0381: public ContentHandler getContentHandler() {
0382: return _contentHandler;
0383: }
0384:
0385: public void setErrorHandler(ErrorHandler handler) {
0386: _errorHandler = handler;
0387: }
0388:
0389: public ErrorHandler getErrorHandler() {
0390: return _errorHandler;
0391: }
0392:
0393: public void parse(InputSource input) throws IOException,
0394: SAXException {
0395: try {
0396: InputStream s = input.getByteStream();
0397: if (s == null) {
0398: String systemId = input.getSystemId();
0399: if (systemId == null) {
0400: throw new SAXException(CommonResourceBundle
0401: .getInstance().getString(
0402: "message.inputSource"));
0403: }
0404: parse(systemId);
0405: } else {
0406: parse(s);
0407: }
0408: } catch (FastInfosetException e) {
0409: e.printStackTrace();
0410: throw new SAXException(e);
0411: }
0412: }
0413:
0414: public void parse(String systemId) throws IOException, SAXException {
0415: try {
0416: systemId = SystemIdResolver.getAbsoluteURI(systemId);
0417: parse(new URL(systemId).openStream());
0418: } catch (FastInfosetException e) {
0419: e.printStackTrace();
0420: throw new SAXException(e);
0421: }
0422: }
0423:
0424: // FastInfosetReader
0425:
0426: public final void parse(InputStream s) throws IOException,
0427: FastInfosetException, SAXException {
0428: setInputStream(s);
0429: parse();
0430: }
0431:
0432: public void setLexicalHandler(LexicalHandler handler) {
0433: _lexicalHandler = handler;
0434: }
0435:
0436: public LexicalHandler getLexicalHandler() {
0437: return _lexicalHandler;
0438: }
0439:
0440: public void setDeclHandler(DeclHandler handler) {
0441: _declHandler = handler;
0442: }
0443:
0444: public DeclHandler getDeclHandler() {
0445: return _declHandler;
0446: }
0447:
0448: public void setEncodingAlgorithmContentHandler(
0449: EncodingAlgorithmContentHandler handler) {
0450: _algorithmHandler = handler;
0451: }
0452:
0453: public EncodingAlgorithmContentHandler getEncodingAlgorithmContentHandler() {
0454: return _algorithmHandler;
0455: }
0456:
0457: public void setPrimitiveTypeContentHandler(
0458: PrimitiveTypeContentHandler handler) {
0459: _primitiveHandler = handler;
0460: }
0461:
0462: public PrimitiveTypeContentHandler getPrimitiveTypeContentHandler() {
0463: return _primitiveHandler;
0464: }
0465:
0466: public final void parse() throws FastInfosetException, IOException {
0467: if (_octetBuffer.length < _bufferSize) {
0468: _octetBuffer = new byte[_bufferSize];
0469: }
0470:
0471: try {
0472: reset();
0473: decodeHeader();
0474: processDII();
0475: } catch (RuntimeException e) {
0476: try {
0477: _errorHandler.fatalError(new SAXParseException(e
0478: .getClass().getName(), null, e));
0479: } catch (Exception ee) {
0480: }
0481: resetOnError();
0482: // Wrap runtime exception
0483: throw new FastInfosetException(e);
0484: } catch (FastInfosetException e) {
0485: try {
0486: _errorHandler.fatalError(new SAXParseException(e
0487: .getClass().getName(), null, e));
0488: } catch (Exception ee) {
0489: }
0490: resetOnError();
0491: throw e;
0492: } catch (IOException e) {
0493: try {
0494: _errorHandler.fatalError(new SAXParseException(e
0495: .getClass().getName(), null, e));
0496: } catch (Exception ee) {
0497: }
0498: resetOnError();
0499: throw e;
0500: }
0501: }
0502:
0503: protected final void processDII() throws FastInfosetException,
0504: IOException {
0505: try {
0506: _contentHandler.startDocument();
0507: } catch (SAXException e) {
0508: throw new FastInfosetException("processDII", e);
0509: }
0510:
0511: _b = read();
0512: if (_b > 0) {
0513: processDIIOptionalProperties();
0514: }
0515:
0516: // Decode one Document Type II, Comment IIs, PI IIs and one EII
0517: boolean firstElementHasOccured = false;
0518: boolean documentTypeDeclarationOccured = false;
0519: while (!_terminate || !firstElementHasOccured) {
0520: _b = read();
0521: switch (DecoderStateTables.DII[_b]) {
0522: case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
0523: processEII(_elementNameTable._array[_b], false);
0524: firstElementHasOccured = true;
0525: break;
0526: case DecoderStateTables.EII_AIIS_INDEX_SMALL:
0527: processEII(
0528: _elementNameTable._array[_b
0529: & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK],
0530: true);
0531: firstElementHasOccured = true;
0532: break;
0533: case DecoderStateTables.EII_INDEX_MEDIUM:
0534: processEII(
0535: decodeEIIIndexMedium(),
0536: (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
0537: firstElementHasOccured = true;
0538: break;
0539: case DecoderStateTables.EII_INDEX_LARGE:
0540: processEII(
0541: decodeEIIIndexLarge(),
0542: (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
0543: firstElementHasOccured = true;
0544: break;
0545: case DecoderStateTables.EII_LITERAL: {
0546: final QualifiedName qn = decodeLiteralQualifiedName(_b
0547: & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
0548: _elementNameTable.add(qn);
0549: processEII(
0550: qn,
0551: (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
0552: firstElementHasOccured = true;
0553: break;
0554: }
0555: case DecoderStateTables.EII_NAMESPACES:
0556: processEIIWithNamespaces();
0557: firstElementHasOccured = true;
0558: break;
0559: case DecoderStateTables.DOCUMENT_TYPE_DECLARATION_II: {
0560: if (documentTypeDeclarationOccured) {
0561: throw new FastInfosetException(CommonResourceBundle
0562: .getInstance().getString(
0563: "message.secondOccurenceOfDTDII"));
0564: }
0565: documentTypeDeclarationOccured = true;
0566:
0567: String system_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_SYSTEM_IDENTIFIER_FLAG) > 0) ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI)
0568: : "";
0569: String public_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_PUBLIC_IDENTIFIER_FLAG) > 0) ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI)
0570: : "";
0571:
0572: _b = read();
0573: while (_b == EncodingConstants.PROCESSING_INSTRUCTION) {
0574: switch (decodeNonIdentifyingStringOnFirstBit()) {
0575: case NISTRING_STRING:
0576: final String data = new String(_charBuffer, 0,
0577: _charBufferLength);
0578: if (_addToTable) {
0579: _v.otherString.add(new CharArray(
0580: _charBuffer, 0, _charBufferLength,
0581: true));
0582: }
0583: break;
0584: case NISTRING_ENCODING_ALGORITHM:
0585: throw new FastInfosetException(
0586: CommonResourceBundle
0587: .getInstance()
0588: .getString(
0589: "message.processingIIWithEncodingAlgorithm"));
0590: case NISTRING_INDEX:
0591: break;
0592: case NISTRING_EMPTY_STRING:
0593: break;
0594: }
0595: _b = read();
0596: }
0597: if ((_b & EncodingConstants.TERMINATOR) != EncodingConstants.TERMINATOR) {
0598: throw new FastInfosetException(
0599: CommonResourceBundle
0600: .getInstance()
0601: .getString(
0602: "message.processingInstructionIIsNotTerminatedCorrectly"));
0603: }
0604: if (_b == EncodingConstants.DOUBLE_TERMINATOR) {
0605: _terminate = true;
0606: }
0607:
0608: _notations.clear();
0609: _unparsedEntities.clear();
0610: /*
0611: * TODO
0612: * Report All events associated with DTD, PIs, notations etc
0613: */
0614: break;
0615: }
0616: case DecoderStateTables.COMMENT_II:
0617: processCommentII();
0618: break;
0619: case DecoderStateTables.PROCESSING_INSTRUCTION_II:
0620: processProcessingII();
0621: break;
0622: case DecoderStateTables.TERMINATOR_DOUBLE:
0623: _doubleTerminate = true;
0624: case DecoderStateTables.TERMINATOR_SINGLE:
0625: _terminate = true;
0626: break;
0627: default:
0628: throw new FastInfosetException(CommonResourceBundle
0629: .getInstance().getString(
0630: "message.IllegalStateDecodingDII"));
0631: }
0632: }
0633:
0634: // Decode any remaining Comment IIs, PI IIs
0635: while (!_terminate) {
0636: _b = read();
0637: switch (DecoderStateTables.DII[_b]) {
0638: case DecoderStateTables.COMMENT_II:
0639: processCommentII();
0640: break;
0641: case DecoderStateTables.PROCESSING_INSTRUCTION_II:
0642: processProcessingII();
0643: break;
0644: case DecoderStateTables.TERMINATOR_DOUBLE:
0645: _doubleTerminate = true;
0646: case DecoderStateTables.TERMINATOR_SINGLE:
0647: _terminate = true;
0648: break;
0649: default:
0650: throw new FastInfosetException(CommonResourceBundle
0651: .getInstance().getString(
0652: "message.IllegalStateDecodingDII"));
0653: }
0654: }
0655:
0656: try {
0657: _contentHandler.endDocument();
0658: } catch (SAXException e) {
0659: throw new FastInfosetException("processDII", e);
0660: }
0661: }
0662:
0663: protected final void processDIIOptionalProperties()
0664: throws FastInfosetException, IOException {
0665: // Optimize for the most common case
0666: if (_b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) {
0667: decodeInitialVocabulary();
0668: return;
0669: }
0670:
0671: if ((_b & EncodingConstants.DOCUMENT_ADDITIONAL_DATA_FLAG) > 0) {
0672: decodeAdditionalData();
0673: /*
0674: * TODO
0675: * how to report the additional data?
0676: */
0677: }
0678:
0679: if ((_b & EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) > 0) {
0680: decodeInitialVocabulary();
0681: }
0682:
0683: if ((_b & EncodingConstants.DOCUMENT_NOTATIONS_FLAG) > 0) {
0684: decodeNotations();
0685: /*
0686: try {
0687: _dtdHandler.notationDecl(name, public_identifier, system_identifier);
0688: } catch (SAXException e) {
0689: throw new IOException("NotationsDeclarationII");
0690: }
0691: */
0692: }
0693:
0694: if ((_b & EncodingConstants.DOCUMENT_UNPARSED_ENTITIES_FLAG) > 0) {
0695: decodeUnparsedEntities();
0696: /*
0697: try {
0698: _dtdHandler.unparsedEntityDecl(name, public_identifier, system_identifier, notation_name);
0699: } catch (SAXException e) {
0700: throw new IOException("UnparsedEntitiesII");
0701: }
0702: */
0703: }
0704:
0705: if ((_b & EncodingConstants.DOCUMENT_CHARACTER_ENCODING_SCHEME) > 0) {
0706: String characterEncodingScheme = decodeCharacterEncodingScheme();
0707: /*
0708: * TODO
0709: * how to report the character encoding scheme?
0710: */
0711: }
0712:
0713: if ((_b & EncodingConstants.DOCUMENT_STANDALONE_FLAG) > 0) {
0714: boolean standalone = (read() > 0) ? true : false;
0715: /*
0716: * TODO
0717: * how to report the standalone flag?
0718: */
0719: }
0720:
0721: if ((_b & EncodingConstants.DOCUMENT_VERSION_FLAG) > 0) {
0722: String version = decodeVersion();
0723: /*
0724: * TODO
0725: * how to report the standalone flag?
0726: */
0727: }
0728: }
0729:
0730: protected final void processEII(QualifiedName name,
0731: boolean hasAttributes) throws FastInfosetException,
0732: IOException {
0733: if (_prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
0734: throw new FastInfosetException(CommonResourceBundle
0735: .getInstance().getString(
0736: "message.qNameOfEIINotInScope"));
0737: }
0738:
0739: if (hasAttributes) {
0740: processAIIs();
0741: }
0742:
0743: try {
0744: _contentHandler.startElement(name.namespaceName,
0745: name.localName, name.qName, _attributes);
0746: } catch (SAXException e) {
0747: e.printStackTrace();
0748: throw new FastInfosetException("processEII", e);
0749: }
0750:
0751: if (_clearAttributes) {
0752: _attributes.clear();
0753: _clearAttributes = false;
0754: }
0755:
0756: while (!_terminate) {
0757: _b = read();
0758: switch (DecoderStateTables.EII[_b]) {
0759: case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
0760: processEII(_elementNameTable._array[_b], false);
0761: break;
0762: case DecoderStateTables.EII_AIIS_INDEX_SMALL:
0763: processEII(
0764: _elementNameTable._array[_b
0765: & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK],
0766: true);
0767: break;
0768: case DecoderStateTables.EII_INDEX_MEDIUM:
0769: processEII(
0770: decodeEIIIndexMedium(),
0771: (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
0772: break;
0773: case DecoderStateTables.EII_INDEX_LARGE:
0774: processEII(
0775: decodeEIIIndexLarge(),
0776: (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
0777: break;
0778: case DecoderStateTables.EII_LITERAL: {
0779: final QualifiedName qn = decodeLiteralQualifiedName(_b
0780: & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
0781: _elementNameTable.add(qn);
0782: processEII(
0783: qn,
0784: (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
0785: break;
0786: }
0787: case DecoderStateTables.EII_NAMESPACES:
0788: processEIIWithNamespaces();
0789: break;
0790: case DecoderStateTables.CII_UTF8_SMALL_LENGTH:
0791: _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK) + 1;
0792: decodeUtf8StringAsCharBuffer();
0793: if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
0794: _characterContentChunkTable.add(_charBuffer,
0795: _charBufferLength);
0796: }
0797:
0798: try {
0799: _contentHandler.characters(_charBuffer, 0,
0800: _charBufferLength);
0801: } catch (SAXException e) {
0802: throw new FastInfosetException("processCII", e);
0803: }
0804: break;
0805: case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH:
0806: _octetBufferLength = read()
0807: + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
0808: decodeUtf8StringAsCharBuffer();
0809: if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
0810: _characterContentChunkTable.add(_charBuffer,
0811: _charBufferLength);
0812: }
0813:
0814: try {
0815: _contentHandler.characters(_charBuffer, 0,
0816: _charBufferLength);
0817: } catch (SAXException e) {
0818: throw new FastInfosetException("processCII", e);
0819: }
0820: break;
0821: case DecoderStateTables.CII_UTF8_LARGE_LENGTH:
0822: _octetBufferLength = ((read() << 24) | (read() << 16)
0823: | (read() << 8) | read())
0824: + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
0825: decodeUtf8StringAsCharBuffer();
0826: if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
0827: _characterContentChunkTable.add(_charBuffer,
0828: _charBufferLength);
0829: }
0830:
0831: try {
0832: _contentHandler.characters(_charBuffer, 0,
0833: _charBufferLength);
0834: } catch (SAXException e) {
0835: throw new FastInfosetException("processCII", e);
0836: }
0837: break;
0838: case DecoderStateTables.CII_UTF16_SMALL_LENGTH:
0839: _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK) + 1;
0840: decodeUtf16StringAsCharBuffer();
0841: if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
0842: _characterContentChunkTable.add(_charBuffer,
0843: _charBufferLength);
0844: }
0845:
0846: try {
0847: _contentHandler.characters(_charBuffer, 0,
0848: _charBufferLength);
0849: } catch (SAXException e) {
0850: throw new FastInfosetException("processCII", e);
0851: }
0852: break;
0853: case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH:
0854: _octetBufferLength = read()
0855: + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
0856: decodeUtf16StringAsCharBuffer();
0857: if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
0858: _characterContentChunkTable.add(_charBuffer,
0859: _charBufferLength);
0860: }
0861:
0862: try {
0863: _contentHandler.characters(_charBuffer, 0,
0864: _charBufferLength);
0865: } catch (SAXException e) {
0866: throw new FastInfosetException("processCII", e);
0867: }
0868: break;
0869: case DecoderStateTables.CII_UTF16_LARGE_LENGTH:
0870: _octetBufferLength = ((read() << 24) | (read() << 16)
0871: | (read() << 8) | read())
0872: + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
0873: decodeUtf16StringAsCharBuffer();
0874: if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
0875: _characterContentChunkTable.add(_charBuffer,
0876: _charBufferLength);
0877: }
0878:
0879: try {
0880: _contentHandler.characters(_charBuffer, 0,
0881: _charBufferLength);
0882: } catch (SAXException e) {
0883: throw new FastInfosetException("processCII", e);
0884: }
0885: break;
0886: case DecoderStateTables.CII_RA: {
0887: final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
0888:
0889: // Decode resitricted alphabet integer
0890: _identifier = (_b & 0x02) << 6;
0891: _b = read();
0892: _identifier |= (_b & 0xFC) >> 2;
0893:
0894: decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
0895:
0896: decodeRestrictedAlphabetAsCharBuffer();
0897:
0898: if (addToTable) {
0899: _characterContentChunkTable.add(_charBuffer,
0900: _charBufferLength);
0901: }
0902:
0903: try {
0904: _contentHandler.characters(_charBuffer, 0,
0905: _charBufferLength);
0906: } catch (SAXException e) {
0907: throw new FastInfosetException("processCII", e);
0908: }
0909: break;
0910: }
0911: case DecoderStateTables.CII_EA: {
0912: if ((_b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
0913: throw new EncodingAlgorithmException(
0914: CommonResourceBundle
0915: .getInstance()
0916: .getString(
0917: "message.addToTableNotSupported"));
0918: }
0919:
0920: // Decode encoding algorithm integer
0921: _identifier = (_b & 0x02) << 6;
0922: _b = read();
0923: _identifier |= (_b & 0xFC) >> 2;
0924:
0925: decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
0926:
0927: processCIIEncodingAlgorithm();
0928: break;
0929: }
0930: case DecoderStateTables.CII_INDEX_SMALL: {
0931: final int index = _b
0932: & EncodingConstants.INTEGER_4TH_BIT_SMALL_MASK;
0933: try {
0934: _contentHandler.characters(
0935: _characterContentChunkTable._array,
0936: _characterContentChunkTable._offset[index],
0937: _characterContentChunkTable._length[index]);
0938: } catch (SAXException e) {
0939: throw new FastInfosetException("processCII", e);
0940: }
0941: break;
0942: }
0943: case DecoderStateTables.CII_INDEX_MEDIUM: {
0944: final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_MEDIUM_MASK) << 8) | read())
0945: + EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT;
0946: try {
0947: _contentHandler.characters(
0948: _characterContentChunkTable._array,
0949: _characterContentChunkTable._offset[index],
0950: _characterContentChunkTable._length[index]);
0951: } catch (SAXException e) {
0952: throw new FastInfosetException("processCII", e);
0953: }
0954: break;
0955: }
0956: case DecoderStateTables.CII_INDEX_LARGE: {
0957: final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_LARGE_MASK) << 16)
0958: | (read() << 8) | read())
0959: + EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT;
0960:
0961: try {
0962: _contentHandler.characters(
0963: _characterContentChunkTable._array,
0964: _characterContentChunkTable._offset[index],
0965: _characterContentChunkTable._length[index]);
0966: } catch (SAXException e) {
0967: throw new FastInfosetException("processCII", e);
0968: }
0969: break;
0970: }
0971: case DecoderStateTables.CII_INDEX_LARGE_LARGE: {
0972: final int index = ((read() << 16) | (read() << 8) | read())
0973: + EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT;
0974:
0975: try {
0976: _contentHandler.characters(
0977: _characterContentChunkTable._array,
0978: _characterContentChunkTable._offset[index],
0979: _characterContentChunkTable._length[index]);
0980: } catch (SAXException e) {
0981: throw new FastInfosetException("processCII", e);
0982: }
0983: break;
0984: }
0985: case DecoderStateTables.COMMENT_II:
0986: processCommentII();
0987: break;
0988: case DecoderStateTables.PROCESSING_INSTRUCTION_II:
0989: processProcessingII();
0990: break;
0991: case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II: {
0992: String entity_reference_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
0993:
0994: String system_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_SYSTEM_IDENTIFIER_FLAG) > 0) ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI)
0995: : "";
0996: String public_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_PUBLIC_IDENTIFIER_FLAG) > 0) ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI)
0997: : "";
0998:
0999: try {
1000: /*
1001: * TODO
1002: * Need to verify if the skippedEntity method:
1003: * http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#skippedEntity(java.lang.String)
1004: * is the correct method to call. It appears so but a more extensive
1005: * check is necessary.
1006: */
1007: _contentHandler
1008: .skippedEntity(entity_reference_name);
1009: } catch (SAXException e) {
1010: throw new FastInfosetException(
1011: "processUnexpandedEntityReferenceII", e);
1012: }
1013: break;
1014: }
1015: case DecoderStateTables.TERMINATOR_DOUBLE:
1016: _doubleTerminate = true;
1017: case DecoderStateTables.TERMINATOR_SINGLE:
1018: _terminate = true;
1019: break;
1020: default:
1021: throw new FastInfosetException(CommonResourceBundle
1022: .getInstance().getString(
1023: "message.IllegalStateDecodingEII"));
1024: }
1025: }
1026:
1027: _terminate = _doubleTerminate;
1028: _doubleTerminate = false;
1029:
1030: try {
1031: _contentHandler.endElement(name.namespaceName,
1032: name.localName, name.qName);
1033: } catch (SAXException e) {
1034: throw new FastInfosetException("processEII", e);
1035: }
1036: }
1037:
1038: protected final void processEIIWithNamespaces()
1039: throws FastInfosetException, IOException {
1040: final boolean hasAttributes = (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0;
1041:
1042: _clearAttributes = (_namespacePrefixesFeature) ? true : false;
1043:
1044: if (++_prefixTable._declarationId == Integer.MAX_VALUE) {
1045: _prefixTable.clearDeclarationIds();
1046: }
1047:
1048: String prefix = "", namespaceName = "";
1049: final int start = _namespacePrefixesIndex;
1050: int b = read();
1051: while ((b & EncodingConstants.NAMESPACE_ATTRIBUTE_MASK) == EncodingConstants.NAMESPACE_ATTRIBUTE) {
1052: if (_namespacePrefixesIndex == _namespacePrefixes.length) {
1053: final int[] namespaceAIIs = new int[_namespacePrefixesIndex * 3 / 2 + 1];
1054: System.arraycopy(_namespacePrefixes, 0, namespaceAIIs,
1055: 0, _namespacePrefixesIndex);
1056: _namespacePrefixes = namespaceAIIs;
1057: }
1058:
1059: switch (b
1060: & EncodingConstants.NAMESPACE_ATTRIBUTE_PREFIX_NAME_MASK) {
1061: // no prefix, no namespace
1062: // Undeclaration of default namespace
1063: case 0:
1064: prefix = namespaceName = "";
1065: _namespaceNameIndex = _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
1066: break;
1067: // no prefix, namespace
1068: // Declaration of default namespace
1069: case 1:
1070: prefix = "";
1071: namespaceName = decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(false);
1072:
1073: _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
1074: break;
1075: // prefix, no namespace
1076: // Undeclaration of namespace
1077: case 2:
1078: prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(false);
1079: namespaceName = "";
1080:
1081: _namespaceNameIndex = -1;
1082: _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
1083: break;
1084: // prefix, namespace
1085: // Declaration of prefixed namespace
1086: case 3:
1087: prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(true);
1088: namespaceName = decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(true);
1089:
1090: _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
1091: break;
1092: }
1093:
1094: _prefixTable.pushScope(_prefixIndex, _namespaceNameIndex);
1095:
1096: if (_namespacePrefixesFeature) {
1097: // Add the namespace delcaration as an attribute
1098: if (prefix != "") {
1099: _attributes.addAttribute(new QualifiedName(
1100: EncodingConstants.XMLNS_NAMESPACE_PREFIX,
1101: EncodingConstants.XMLNS_NAMESPACE_NAME,
1102: prefix), namespaceName);
1103: } else {
1104: _attributes
1105: .addAttribute(
1106: EncodingConstants.DEFAULT_NAMESPACE_DECLARATION,
1107: namespaceName);
1108: }
1109: }
1110:
1111: try {
1112: _contentHandler.startPrefixMapping(prefix,
1113: namespaceName);
1114: } catch (SAXException e) {
1115: throw new IOException("processStartNamespaceAII");
1116: }
1117:
1118: b = read();
1119: }
1120: if (b != EncodingConstants.TERMINATOR) {
1121: throw new IOException(
1122: CommonResourceBundle
1123: .getInstance()
1124: .getString(
1125: "message.EIInamespaceNameNotTerminatedCorrectly"));
1126: }
1127: final int end = _namespacePrefixesIndex;
1128:
1129: _b = read();
1130: switch (DecoderStateTables.EII[_b]) {
1131: case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
1132: processEII(_elementNameTable._array[_b], hasAttributes);
1133: break;
1134: case DecoderStateTables.EII_INDEX_MEDIUM:
1135: processEII(decodeEIIIndexMedium(), hasAttributes);
1136: break;
1137: case DecoderStateTables.EII_INDEX_LARGE:
1138: processEII(decodeEIIIndexLarge(), hasAttributes);
1139: break;
1140: case DecoderStateTables.EII_LITERAL: {
1141: final QualifiedName qn = decodeLiteralQualifiedName(_b
1142: & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
1143: _elementNameTable.add(qn);
1144: processEII(qn, hasAttributes);
1145: break;
1146: }
1147: default:
1148: throw new IOException(CommonResourceBundle.getInstance()
1149: .getString(
1150: "message.IllegalStateDecodingEIIAfterAIIs"));
1151: }
1152:
1153: try {
1154: for (int i = end - 1; i >= start; i--) {
1155: final int prefixIndex = _namespacePrefixes[i];
1156: _prefixTable.popScope(prefixIndex);
1157: prefix = (prefixIndex > 0) ? _prefixTable
1158: .get(prefixIndex - 1)
1159: : (prefixIndex == -1) ? ""
1160: : EncodingConstants.XML_NAMESPACE_PREFIX;
1161: _contentHandler.endPrefixMapping(prefix);
1162: }
1163: _namespacePrefixesIndex = start;
1164: } catch (SAXException e) {
1165: throw new IOException("processStartNamespaceAII");
1166: }
1167: }
1168:
1169: protected final void processAIIs() throws FastInfosetException,
1170: IOException {
1171: QualifiedName name;
1172: int b;
1173: String value;
1174:
1175: _clearAttributes = true;
1176:
1177: if (++_duplicateAttributeVerifier._currentIteration == Integer.MAX_VALUE) {
1178: _duplicateAttributeVerifier.clear();
1179: }
1180:
1181: do {
1182: // AII qualified name
1183: b = read();
1184: switch (DecoderStateTables.AII[b]) {
1185: case DecoderStateTables.AII_INDEX_SMALL:
1186: name = _attributeNameTable._array[b];
1187: break;
1188: case DecoderStateTables.AII_INDEX_MEDIUM: {
1189: final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
1190: + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
1191: name = _attributeNameTable._array[i];
1192: break;
1193: }
1194: case DecoderStateTables.AII_INDEX_LARGE: {
1195: final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16)
1196: | (read() << 8) | read())
1197: + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
1198: name = _attributeNameTable._array[i];
1199: break;
1200: }
1201: case DecoderStateTables.AII_LITERAL:
1202: name = decodeLiteralQualifiedName(b
1203: & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
1204: name
1205: .createAttributeValues(_duplicateAttributeVerifier.MAP_SIZE);
1206: _attributeNameTable.add(name);
1207: break;
1208: case DecoderStateTables.AII_TERMINATOR_DOUBLE:
1209: _doubleTerminate = true;
1210: case DecoderStateTables.AII_TERMINATOR_SINGLE:
1211: _terminate = true;
1212: // AIIs have finished break out of loop
1213: continue;
1214: default:
1215: throw new IOException(CommonResourceBundle
1216: .getInstance()
1217: .getString("message.decodingAIIs"));
1218: }
1219:
1220: if (name.prefixIndex > 0
1221: && _prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
1222: throw new FastInfosetException(CommonResourceBundle
1223: .getInstance().getString(
1224: "message.AIIqNameNotInScope"));
1225: }
1226:
1227: _duplicateAttributeVerifier.checkForDuplicateAttribute(
1228: name.attributeHash, name.attributeId);
1229:
1230: // [normalized value] of AII
1231:
1232: b = read();
1233: switch (DecoderStateTables.NISTRING[b]) {
1234: case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
1235: _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
1236: value = decodeUtf8StringAsString();
1237: if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1238: _attributeValueTable.add(value);
1239: }
1240:
1241: _attributes.addAttribute(name, value);
1242: break;
1243: case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
1244: _octetBufferLength = read()
1245: + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
1246: value = decodeUtf8StringAsString();
1247: if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1248: _attributeValueTable.add(value);
1249: }
1250:
1251: _attributes.addAttribute(name, value);
1252: break;
1253: case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
1254: _octetBufferLength = ((read() << 24) | (read() << 16)
1255: | (read() << 8) | read())
1256: + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
1257: value = decodeUtf8StringAsString();
1258: if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1259: _attributeValueTable.add(value);
1260: }
1261:
1262: _attributes.addAttribute(name, value);
1263: break;
1264: case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH:
1265: _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
1266: value = decodeUtf16StringAsString();
1267: if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1268: _attributeValueTable.add(value);
1269: }
1270:
1271: _attributes.addAttribute(name, value);
1272: break;
1273: case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH:
1274: _octetBufferLength = read()
1275: + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
1276: value = decodeUtf16StringAsString();
1277: if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1278: _attributeValueTable.add(value);
1279: }
1280:
1281: _attributes.addAttribute(name, value);
1282: break;
1283: case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH:
1284: _octetBufferLength = ((read() << 24) | (read() << 16)
1285: | (read() << 8) | read())
1286: + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
1287: value = decodeUtf16StringAsString();
1288: if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1289: _attributeValueTable.add(value);
1290: }
1291:
1292: _attributes.addAttribute(name, value);
1293: break;
1294: case DecoderStateTables.NISTRING_RA: {
1295: final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
1296: // Decode resitricted alphabet integer
1297: _identifier = (b & 0x0F) << 4;
1298: b = read();
1299: _identifier |= (b & 0xF0) >> 4;
1300:
1301: decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
1302:
1303: value = decodeRestrictedAlphabetAsString();
1304: if (addToTable) {
1305: _attributeValueTable.add(value);
1306: }
1307:
1308: _attributes.addAttribute(name, value);
1309: break;
1310: }
1311: case DecoderStateTables.NISTRING_EA: {
1312: if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1313: throw new EncodingAlgorithmException(
1314: CommonResourceBundle
1315: .getInstance()
1316: .getString(
1317: "message.addToTableNotSupported"));
1318: }
1319:
1320: _identifier = (b & 0x0F) << 4;
1321: b = read();
1322: _identifier |= (b & 0xF0) >> 4;
1323:
1324: decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
1325:
1326: processAIIEncodingAlgorithm(name);
1327: break;
1328: }
1329: case DecoderStateTables.NISTRING_INDEX_SMALL:
1330: _attributes
1331: .addAttribute(
1332: name,
1333: _attributeValueTable._array[b
1334: & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK]);
1335: break;
1336: case DecoderStateTables.NISTRING_INDEX_MEDIUM: {
1337: final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
1338: + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
1339:
1340: _attributes.addAttribute(name,
1341: _attributeValueTable._array[index]);
1342: break;
1343: }
1344: case DecoderStateTables.NISTRING_INDEX_LARGE: {
1345: final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16)
1346: | (read() << 8) | read())
1347: + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
1348:
1349: _attributes.addAttribute(name,
1350: _attributeValueTable._array[index]);
1351: break;
1352: }
1353: case DecoderStateTables.NISTRING_EMPTY:
1354: _attributes.addAttribute(name, "");
1355: break;
1356: default:
1357: throw new IOException(CommonResourceBundle
1358: .getInstance().getString(
1359: "message.decodingAIIValue"));
1360: }
1361:
1362: } while (!_terminate);
1363:
1364: // Reset duplication attribute verfifier
1365: _duplicateAttributeVerifier._poolCurrent = _duplicateAttributeVerifier._poolHead;
1366:
1367: _terminate = _doubleTerminate;
1368: _doubleTerminate = false;
1369: }
1370:
1371: protected final void processCommentII()
1372: throws FastInfosetException, IOException {
1373: switch (decodeNonIdentifyingStringOnFirstBit()) {
1374: case NISTRING_STRING:
1375: if (_addToTable) {
1376: _v.otherString.add(new CharArray(_charBuffer, 0,
1377: _charBufferLength, true));
1378: }
1379:
1380: try {
1381: _lexicalHandler.comment(_charBuffer, 0,
1382: _charBufferLength);
1383: } catch (SAXException e) {
1384: throw new FastInfosetException("processCommentII", e);
1385: }
1386: break;
1387: case NISTRING_ENCODING_ALGORITHM:
1388: throw new IOException(
1389: CommonResourceBundle.getInstance().getString(
1390: "message.commentIIAlgorithmNotSupported"));
1391: case NISTRING_INDEX:
1392: final CharArray ca = _v.otherString.get(_integer);
1393:
1394: try {
1395: _lexicalHandler.comment(ca.ch, ca.start, ca.length);
1396: } catch (SAXException e) {
1397: throw new FastInfosetException("processCommentII", e);
1398: }
1399: break;
1400: case NISTRING_EMPTY_STRING:
1401: try {
1402: _lexicalHandler.comment(_charBuffer, 0, 0);
1403: } catch (SAXException e) {
1404: throw new FastInfosetException("processCommentII", e);
1405: }
1406: break;
1407: }
1408: }
1409:
1410: protected final void processProcessingII()
1411: throws FastInfosetException, IOException {
1412: final String target = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
1413:
1414: switch (decodeNonIdentifyingStringOnFirstBit()) {
1415: case NISTRING_STRING:
1416: final String data = new String(_charBuffer, 0,
1417: _charBufferLength);
1418: if (_addToTable) {
1419: _v.otherString.add(new CharArrayString(data));
1420: }
1421: try {
1422: _contentHandler.processingInstruction(target, data);
1423: } catch (SAXException e) {
1424: throw new FastInfosetException("processProcessingII", e);
1425: }
1426: break;
1427: case NISTRING_ENCODING_ALGORITHM:
1428: throw new IOException(
1429: CommonResourceBundle
1430: .getInstance()
1431: .getString(
1432: "message.processingIIWithEncodingAlgorithm"));
1433: case NISTRING_INDEX:
1434: try {
1435: _contentHandler.processingInstruction(target,
1436: _v.otherString.get(_integer).toString());
1437: } catch (SAXException e) {
1438: throw new FastInfosetException("processProcessingII", e);
1439: }
1440: break;
1441: case NISTRING_EMPTY_STRING:
1442: try {
1443: _contentHandler.processingInstruction(target, "");
1444: } catch (SAXException e) {
1445: throw new FastInfosetException("processProcessingII", e);
1446: }
1447: break;
1448: }
1449: }
1450:
1451: protected final void processCIIEncodingAlgorithm()
1452: throws FastInfosetException, IOException {
1453: if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
1454: if (_primitiveHandler != null) {
1455: processCIIBuiltInEncodingAlgorithmAsPrimitive();
1456: } else if (_algorithmHandler != null) {
1457: Object array = processBuiltInEncodingAlgorithmAsObject();
1458:
1459: try {
1460: _algorithmHandler.object(null, _identifier, array);
1461: } catch (SAXException e) {
1462: throw new FastInfosetException(e);
1463: }
1464: } else {
1465: StringBuffer buffer = new StringBuffer();
1466: processBuiltInEncodingAlgorithmAsCharacters(buffer);
1467:
1468: try {
1469: _contentHandler.characters(buffer.toString()
1470: .toCharArray(), 0, buffer.length());
1471: } catch (SAXException e) {
1472: throw new FastInfosetException(e);
1473: }
1474: }
1475: } else if (_identifier == EncodingAlgorithmIndexes.CDATA) {
1476: // Set back buffer position to start of encoded string
1477: _octetBufferOffset -= _octetBufferLength;
1478: decodeUtf8StringIntoCharBuffer();
1479:
1480: try {
1481: _lexicalHandler.startCDATA();
1482: _contentHandler.characters(_charBuffer, 0,
1483: _charBufferLength);
1484: _lexicalHandler.endCDATA();
1485: } catch (SAXException e) {
1486: throw new FastInfosetException(e);
1487: }
1488: } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START
1489: && _algorithmHandler != null) {
1490: final String URI = _v.encodingAlgorithm
1491: .get(_identifier
1492: - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
1493: if (URI == null) {
1494: throw new EncodingAlgorithmException(
1495: CommonResourceBundle.getInstance()
1496: .getString(
1497: "message.URINotPresent",
1498: new Object[] { new Integer(
1499: _identifier) }));
1500: }
1501:
1502: final EncodingAlgorithm ea = (EncodingAlgorithm) _registeredEncodingAlgorithms
1503: .get(URI);
1504: if (ea != null) {
1505: final Object data = ea.decodeFromBytes(_octetBuffer,
1506: _octetBufferStart, _octetBufferLength);
1507: try {
1508: _algorithmHandler.object(URI, _identifier, data);
1509: } catch (SAXException e) {
1510: throw new FastInfosetException(e);
1511: }
1512: } else {
1513: try {
1514: _algorithmHandler.octets(URI, _identifier,
1515: _octetBuffer, _octetBufferStart,
1516: _octetBufferLength);
1517: } catch (SAXException e) {
1518: throw new FastInfosetException(e);
1519: }
1520: }
1521: } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
1522: // TODO should have property to ignore
1523: throw new EncodingAlgorithmException(CommonResourceBundle
1524: .getInstance().getString(
1525: "message.algorithmDataCannotBeReported"));
1526: } else {
1527: // Reserved built-in algorithms for future use
1528: // TODO should use sax property to decide if event will be
1529: // reported, allows for support through handler if required.
1530: throw new EncodingAlgorithmException(CommonResourceBundle
1531: .getInstance().getString(
1532: "message.identifiers10to31Reserved"));
1533: }
1534: }
1535:
1536: protected final void processCIIBuiltInEncodingAlgorithmAsPrimitive()
1537: throws FastInfosetException, IOException {
1538: try {
1539: int length;
1540: switch (_identifier) {
1541: case EncodingAlgorithmIndexes.HEXADECIMAL:
1542: _primitiveHandler.bytes(_octetBuffer,
1543: _octetBufferStart, _octetBufferLength);
1544: break;
1545: case EncodingAlgorithmIndexes.BASE64:
1546: _primitiveHandler.bytes(_octetBuffer,
1547: _octetBufferStart, _octetBufferLength);
1548: break;
1549: case EncodingAlgorithmIndexes.SHORT:
1550: length = BuiltInEncodingAlgorithmFactory.shortEncodingAlgorithm
1551: .getPrimtiveLengthFromOctetLength(_octetBufferLength);
1552: if (length > builtInAlgorithmState.shortArray.length) {
1553: final short[] array = new short[length * 3 / 2 + 1];
1554: System.arraycopy(builtInAlgorithmState.shortArray,
1555: 0, array, 0,
1556: builtInAlgorithmState.shortArray.length);
1557: builtInAlgorithmState.shortArray = array;
1558: }
1559:
1560: BuiltInEncodingAlgorithmFactory.shortEncodingAlgorithm
1561: .decodeFromBytesToShortArray(
1562: builtInAlgorithmState.shortArray, 0,
1563: _octetBuffer, _octetBufferStart,
1564: _octetBufferLength);
1565: _primitiveHandler.shorts(
1566: builtInAlgorithmState.shortArray, 0, length);
1567: break;
1568: case EncodingAlgorithmIndexes.INT:
1569: length = BuiltInEncodingAlgorithmFactory.intEncodingAlgorithm
1570: .getPrimtiveLengthFromOctetLength(_octetBufferLength);
1571: if (length > builtInAlgorithmState.intArray.length) {
1572: final int[] array = new int[length * 3 / 2 + 1];
1573: System.arraycopy(builtInAlgorithmState.intArray, 0,
1574: array, 0,
1575: builtInAlgorithmState.intArray.length);
1576: builtInAlgorithmState.intArray = array;
1577: }
1578:
1579: BuiltInEncodingAlgorithmFactory.intEncodingAlgorithm
1580: .decodeFromBytesToIntArray(
1581: builtInAlgorithmState.intArray, 0,
1582: _octetBuffer, _octetBufferStart,
1583: _octetBufferLength);
1584: _primitiveHandler.ints(builtInAlgorithmState.intArray,
1585: 0, length);
1586: break;
1587: case EncodingAlgorithmIndexes.LONG:
1588: length = BuiltInEncodingAlgorithmFactory.longEncodingAlgorithm
1589: .getPrimtiveLengthFromOctetLength(_octetBufferLength);
1590: if (length > builtInAlgorithmState.longArray.length) {
1591: final long[] array = new long[length * 3 / 2 + 1];
1592: System.arraycopy(builtInAlgorithmState.longArray,
1593: 0, array, 0,
1594: builtInAlgorithmState.longArray.length);
1595: builtInAlgorithmState.longArray = array;
1596: }
1597:
1598: BuiltInEncodingAlgorithmFactory.longEncodingAlgorithm
1599: .decodeFromBytesToLongArray(
1600: builtInAlgorithmState.longArray, 0,
1601: _octetBuffer, _octetBufferStart,
1602: _octetBufferLength);
1603: _primitiveHandler.longs(
1604: builtInAlgorithmState.longArray, 0, length);
1605: break;
1606: case EncodingAlgorithmIndexes.BOOLEAN:
1607: length = BuiltInEncodingAlgorithmFactory.booleanEncodingAlgorithm
1608: .getPrimtiveLengthFromOctetLength(
1609: _octetBufferLength,
1610: _octetBuffer[_octetBufferStart] & 0xFF);
1611: if (length > builtInAlgorithmState.booleanArray.length) {
1612: final boolean[] array = new boolean[length * 3 / 2 + 1];
1613: System.arraycopy(
1614: builtInAlgorithmState.booleanArray, 0,
1615: array, 0,
1616: builtInAlgorithmState.booleanArray.length);
1617: builtInAlgorithmState.booleanArray = array;
1618: }
1619:
1620: BuiltInEncodingAlgorithmFactory.booleanEncodingAlgorithm
1621: .decodeFromBytesToBooleanArray(
1622: builtInAlgorithmState.booleanArray, 0,
1623: length, _octetBuffer,
1624: _octetBufferStart, _octetBufferLength);
1625: _primitiveHandler.booleans(
1626: builtInAlgorithmState.booleanArray, 0, length);
1627: break;
1628: case EncodingAlgorithmIndexes.FLOAT:
1629: length = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm
1630: .getPrimtiveLengthFromOctetLength(_octetBufferLength);
1631: if (length > builtInAlgorithmState.floatArray.length) {
1632: final float[] array = new float[length * 3 / 2 + 1];
1633: System.arraycopy(builtInAlgorithmState.floatArray,
1634: 0, array, 0,
1635: builtInAlgorithmState.floatArray.length);
1636: builtInAlgorithmState.floatArray = array;
1637: }
1638:
1639: BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm
1640: .decodeFromBytesToFloatArray(
1641: builtInAlgorithmState.floatArray, 0,
1642: _octetBuffer, _octetBufferStart,
1643: _octetBufferLength);
1644: _primitiveHandler.floats(
1645: builtInAlgorithmState.floatArray, 0, length);
1646: break;
1647: case EncodingAlgorithmIndexes.DOUBLE:
1648: length = BuiltInEncodingAlgorithmFactory.doubleEncodingAlgorithm
1649: .getPrimtiveLengthFromOctetLength(_octetBufferLength);
1650: if (length > builtInAlgorithmState.doubleArray.length) {
1651: final double[] array = new double[length * 3 / 2 + 1];
1652: System.arraycopy(builtInAlgorithmState.doubleArray,
1653: 0, array, 0,
1654: builtInAlgorithmState.doubleArray.length);
1655: builtInAlgorithmState.doubleArray = array;
1656: }
1657:
1658: BuiltInEncodingAlgorithmFactory.doubleEncodingAlgorithm
1659: .decodeFromBytesToDoubleArray(
1660: builtInAlgorithmState.doubleArray, 0,
1661: _octetBuffer, _octetBufferStart,
1662: _octetBufferLength);
1663: _primitiveHandler.doubles(
1664: builtInAlgorithmState.doubleArray, 0, length);
1665: break;
1666: case EncodingAlgorithmIndexes.UUID:
1667: length = BuiltInEncodingAlgorithmFactory.uuidEncodingAlgorithm
1668: .getPrimtiveLengthFromOctetLength(_octetBufferLength);
1669: if (length > builtInAlgorithmState.longArray.length) {
1670: final long[] array = new long[length * 3 / 2 + 1];
1671: System.arraycopy(builtInAlgorithmState.longArray,
1672: 0, array, 0,
1673: builtInAlgorithmState.longArray.length);
1674: builtInAlgorithmState.longArray = array;
1675: }
1676:
1677: BuiltInEncodingAlgorithmFactory.uuidEncodingAlgorithm
1678: .decodeFromBytesToLongArray(
1679: builtInAlgorithmState.longArray, 0,
1680: _octetBuffer, _octetBufferStart,
1681: _octetBufferLength);
1682: _primitiveHandler.uuids(
1683: builtInAlgorithmState.longArray, 0, length);
1684: break;
1685: case EncodingAlgorithmIndexes.CDATA:
1686: throw new UnsupportedOperationException("CDATA");
1687: default:
1688: throw new FastInfosetException(
1689: CommonResourceBundle.getInstance()
1690: .getString(
1691: "message.unsupportedAlgorithm",
1692: new Object[] { new Integer(
1693: _identifier) }));
1694: }
1695: } catch (SAXException e) {
1696: throw new FastInfosetException(e);
1697: }
1698: }
1699:
1700: protected final void processAIIEncodingAlgorithm(QualifiedName name)
1701: throws FastInfosetException, IOException {
1702: if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
1703: if (_primitiveHandler != null || _algorithmHandler != null) {
1704: Object data = processBuiltInEncodingAlgorithmAsObject();
1705: _attributes.addAttributeWithAlgorithmData(name, null,
1706: _identifier, data);
1707: } else {
1708: StringBuffer buffer = new StringBuffer();
1709: processBuiltInEncodingAlgorithmAsCharacters(buffer);
1710: _attributes.addAttribute(name, buffer.toString());
1711: }
1712: } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START
1713: && _algorithmHandler != null) {
1714: final String URI = _v.encodingAlgorithm
1715: .get(_identifier
1716: - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
1717: if (URI == null) {
1718: throw new EncodingAlgorithmException(
1719: CommonResourceBundle.getInstance()
1720: .getString(
1721: "message.URINotPresent",
1722: new Object[] { new Integer(
1723: _identifier) }));
1724: }
1725:
1726: final EncodingAlgorithm ea = (EncodingAlgorithm) _registeredEncodingAlgorithms
1727: .get(URI);
1728: if (ea != null) {
1729: final Object data = ea.decodeFromBytes(_octetBuffer,
1730: _octetBufferStart, _octetBufferLength);
1731: _attributes.addAttributeWithAlgorithmData(name, URI,
1732: _identifier, data);
1733: } else {
1734: final byte[] data = new byte[_octetBufferLength];
1735: System.arraycopy(_octetBuffer, _octetBufferStart, data,
1736: 0, _octetBufferLength);
1737: _attributes.addAttributeWithAlgorithmData(name, URI,
1738: _identifier, data);
1739: }
1740: } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
1741: // TODO should have property to ignore
1742: throw new EncodingAlgorithmException(CommonResourceBundle
1743: .getInstance().getString(
1744: "message.algorithmDataCannotBeReported"));
1745: } else if (_identifier == EncodingAlgorithmIndexes.CDATA) {
1746: throw new EncodingAlgorithmException(CommonResourceBundle
1747: .getInstance().getString(
1748: "message.CDATAAlgorithmNotSupported"));
1749: } else {
1750: // Reserved built-in algorithms for future use
1751: // TODO should use sax property to decide if event will be
1752: // reported, allows for support through handler if required.
1753: throw new EncodingAlgorithmException(CommonResourceBundle
1754: .getInstance().getString(
1755: "message.identifiers10to31Reserved"));
1756: }
1757: }
1758:
1759: protected final void processBuiltInEncodingAlgorithmAsCharacters(
1760: StringBuffer buffer) throws FastInfosetException,
1761: IOException {
1762: // TODO not very efficient, need to reuse buffers
1763: Object array = BuiltInEncodingAlgorithmFactory.table[_identifier]
1764: .decodeFromBytes(_octetBuffer, _octetBufferStart,
1765: _octetBufferLength);
1766:
1767: BuiltInEncodingAlgorithmFactory.table[_identifier]
1768: .convertToCharacters(array, buffer);
1769: }
1770:
1771: protected final Object processBuiltInEncodingAlgorithmAsObject()
1772: throws FastInfosetException, IOException {
1773: return BuiltInEncodingAlgorithmFactory.table[_identifier]
1774: .decodeFromBytes(_octetBuffer, _octetBufferStart,
1775: _octetBufferLength);
1776: }
1777: }
|