| /* |
| * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| * |
| * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC. |
| */ |
| |
| package com.sun.xml.internal.fastinfoset.sax; |
| |
| import com.sun.xml.internal.fastinfoset.Decoder; |
| import com.sun.xml.internal.fastinfoset.DecoderStateTables; |
| import com.sun.xml.internal.fastinfoset.EncodingConstants; |
| import com.sun.xml.internal.fastinfoset.QualifiedName; |
| import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory; |
| import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmState; |
| import com.sun.xml.internal.org.jvnet.fastinfoset.sax.EncodingAlgorithmContentHandler; |
| import com.sun.xml.internal.org.jvnet.fastinfoset.sax.FastInfosetReader; |
| import com.sun.xml.internal.org.jvnet.fastinfoset.sax.PrimitiveTypeContentHandler; |
| import com.sun.xml.internal.fastinfoset.util.CharArray; |
| import com.sun.xml.internal.fastinfoset.util.CharArrayString; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.util.Map; |
| import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithm; |
| import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException; |
| import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes; |
| import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException; |
| import org.xml.sax.ContentHandler; |
| import org.xml.sax.DTDHandler; |
| import org.xml.sax.EntityResolver; |
| import org.xml.sax.ErrorHandler; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXNotRecognizedException; |
| import org.xml.sax.SAXNotSupportedException; |
| import org.xml.sax.SAXParseException; |
| import org.xml.sax.ext.LexicalHandler; |
| import org.xml.sax.helpers.DefaultHandler; |
| import com.sun.xml.internal.fastinfoset.CommonResourceBundle; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import org.xml.sax.ext.DeclHandler; |
| |
| /** |
| * The Fast Infoset SAX parser. |
| * <p> |
| * Instantiate this parser to parse a fast infoset document in accordance |
| * with the SAX API. |
| * |
| * <p> |
| * More than one fast infoset document may be decoded from the |
| * {@link java.io.InputStream}. |
| */ |
| public class SAXDocumentParser extends Decoder implements FastInfosetReader { |
| private static final Logger logger = Logger.getLogger(SAXDocumentParser.class.getName()); |
| |
| /* |
| * Empty lexical handler used by default to report |
| * lexical-based events |
| */ |
| private static final class LexicalHandlerImpl implements LexicalHandler { |
| public void comment(char[] ch, int start, int end) { } |
| |
| public void startDTD(String name, String publicId, String systemId) { } |
| public void endDTD() { } |
| |
| public void startEntity(String name) { } |
| public void endEntity(String name) { } |
| |
| public void startCDATA() { } |
| public void endCDATA() { } |
| }; |
| |
| /* |
| * Empty DTD declaration handler used by default to report |
| * DTD declaration-based events |
| */ |
| private static final class DeclHandlerImpl implements DeclHandler { |
| public void elementDecl(String name, String model) throws SAXException { |
| } |
| |
| public void attributeDecl(String eName, String aName, |
| String type, String mode, String value) throws SAXException { |
| } |
| |
| public void internalEntityDecl(String name, |
| String value) throws SAXException { |
| } |
| |
| public void externalEntityDecl(String name, |
| String publicId, String systemId) throws SAXException { |
| } |
| } |
| |
| /** |
| * SAX Namespace attributes features |
| */ |
| protected boolean _namespacePrefixesFeature = false; |
| |
| /** |
| * Reference to entity resolver. |
| */ |
| protected EntityResolver _entityResolver; |
| |
| /** |
| * Reference to dtd handler. |
| */ |
| protected DTDHandler _dtdHandler; |
| |
| /** |
| * Reference to content handler. |
| */ |
| protected ContentHandler _contentHandler; |
| |
| /** |
| * Reference to error handler. |
| */ |
| protected ErrorHandler _errorHandler; |
| |
| /** |
| * Reference to lexical handler. |
| */ |
| protected LexicalHandler _lexicalHandler; |
| |
| /** |
| * Reference to DTD declaration handler. |
| */ |
| protected DeclHandler _declHandler; |
| |
| protected EncodingAlgorithmContentHandler _algorithmHandler; |
| |
| protected PrimitiveTypeContentHandler _primitiveHandler; |
| |
| protected BuiltInEncodingAlgorithmState builtInAlgorithmState = |
| new BuiltInEncodingAlgorithmState(); |
| |
| protected AttributesHolder _attributes; |
| |
| protected int[] _namespacePrefixes = new int[16]; |
| |
| protected int _namespacePrefixesIndex; |
| |
| protected boolean _clearAttributes = false; |
| |
| /** Creates a new instance of DocumetParser2 */ |
| public SAXDocumentParser() { |
| DefaultHandler handler = new DefaultHandler(); |
| _attributes = new AttributesHolder(_registeredEncodingAlgorithms); |
| |
| _entityResolver = handler; |
| _dtdHandler = handler; |
| _contentHandler = handler; |
| _errorHandler = handler; |
| _lexicalHandler = new LexicalHandlerImpl(); |
| _declHandler = new DeclHandlerImpl(); |
| } |
| |
| protected void resetOnError() { |
| _clearAttributes = false; |
| _attributes.clear(); |
| _namespacePrefixesIndex = 0; |
| |
| if (_v != null) { |
| _v.prefix.clearCompletely(); |
| } |
| _duplicateAttributeVerifier.clear(); |
| } |
| |
| // XMLReader interface |
| |
| public boolean getFeature(String name) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| if (name.equals(Features.NAMESPACES_FEATURE)) { |
| return true; |
| } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) { |
| return _namespacePrefixesFeature; |
| } else if (name.equals(Features.STRING_INTERNING_FEATURE) || |
| name.equals(FastInfosetReader.STRING_INTERNING_PROPERTY)) { |
| return getStringInterning(); |
| } else { |
| throw new SAXNotRecognizedException( |
| CommonResourceBundle.getInstance().getString("message.featureNotSupported") + name); |
| } |
| } |
| |
| public void setFeature(String name, boolean value) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| if (name.equals(Features.NAMESPACES_FEATURE)) { |
| if (value == false) { |
| throw new SAXNotSupportedException(name + ":" + value); |
| } |
| } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) { |
| _namespacePrefixesFeature = value; |
| } else if (name.equals(Features.STRING_INTERNING_FEATURE) || |
| name.equals(FastInfosetReader.STRING_INTERNING_PROPERTY)) { |
| setStringInterning(value); |
| } else { |
| throw new SAXNotRecognizedException( |
| CommonResourceBundle.getInstance().getString("message.featureNotSupported") + name); |
| } |
| } |
| |
| public Object getProperty(String name) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) { |
| return getLexicalHandler(); |
| } else if (name.equals(Properties.DTD_DECLARATION_HANDLER_PROPERTY)) { |
| return getDeclHandler(); |
| } else if (name.equals(FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY)) { |
| return getExternalVocabularies(); |
| } else if (name.equals(FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY)) { |
| return getRegisteredEncodingAlgorithms(); |
| } else if (name.equals(FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY)) { |
| return getEncodingAlgorithmContentHandler(); |
| } else if (name.equals(FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY)) { |
| return getPrimitiveTypeContentHandler(); |
| } else { |
| throw new SAXNotRecognizedException(CommonResourceBundle.getInstance(). |
| getString("message.propertyNotRecognized", new Object[]{name})); |
| } |
| } |
| |
| public void setProperty(String name, Object value) |
| throws SAXNotRecognizedException, SAXNotSupportedException { |
| if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) { |
| if (value instanceof LexicalHandler) { |
| setLexicalHandler((LexicalHandler)value); |
| } else { |
| throw new SAXNotSupportedException(Properties.LEXICAL_HANDLER_PROPERTY); |
| } |
| } else if (name.equals(Properties.DTD_DECLARATION_HANDLER_PROPERTY)) { |
| if (value instanceof DeclHandler) { |
| setDeclHandler((DeclHandler)value); |
| } else { |
| throw new SAXNotSupportedException(Properties.LEXICAL_HANDLER_PROPERTY); |
| } |
| } else if (name.equals(FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY)) { |
| if (value instanceof Map) { |
| setExternalVocabularies((Map)value); |
| } else { |
| throw new SAXNotSupportedException(FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY); |
| } |
| } else if (name.equals(FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY)) { |
| if (value instanceof Map) { |
| setRegisteredEncodingAlgorithms((Map)value); |
| } else { |
| throw new SAXNotSupportedException(FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY); |
| } |
| } else if (name.equals(FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY)) { |
| if (value instanceof EncodingAlgorithmContentHandler) { |
| setEncodingAlgorithmContentHandler((EncodingAlgorithmContentHandler)value); |
| } else { |
| throw new SAXNotSupportedException(FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY); |
| } |
| } else if (name.equals(FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY)) { |
| if (value instanceof PrimitiveTypeContentHandler) { |
| setPrimitiveTypeContentHandler((PrimitiveTypeContentHandler)value); |
| } else { |
| throw new SAXNotSupportedException(FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY); |
| } |
| } else if (name.equals(FastInfosetReader.BUFFER_SIZE_PROPERTY)) { |
| if (value instanceof Integer) { |
| setBufferSize(((Integer)value).intValue()); |
| } else { |
| throw new SAXNotSupportedException(FastInfosetReader.BUFFER_SIZE_PROPERTY); |
| } |
| } else { |
| throw new SAXNotRecognizedException(CommonResourceBundle.getInstance(). |
| getString("message.propertyNotRecognized", new Object[]{name})); |
| } |
| } |
| |
| public void setEntityResolver(EntityResolver resolver) { |
| _entityResolver = resolver; |
| } |
| |
| public EntityResolver getEntityResolver() { |
| return _entityResolver; |
| } |
| |
| public void setDTDHandler(DTDHandler handler) { |
| _dtdHandler = handler; |
| } |
| |
| public DTDHandler getDTDHandler() { |
| return _dtdHandler; |
| } |
| public void setContentHandler(ContentHandler handler) { |
| _contentHandler = handler; |
| } |
| |
| public ContentHandler getContentHandler() { |
| return _contentHandler; |
| } |
| |
| public void setErrorHandler(ErrorHandler handler) { |
| _errorHandler = handler; |
| } |
| |
| public ErrorHandler getErrorHandler() { |
| return _errorHandler; |
| } |
| |
| public void parse(InputSource input) throws IOException, SAXException { |
| try { |
| InputStream s = input.getByteStream(); |
| if (s == null) { |
| String systemId = input.getSystemId(); |
| if (systemId == null) { |
| throw new SAXException(CommonResourceBundle.getInstance().getString("message.inputSource")); |
| } |
| parse(systemId); |
| } else { |
| parse(s); |
| } |
| } catch (FastInfosetException e) { |
| logger.log(Level.FINE, "parsing error", e); |
| throw new SAXException(e); |
| } |
| } |
| |
| public void parse(String systemId) throws IOException, SAXException { |
| try { |
| systemId = SystemIdResolver.getAbsoluteURI(systemId); |
| parse(new URL(systemId).openStream()); |
| } catch (FastInfosetException e) { |
| logger.log(Level.FINE, "parsing error", e); |
| throw new SAXException(e); |
| } |
| } |
| |
| |
| |
| |
| // FastInfosetReader |
| |
| public final void parse(InputStream s) throws IOException, FastInfosetException, SAXException { |
| setInputStream(s); |
| parse(); |
| } |
| |
| public void setLexicalHandler(LexicalHandler handler) { |
| _lexicalHandler = handler; |
| } |
| |
| public LexicalHandler getLexicalHandler() { |
| return _lexicalHandler; |
| } |
| |
| public void setDeclHandler(DeclHandler handler) { |
| _declHandler = handler; |
| } |
| |
| public DeclHandler getDeclHandler() { |
| return _declHandler; |
| } |
| |
| public void setEncodingAlgorithmContentHandler(EncodingAlgorithmContentHandler handler) { |
| _algorithmHandler = handler; |
| } |
| |
| public EncodingAlgorithmContentHandler getEncodingAlgorithmContentHandler() { |
| return _algorithmHandler; |
| } |
| |
| public void setPrimitiveTypeContentHandler(PrimitiveTypeContentHandler handler) { |
| _primitiveHandler = handler; |
| } |
| |
| public PrimitiveTypeContentHandler getPrimitiveTypeContentHandler() { |
| return _primitiveHandler; |
| } |
| |
| |
| |
| |
| public final void parse() throws FastInfosetException, IOException { |
| if (_octetBuffer.length < _bufferSize) { |
| _octetBuffer = new byte[_bufferSize]; |
| } |
| |
| try { |
| reset(); |
| decodeHeader(); |
| if (_parseFragments) |
| processDIIFragment(); |
| else |
| processDII(); |
| } catch (RuntimeException e) { |
| try { |
| _errorHandler.fatalError(new SAXParseException(e.getClass().getName(), null, e)); |
| } catch (Exception ee) { |
| } |
| resetOnError(); |
| // Wrap runtime exception |
| throw new FastInfosetException(e); |
| } catch (FastInfosetException e) { |
| try { |
| _errorHandler.fatalError(new SAXParseException(e.getClass().getName(), null, e)); |
| } catch (Exception ee) { |
| } |
| resetOnError(); |
| throw e; |
| } catch (IOException e) { |
| try { |
| _errorHandler.fatalError(new SAXParseException(e.getClass().getName(), null, e)); |
| } catch (Exception ee) { |
| } |
| resetOnError(); |
| throw e; |
| } |
| } |
| |
| protected final void processDII() throws FastInfosetException, IOException { |
| try { |
| _contentHandler.startDocument(); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processDII", e); |
| } |
| |
| _b = read(); |
| if (_b > 0) { |
| processDIIOptionalProperties(); |
| } |
| |
| // Decode one Document Type II, Comment IIs, PI IIs and one EII |
| boolean firstElementHasOccured = false; |
| boolean documentTypeDeclarationOccured = false; |
| while(!_terminate || !firstElementHasOccured) { |
| _b = read(); |
| switch(DecoderStateTables.DII(_b)) { |
| case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL: |
| processEII(_elementNameTable._array[_b], false); |
| firstElementHasOccured = true; |
| break; |
| case DecoderStateTables.EII_AIIS_INDEX_SMALL: |
| processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true); |
| firstElementHasOccured = true; |
| break; |
| case DecoderStateTables.EII_INDEX_MEDIUM: |
| processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| firstElementHasOccured = true; |
| break; |
| case DecoderStateTables.EII_INDEX_LARGE: |
| processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| firstElementHasOccured = true; |
| break; |
| case DecoderStateTables.EII_LITERAL: |
| { |
| final QualifiedName qn = decodeLiteralQualifiedName( |
| _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK, |
| _elementNameTable.getNext()); |
| _elementNameTable.add(qn); |
| processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| firstElementHasOccured = true; |
| break; |
| } |
| case DecoderStateTables.EII_NAMESPACES: |
| processEIIWithNamespaces(); |
| firstElementHasOccured = true; |
| break; |
| case DecoderStateTables.DOCUMENT_TYPE_DECLARATION_II: |
| { |
| if (documentTypeDeclarationOccured) { |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.secondOccurenceOfDTDII")); |
| } |
| documentTypeDeclarationOccured = true; |
| |
| String system_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_SYSTEM_IDENTIFIER_FLAG) > 0) |
| ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; |
| String public_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_PUBLIC_IDENTIFIER_FLAG) > 0) |
| ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; |
| |
| _b = read(); |
| while (_b == EncodingConstants.PROCESSING_INSTRUCTION) { |
| switch(decodeNonIdentifyingStringOnFirstBit()) { |
| case NISTRING_STRING: |
| if (_addToTable) { |
| _v.otherString.add(new CharArray(_charBuffer, 0, _charBufferLength, true)); |
| } |
| break; |
| case NISTRING_ENCODING_ALGORITHM: |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm")); |
| case NISTRING_INDEX: |
| break; |
| case NISTRING_EMPTY_STRING: |
| break; |
| } |
| _b = read(); |
| } |
| if ((_b & EncodingConstants.TERMINATOR) != EncodingConstants.TERMINATOR) { |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingInstructionIIsNotTerminatedCorrectly")); |
| } |
| if (_b == EncodingConstants.DOUBLE_TERMINATOR) { |
| _terminate = true; |
| } |
| |
| if (_notations != null) _notations.clear(); |
| if (_unparsedEntities != null) _unparsedEntities.clear(); |
| /* |
| * TODO |
| * Report All events associated with DTD, PIs, notations etc |
| */ |
| break; |
| } |
| case DecoderStateTables.COMMENT_II: |
| processCommentII(); |
| break; |
| case DecoderStateTables.PROCESSING_INSTRUCTION_II: |
| processProcessingII(); |
| break; |
| case DecoderStateTables.TERMINATOR_DOUBLE: |
| _doubleTerminate = true; |
| case DecoderStateTables.TERMINATOR_SINGLE: |
| _terminate = true; |
| break; |
| default: |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII")); |
| } |
| } |
| |
| // Decode any remaining Comment IIs, PI IIs |
| while(!_terminate) { |
| _b = read(); |
| switch(DecoderStateTables.DII(_b)) { |
| case DecoderStateTables.COMMENT_II: |
| processCommentII(); |
| break; |
| case DecoderStateTables.PROCESSING_INSTRUCTION_II: |
| processProcessingII(); |
| break; |
| case DecoderStateTables.TERMINATOR_DOUBLE: |
| _doubleTerminate = true; |
| case DecoderStateTables.TERMINATOR_SINGLE: |
| _terminate = true; |
| break; |
| default: |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII")); |
| } |
| } |
| |
| try { |
| _contentHandler.endDocument(); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processDII", e); |
| } |
| } |
| |
| protected final void processDIIFragment() throws FastInfosetException, IOException { |
| try { |
| _contentHandler.startDocument(); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processDII", e); |
| } |
| |
| _b = read(); |
| if (_b > 0) { |
| processDIIOptionalProperties(); |
| } |
| |
| while(!_terminate) { |
| _b = read(); |
| switch(DecoderStateTables.EII(_b)) { |
| case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL: |
| processEII(_elementNameTable._array[_b], false); |
| break; |
| case DecoderStateTables.EII_AIIS_INDEX_SMALL: |
| processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true); |
| break; |
| case DecoderStateTables.EII_INDEX_MEDIUM: |
| processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| break; |
| case DecoderStateTables.EII_INDEX_LARGE: |
| processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| break; |
| case DecoderStateTables.EII_LITERAL: |
| { |
| final QualifiedName qn = decodeLiteralQualifiedName( |
| _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK, |
| _elementNameTable.getNext()); |
| _elementNameTable.add(qn); |
| processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| break; |
| } |
| case DecoderStateTables.EII_NAMESPACES: |
| processEIIWithNamespaces(); |
| break; |
| case DecoderStateTables.CII_UTF8_SMALL_LENGTH: |
| _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK) |
| + 1; |
| processUtf8CharacterString(); |
| break; |
| case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH: |
| _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT; |
| processUtf8CharacterString(); |
| break; |
| case DecoderStateTables.CII_UTF8_LARGE_LENGTH: |
| _octetBufferLength = ((read() << 24) | |
| (read() << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT; |
| processUtf8CharacterString(); |
| break; |
| case DecoderStateTables.CII_UTF16_SMALL_LENGTH: |
| _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK) |
| + 1; |
| decodeUtf16StringAsCharBuffer(); |
| if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH: |
| _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT; |
| decodeUtf16StringAsCharBuffer(); |
| if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| case DecoderStateTables.CII_UTF16_LARGE_LENGTH: |
| _octetBufferLength = ((read() << 24) | |
| (read() << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT; |
| decodeUtf16StringAsCharBuffer(); |
| if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| case DecoderStateTables.CII_RA: |
| { |
| final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0; |
| |
| // Decode resitricted alphabet integer |
| _identifier = (_b & 0x02) << 6; |
| _b = read(); |
| _identifier |= (_b & 0xFC) >> 2; |
| |
| decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b); |
| |
| decodeRestrictedAlphabetAsCharBuffer(); |
| |
| if (addToTable) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.CII_EA: |
| { |
| final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0; |
| |
| // Decode encoding algorithm integer |
| _identifier = (_b & 0x02) << 6; |
| _b = read(); |
| _identifier |= (_b & 0xFC) >> 2; |
| |
| decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b); |
| |
| processCIIEncodingAlgorithm(addToTable); |
| break; |
| } |
| case DecoderStateTables.CII_INDEX_SMALL: |
| { |
| final int index = _b & EncodingConstants.INTEGER_4TH_BIT_SMALL_MASK; |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, |
| _characterContentChunkTable._offset[index], |
| _characterContentChunkTable._length[index]); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.CII_INDEX_MEDIUM: |
| { |
| final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_MEDIUM_MASK) << 8) | read()) |
| + EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT; |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, |
| _characterContentChunkTable._offset[index], |
| _characterContentChunkTable._length[index]); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.CII_INDEX_LARGE: |
| { |
| final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_LARGE_MASK) << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT; |
| |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, |
| _characterContentChunkTable._offset[index], |
| _characterContentChunkTable._length[index]); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.CII_INDEX_LARGE_LARGE: |
| { |
| final int index = ((read() << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT; |
| |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, |
| _characterContentChunkTable._offset[index], |
| _characterContentChunkTable._length[index]); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.COMMENT_II: |
| processCommentII(); |
| break; |
| case DecoderStateTables.PROCESSING_INSTRUCTION_II: |
| processProcessingII(); |
| break; |
| case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II: |
| { |
| String entity_reference_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName); |
| |
| String system_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_SYSTEM_IDENTIFIER_FLAG) > 0) |
| ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; |
| String public_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_PUBLIC_IDENTIFIER_FLAG) > 0) |
| ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; |
| |
| try { |
| /* |
| * TODO |
| * Need to verify if the skippedEntity method: |
| * http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#skippedEntity(java.lang.String) |
| * is the correct method to call. It appears so but a more extensive |
| * check is necessary. |
| */ |
| _contentHandler.skippedEntity(entity_reference_name); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processUnexpandedEntityReferenceII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.TERMINATOR_DOUBLE: |
| _doubleTerminate = true; |
| case DecoderStateTables.TERMINATOR_SINGLE: |
| _terminate = true; |
| break; |
| default: |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEII")); |
| } |
| } |
| |
| try { |
| _contentHandler.endDocument(); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processDII", e); |
| } |
| } |
| |
| protected final void processDIIOptionalProperties() throws FastInfosetException, IOException { |
| // Optimize for the most common case |
| if (_b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) { |
| decodeInitialVocabulary(); |
| return; |
| } |
| |
| if ((_b & EncodingConstants.DOCUMENT_ADDITIONAL_DATA_FLAG) > 0) { |
| decodeAdditionalData(); |
| /* |
| * TODO |
| * how to report the additional data? |
| */ |
| } |
| |
| if ((_b & EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) > 0) { |
| decodeInitialVocabulary(); |
| } |
| |
| if ((_b & EncodingConstants.DOCUMENT_NOTATIONS_FLAG) > 0) { |
| decodeNotations(); |
| /* |
| try { |
| _dtdHandler.notationDecl(name, public_identifier, system_identifier); |
| } catch (SAXException e) { |
| throw new IOException("NotationsDeclarationII"); |
| } |
| */ |
| } |
| |
| if ((_b & EncodingConstants.DOCUMENT_UNPARSED_ENTITIES_FLAG) > 0) { |
| decodeUnparsedEntities(); |
| /* |
| try { |
| _dtdHandler.unparsedEntityDecl(name, public_identifier, system_identifier, notation_name); |
| } catch (SAXException e) { |
| throw new IOException("UnparsedEntitiesII"); |
| } |
| */ |
| } |
| |
| if ((_b & EncodingConstants.DOCUMENT_CHARACTER_ENCODING_SCHEME) > 0) { |
| /*String characterEncodingScheme = */decodeCharacterEncodingScheme(); |
| /* |
| * TODO |
| * how to report the character encoding scheme? |
| */ |
| } |
| |
| if ((_b & EncodingConstants.DOCUMENT_STANDALONE_FLAG) > 0) { |
| /*boolean standalone = (*/read()/* > 0) ? true : false*/ ; |
| /* |
| * TODO |
| * how to report the standalone flag? |
| */ |
| } |
| |
| if ((_b & EncodingConstants.DOCUMENT_VERSION_FLAG) > 0) { |
| decodeVersion(); |
| /* |
| * TODO |
| * how to report the standalone flag? |
| */ |
| } |
| } |
| |
| protected final void processEII(QualifiedName name, boolean hasAttributes) throws FastInfosetException, IOException { |
| if (_prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) { |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameOfEIINotInScope")); |
| } |
| |
| if (hasAttributes) { |
| processAIIs(); |
| } |
| |
| try { |
| _contentHandler.startElement(name.namespaceName, name.localName, name.qName, _attributes); |
| } catch (SAXException e) { |
| logger.log(Level.FINE, "processEII error", e); |
| throw new FastInfosetException("processEII", e); |
| } |
| |
| if (_clearAttributes) { |
| _attributes.clear(); |
| _clearAttributes = false; |
| } |
| |
| while(!_terminate) { |
| _b = read(); |
| switch(DecoderStateTables.EII(_b)) { |
| case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL: |
| processEII(_elementNameTable._array[_b], false); |
| break; |
| case DecoderStateTables.EII_AIIS_INDEX_SMALL: |
| processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true); |
| break; |
| case DecoderStateTables.EII_INDEX_MEDIUM: |
| processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| break; |
| case DecoderStateTables.EII_INDEX_LARGE: |
| processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| break; |
| case DecoderStateTables.EII_LITERAL: |
| { |
| final QualifiedName qn = decodeLiteralQualifiedName( |
| _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK, |
| _elementNameTable.getNext()); |
| _elementNameTable.add(qn); |
| processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0); |
| break; |
| } |
| case DecoderStateTables.EII_NAMESPACES: |
| processEIIWithNamespaces(); |
| break; |
| case DecoderStateTables.CII_UTF8_SMALL_LENGTH: |
| _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK) |
| + 1; |
| processUtf8CharacterString(); |
| break; |
| case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH: |
| _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT; |
| processUtf8CharacterString(); |
| break; |
| case DecoderStateTables.CII_UTF8_LARGE_LENGTH: |
| _octetBufferLength = ((read() << 24) | |
| (read() << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT; |
| processUtf8CharacterString(); |
| break; |
| case DecoderStateTables.CII_UTF16_SMALL_LENGTH: |
| _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK) |
| + 1; |
| decodeUtf16StringAsCharBuffer(); |
| if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH: |
| _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT; |
| decodeUtf16StringAsCharBuffer(); |
| if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| case DecoderStateTables.CII_UTF16_LARGE_LENGTH: |
| _octetBufferLength = ((read() << 24) | |
| (read() << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT; |
| decodeUtf16StringAsCharBuffer(); |
| if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| case DecoderStateTables.CII_RA: |
| { |
| final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0; |
| |
| // Decode resitricted alphabet integer |
| _identifier = (_b & 0x02) << 6; |
| _b = read(); |
| _identifier |= (_b & 0xFC) >> 2; |
| |
| decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b); |
| |
| decodeRestrictedAlphabetAsCharBuffer(); |
| |
| if (addToTable) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.CII_EA: |
| { |
| final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0; |
| // Decode encoding algorithm integer |
| _identifier = (_b & 0x02) << 6; |
| _b = read(); |
| _identifier |= (_b & 0xFC) >> 2; |
| |
| decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b); |
| |
| processCIIEncodingAlgorithm(addToTable); |
| break; |
| } |
| case DecoderStateTables.CII_INDEX_SMALL: |
| { |
| final int index = _b & EncodingConstants.INTEGER_4TH_BIT_SMALL_MASK; |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, |
| _characterContentChunkTable._offset[index], |
| _characterContentChunkTable._length[index]); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.CII_INDEX_MEDIUM: |
| { |
| final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_MEDIUM_MASK) << 8) | read()) |
| + EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT; |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, |
| _characterContentChunkTable._offset[index], |
| _characterContentChunkTable._length[index]); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.CII_INDEX_LARGE: |
| { |
| final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_LARGE_MASK) << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT; |
| |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, |
| _characterContentChunkTable._offset[index], |
| _characterContentChunkTable._length[index]); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.CII_INDEX_LARGE_LARGE: |
| { |
| final int index = ((read() << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT; |
| |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, |
| _characterContentChunkTable._offset[index], |
| _characterContentChunkTable._length[index]); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.COMMENT_II: |
| processCommentII(); |
| break; |
| case DecoderStateTables.PROCESSING_INSTRUCTION_II: |
| processProcessingII(); |
| break; |
| case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II: |
| { |
| String entity_reference_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName); |
| |
| String system_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_SYSTEM_IDENTIFIER_FLAG) > 0) |
| ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; |
| String public_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_PUBLIC_IDENTIFIER_FLAG) > 0) |
| ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; |
| |
| try { |
| /* |
| * TODO |
| * Need to verify if the skippedEntity method: |
| * http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#skippedEntity(java.lang.String) |
| * is the correct method to call. It appears so but a more extensive |
| * check is necessary. |
| */ |
| _contentHandler.skippedEntity(entity_reference_name); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processUnexpandedEntityReferenceII", e); |
| } |
| break; |
| } |
| case DecoderStateTables.TERMINATOR_DOUBLE: |
| _doubleTerminate = true; |
| case DecoderStateTables.TERMINATOR_SINGLE: |
| _terminate = true; |
| break; |
| default: |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEII")); |
| } |
| } |
| |
| _terminate = _doubleTerminate; |
| _doubleTerminate = false; |
| |
| try { |
| _contentHandler.endElement(name.namespaceName, name.localName, name.qName); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processEII", e); |
| } |
| } |
| |
| private final void processUtf8CharacterString() throws FastInfosetException, IOException { |
| if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) { |
| _characterContentChunkTable.ensureSize(_octetBufferLength); |
| final int charactersOffset = _characterContentChunkTable._arrayIndex; |
| decodeUtf8StringAsCharBuffer(_characterContentChunkTable._array, charactersOffset); |
| _characterContentChunkTable.add(_charBufferLength); |
| try { |
| _contentHandler.characters(_characterContentChunkTable._array, charactersOffset, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| } else { |
| decodeUtf8StringAsCharBuffer(); |
| try { |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCII", e); |
| } |
| } |
| } |
| |
| protected final void processEIIWithNamespaces() throws FastInfosetException, IOException { |
| final boolean hasAttributes = (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0; |
| |
| _clearAttributes = (_namespacePrefixesFeature) ? true : false; |
| |
| if (++_prefixTable._declarationId == Integer.MAX_VALUE) { |
| _prefixTable.clearDeclarationIds(); |
| } |
| |
| String prefix = "", namespaceName = ""; |
| final int start = _namespacePrefixesIndex; |
| int b = read(); |
| while ((b & EncodingConstants.NAMESPACE_ATTRIBUTE_MASK) == EncodingConstants.NAMESPACE_ATTRIBUTE) { |
| if (_namespacePrefixesIndex == _namespacePrefixes.length) { |
| final int[] namespaceAIIs = new int[_namespacePrefixesIndex * 3 / 2 + 1]; |
| System.arraycopy(_namespacePrefixes, 0, namespaceAIIs, 0, _namespacePrefixesIndex); |
| _namespacePrefixes = namespaceAIIs; |
| } |
| |
| switch (b & EncodingConstants.NAMESPACE_ATTRIBUTE_PREFIX_NAME_MASK) { |
| // no prefix, no namespace |
| // Undeclaration of default namespace |
| case 0: |
| prefix = namespaceName = ""; |
| _namespaceNameIndex = _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1; |
| break; |
| // no prefix, namespace |
| // Declaration of default namespace |
| case 1: |
| prefix = ""; |
| namespaceName = decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(false); |
| |
| _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1; |
| break; |
| // prefix, no namespace |
| // Undeclaration of namespace |
| case 2: |
| prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(false); |
| namespaceName = ""; |
| |
| _namespaceNameIndex = -1; |
| _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex; |
| break; |
| // prefix, namespace |
| // Declaration of prefixed namespace |
| case 3: |
| prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(true); |
| namespaceName = decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(true); |
| |
| _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex; |
| break; |
| } |
| |
| _prefixTable.pushScope(_prefixIndex, _namespaceNameIndex); |
| |
| if (_namespacePrefixesFeature) { |
| // Add the namespace delcaration as an attribute |
| if (prefix != "") { |
| _attributes.addAttribute(new QualifiedName( |
| EncodingConstants.XMLNS_NAMESPACE_PREFIX, |
| EncodingConstants.XMLNS_NAMESPACE_NAME, |
| prefix), |
| namespaceName); |
| } else { |
| _attributes.addAttribute(EncodingConstants.DEFAULT_NAMESPACE_DECLARATION, |
| namespaceName); |
| } |
| } |
| |
| try { |
| _contentHandler.startPrefixMapping(prefix, namespaceName); |
| } catch (SAXException e) { |
| throw new IOException("processStartNamespaceAII"); |
| } |
| |
| b = read(); |
| } |
| if (b != EncodingConstants.TERMINATOR) { |
| throw new IOException(CommonResourceBundle.getInstance().getString("message.EIInamespaceNameNotTerminatedCorrectly")); |
| } |
| final int end = _namespacePrefixesIndex; |
| |
| _b = read(); |
| switch(DecoderStateTables.EII(_b)) { |
| case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL: |
| processEII(_elementNameTable._array[_b], hasAttributes); |
| break; |
| case DecoderStateTables.EII_INDEX_MEDIUM: |
| processEII(decodeEIIIndexMedium(), hasAttributes); |
| break; |
| case DecoderStateTables.EII_INDEX_LARGE: |
| processEII(decodeEIIIndexLarge(), hasAttributes); |
| break; |
| case DecoderStateTables.EII_LITERAL: |
| { |
| final QualifiedName qn = decodeLiteralQualifiedName( |
| _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK, |
| _elementNameTable.getNext()); |
| _elementNameTable.add(qn); |
| processEII(qn, hasAttributes); |
| break; |
| } |
| default: |
| throw new IOException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEIIAfterAIIs")); |
| } |
| |
| try { |
| for (int i = end - 1; i >= start; i--) { |
| final int prefixIndex = _namespacePrefixes[i]; |
| _prefixTable.popScope(prefixIndex); |
| prefix = (prefixIndex > 0) ? _prefixTable.get(prefixIndex - 1) : |
| (prefixIndex == -1) ? "" : EncodingConstants.XML_NAMESPACE_PREFIX; |
| _contentHandler.endPrefixMapping(prefix); |
| } |
| _namespacePrefixesIndex = start; |
| } catch (SAXException e) { |
| throw new IOException("processStartNamespaceAII"); |
| } |
| } |
| |
| protected final void processAIIs() throws FastInfosetException, IOException { |
| QualifiedName name; |
| int b; |
| String value; |
| |
| _clearAttributes = true; |
| |
| if (++_duplicateAttributeVerifier._currentIteration == Integer.MAX_VALUE) { |
| _duplicateAttributeVerifier.clear(); |
| } |
| |
| do { |
| // AII qualified name |
| b = read(); |
| switch (DecoderStateTables.AII(b)) { |
| case DecoderStateTables.AII_INDEX_SMALL: |
| name = _attributeNameTable._array[b]; |
| break; |
| case DecoderStateTables.AII_INDEX_MEDIUM: |
| { |
| final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) |
| + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; |
| name = _attributeNameTable._array[i]; |
| break; |
| } |
| case DecoderStateTables.AII_INDEX_LARGE: |
| { |
| final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) |
| + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; |
| name = _attributeNameTable._array[i]; |
| break; |
| } |
| case DecoderStateTables.AII_LITERAL: |
| name = decodeLiteralQualifiedName( |
| b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK, |
| _attributeNameTable.getNext()); |
| name.createAttributeValues(_duplicateAttributeVerifier.MAP_SIZE); |
| _attributeNameTable.add(name); |
| break; |
| case DecoderStateTables.AII_TERMINATOR_DOUBLE: |
| _doubleTerminate = true; |
| case DecoderStateTables.AII_TERMINATOR_SINGLE: |
| _terminate = true; |
| // AIIs have finished break out of loop |
| continue; |
| default: |
| throw new IOException(CommonResourceBundle.getInstance().getString("message.decodingAIIs")); |
| } |
| |
| if (name.prefixIndex > 0 && _prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) { |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.AIIqNameNotInScope")); |
| } |
| |
| _duplicateAttributeVerifier.checkForDuplicateAttribute(name.attributeHash, name.attributeId); |
| |
| // [normalized value] of AII |
| |
| b = read(); |
| switch(DecoderStateTables.NISTRING(b)) { |
| case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH: |
| _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1; |
| value = decodeUtf8StringAsString(); |
| if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) { |
| _attributeValueTable.add(value); |
| } |
| |
| _attributes.addAttribute(name, value); |
| break; |
| case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH: |
| _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT; |
| value = decodeUtf8StringAsString(); |
| if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) { |
| _attributeValueTable.add(value); |
| } |
| |
| _attributes.addAttribute(name, value); |
| break; |
| case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH: |
| _octetBufferLength = ((read() << 24) | |
| (read() << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT; |
| value = decodeUtf8StringAsString(); |
| if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) { |
| _attributeValueTable.add(value); |
| } |
| |
| _attributes.addAttribute(name, value); |
| break; |
| case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH: |
| _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1; |
| value = decodeUtf16StringAsString(); |
| if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) { |
| _attributeValueTable.add(value); |
| } |
| |
| _attributes.addAttribute(name, value); |
| break; |
| case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH: |
| _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT; |
| value = decodeUtf16StringAsString(); |
| if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) { |
| _attributeValueTable.add(value); |
| } |
| |
| _attributes.addAttribute(name, value); |
| break; |
| case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH: |
| _octetBufferLength = ((read() << 24) | |
| (read() << 16) | |
| (read() << 8) | |
| read()) |
| + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT; |
| value = decodeUtf16StringAsString(); |
| if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) { |
| _attributeValueTable.add(value); |
| } |
| |
| _attributes.addAttribute(name, value); |
| break; |
| case DecoderStateTables.NISTRING_RA: |
| { |
| final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; |
| // Decode resitricted alphabet integer |
| _identifier = (b & 0x0F) << 4; |
| b = read(); |
| _identifier |= (b & 0xF0) >> 4; |
| |
| decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b); |
| |
| value = decodeRestrictedAlphabetAsString(); |
| if (addToTable) { |
| _attributeValueTable.add(value); |
| } |
| |
| _attributes.addAttribute(name, value); |
| break; |
| } |
| case DecoderStateTables.NISTRING_EA: |
| { |
| final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; |
| |
| _identifier = (b & 0x0F) << 4; |
| b = read(); |
| _identifier |= (b & 0xF0) >> 4; |
| |
| decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b); |
| |
| processAIIEncodingAlgorithm(name, addToTable); |
| break; |
| } |
| case DecoderStateTables.NISTRING_INDEX_SMALL: |
| _attributes.addAttribute(name, |
| _attributeValueTable._array[b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK]); |
| break; |
| case DecoderStateTables.NISTRING_INDEX_MEDIUM: |
| { |
| final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) |
| + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; |
| |
| _attributes.addAttribute(name, |
| _attributeValueTable._array[index]); |
| break; |
| } |
| case DecoderStateTables.NISTRING_INDEX_LARGE: |
| { |
| final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) |
| + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; |
| |
| _attributes.addAttribute(name, |
| _attributeValueTable._array[index]); |
| break; |
| } |
| case DecoderStateTables.NISTRING_EMPTY: |
| _attributes.addAttribute(name, ""); |
| break; |
| default: |
| throw new IOException(CommonResourceBundle.getInstance().getString("message.decodingAIIValue")); |
| } |
| |
| } while (!_terminate); |
| |
| // Reset duplication attribute verfifier |
| _duplicateAttributeVerifier._poolCurrent = _duplicateAttributeVerifier._poolHead; |
| |
| _terminate = _doubleTerminate; |
| _doubleTerminate = false; |
| } |
| |
| protected final void processCommentII() throws FastInfosetException, IOException { |
| switch(decodeNonIdentifyingStringOnFirstBit()) { |
| case NISTRING_STRING: |
| if (_addToTable) { |
| _v.otherString.add(new CharArray(_charBuffer, 0, _charBufferLength, true)); |
| } |
| |
| try { |
| _lexicalHandler.comment(_charBuffer, 0, _charBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCommentII", e); |
| } |
| break; |
| case NISTRING_ENCODING_ALGORITHM: |
| throw new IOException(CommonResourceBundle.getInstance().getString("message.commentIIAlgorithmNotSupported")); |
| case NISTRING_INDEX: |
| final CharArray ca = _v.otherString.get(_integer); |
| |
| try { |
| _lexicalHandler.comment(ca.ch, ca.start, ca.length); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCommentII", e); |
| } |
| break; |
| case NISTRING_EMPTY_STRING: |
| try { |
| _lexicalHandler.comment(_charBuffer, 0, 0); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processCommentII", e); |
| } |
| break; |
| } |
| } |
| |
| protected final void processProcessingII() throws FastInfosetException, IOException { |
| final String target = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName); |
| |
| switch(decodeNonIdentifyingStringOnFirstBit()) { |
| case NISTRING_STRING: |
| final String data = new String(_charBuffer, 0, _charBufferLength); |
| if (_addToTable) { |
| _v.otherString.add(new CharArrayString(data)); |
| } |
| try { |
| _contentHandler.processingInstruction(target, data); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processProcessingII", e); |
| } |
| break; |
| case NISTRING_ENCODING_ALGORITHM: |
| throw new IOException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm")); |
| case NISTRING_INDEX: |
| try { |
| _contentHandler.processingInstruction(target, _v.otherString.get(_integer).toString()); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processProcessingII", e); |
| } |
| break; |
| case NISTRING_EMPTY_STRING: |
| try { |
| _contentHandler.processingInstruction(target, ""); |
| } catch (SAXException e) { |
| throw new FastInfosetException("processProcessingII", e); |
| } |
| break; |
| } |
| } |
| |
| protected final void processCIIEncodingAlgorithm(boolean addToTable) throws FastInfosetException, IOException { |
| if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) { |
| if (_primitiveHandler != null) { |
| processCIIBuiltInEncodingAlgorithmAsPrimitive(); |
| } else if (_algorithmHandler != null) { |
| Object array = processBuiltInEncodingAlgorithmAsObject(); |
| |
| try { |
| _algorithmHandler.object(null, _identifier, array); |
| } catch (SAXException e) { |
| throw new FastInfosetException(e); |
| } |
| } else { |
| StringBuffer buffer = new StringBuffer(); |
| processBuiltInEncodingAlgorithmAsCharacters(buffer); |
| |
| try { |
| _contentHandler.characters(buffer.toString().toCharArray(), 0, buffer.length()); |
| } catch (SAXException e) { |
| throw new FastInfosetException(e); |
| } |
| } |
| |
| if (addToTable) { |
| StringBuffer buffer = new StringBuffer(); |
| processBuiltInEncodingAlgorithmAsCharacters(buffer); |
| _characterContentChunkTable.add(buffer.toString().toCharArray(), buffer.length()); |
| } |
| } else if (_identifier == EncodingAlgorithmIndexes.CDATA) { |
| // Set back buffer position to start of encoded string |
| _octetBufferOffset -= _octetBufferLength; |
| decodeUtf8StringIntoCharBuffer(); |
| |
| try { |
| _lexicalHandler.startCDATA(); |
| _contentHandler.characters(_charBuffer, 0, _charBufferLength); |
| _lexicalHandler.endCDATA(); |
| } catch (SAXException e) { |
| throw new FastInfosetException(e); |
| } |
| |
| if (addToTable) { |
| _characterContentChunkTable.add(_charBuffer, _charBufferLength); |
| } |
| } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START && _algorithmHandler != null) { |
| final String URI = _v.encodingAlgorithm.get(_identifier - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START); |
| if (URI == null) { |
| throw new EncodingAlgorithmException(CommonResourceBundle.getInstance(). |
| getString("message.URINotPresent", new Object[]{Integer.valueOf(_identifier)})); |
| } |
| |
| final EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI); |
| if (ea != null) { |
| final Object data = ea.decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength); |
| try { |
| _algorithmHandler.object(URI, _identifier, data); |
| } catch (SAXException e) { |
| throw new FastInfosetException(e); |
| } |
| } else { |
| try { |
| _algorithmHandler.octets(URI, _identifier, _octetBuffer, _octetBufferStart, _octetBufferLength); |
| } catch (SAXException e) { |
| throw new FastInfosetException(e); |
| } |
| } |
| if (addToTable) { |
| throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.addToTableNotSupported")); |
| } |
| } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) { |
| // TODO should have property to ignore |
| throw new EncodingAlgorithmException( |
| CommonResourceBundle.getInstance().getString("message.algorithmDataCannotBeReported")); |
| } else { |
| // Reserved built-in algorithms for future use |
| // TODO should use sax property to decide if event will be |
| // reported, allows for support through handler if required. |
| throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved")); |
| } |
| } |
| |
| protected final void processCIIBuiltInEncodingAlgorithmAsPrimitive() throws FastInfosetException, IOException { |
| try { |
| int length; |
| switch(_identifier) { |
| case EncodingAlgorithmIndexes.HEXADECIMAL: |
| case EncodingAlgorithmIndexes.BASE64: |
| _primitiveHandler.bytes(_octetBuffer, _octetBufferStart, _octetBufferLength); |
| break; |
| case EncodingAlgorithmIndexes.SHORT: |
| length = BuiltInEncodingAlgorithmFactory.shortEncodingAlgorithm. |
| getPrimtiveLengthFromOctetLength(_octetBufferLength); |
| if (length > builtInAlgorithmState.shortArray.length) { |
| final short[] array = new short[length * 3 / 2 + 1]; |
| System.arraycopy(builtInAlgorithmState.shortArray, 0, |
| array, 0, builtInAlgorithmState.shortArray.length); |
| builtInAlgorithmState.shortArray = array; |
| } |
| |
| BuiltInEncodingAlgorithmFactory.shortEncodingAlgorithm. |
| decodeFromBytesToShortArray(builtInAlgorithmState.shortArray, 0, |
| _octetBuffer, _octetBufferStart, _octetBufferLength); |
| _primitiveHandler.shorts(builtInAlgorithmState.shortArray, 0, length); |
| break; |
| case EncodingAlgorithmIndexes.INT: |
| length = BuiltInEncodingAlgorithmFactory.intEncodingAlgorithm. |
| getPrimtiveLengthFromOctetLength(_octetBufferLength); |
| if (length > builtInAlgorithmState.intArray.length) { |
| final int[] array = new int[length * 3 / 2 + 1]; |
| System.arraycopy(builtInAlgorithmState.intArray, 0, |
| array, 0, builtInAlgorithmState.intArray.length); |
| builtInAlgorithmState.intArray = array; |
| } |
| |
| BuiltInEncodingAlgorithmFactory.intEncodingAlgorithm. |
| decodeFromBytesToIntArray(builtInAlgorithmState.intArray, 0, |
| _octetBuffer, _octetBufferStart, _octetBufferLength); |
| _primitiveHandler.ints(builtInAlgorithmState.intArray, 0, length); |
| break; |
| case EncodingAlgorithmIndexes.LONG: |
| length = BuiltInEncodingAlgorithmFactory.longEncodingAlgorithm. |
| getPrimtiveLengthFromOctetLength(_octetBufferLength); |
| if (length > builtInAlgorithmState.longArray.length) { |
| final long[] array = new long[length * 3 / 2 + 1]; |
| System.arraycopy(builtInAlgorithmState.longArray, 0, |
| array, 0, builtInAlgorithmState.longArray.length); |
| builtInAlgorithmState.longArray = array; |
| } |
| |
| BuiltInEncodingAlgorithmFactory.longEncodingAlgorithm. |
| decodeFromBytesToLongArray(builtInAlgorithmState.longArray, 0, |
| _octetBuffer, _octetBufferStart, _octetBufferLength); |
| _primitiveHandler.longs(builtInAlgorithmState.longArray, 0, length); |
| break; |
| case EncodingAlgorithmIndexes.BOOLEAN: |
| length = BuiltInEncodingAlgorithmFactory.booleanEncodingAlgorithm. |
| getPrimtiveLengthFromOctetLength(_octetBufferLength, _octetBuffer[_octetBufferStart] & 0xFF); |
| if (length > builtInAlgorithmState.booleanArray.length) { |
| final boolean[] array = new boolean[length * 3 / 2 + 1]; |
| System.arraycopy(builtInAlgorithmState.booleanArray, 0, |
| array, 0, builtInAlgorithmState.booleanArray.length); |
| builtInAlgorithmState.booleanArray = array; |
| } |
| |
| BuiltInEncodingAlgorithmFactory.booleanEncodingAlgorithm. |
| decodeFromBytesToBooleanArray( |
| builtInAlgorithmState.booleanArray, 0, length, |
| _octetBuffer, _octetBufferStart, _octetBufferLength); |
| _primitiveHandler.booleans(builtInAlgorithmState.booleanArray, 0, length); |
| break; |
| case EncodingAlgorithmIndexes.FLOAT: |
| length = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm. |
| getPrimtiveLengthFromOctetLength(_octetBufferLength); |
| if (length > builtInAlgorithmState.floatArray.length) { |
| final float[] array = new float[length * 3 / 2 + 1]; |
| System.arraycopy(builtInAlgorithmState.floatArray, 0, |
| array, 0, builtInAlgorithmState.floatArray.length); |
| builtInAlgorithmState.floatArray = array; |
| } |
| |
| BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm. |
| decodeFromBytesToFloatArray(builtInAlgorithmState.floatArray, 0, |
| _octetBuffer, _octetBufferStart, _octetBufferLength); |
| _primitiveHandler.floats(builtInAlgorithmState.floatArray, 0, length); |
| break; |
| case EncodingAlgorithmIndexes.DOUBLE: |
| length = BuiltInEncodingAlgorithmFactory.doubleEncodingAlgorithm. |
| getPrimtiveLengthFromOctetLength(_octetBufferLength); |
| if (length > builtInAlgorithmState.doubleArray.length) { |
| final double[] array = new double[length * 3 / 2 + 1]; |
| System.arraycopy(builtInAlgorithmState.doubleArray, 0, |
| array, 0, builtInAlgorithmState.doubleArray.length); |
| builtInAlgorithmState.doubleArray = array; |
| } |
| |
| BuiltInEncodingAlgorithmFactory.doubleEncodingAlgorithm. |
| decodeFromBytesToDoubleArray(builtInAlgorithmState.doubleArray, 0, |
| _octetBuffer, _octetBufferStart, _octetBufferLength); |
| _primitiveHandler.doubles(builtInAlgorithmState.doubleArray, 0, length); |
| break; |
| case EncodingAlgorithmIndexes.UUID: |
| length = BuiltInEncodingAlgorithmFactory.uuidEncodingAlgorithm. |
| getPrimtiveLengthFromOctetLength(_octetBufferLength); |
| if (length > builtInAlgorithmState.longArray.length) { |
| final long[] array = new long[length * 3 / 2 + 1]; |
| System.arraycopy(builtInAlgorithmState.longArray, 0, |
| array, 0, builtInAlgorithmState.longArray.length); |
| builtInAlgorithmState.longArray = array; |
| } |
| |
| BuiltInEncodingAlgorithmFactory.uuidEncodingAlgorithm. |
| decodeFromBytesToLongArray(builtInAlgorithmState.longArray, 0, |
| _octetBuffer, _octetBufferStart, _octetBufferLength); |
| _primitiveHandler.uuids(builtInAlgorithmState.longArray, 0, length); |
| break; |
| case EncodingAlgorithmIndexes.CDATA: |
| throw new UnsupportedOperationException("CDATA"); |
| default: |
| throw new FastInfosetException(CommonResourceBundle.getInstance(). |
| getString("message.unsupportedAlgorithm", new Object[]{Integer.valueOf(_identifier)})); |
| } |
| } catch (SAXException e) { |
| throw new FastInfosetException(e); |
| } |
| } |
| |
| |
| protected final void processAIIEncodingAlgorithm(QualifiedName name, boolean addToTable) throws FastInfosetException, IOException { |
| if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) { |
| if (_primitiveHandler != null || _algorithmHandler != null) { |
| Object data = processBuiltInEncodingAlgorithmAsObject(); |
| _attributes.addAttributeWithAlgorithmData(name, null, _identifier, data); |
| } else { |
| StringBuffer buffer = new StringBuffer(); |
| processBuiltInEncodingAlgorithmAsCharacters(buffer); |
| _attributes.addAttribute(name, buffer.toString()); |
| } |
| } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START && _algorithmHandler != null) { |
| final String URI = _v.encodingAlgorithm.get(_identifier - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START); |
| if (URI == null) { |
| throw new EncodingAlgorithmException(CommonResourceBundle.getInstance(). |
| getString("message.URINotPresent", new Object[]{Integer.valueOf(_identifier)})); |
| } |
| |
| final EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI); |
| if (ea != null) { |
| final Object data = ea.decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength); |
| _attributes.addAttributeWithAlgorithmData(name, URI, _identifier, data); |
| } else { |
| final byte[] data = new byte[_octetBufferLength]; |
| System.arraycopy(_octetBuffer, _octetBufferStart, data, 0, _octetBufferLength); |
| _attributes.addAttributeWithAlgorithmData(name, URI, _identifier, data); |
| } |
| } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) { |
| // TODO should have property to ignore |
| throw new EncodingAlgorithmException( |
| CommonResourceBundle.getInstance().getString("message.algorithmDataCannotBeReported")); |
| } else if (_identifier == EncodingAlgorithmIndexes.CDATA) { |
| throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported")); |
| } else { |
| // Reserved built-in algorithms for future use |
| // TODO should use sax property to decide if event will be |
| // reported, allows for support through handler if required. |
| throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved")); |
| } |
| |
| if (addToTable) { |
| _attributeValueTable.add(_attributes.getValue(_attributes.getIndex(name.qName))); |
| } |
| } |
| |
| protected final void processBuiltInEncodingAlgorithmAsCharacters(StringBuffer buffer) throws FastInfosetException, IOException { |
| // TODO not very efficient, need to reuse buffers |
| Object array = BuiltInEncodingAlgorithmFactory.getAlgorithm(_identifier). |
| decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength); |
| |
| BuiltInEncodingAlgorithmFactory.getAlgorithm(_identifier).convertToCharacters(array, buffer); |
| } |
| |
| protected final Object processBuiltInEncodingAlgorithmAsObject() throws FastInfosetException, IOException { |
| return BuiltInEncodingAlgorithmFactory.getAlgorithm(_identifier). |
| decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength); |
| } |
| } |