src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/stax/StAXDocumentParser.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 384
8f2986ff0235
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  *
    25  * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
    26  */
    28 package com.sun.xml.internal.fastinfoset.stax;
    30 import com.sun.xml.internal.fastinfoset.Decoder;
    31 import com.sun.xml.internal.fastinfoset.DecoderStateTables;
    32 import com.sun.xml.internal.fastinfoset.EncodingConstants;
    33 import com.sun.xml.internal.fastinfoset.OctetBufferListener;
    34 import com.sun.xml.internal.fastinfoset.QualifiedName;
    35 import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
    36 import com.sun.xml.internal.fastinfoset.sax.AttributesHolder;
    37 import com.sun.xml.internal.fastinfoset.util.CharArray;
    38 import com.sun.xml.internal.fastinfoset.util.CharArrayString;
    39 import java.io.IOException;
    40 import java.io.InputStream;
    41 import java.util.Iterator;
    42 import java.util.NoSuchElementException;
    43 import javax.xml.namespace.NamespaceContext;
    44 import javax.xml.namespace.QName;
    45 import javax.xml.stream.Location;
    46 import javax.xml.stream.XMLStreamException;
    47 import javax.xml.stream.XMLStreamReader;
    48 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithm;
    49 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException;
    50 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
    51 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
    52 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
    53 import com.sun.xml.internal.fastinfoset.org.apache.xerces.util.XMLChar;
    54 import com.sun.xml.internal.fastinfoset.util.DuplicateAttributeVerifier;
    55 import java.util.logging.Level;
    56 import java.util.logging.Logger;
    57 import com.sun.xml.internal.org.jvnet.fastinfoset.stax.FastInfosetStreamReader;
    59 /**
    60  * The Fast Infoset StAX parser.
    61  * <p>
    62  * Instantiate this parser to parse a fast infoset document in accordance
    63  * with the StAX API.
    64  *
    65  * <p>
    66  * More than one fast infoset document may be decoded from the
    67  * {@link java.io.InputStream}.
    68  */
    69 public class StAXDocumentParser extends Decoder
    70         implements XMLStreamReader, FastInfosetStreamReader, OctetBufferListener {
    71     private static final Logger logger = Logger.getLogger(StAXDocumentParser.class.getName());
    73     protected static final int INTERNAL_STATE_START_DOCUMENT = 0;
    74     protected static final int INTERNAL_STATE_START_ELEMENT_TERMINATE = 1;
    75     protected static final int INTERNAL_STATE_SINGLE_TERMINATE_ELEMENT_WITH_NAMESPACES = 2;
    76     protected static final int INTERNAL_STATE_DOUBLE_TERMINATE_ELEMENT = 3;
    77     protected static final int INTERNAL_STATE_END_DOCUMENT = 4;
    78     protected static final int INTERNAL_STATE_VOID = -1;
    80     protected int _internalState;
    82     /**
    83      * Current event
    84      */
    85     protected int _eventType;
    87     /**
    88      * Stack of qualified names and namespaces
    89      */
    90     protected QualifiedName[] _qNameStack = new QualifiedName[32];
    91     protected int[] _namespaceAIIsStartStack = new int[32];
    92     protected int[] _namespaceAIIsEndStack = new int[32];
    93     protected int _stackCount = -1;
    95     protected String[] _namespaceAIIsPrefix = new String[32];
    96     protected String[] _namespaceAIIsNamespaceName = new String[32];
    97     protected int[] _namespaceAIIsPrefixIndex = new int[32];
    98     protected int _namespaceAIIsIndex;
   100     /**
   101      * Namespaces associated with START_ELEMENT or END_ELEMENT
   102      */
   103     protected int _currentNamespaceAIIsStart;
   104     protected int _currentNamespaceAIIsEnd;
   106     /**
   107      * Qualified name associated with START_ELEMENT or END_ELEMENT.
   108      */
   109     protected QualifiedName _qualifiedName;
   111     /**
   112      * List of attributes
   113      */
   114     protected AttributesHolder _attributes = new AttributesHolder();
   116     protected boolean _clearAttributes = false;
   118     /**
   119      * Characters associated with event.
   120      */
   121     protected char[] _characters;
   122     protected int _charactersOffset;
   124     protected String _algorithmURI;
   125     protected int _algorithmId;
   126     protected boolean _isAlgorithmDataCloned;
   127     protected byte[] _algorithmData;
   128     protected int _algorithmDataOffset;
   129     protected int _algorithmDataLength;
   131     /**
   132      * State for processing instruction
   133      */
   134     protected String _piTarget;
   135     protected String _piData;
   137     protected NamespaceContextImpl _nsContext = new NamespaceContextImpl();
   139     protected String _characterEncodingScheme;
   141     protected StAXManager _manager;
   143     public StAXDocumentParser() {
   144         reset();
   145         _manager = new StAXManager(StAXManager.CONTEXT_READER);
   146     }
   148     public StAXDocumentParser(InputStream s) {
   149         this();
   150         setInputStream(s);
   151         _manager = new StAXManager(StAXManager.CONTEXT_READER);
   152     }
   154     public StAXDocumentParser(InputStream s, StAXManager manager) {
   155         this(s);
   156         _manager = manager;
   157     }
   159     @Override
   160     public void setInputStream(InputStream s) {
   161         super.setInputStream(s);
   162         reset();
   163     }
   165     @Override
   166     public void reset() {
   167         super.reset();
   168         if (_internalState != INTERNAL_STATE_START_DOCUMENT &&
   169                 _internalState != INTERNAL_STATE_END_DOCUMENT) {
   171             for (int i = _namespaceAIIsIndex - 1; i >= 0; i--) {
   172                 _prefixTable.popScopeWithPrefixEntry(_namespaceAIIsPrefixIndex[i]);
   173             }
   175             _stackCount = -1;
   177             _namespaceAIIsIndex = 0;
   178             _characters = null;
   179             _algorithmData = null;
   180         }
   182         _characterEncodingScheme = "UTF-8";
   183         _eventType = START_DOCUMENT;
   184         _internalState = INTERNAL_STATE_START_DOCUMENT;
   185     }
   187     protected void resetOnError() {
   188         super.reset();
   190         if (_v != null) {
   191             _prefixTable.clearCompletely();
   192         }
   193         _duplicateAttributeVerifier.clear();
   195         _stackCount = -1;
   197         _namespaceAIIsIndex = 0;
   198         _characters = null;
   199         _algorithmData = null;
   201         _eventType = START_DOCUMENT;
   202         _internalState = INTERNAL_STATE_START_DOCUMENT;
   203     }
   205     // -- XMLStreamReader Interface -------------------------------------------
   207     public Object getProperty(java.lang.String name)
   208     throws java.lang.IllegalArgumentException {
   209         if (_manager != null) {
   210             return _manager.getProperty(name);
   211         }
   212         return null;
   213     }
   215     public int next() throws XMLStreamException {
   216         try {
   217             if (_internalState != INTERNAL_STATE_VOID) {
   218                 switch (_internalState) {
   219                     case INTERNAL_STATE_START_DOCUMENT:
   220                         decodeHeader();
   221                         processDII();
   223                         _internalState = INTERNAL_STATE_VOID;
   224                         break;
   225                     case INTERNAL_STATE_START_ELEMENT_TERMINATE:
   226                         if (_currentNamespaceAIIsEnd > 0) {
   227                             for (int i = _currentNamespaceAIIsEnd - 1; i >= _currentNamespaceAIIsStart; i--) {
   228                                 _prefixTable.popScopeWithPrefixEntry(_namespaceAIIsPrefixIndex[i]);
   229                             }
   230                             _namespaceAIIsIndex = _currentNamespaceAIIsStart;
   231                         }
   233                         // Pop information off the stack
   234                         popStack();
   236                         _internalState = INTERNAL_STATE_VOID;
   237                         return _eventType = END_ELEMENT;
   238                     case INTERNAL_STATE_SINGLE_TERMINATE_ELEMENT_WITH_NAMESPACES:
   239                         // Undeclare namespaces
   240                         for (int i = _currentNamespaceAIIsEnd - 1; i >= _currentNamespaceAIIsStart; i--) {
   241                             _prefixTable.popScopeWithPrefixEntry(_namespaceAIIsPrefixIndex[i]);
   242                         }
   243                         _namespaceAIIsIndex = _currentNamespaceAIIsStart;
   244                         _internalState = INTERNAL_STATE_VOID;
   245                         break;
   246                     case INTERNAL_STATE_DOUBLE_TERMINATE_ELEMENT:
   247                         // Undeclare namespaces
   248                         if (_currentNamespaceAIIsEnd > 0) {
   249                             for (int i = _currentNamespaceAIIsEnd - 1; i >= _currentNamespaceAIIsStart; i--) {
   250                                 _prefixTable.popScopeWithPrefixEntry(_namespaceAIIsPrefixIndex[i]);
   251                             }
   252                             _namespaceAIIsIndex = _currentNamespaceAIIsStart;
   253                         }
   255                         if (_stackCount == -1) {
   256                             _internalState = INTERNAL_STATE_END_DOCUMENT;
   257                             return _eventType = END_DOCUMENT;
   258                         }
   260                         // Pop information off the stack
   261                         popStack();
   263                         _internalState = (_currentNamespaceAIIsEnd > 0) ?
   264                             INTERNAL_STATE_SINGLE_TERMINATE_ELEMENT_WITH_NAMESPACES :
   265                             INTERNAL_STATE_VOID;
   266                         return _eventType = END_ELEMENT;
   267                     case INTERNAL_STATE_END_DOCUMENT:
   268                         throw new NoSuchElementException(CommonResourceBundle.getInstance().getString("message.noMoreEvents"));
   269                 }
   270             }
   272             // Reset internal state
   273             _characters = null;
   274             _algorithmData = null;
   275             _currentNamespaceAIIsEnd = 0;
   277             // Process information item
   278             final int b = read();
   279             switch(DecoderStateTables.EII(b)) {
   280                 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
   281                     processEII(_elementNameTable._array[b], false);
   282                     return _eventType;
   283                 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
   284                     processEII(_elementNameTable._array[b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
   285                     return _eventType;
   286                 case DecoderStateTables.EII_INDEX_MEDIUM:
   287                     processEII(processEIIIndexMedium(b), (b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   288                     return _eventType;
   289                 case DecoderStateTables.EII_INDEX_LARGE:
   290                     processEII(processEIIIndexLarge(b), (b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   291                     return _eventType;
   292                 case DecoderStateTables.EII_LITERAL:
   293                 {
   294                     final QualifiedName qn = processLiteralQualifiedName(
   295                             b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
   296                             _elementNameTable.getNext());
   297                     _elementNameTable.add(qn);
   298                     processEII(qn, (b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   299                     return _eventType;
   300                 }
   301                 case DecoderStateTables.EII_NAMESPACES:
   302                     processEIIWithNamespaces((b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   303                     return _eventType;
   304                 case DecoderStateTables.CII_UTF8_SMALL_LENGTH:
   305                     _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
   306                     + 1;
   307                     processUtf8CharacterString(b);
   308                     return _eventType = CHARACTERS;
   309                 case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH:
   310                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
   311                     processUtf8CharacterString(b);
   312                     return _eventType = CHARACTERS;
   313                 case DecoderStateTables.CII_UTF8_LARGE_LENGTH:
   314                     _octetBufferLength = ((read() << 24) |
   315                             (read() << 16) |
   316                             (read() << 8) |
   317                             read())
   318                             + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
   319                     processUtf8CharacterString(b);
   320                     return _eventType = CHARACTERS;
   321                 case DecoderStateTables.CII_UTF16_SMALL_LENGTH:
   322                     _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
   323                     + 1;
   324                     processUtf16CharacterString(b);
   325                     return _eventType = CHARACTERS;
   326                 case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH:
   327                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
   328                     processUtf16CharacterString(b);
   329                     return _eventType = CHARACTERS;
   330                 case DecoderStateTables.CII_UTF16_LARGE_LENGTH:
   331                     _octetBufferLength = ((read() << 24) |
   332                             (read() << 16) |
   333                             (read() << 8) |
   334                             read())
   335                             + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
   336                     processUtf16CharacterString(b);
   337                     return _eventType = CHARACTERS;
   338                 case DecoderStateTables.CII_RA:
   339                 {
   340                     final boolean addToTable = (b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
   342                     _identifier = (b & 0x02) << 6;
   343                     final int b2 = read();
   344                     _identifier |= (b2 & 0xFC) >> 2;
   346                     decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(b2);
   348                     decodeRestrictedAlphabetAsCharBuffer();
   350                     if (addToTable) {
   351                         _charactersOffset = _characterContentChunkTable.add(_charBuffer, _charBufferLength);
   352                         _characters = _characterContentChunkTable._array;
   353                     } else {
   354                         _characters = _charBuffer;
   355                         _charactersOffset = 0;
   356                     }
   357                     return _eventType = CHARACTERS;
   358                 }
   359                 case DecoderStateTables.CII_EA:
   360                 {
   361                     final boolean addToTable = (b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
   362                     // Decode encoding algorithm integer
   363                     _algorithmId = (b & 0x02) << 6;
   364                     final int b2 = read();
   365                     _algorithmId |= (b2 & 0xFC) >> 2;
   367                     decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(b2);
   368                     processCIIEncodingAlgorithm(addToTable);
   370                     if (_algorithmId == EncodingAlgorithmIndexes.CDATA) {
   371                         return _eventType = CDATA;
   372                     }
   374                     return _eventType = CHARACTERS;
   375                 }
   376                 case DecoderStateTables.CII_INDEX_SMALL:
   377                 {
   378                     final int index = b & EncodingConstants.INTEGER_4TH_BIT_SMALL_MASK;
   379                     _characterContentChunkTable._cachedIndex = index;
   381                     _characters = _characterContentChunkTable._array;
   382                     _charactersOffset = _characterContentChunkTable._offset[index];
   383                     _charBufferLength = _characterContentChunkTable._length[index];
   384                     return _eventType = CHARACTERS;
   385                 }
   386                 case DecoderStateTables.CII_INDEX_MEDIUM:
   387                 {
   388                     final int index = (((b & EncodingConstants.INTEGER_4TH_BIT_MEDIUM_MASK) << 8) | read())
   389                     + EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT;
   390                     _characterContentChunkTable._cachedIndex = index;
   392                     _characters = _characterContentChunkTable._array;
   393                     _charactersOffset = _characterContentChunkTable._offset[index];
   394                     _charBufferLength = _characterContentChunkTable._length[index];
   395                     return _eventType = CHARACTERS;
   396                 }
   397                 case DecoderStateTables.CII_INDEX_LARGE:
   398                 {
   399                     final int index = (((b & EncodingConstants.INTEGER_4TH_BIT_LARGE_MASK) << 16) |
   400                             (read() << 8) |
   401                             read())
   402                             + EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT;
   403                     _characterContentChunkTable._cachedIndex = index;
   405                     _characters = _characterContentChunkTable._array;
   406                     _charactersOffset = _characterContentChunkTable._offset[index];
   407                     _charBufferLength = _characterContentChunkTable._length[index];
   408                     return _eventType = CHARACTERS;
   409                 }
   410                 case DecoderStateTables.CII_INDEX_LARGE_LARGE:
   411                 {
   412                     final int index = ((read() << 16) |
   413                             (read() << 8) |
   414                             read())
   415                             + EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT;
   416                     _characterContentChunkTable._cachedIndex = index;
   418                     _characters = _characterContentChunkTable._array;
   419                     _charactersOffset = _characterContentChunkTable._offset[index];
   420                     _charBufferLength = _characterContentChunkTable._length[index];
   421                     return _eventType = CHARACTERS;
   422                 }
   423                 case DecoderStateTables.COMMENT_II:
   424                     processCommentII();
   425                     return _eventType;
   426                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
   427                     processProcessingII();
   428                     return _eventType;
   429                 case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II:
   430                 {
   431                     processUnexpandedEntityReference(b);
   432                     // Skip the reference
   433                     return next();
   434                 }
   435                 case DecoderStateTables.TERMINATOR_DOUBLE:
   436                     if (_stackCount != -1) {
   437                         // Pop information off the stack
   438                         popStack();
   440                         _internalState = INTERNAL_STATE_DOUBLE_TERMINATE_ELEMENT;
   441                         return _eventType = END_ELEMENT;
   442                     }
   444                     _internalState = INTERNAL_STATE_END_DOCUMENT;
   445                     return _eventType = END_DOCUMENT;
   446                 case DecoderStateTables.TERMINATOR_SINGLE:
   447                     if (_stackCount != -1) {
   448                         // Pop information off the stack
   449                         popStack();
   451                         if (_currentNamespaceAIIsEnd > 0) {
   452                             _internalState = INTERNAL_STATE_SINGLE_TERMINATE_ELEMENT_WITH_NAMESPACES;
   453                         }
   454                         return _eventType = END_ELEMENT;
   455                     }
   457                     _internalState = INTERNAL_STATE_END_DOCUMENT;
   458                     return _eventType = END_DOCUMENT;
   459                 default:
   460                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEII"));
   461             }
   462         } catch (IOException e) {
   463             resetOnError();
   464             logger.log(Level.FINE, "next() exception", e);
   465             throw new XMLStreamException(e);
   466         } catch (FastInfosetException e) {
   467             resetOnError();
   468             logger.log(Level.FINE, "next() exception", e);
   469             throw new XMLStreamException(e);
   470         } catch (RuntimeException e) {
   471             resetOnError();
   472             logger.log(Level.FINE, "next() exception", e);
   473             throw e;
   474         }
   475     }
   477     private final void processUtf8CharacterString(final int b) throws IOException {
   478         if ((b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
   479             _characterContentChunkTable.ensureSize(_octetBufferLength);
   480             _characters = _characterContentChunkTable._array;
   481             _charactersOffset = _characterContentChunkTable._arrayIndex;
   482             decodeUtf8StringAsCharBuffer(_characterContentChunkTable._array, _charactersOffset);
   483             _characterContentChunkTable.add(_charBufferLength);
   484         } else {
   485             decodeUtf8StringAsCharBuffer();
   486             _characters = _charBuffer;
   487             _charactersOffset = 0;
   488         }
   489     }
   491     private final void processUtf16CharacterString(final int b) throws IOException {
   492         decodeUtf16StringAsCharBuffer();
   493         if ((b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
   494             _charactersOffset = _characterContentChunkTable.add(_charBuffer, _charBufferLength);
   495             _characters = _characterContentChunkTable._array;
   496         } else {
   497             _characters = _charBuffer;
   498             _charactersOffset = 0;
   499         }
   500     }
   502     private void popStack() {
   503         // Pop information off the stack
   504         _qualifiedName = _qNameStack[_stackCount];
   505         _currentNamespaceAIIsStart = _namespaceAIIsStartStack[_stackCount];
   506         _currentNamespaceAIIsEnd = _namespaceAIIsEndStack[_stackCount];
   507         _qNameStack[_stackCount--] = null;
   508     }
   510     /** Test if the current event is of the given type and if the namespace and name match the current namespace and name of the current event.
   511      * If the namespaceURI is null it is not checked for equality, if the localName is null it is not checked for equality.
   512      * @param type the event type
   513      * @param namespaceURI the uri of the event, may be null
   514      * @param localName the localName of the event, may be null
   515      * @throws XMLStreamException if the required values are not matched.
   516      */
   517     public final void require(int type, String namespaceURI, String localName)
   518     throws XMLStreamException {
   519         if( type != _eventType)
   520             throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.eventTypeNotMatch", new Object[]{getEventTypeString(type)}));
   521         if( namespaceURI != null && !namespaceURI.equals(getNamespaceURI()) )
   522             throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.namespaceURINotMatch", new Object[]{namespaceURI}));
   523         if(localName != null && !localName.equals(getLocalName()))
   524             throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.localNameNotMatch", new Object[]{localName}));
   525     }
   527     /** Reads the content of a text-only element. Precondition:
   528      * the current event is START_ELEMENT. Postcondition:
   529      * The current event is the corresponding END_ELEMENT.
   530      * @throws XMLStreamException if the current event is not a START_ELEMENT or if
   531      * a non text element is encountered
   532      */
   533     public final String getElementText() throws XMLStreamException {
   535         if(getEventType() != START_ELEMENT) {
   536             throw new XMLStreamException(
   537                     CommonResourceBundle.getInstance().getString("message.mustBeOnSTARTELEMENT"), getLocation());
   538         }
   539         //current is StartElement, move to the next
   540         next();
   541         return getElementText(true);
   542     }
   543     /**
   544      * @param startElementRead flag if start element has already been read
   545      */
   546     public final String getElementText(boolean startElementRead) throws XMLStreamException {
   547         if (!startElementRead) {
   548             throw new XMLStreamException(
   549                     CommonResourceBundle.getInstance().getString("message.mustBeOnSTARTELEMENT"), getLocation());
   550         }
   551         int eventType = getEventType();
   552         StringBuilder content = new StringBuilder();
   553         while(eventType != END_ELEMENT ) {
   554             if(eventType == CHARACTERS
   555                     || eventType == CDATA
   556                     || eventType == SPACE
   557                     || eventType == ENTITY_REFERENCE) {
   558                 content.append(getText());
   559             } else if(eventType == PROCESSING_INSTRUCTION
   560                     || eventType == COMMENT) {
   561                 // skipping
   562             } else if(eventType == END_DOCUMENT) {
   563                 throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.unexpectedEOF"));
   564             } else if(eventType == START_ELEMENT) {
   565                 throw new XMLStreamException(
   566                         CommonResourceBundle.getInstance().getString("message.getElementTextExpectTextOnly"), getLocation());
   567             } else {
   568                 throw new XMLStreamException(
   569                         CommonResourceBundle.getInstance().getString("message.unexpectedEventType")+ getEventTypeString(eventType), getLocation());
   570             }
   571             eventType = next();
   572         }
   573         return content.toString();
   574     }
   576     /** Skips any white space (isWhiteSpace() returns true), COMMENT,
   577      * or PROCESSING_INSTRUCTION,
   578      * until a START_ELEMENT or END_ELEMENT is reached.
   579      * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
   580      * are encountered, an exception is thrown. This method should
   581      * be used when processing element-only content seperated by white space.
   582      * This method should
   583      * be used when processing element-only content because
   584      * the parser is not able to recognize ignorable whitespace if
   585      * then DTD is missing or not interpreted.
   586      * @return the event type of the element read
   587      * @throws XMLStreamException if the current event is not white space
   588      */
   589     public final int nextTag() throws XMLStreamException {
   590         next();
   591         return nextTag(true);
   592     }
   593     /** if the current tag has already read, such as in the case EventReader's
   594      * peek() has been called, the current cursor should not move before the loop
   595      */
   596     public final int nextTag(boolean currentTagRead) throws XMLStreamException {
   597         int eventType = getEventType();
   598         if (!currentTagRead) {
   599             eventType = next();
   600         }
   601         while((eventType == CHARACTERS && isWhiteSpace()) // skip whitespace
   602         || (eventType == CDATA && isWhiteSpace())
   603         || eventType == SPACE
   604                 || eventType == PROCESSING_INSTRUCTION
   605                 || eventType == COMMENT) {
   606             eventType = next();
   607         }
   608         if (eventType != START_ELEMENT && eventType != END_ELEMENT) {
   609             throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.expectedStartOrEnd"), getLocation());
   610         }
   611         return eventType;
   612     }
   614     public final boolean hasNext() throws XMLStreamException {
   615         return (_eventType != END_DOCUMENT);
   616     }
   618     public void close() throws XMLStreamException {
   619         try {
   620             super.closeIfRequired();
   621         } catch (IOException ex) {
   622         }
   623     }
   625     public final String getNamespaceURI(String prefix) {
   626         String namespace = getNamespaceDecl(prefix);
   627         if (namespace == null) {
   628             if (prefix == null) {
   629                 throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.nullPrefix"));
   630             }
   631             return null;  // unbound
   632         }
   633         return namespace;
   634     }
   636     public final boolean isStartElement() {
   637         return (_eventType == START_ELEMENT);
   638     }
   640     public final boolean isEndElement() {
   641         return (_eventType == END_ELEMENT);
   642     }
   644     public final boolean isCharacters() {
   645         return (_eventType == CHARACTERS);
   646     }
   648     /**
   649      *  Returns true if the cursor points to a character data event that consists of all whitespace
   650      *  Application calling this method needs to cache the value and avoid calling this method again
   651      *  for the same event.
   652      * @return true if the cursor points to all whitespace, false otherwise
   653      */
   654     public final boolean isWhiteSpace() {
   655         if(isCharacters() || (_eventType == CDATA)){
   656             char [] ch = this.getTextCharacters();
   657             int start = this.getTextStart();
   658             int length = this.getTextLength();
   659             for (int i = start; i < start + length; i++){
   660                 if(!XMLChar.isSpace(ch[i])){
   661                     return false;
   662                 }
   663             }
   664             return true;
   665         }
   666         return false;
   667     }
   669     public final String getAttributeValue(String namespaceURI, String localName) {
   670         if (_eventType != START_ELEMENT) {
   671             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   672         }
   674         if (localName == null)
   675             throw new IllegalArgumentException();
   677         // Search for the attributes in _attributes
   678         if (namespaceURI != null) {
   679             for (int i = 0; i < _attributes.getLength(); i++) {
   680                 if (_attributes.getLocalName(i).equals(localName) &&
   681                         _attributes.getURI(i).equals(namespaceURI)) {
   682                     return _attributes.getValue(i);
   683                 }
   684             }
   685         } else {
   686             for (int i = 0; i < _attributes.getLength(); i++) {
   687                 if (_attributes.getLocalName(i).equals(localName)) {
   688                     return _attributes.getValue(i);
   689                 }
   690             }
   691         }
   693         return null;
   694     }
   696     public final int getAttributeCount() {
   697         if (_eventType != START_ELEMENT) {
   698             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   699         }
   701         return _attributes.getLength();
   702     }
   704     public final javax.xml.namespace.QName getAttributeName(int index) {
   705         if (_eventType != START_ELEMENT) {
   706             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   707         }
   708         return _attributes.getQualifiedName(index).getQName();
   709     }
   711     public final String getAttributeNamespace(int index) {
   712         if (_eventType != START_ELEMENT) {
   713             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   714         }
   716         return _attributes.getURI(index);
   717     }
   719     public final String getAttributeLocalName(int index) {
   720         if (_eventType != START_ELEMENT) {
   721             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   722         }
   723         return _attributes.getLocalName(index);
   724     }
   726     public final String getAttributePrefix(int index) {
   727         if (_eventType != START_ELEMENT) {
   728             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   729         }
   730         return _attributes.getPrefix(index);
   731     }
   733     public final String getAttributeType(int index) {
   734         if (_eventType != START_ELEMENT) {
   735             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   736         }
   737         return _attributes.getType(index);
   738     }
   740     public final String getAttributeValue(int index) {
   741         if (_eventType != START_ELEMENT) {
   742             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   743         }
   744         return _attributes.getValue(index);
   745     }
   747     public final boolean isAttributeSpecified(int index) {
   748         return false;   // non-validating parser
   749     }
   751     public final int getNamespaceCount() {
   752         if (_eventType == START_ELEMENT || _eventType == END_ELEMENT) {
   753             return (_currentNamespaceAIIsEnd > 0) ? (_currentNamespaceAIIsEnd - _currentNamespaceAIIsStart) : 0;
   754         } else {
   755             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetNamespaceCount"));
   756         }
   757     }
   759     public final String getNamespacePrefix(int index) {
   760         if (_eventType == START_ELEMENT || _eventType == END_ELEMENT) {
   761             return _namespaceAIIsPrefix[_currentNamespaceAIIsStart + index];
   762         } else {
   763             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetNamespacePrefix"));
   764         }
   765     }
   767     public final String getNamespaceURI(int index) {
   768         if (_eventType == START_ELEMENT || _eventType == END_ELEMENT) {
   769             return _namespaceAIIsNamespaceName[_currentNamespaceAIIsStart + index];
   770         } else {
   771             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetNamespacePrefix"));
   772         }
   773     }
   775     public final NamespaceContext getNamespaceContext() {
   776         return _nsContext;
   777     }
   779     public final int getEventType() {
   780         return _eventType;
   781     }
   783     public final String getText() {
   784         if (_characters == null) {
   785             checkTextState();
   786         }
   788         if (_characters == _characterContentChunkTable._array) {
   789             return _characterContentChunkTable.getString(_characterContentChunkTable._cachedIndex);
   790         } else {
   791             return new String(_characters, _charactersOffset, _charBufferLength);
   792         }
   793     }
   795     public final char[] getTextCharacters() {
   796         if (_characters == null) {
   797             checkTextState();
   798         }
   800         return _characters;
   801     }
   803     public final int getTextStart() {
   804         if (_characters == null) {
   805             checkTextState();
   806         }
   808         return _charactersOffset;
   809     }
   811     public final int getTextLength() {
   812         if (_characters == null) {
   813             checkTextState();
   814         }
   816         return _charBufferLength;
   817     }
   819     public final int getTextCharacters(int sourceStart, char[] target,
   820             int targetStart, int length) throws XMLStreamException {
   821         if (_characters == null) {
   822             checkTextState();
   823         }
   825         try {
   826             int bytesToCopy = Math.min(_charBufferLength, length);
   827             System.arraycopy(_characters, _charactersOffset + sourceStart,
   828                     target, targetStart, bytesToCopy);
   829             return bytesToCopy;
   830         } catch (IndexOutOfBoundsException e) {
   831             throw new XMLStreamException(e);
   832         }
   833     }
   835     protected final void checkTextState() {
   836         if (_algorithmData == null) {
   837             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.InvalidStateForText"));
   838         }
   840         try {
   841             convertEncodingAlgorithmDataToCharacters();
   842         } catch (Exception e) {
   843             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.InvalidStateForText"));
   844         }
   845     }
   847     public final String getEncoding() {
   848         return _characterEncodingScheme;
   849     }
   851     public final boolean hasText() {
   852         return (_characters != null);
   853     }
   855     public final Location getLocation() {
   856         //location should be created in next()
   857         //returns a nil location for now
   858         return EventLocation.getNilLocation();
   859     }
   861     public final QName getName() {
   862         if (_eventType == START_ELEMENT || _eventType == END_ELEMENT) {
   863             return _qualifiedName.getQName();
   864         } else {
   865             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetName"));
   866         }
   867     }
   869     public final String getLocalName() {
   870         if (_eventType == START_ELEMENT || _eventType == END_ELEMENT) {
   871             return _qualifiedName.localName;
   872         } else {
   873             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetLocalName"));
   874         }
   875     }
   877     public final boolean hasName() {
   878         return (_eventType == START_ELEMENT || _eventType == END_ELEMENT);
   879     }
   881     public final String getNamespaceURI() {
   882         if (_eventType == START_ELEMENT || _eventType == END_ELEMENT) {
   883             return _qualifiedName.namespaceName;
   884         } else {
   885             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetNamespaceURI"));
   886         }
   887     }
   889     public final String getPrefix() {
   890         if (_eventType == START_ELEMENT || _eventType == END_ELEMENT) {
   891             return _qualifiedName.prefix;
   892         } else {
   893             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetPrefix"));
   894         }
   895     }
   897     public final String getVersion() {
   898         return null;
   899     }
   901     public final boolean isStandalone() {
   902         return false;
   903     }
   905     public final boolean standaloneSet() {
   906         return false;
   907     }
   909     public final String getCharacterEncodingScheme() {
   910         return null;
   911     }
   913     public final String getPITarget() {
   914         if (_eventType != PROCESSING_INSTRUCTION) {
   915             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetPITarget"));
   916         }
   918         return _piTarget;
   919     }
   921     public final String getPIData() {
   922         if (_eventType != PROCESSING_INSTRUCTION) {
   923             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetPIData"));
   924         }
   926         return _piData;
   927     }
   932     public final String getNameString() {
   933         if (_eventType == START_ELEMENT || _eventType == END_ELEMENT) {
   934             return _qualifiedName.getQNameString();
   935         } else {
   936             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetName"));
   937         }
   938     }
   940     public final String getAttributeNameString(int index) {
   941         if (_eventType != START_ELEMENT) {
   942             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.invalidCallingGetAttributeValue"));
   943         }
   944         return _attributes.getQualifiedName(index).getQNameString();
   945     }
   948     public final String getTextAlgorithmURI() {
   949         return _algorithmURI;
   950     }
   952     public final int getTextAlgorithmIndex() {
   953         return _algorithmId;
   954     }
   956     public final boolean hasTextAlgorithmBytes() {
   957         return _algorithmData != null;
   958     }
   961     /**
   962      * Returns the byte[], which represents text algorithms.
   963      * @deprecated was deprecated due to security reasons. Now the method return cloned byte[].
   964      *
   965      * @return
   966      */
   967     public final byte[] getTextAlgorithmBytes() {
   968         // Do not return the actual _algorithmData due to security reasons
   969 //        return _algorithmData;
   970         if (_algorithmData == null) {
   971             return null;
   972         }
   974         final byte[] algorithmData = new byte[_algorithmData.length];
   975         System.arraycopy(_algorithmData, 0, algorithmData, 0, _algorithmData.length);
   976         return algorithmData;
   977     }
   979     public final byte[] getTextAlgorithmBytesClone() {
   980         if (_algorithmData == null) {
   981             return null;
   982         }
   984         byte[] algorithmData = new byte[_algorithmDataLength];
   985         System.arraycopy(_algorithmData, _algorithmDataOffset, algorithmData, 0, _algorithmDataLength);
   986         return algorithmData;
   987     }
   989     public final int getTextAlgorithmStart() {
   990         return _algorithmDataOffset;
   991     }
   993     public final int getTextAlgorithmLength() {
   994         return _algorithmDataLength;
   995     }
   997     public final int getTextAlgorithmBytes(int sourceStart, byte[] target,
   998             int targetStart, int length) throws XMLStreamException {
   999         try {
  1000             System.arraycopy(_algorithmData, sourceStart, target,
  1001                     targetStart, length);
  1002             return length;
  1003         } catch (IndexOutOfBoundsException e) {
  1004             throw new XMLStreamException(e);
  1008     // FastInfosetStreamReader impl
  1010     public final int peekNext() throws XMLStreamException {
  1011         try {
  1012             switch(DecoderStateTables.EII(peek(this))) {
  1013                 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
  1014                 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
  1015                 case DecoderStateTables.EII_INDEX_MEDIUM:
  1016                 case DecoderStateTables.EII_INDEX_LARGE:
  1017                 case DecoderStateTables.EII_LITERAL:
  1018                 case DecoderStateTables.EII_NAMESPACES:
  1019                     return START_ELEMENT;
  1020                 case DecoderStateTables.CII_UTF8_SMALL_LENGTH:
  1021                 case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH:
  1022                 case DecoderStateTables.CII_UTF8_LARGE_LENGTH:
  1023                 case DecoderStateTables.CII_UTF16_SMALL_LENGTH:
  1024                 case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH:
  1025                 case DecoderStateTables.CII_UTF16_LARGE_LENGTH:
  1026                 case DecoderStateTables.CII_RA:
  1027                 case DecoderStateTables.CII_EA:
  1028                 case DecoderStateTables.CII_INDEX_SMALL:
  1029                 case DecoderStateTables.CII_INDEX_MEDIUM:
  1030                 case DecoderStateTables.CII_INDEX_LARGE:
  1031                 case DecoderStateTables.CII_INDEX_LARGE_LARGE:
  1032                     return CHARACTERS;
  1033                 case DecoderStateTables.COMMENT_II:
  1034                     return COMMENT;
  1035                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
  1036                     return PROCESSING_INSTRUCTION;
  1037                 case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II:
  1038                     return ENTITY_REFERENCE;
  1039                 case DecoderStateTables.TERMINATOR_DOUBLE:
  1040                 case DecoderStateTables.TERMINATOR_SINGLE:
  1041                     return (_stackCount != -1) ? END_ELEMENT : END_DOCUMENT;
  1042                 default:
  1043                     throw new FastInfosetException(
  1044                             CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEII"));
  1046         } catch (IOException e) {
  1047             throw new XMLStreamException(e);
  1048         } catch (FastInfosetException e) {
  1049             throw new XMLStreamException(e);
  1053     public void onBeforeOctetBufferOverwrite() {
  1054         if (_algorithmData != null) {
  1055             _algorithmData = getTextAlgorithmBytesClone();
  1056             _algorithmDataOffset = 0;
  1057             _isAlgorithmDataCloned = true;
  1061     // Faster access methods without checks
  1063     public final int accessNamespaceCount() {
  1064         return (_currentNamespaceAIIsEnd > 0) ? (_currentNamespaceAIIsEnd - _currentNamespaceAIIsStart) : 0;
  1067     public final String accessLocalName() {
  1068         return _qualifiedName.localName;
  1071     public final String accessNamespaceURI() {
  1072         return _qualifiedName.namespaceName;
  1075     public final String accessPrefix() {
  1076         return _qualifiedName.prefix;
  1079     public final char[] accessTextCharacters() {
  1080         if (_characters == null) return null;
  1082         // we return a cloned version of _characters
  1083         final char[] clonedCharacters = new char[_characters.length];
  1084         System.arraycopy(_characters, 0, clonedCharacters, 0, _characters.length);
  1085         return clonedCharacters;
  1088     public final int accessTextStart() {
  1089         return _charactersOffset;
  1092     public final int accessTextLength() {
  1093         return _charBufferLength;
  1096     //
  1098     protected final void processDII() throws FastInfosetException, IOException {
  1099         final int b = read();
  1100         if (b > 0) {
  1101             processDIIOptionalProperties(b);
  1105     protected final void processDIIOptionalProperties(int b) throws FastInfosetException, IOException {
  1106         // Optimize for the most common case
  1107         if (b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) {
  1108             decodeInitialVocabulary();
  1109             return;
  1112         if ((b & EncodingConstants.DOCUMENT_ADDITIONAL_DATA_FLAG) > 0) {
  1113             decodeAdditionalData();
  1114             /*
  1115              * TODO
  1116              * how to report the additional data?
  1117              */
  1120         if ((b & EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) > 0) {
  1121             decodeInitialVocabulary();
  1124         if ((b & EncodingConstants.DOCUMENT_NOTATIONS_FLAG) > 0) {
  1125             decodeNotations();
  1126             /*
  1127                 try {
  1128                     _dtdHandler.notationDecl(name, public_identifier, system_identifier);
  1129                 } catch (SAXException e) {
  1130                     throw new IOException("NotationsDeclarationII");
  1132              */
  1135         if ((b & EncodingConstants.DOCUMENT_UNPARSED_ENTITIES_FLAG) > 0) {
  1136             decodeUnparsedEntities();
  1137             /*
  1138                 try {
  1139                     _dtdHandler.unparsedEntityDecl(name, public_identifier, system_identifier, notation_name);
  1140                 } catch (SAXException e) {
  1141                     throw new IOException("UnparsedEntitiesII");
  1143              */
  1146         if ((b & EncodingConstants.DOCUMENT_CHARACTER_ENCODING_SCHEME) > 0) {
  1147             _characterEncodingScheme = decodeCharacterEncodingScheme();
  1150         if ((b & EncodingConstants.DOCUMENT_STANDALONE_FLAG) > 0) {
  1151             boolean standalone = (read() > 0) ? true : false ;
  1152             /*
  1153              * TODO
  1154              * how to report the standalone flag?
  1155              */
  1158         if ((b & EncodingConstants.DOCUMENT_VERSION_FLAG) > 0) {
  1159             decodeVersion();
  1160             /*
  1161              * TODO
  1162              * how to report the standalone flag?
  1163              */
  1168     protected final void resizeNamespaceAIIs() {
  1169         final String[] namespaceAIIsPrefix = new String[_namespaceAIIsIndex * 2];
  1170         System.arraycopy(_namespaceAIIsPrefix, 0, namespaceAIIsPrefix, 0, _namespaceAIIsIndex);
  1171         _namespaceAIIsPrefix = namespaceAIIsPrefix;
  1173         final String[] namespaceAIIsNamespaceName = new String[_namespaceAIIsIndex * 2];
  1174         System.arraycopy(_namespaceAIIsNamespaceName, 0, namespaceAIIsNamespaceName, 0, _namespaceAIIsIndex);
  1175         _namespaceAIIsNamespaceName = namespaceAIIsNamespaceName;
  1177         final int[] namespaceAIIsPrefixIndex = new int[_namespaceAIIsIndex * 2];
  1178         System.arraycopy(_namespaceAIIsPrefixIndex, 0, namespaceAIIsPrefixIndex, 0, _namespaceAIIsIndex);
  1179         _namespaceAIIsPrefixIndex = namespaceAIIsPrefixIndex;
  1182     protected final void processEIIWithNamespaces(boolean hasAttributes) throws FastInfosetException, IOException {
  1183         if (++_prefixTable._declarationId == Integer.MAX_VALUE) {
  1184             _prefixTable.clearDeclarationIds();
  1187         _currentNamespaceAIIsStart = _namespaceAIIsIndex;
  1188         String prefix = "", namespaceName = "";
  1189         int b = read();
  1190         while ((b & EncodingConstants.NAMESPACE_ATTRIBUTE_MASK) == EncodingConstants.NAMESPACE_ATTRIBUTE) {
  1191             if (_namespaceAIIsIndex == _namespaceAIIsPrefix.length) {
  1192                 resizeNamespaceAIIs();
  1195             switch (b & EncodingConstants.NAMESPACE_ATTRIBUTE_PREFIX_NAME_MASK) {
  1196                 // no prefix, no namespace
  1197                 // Undeclaration of default namespace
  1198                 case 0:
  1199                     prefix = namespaceName =
  1200                             _namespaceAIIsPrefix[_namespaceAIIsIndex] =
  1201                             _namespaceAIIsNamespaceName[_namespaceAIIsIndex] = "";
  1203                     _namespaceNameIndex = _prefixIndex = _namespaceAIIsPrefixIndex[_namespaceAIIsIndex++] = -1;
  1204                     break;
  1205                     // no prefix, namespace
  1206                     // Declaration of default namespace
  1207                 case 1:
  1208                     prefix = _namespaceAIIsPrefix[_namespaceAIIsIndex] = "";
  1209                     namespaceName = _namespaceAIIsNamespaceName[_namespaceAIIsIndex] =
  1210                             decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(false);
  1212                     _prefixIndex = _namespaceAIIsPrefixIndex[_namespaceAIIsIndex++] = -1;
  1213                     break;
  1214                     // prefix, no namespace
  1215                     // Undeclaration of namespace
  1216                 case 2:
  1217                     prefix = _namespaceAIIsPrefix[_namespaceAIIsIndex] =
  1218                             decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(false);
  1219                     namespaceName = _namespaceAIIsNamespaceName[_namespaceAIIsIndex] = "";
  1221                     _namespaceNameIndex = -1;
  1222                     _namespaceAIIsPrefixIndex[_namespaceAIIsIndex++] = _prefixIndex;
  1223                     break;
  1224                     // prefix, namespace
  1225                     // Declaration of prefixed namespace
  1226                 case 3:
  1227                     prefix = _namespaceAIIsPrefix[_namespaceAIIsIndex] =
  1228                             decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(true);
  1229                     namespaceName = _namespaceAIIsNamespaceName[_namespaceAIIsIndex] =
  1230                             decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(true);
  1232                     _namespaceAIIsPrefixIndex[_namespaceAIIsIndex++] = _prefixIndex;
  1233                     break;
  1236             // Push namespace declarations onto the stack
  1237             _prefixTable.pushScopeWithPrefixEntry(prefix, namespaceName, _prefixIndex, _namespaceNameIndex);
  1239             b = read();
  1241         if (b != EncodingConstants.TERMINATOR) {
  1242             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.EIInamespaceNameNotTerminatedCorrectly"));
  1244         _currentNamespaceAIIsEnd = _namespaceAIIsIndex;
  1246         b = read();
  1247         switch(DecoderStateTables.EII(b)) {
  1248             case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
  1249                 processEII(_elementNameTable._array[b], hasAttributes);
  1250                 break;
  1251             case DecoderStateTables.EII_INDEX_MEDIUM:
  1252                 processEII(processEIIIndexMedium(b), hasAttributes);
  1253                 break;
  1254             case DecoderStateTables.EII_INDEX_LARGE:
  1255                 processEII(processEIIIndexLarge(b), hasAttributes);
  1256                 break;
  1257             case DecoderStateTables.EII_LITERAL:
  1259                 final QualifiedName qn = processLiteralQualifiedName(
  1260                         b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
  1261                         _elementNameTable.getNext());
  1262                 _elementNameTable.add(qn);
  1263                 processEII(qn, hasAttributes);
  1264                 break;
  1266             default:
  1267                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEIIAfterAIIs"));
  1271     protected final void processEII(QualifiedName name, boolean hasAttributes) throws FastInfosetException, IOException {
  1272         if (_prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
  1273             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qnameOfEIINotInScope"));
  1276         _eventType = START_ELEMENT;
  1277         _qualifiedName = name;
  1279         if (_clearAttributes) {
  1280             _attributes.clear();
  1281             _clearAttributes = false;
  1284         if (hasAttributes) {
  1285             processAIIs();
  1288         // Push element holder onto the stack
  1289         _stackCount++;
  1290         if (_stackCount == _qNameStack.length) {
  1291             QualifiedName[] qNameStack = new QualifiedName[_qNameStack.length * 2];
  1292             System.arraycopy(_qNameStack, 0, qNameStack, 0, _qNameStack.length);
  1293             _qNameStack = qNameStack;
  1295             int[] namespaceAIIsStartStack = new int[_namespaceAIIsStartStack.length * 2];
  1296             System.arraycopy(_namespaceAIIsStartStack, 0, namespaceAIIsStartStack, 0, _namespaceAIIsStartStack.length);
  1297             _namespaceAIIsStartStack = namespaceAIIsStartStack;
  1299             int[] namespaceAIIsEndStack = new int[_namespaceAIIsEndStack.length * 2];
  1300             System.arraycopy(_namespaceAIIsEndStack, 0, namespaceAIIsEndStack, 0, _namespaceAIIsEndStack.length);
  1301             _namespaceAIIsEndStack = namespaceAIIsEndStack;
  1303         _qNameStack[_stackCount] = _qualifiedName;
  1304         _namespaceAIIsStartStack[_stackCount] = _currentNamespaceAIIsStart;
  1305         _namespaceAIIsEndStack[_stackCount] = _currentNamespaceAIIsEnd;
  1308     protected final void processAIIs() throws FastInfosetException, IOException {
  1309         QualifiedName name;
  1310         int b;
  1311         String value;
  1313         if (++_duplicateAttributeVerifier._currentIteration == Integer.MAX_VALUE) {
  1314             _duplicateAttributeVerifier.clear();
  1317         _clearAttributes = true;
  1318         boolean terminate = false;
  1319         do {
  1320             // AII qualified name
  1321             b = read();
  1322             switch (DecoderStateTables.AII(b)) {
  1323                 case DecoderStateTables.AII_INDEX_SMALL:
  1324                     name = _attributeNameTable._array[b];
  1325                     break;
  1326                 case DecoderStateTables.AII_INDEX_MEDIUM:
  1328                     final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
  1329                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
  1330                     name = _attributeNameTable._array[i];
  1331                     break;
  1333                 case DecoderStateTables.AII_INDEX_LARGE:
  1335                     final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
  1336                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
  1337                     name = _attributeNameTable._array[i];
  1338                     break;
  1340                 case DecoderStateTables.AII_LITERAL:
  1341                     name = processLiteralQualifiedName(
  1342                             b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
  1343                             _attributeNameTable.getNext());
  1344                     name.createAttributeValues(DuplicateAttributeVerifier.MAP_SIZE);
  1345                     _attributeNameTable.add(name);
  1346                     break;
  1347                 case DecoderStateTables.AII_TERMINATOR_DOUBLE:
  1348                     _internalState = INTERNAL_STATE_START_ELEMENT_TERMINATE;
  1349                 case DecoderStateTables.AII_TERMINATOR_SINGLE:
  1350                     terminate = true;
  1351                     // AIIs have finished break out of loop
  1352                     continue;
  1353                 default:
  1354                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingAIIs"));
  1357             // [normalized value] of AII
  1359             if (name.prefixIndex > 0 && _prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
  1360                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.AIIqNameNotInScope"));
  1363             _duplicateAttributeVerifier.checkForDuplicateAttribute(name.attributeHash, name.attributeId);
  1365             b = read();
  1366             switch(DecoderStateTables.NISTRING(b)) {
  1367                 case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
  1368                     _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
  1369                     value = decodeUtf8StringAsString();
  1370                     if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
  1371                         _attributeValueTable.add(value);
  1374                     _attributes.addAttribute(name, value);
  1375                     break;
  1376                 case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
  1377                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
  1378                     value = decodeUtf8StringAsString();
  1379                     if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
  1380                         _attributeValueTable.add(value);
  1383                     _attributes.addAttribute(name, value);
  1384                     break;
  1385                 case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
  1386                     _octetBufferLength = ((read() << 24) |
  1387                             (read() << 16) |
  1388                             (read() << 8) |
  1389                             read())
  1390                             + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
  1391                     value = decodeUtf8StringAsString();
  1392                     if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
  1393                         _attributeValueTable.add(value);
  1396                     _attributes.addAttribute(name, value);
  1397                     break;
  1398                 case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH:
  1399                     _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
  1400                     value = decodeUtf16StringAsString();
  1401                     if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
  1402                         _attributeValueTable.add(value);
  1405                     _attributes.addAttribute(name, value);
  1406                     break;
  1407                 case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH:
  1408                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
  1409                     value = decodeUtf16StringAsString();
  1410                     if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
  1411                         _attributeValueTable.add(value);
  1414                     _attributes.addAttribute(name, value);
  1415                     break;
  1416                 case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH:
  1417                     _octetBufferLength = ((read() << 24) |
  1418                             (read() << 16) |
  1419                             (read() << 8) |
  1420                             read())
  1421                             + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
  1422                     value = decodeUtf16StringAsString();
  1423                     if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
  1424                         _attributeValueTable.add(value);
  1427                     _attributes.addAttribute(name, value);
  1428                     break;
  1429                 case DecoderStateTables.NISTRING_RA:
  1431                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
  1432                     // Decode resitricted alphabet integer
  1433                     _identifier = (b & 0x0F) << 4;
  1434                     b = read();
  1435                     _identifier |= (b & 0xF0) >> 4;
  1437                     decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
  1439                     value = decodeRestrictedAlphabetAsString();
  1440                     if (addToTable) {
  1441                         _attributeValueTable.add(value);
  1444                     _attributes.addAttribute(name, value);
  1445                     break;
  1447                 case DecoderStateTables.NISTRING_EA:
  1449                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
  1450                     // Decode encoding algorithm integer
  1451                     _identifier = (b & 0x0F) << 4;
  1452                     b = read();
  1453                     _identifier |= (b & 0xF0) >> 4;
  1455                     decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
  1456                     processAIIEncodingAlgorithm(name, addToTable);
  1457                     break;
  1459                 case DecoderStateTables.NISTRING_INDEX_SMALL:
  1460                     _attributes.addAttribute(name,
  1461                             _attributeValueTable._array[b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK]);
  1462                     break;
  1463                 case DecoderStateTables.NISTRING_INDEX_MEDIUM:
  1465                     final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
  1466                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
  1468                     _attributes.addAttribute(name,
  1469                             _attributeValueTable._array[index]);
  1470                     break;
  1472                 case DecoderStateTables.NISTRING_INDEX_LARGE:
  1474                     final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
  1475                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
  1477                     _attributes.addAttribute(name,
  1478                             _attributeValueTable._array[index]);
  1479                     break;
  1481                 case DecoderStateTables.NISTRING_EMPTY:
  1482                     _attributes.addAttribute(name, "");
  1483                     break;
  1484                 default:
  1485                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingAIIValue"));
  1488         } while (!terminate);
  1490         // Reset duplication attribute verfifier
  1491         _duplicateAttributeVerifier._poolCurrent = _duplicateAttributeVerifier._poolHead;
  1494     protected final QualifiedName processEIIIndexMedium(int b) throws FastInfosetException, IOException {
  1495         final int i = (((b & EncodingConstants.INTEGER_3RD_BIT_MEDIUM_MASK) << 8) | read())
  1496         + EncodingConstants.INTEGER_3RD_BIT_SMALL_LIMIT;
  1497         return _elementNameTable._array[i];
  1500     protected final QualifiedName processEIIIndexLarge(int b) throws FastInfosetException, IOException {
  1501         int i;
  1502         if ((b & EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_FLAG) == 0x20) {
  1503             // EII large index
  1504             i = (((b & EncodingConstants.INTEGER_3RD_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
  1505             + EncodingConstants.INTEGER_3RD_BIT_MEDIUM_LIMIT;
  1506         } else {
  1507             // EII large large index
  1508             i = (((read() & EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_MASK) << 16) | (read() << 8) | read())
  1509             + EncodingConstants.INTEGER_3RD_BIT_LARGE_LIMIT;
  1511         return _elementNameTable._array[i];
  1514     protected final QualifiedName processLiteralQualifiedName(int state, QualifiedName q)
  1515     throws FastInfosetException, IOException {
  1516         if (q == null) q = new QualifiedName();
  1518         switch (state) {
  1519             // no prefix, no namespace
  1520             case 0:
  1521                 return q.set(
  1522                         "",
  1523                         "",
  1524                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
  1525                         "",
  1526                         0,
  1527                         -1,
  1528                         -1,
  1529                         _identifier);
  1530                 // no prefix, namespace
  1531             case 1:
  1532                 return q.set(
  1533                         "",
  1534                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false),
  1535                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
  1536                         "",
  1537                         0,
  1538                         -1,
  1539                         _namespaceNameIndex,
  1540                         _identifier);
  1541                 // prefix, no namespace
  1542             case 2:
  1543                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName"));
  1544                 // prefix, namespace
  1545             case 3:
  1546                 return q.set(
  1547                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true),
  1548                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true),
  1549                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
  1550                         "",
  1551                         0,
  1552                         _prefixIndex,
  1553                         _namespaceNameIndex,
  1554                         _identifier);
  1555             default:
  1556                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII"));
  1560     protected final void processCommentII() throws FastInfosetException, IOException {
  1561         _eventType = COMMENT;
  1563         switch(decodeNonIdentifyingStringOnFirstBit()) {
  1564             case NISTRING_STRING:
  1565                 if (_addToTable) {
  1566                     _v.otherString.add(new CharArray(_charBuffer, 0, _charBufferLength, true));
  1569                 _characters = _charBuffer;
  1570                 _charactersOffset = 0;
  1571                 break;
  1572             case NISTRING_ENCODING_ALGORITHM:
  1573                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.commentIIAlgorithmNotSupported"));
  1574             case NISTRING_INDEX:
  1575                 final CharArray ca = _v.otherString.get(_integer);
  1577                 _characters = ca.ch;
  1578                 _charactersOffset = ca.start;
  1579                 _charBufferLength = ca.length;
  1580                 break;
  1581             case NISTRING_EMPTY_STRING:
  1582                 _characters = _charBuffer;
  1583                 _charactersOffset = 0;
  1584                 _charBufferLength = 0;
  1585                 break;
  1589     protected final void processProcessingII() throws FastInfosetException, IOException {
  1590         _eventType = PROCESSING_INSTRUCTION;
  1592         _piTarget = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
  1594         switch(decodeNonIdentifyingStringOnFirstBit()) {
  1595             case NISTRING_STRING:
  1596                 _piData = new String(_charBuffer, 0, _charBufferLength);
  1597                 if (_addToTable) {
  1598                     _v.otherString.add(new CharArrayString(_piData));
  1600                 break;
  1601             case NISTRING_ENCODING_ALGORITHM:
  1602                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
  1603             case NISTRING_INDEX:
  1604                 _piData = _v.otherString.get(_integer).toString();
  1605                 break;
  1606             case NISTRING_EMPTY_STRING:
  1607                 _piData = "";
  1608                 break;
  1612     protected final void processUnexpandedEntityReference(final int b) throws FastInfosetException, IOException {
  1613         _eventType = ENTITY_REFERENCE;
  1615         /*
  1616          * TODO
  1617          * How does StAX report such events?
  1618          */
  1619         String entity_reference_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
  1621         String system_identifier = ((b & EncodingConstants.UNEXPANDED_ENTITY_SYSTEM_IDENTIFIER_FLAG) > 0)
  1622         ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
  1623         String public_identifier = ((b & EncodingConstants.UNEXPANDED_ENTITY_PUBLIC_IDENTIFIER_FLAG) > 0)
  1624         ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
  1626         if (logger.isLoggable(Level.FINEST)) {
  1627             logger.log(Level.FINEST, "processUnexpandedEntityReference: entity_reference_name={0} system_identifier={1}public_identifier={2}",
  1628                     new Object[]{entity_reference_name, system_identifier, public_identifier});
  1632     protected final void processCIIEncodingAlgorithm(boolean addToTable) throws FastInfosetException, IOException {
  1633         _algorithmData = _octetBuffer;
  1634         _algorithmDataOffset = _octetBufferStart;
  1635         _algorithmDataLength = _octetBufferLength;
  1636         _isAlgorithmDataCloned = false;
  1638         if (_algorithmId >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
  1639             _algorithmURI = _v.encodingAlgorithm.get(_algorithmId - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
  1640             if (_algorithmURI == null) {
  1641                 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.URINotPresent", new Object[]{Integer.valueOf(_identifier)}));
  1643         } else if (_algorithmId > EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
  1644             // Reserved built-in algorithms for future use
  1645             // TODO should use sax property to decide if event will be
  1646             // reported, allows for support through handler if required.
  1647             throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved"));
  1650         if (addToTable) {
  1651             convertEncodingAlgorithmDataToCharacters();
  1652             _characterContentChunkTable.add(_characters, _characters.length);
  1656     protected final void processAIIEncodingAlgorithm(QualifiedName name, boolean addToTable) throws FastInfosetException, IOException {
  1657         EncodingAlgorithm ea = null;
  1658         String URI = null;
  1659         if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
  1660             URI = _v.encodingAlgorithm.get(_identifier - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
  1661             if (URI == null) {
  1662                 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.URINotPresent", new Object[]{Integer.valueOf(_identifier)}));
  1663             } else if (_registeredEncodingAlgorithms != null) {
  1664                 ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
  1666         } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
  1667             if (_identifier == EncodingAlgorithmIndexes.CDATA) {
  1668                 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported"));
  1671             // Reserved built-in algorithms for future use
  1672             // TODO should use sax property to decide if event will be
  1673             // reported, allows for support through handler if required.
  1674             throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved"));
  1675         } else {
  1676             ea = BuiltInEncodingAlgorithmFactory.getAlgorithm(_identifier);
  1679         Object algorithmData;
  1681         if (ea != null) {
  1682             algorithmData = ea.decodeFromBytes(_octetBuffer, _octetBufferStart,
  1683                     _octetBufferLength);
  1684         } else {
  1685             final byte[] data = new byte[_octetBufferLength];
  1686             System.arraycopy(_octetBuffer, _octetBufferStart, data, 0,
  1687                     _octetBufferLength);
  1688             algorithmData = data;
  1691         _attributes.addAttributeWithAlgorithmData(name, URI, _identifier,
  1692                 algorithmData);
  1693         if (addToTable) {
  1694             _attributeValueTable.add(_attributes.getValue(_attributes.getIndex(name.qName)));
  1698     protected final void convertEncodingAlgorithmDataToCharacters() throws FastInfosetException, IOException {
  1699         StringBuffer buffer = new StringBuffer();
  1700         if (_algorithmId == EncodingAlgorithmIndexes.BASE64) {
  1701             convertBase64AlorithmDataToCharacters(buffer);
  1702         } else if (_algorithmId < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
  1703             Object array = BuiltInEncodingAlgorithmFactory.getAlgorithm(_algorithmId).
  1704                     decodeFromBytes(_algorithmData, _algorithmDataOffset, _algorithmDataLength);
  1705             BuiltInEncodingAlgorithmFactory.getAlgorithm(_algorithmId).convertToCharacters(array,  buffer);
  1706         } else if (_algorithmId == EncodingAlgorithmIndexes.CDATA) {
  1707             _octetBufferOffset -= _octetBufferLength;
  1708             decodeUtf8StringIntoCharBuffer();
  1710             _characters = _charBuffer;
  1711             _charactersOffset = 0;
  1712             return;
  1713         } else if (_algorithmId >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
  1714             final EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(_algorithmURI);
  1715             if (ea != null) {
  1716                 final Object data = ea.decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
  1717                 ea.convertToCharacters(data, buffer);
  1718             } else {
  1719                 throw new EncodingAlgorithmException(
  1720                         CommonResourceBundle.getInstance().getString("message.algorithmDataCannotBeReported"));
  1724         _characters = new char[buffer.length()];
  1725         buffer.getChars(0, buffer.length(), _characters, 0);
  1726         _charactersOffset = 0;
  1727         _charBufferLength = _characters.length;
  1730     /* If base64 data comes is chunks, bytes, which were cut to align 3,
  1731      * from prev. base64 chunk are stored in this buffer */
  1732     private byte[] base64TaleBytes = new byte[3];
  1733     private int base64TaleLength;
  1734     /*
  1735      * Method converts _algorithmData to base64 encoded String
  1736      * Counts with base64 data coming in chunks, aligning input chunks by 3,
  1737      * avoiding double cloning, happening after possible peek, peek2 cloning by Base64 algorithm
  1738      */
  1739     protected void convertBase64AlorithmDataToCharacters(StringBuffer buffer) throws EncodingAlgorithmException, IOException {
  1740         // How much new came data was serialized with prev. tale
  1741         int afterTaleOffset = 0;
  1743         if (base64TaleLength > 0) {
  1744             // Serialize tale left from prev. chunk
  1745             int bytesToCopy = Math.min(3 - base64TaleLength, _algorithmDataLength);
  1746             System.arraycopy(_algorithmData, _algorithmDataOffset, base64TaleBytes, base64TaleLength, bytesToCopy);
  1747             if (base64TaleLength + bytesToCopy == 3) {
  1748                 base64DecodeWithCloning(buffer, base64TaleBytes, 0, 3);
  1749             } else if (!isBase64Follows()) {
  1750                 // End of text was read to temp array
  1751                 base64DecodeWithCloning(buffer, base64TaleBytes, 0, base64TaleLength + bytesToCopy);
  1752                 return;
  1753             } else {
  1754                 // If the end of chunk fit to tmp array, but next chunk is expected
  1755                 base64TaleLength += bytesToCopy;
  1756                 return;
  1759             afterTaleOffset = bytesToCopy;
  1760             base64TaleLength = 0;
  1763         int taleBytesRemaining = isBase64Follows() ? (_algorithmDataLength - afterTaleOffset) % 3 : 0;
  1765         if (_isAlgorithmDataCloned) {
  1766             base64DecodeWithoutCloning(buffer, _algorithmData, _algorithmDataOffset + afterTaleOffset,
  1767                     _algorithmDataLength - afterTaleOffset - taleBytesRemaining);
  1768         } else {
  1769             base64DecodeWithCloning(buffer, _algorithmData, _algorithmDataOffset + afterTaleOffset,
  1770                     _algorithmDataLength - afterTaleOffset - taleBytesRemaining);
  1773         if (taleBytesRemaining > 0) {
  1774             System.arraycopy(_algorithmData, _algorithmDataOffset + _algorithmDataLength - taleBytesRemaining,
  1775                     base64TaleBytes, 0, taleBytesRemaining);
  1776             base64TaleLength = taleBytesRemaining;
  1780     /*
  1781      * Encodes incoming data to Base64 string.
  1782      * Method performs additional input data cloning
  1783      */
  1784     private void base64DecodeWithCloning(StringBuffer dstBuffer, byte[] data, int offset, int length) throws EncodingAlgorithmException {
  1785         Object array = BuiltInEncodingAlgorithmFactory.base64EncodingAlgorithm.
  1786                 decodeFromBytes(data, offset, length);
  1787         BuiltInEncodingAlgorithmFactory.base64EncodingAlgorithm.convertToCharacters(array, dstBuffer);
  1790     /*
  1791      * Encodes incoming data to Base64 string.
  1792      * Avoids input data cloning
  1793      */
  1794     private void base64DecodeWithoutCloning(StringBuffer dstBuffer, byte[] data, int offset, int length) throws EncodingAlgorithmException {
  1795         BuiltInEncodingAlgorithmFactory.base64EncodingAlgorithm.convertToCharacters(data, offset, length, dstBuffer);
  1799     /*
  1800      * Looks ahead in InputStream, whether next data is Base64 chunk
  1801      */
  1802     public boolean isBase64Follows() throws IOException {
  1803         // Process information item
  1804         int b = peek(this);
  1805         switch (DecoderStateTables.EII(b)) {
  1806             case DecoderStateTables.CII_EA:
  1807                 int algorithmId = (b & 0x02) << 6;
  1808                 int b2 = peek2(this);
  1809                 algorithmId |= (b2 & 0xFC) >> 2;
  1811                 return algorithmId == EncodingAlgorithmIndexes.BASE64;
  1812             default:
  1813                 return false;
  1817     protected class NamespaceContextImpl implements NamespaceContext {
  1818         public final String getNamespaceURI(String prefix) {
  1819             return _prefixTable.getNamespaceFromPrefix(prefix);
  1822         public final String getPrefix(String namespaceURI) {
  1823             return _prefixTable.getPrefixFromNamespace(namespaceURI);
  1826         public final Iterator getPrefixes(String namespaceURI) {
  1827             return _prefixTable.getPrefixesFromNamespace(namespaceURI);
  1831     public final String getNamespaceDecl(String prefix) {
  1832         return _prefixTable.getNamespaceFromPrefix(prefix);
  1835     public final String getURI(String prefix) {
  1836         return getNamespaceDecl(prefix);
  1839     public final Iterator getPrefixes() {
  1840         return _prefixTable.getPrefixes();
  1843     public final AttributesHolder getAttributesHolder() {
  1844         return _attributes;
  1847     public final void setManager(StAXManager manager) {
  1848         _manager = manager;
  1851     final static String getEventTypeString(int eventType) {
  1852         switch (eventType){
  1853             case START_ELEMENT:
  1854                 return "START_ELEMENT";
  1855             case END_ELEMENT:
  1856                 return "END_ELEMENT";
  1857             case PROCESSING_INSTRUCTION:
  1858                 return "PROCESSING_INSTRUCTION";
  1859             case CHARACTERS:
  1860                 return "CHARACTERS";
  1861             case COMMENT:
  1862                 return "COMMENT";
  1863             case START_DOCUMENT:
  1864                 return "START_DOCUMENT";
  1865             case END_DOCUMENT:
  1866                 return "END_DOCUMENT";
  1867             case ENTITY_REFERENCE:
  1868                 return "ENTITY_REFERENCE";
  1869             case ATTRIBUTE:
  1870                 return "ATTRIBUTE";
  1871             case DTD:
  1872                 return "DTD";
  1873             case CDATA:
  1874                 return "CDATA";
  1876         return "UNKNOWN_EVENT_TYPE";

mercurial