src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/dom/DOMDocumentParser.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, 2012, 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.dom;
    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.QualifiedName;
    34 import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
    35 import com.sun.xml.internal.fastinfoset.util.CharArray;
    36 import com.sun.xml.internal.fastinfoset.util.CharArrayString;
    37 import java.io.IOException;
    38 import java.io.InputStream;
    39 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithm;
    40 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException;
    41 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
    42 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
    43 import org.w3c.dom.Attr;
    44 import org.w3c.dom.Document;
    45 import org.w3c.dom.Element;
    46 import org.w3c.dom.Node;
    47 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
    48 import com.sun.xml.internal.fastinfoset.util.DuplicateAttributeVerifier;
    49 import org.w3c.dom.Text;
    51 /**
    52  * The Fast Infoset DOM parser.
    53  * <p>
    54  * Instantiate this parser to parse a fast infoset document in accordance
    55  * with the DOM API.
    56  *
    57  */
    58 public class DOMDocumentParser extends Decoder {
    59     protected Document _document;
    61     protected Node _currentNode;
    63     protected Element _currentElement;
    65     protected Attr[] _namespaceAttributes = new Attr[16];
    67     protected int _namespaceAttributesIndex;
    69     protected int[] _namespacePrefixes = new int[16];
    71     protected int _namespacePrefixesIndex;
    73     /**
    74      * Parse a fast infoset document into a {@link Document} instance.
    75      * <p>
    76      * {@link Node}s will be created and appended to the {@link Document}
    77      * instance.
    78      *
    79      * @param d the {@link Document} instance.
    80      * @param s the input stream containing the fast infoset document.
    81      */
    82     public void parse(Document d, InputStream s) throws FastInfosetException, IOException {
    83         _currentNode = _document = d;
    84         _namespaceAttributesIndex = 0;
    86         parse(s);
    87     }
    89     protected final void parse(InputStream s) throws FastInfosetException, IOException {
    90         setInputStream(s);
    91         parse();
    92     }
    94     protected void resetOnError() {
    95         _namespacePrefixesIndex = 0;
    97         if (_v == null) {
    98             _prefixTable.clearCompletely();
    99         }
   100         _duplicateAttributeVerifier.clear();
   101     }
   103     protected final void parse() throws FastInfosetException, IOException {
   104         try {
   105             reset();
   106             decodeHeader();
   107             processDII();
   108         } catch (RuntimeException e) {
   109             resetOnError();
   110             // Wrap runtime exception
   111             throw new FastInfosetException(e);
   112         } catch (FastInfosetException e) {
   113             resetOnError();
   114             throw e;
   115         } catch (IOException e) {
   116             resetOnError();
   117             throw e;
   118         }
   119     }
   121     protected final void processDII() throws FastInfosetException, IOException {
   122         _b = read();
   123         if (_b > 0) {
   124             processDIIOptionalProperties();
   125         }
   127         // Decode one Document Type II, Comment IIs, PI IIs and one EII
   128         boolean firstElementHasOccured = false;
   129         boolean documentTypeDeclarationOccured = false;
   130         while(!_terminate || !firstElementHasOccured) {
   131             _b = read();
   132             switch(DecoderStateTables.DII(_b)) {
   133                 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
   134                     processEII(_elementNameTable._array[_b], false);
   135                     firstElementHasOccured = true;
   136                     break;
   137                 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
   138                     processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
   139                     firstElementHasOccured = true;
   140                     break;
   141                 case DecoderStateTables.EII_INDEX_MEDIUM:
   142                     processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   143                     firstElementHasOccured = true;
   144                     break;
   145                 case DecoderStateTables.EII_INDEX_LARGE:
   146                     processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   147                     firstElementHasOccured = true;
   148                     break;
   149                 case DecoderStateTables.EII_LITERAL:
   150                 {
   151                     final QualifiedName qn = processLiteralQualifiedName(
   152                             _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
   153                             _elementNameTable.getNext());
   154                     _elementNameTable.add(qn);
   155                     processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   156                     firstElementHasOccured = true;
   157                     break;
   158                 }
   159                 case DecoderStateTables.EII_NAMESPACES:
   160                     processEIIWithNamespaces();
   161                     firstElementHasOccured = true;
   162                     break;
   163                 case DecoderStateTables.DOCUMENT_TYPE_DECLARATION_II:
   164                 {
   165                     if (documentTypeDeclarationOccured) {
   166                         throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.secondOccurenceOfDTDII"));
   167                     }
   168                     documentTypeDeclarationOccured = true;
   170                     String system_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_SYSTEM_IDENTIFIER_FLAG) > 0)
   171                     ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
   172                     String public_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_PUBLIC_IDENTIFIER_FLAG) > 0)
   173                     ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
   175                     _b = read();
   176                     while (_b == EncodingConstants.PROCESSING_INSTRUCTION) {
   177                         switch(decodeNonIdentifyingStringOnFirstBit()) {
   178                             case NISTRING_STRING:
   179                                 if (_addToTable) {
   180                                     _v.otherString.add(new CharArray(_charBuffer, 0, _charBufferLength, true));
   181                                 }
   182                                 break;
   183                             case NISTRING_ENCODING_ALGORITHM:
   184                                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
   185                             case NISTRING_INDEX:
   186                                 break;
   187                             case NISTRING_EMPTY_STRING:
   188                                 break;
   189                         }
   190                         _b = read();
   191                     }
   192                     if ((_b & EncodingConstants.TERMINATOR) != EncodingConstants.TERMINATOR) {
   193                         throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingInstructionIIsNotTerminatedCorrectly"));
   194                     }
   195                     if (_b == EncodingConstants.DOUBLE_TERMINATOR) {
   196                         _terminate = true;
   197                     }
   199                     _notations.clear();
   200                     _unparsedEntities.clear();
   201                     /*
   202                      * TODO
   203                      * Report All events associated with DTD, PIs, notations etc
   204                      */
   205                     break;
   206                 }
   207                 case DecoderStateTables.COMMENT_II:
   208                     processCommentII();
   209                     break;
   210                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
   211                     processProcessingII();
   212                     break;
   213                 case DecoderStateTables.TERMINATOR_DOUBLE:
   214                     _doubleTerminate = true;
   215                 case DecoderStateTables.TERMINATOR_SINGLE:
   216                     _terminate = true;
   217                     break;
   218                 default:
   219                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII"));
   220             }
   221         }
   223         // Decode any remaining Comment IIs, PI IIs
   224         while(!_terminate) {
   225             _b = read();
   226             switch(DecoderStateTables.DII(_b)) {
   227                 case DecoderStateTables.COMMENT_II:
   228                     processCommentII();
   229                     break;
   230                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
   231                     processProcessingII();
   232                     break;
   233                 case DecoderStateTables.TERMINATOR_DOUBLE:
   234                     _doubleTerminate = true;
   235                 case DecoderStateTables.TERMINATOR_SINGLE:
   236                     _terminate = true;
   237                     break;
   238                 default:
   239                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII"));
   240             }
   241         }
   243     }
   245     protected final void processDIIOptionalProperties() throws FastInfosetException, IOException {
   246         // Optimize for the most common case
   247         if (_b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) {
   248             decodeInitialVocabulary();
   249             return;
   250         }
   252         if ((_b & EncodingConstants.DOCUMENT_ADDITIONAL_DATA_FLAG) > 0) {
   253             decodeAdditionalData();
   254             /*
   255              * TODO
   256              * how to report the additional data?
   257              */
   258         }
   260         if ((_b & EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) > 0) {
   261             decodeInitialVocabulary();
   262         }
   264         if ((_b & EncodingConstants.DOCUMENT_NOTATIONS_FLAG) > 0) {
   265             decodeNotations();
   266             // TODO Report notations
   267         }
   269         if ((_b & EncodingConstants.DOCUMENT_UNPARSED_ENTITIES_FLAG) > 0) {
   270             decodeUnparsedEntities();
   271             // TODO Report unparsed entities
   272         }
   274         if ((_b & EncodingConstants.DOCUMENT_CHARACTER_ENCODING_SCHEME) > 0) {
   275             /*String version = */decodeCharacterEncodingScheme();
   276             /*
   277              * TODO
   278              * how to report the character encoding scheme?
   279              */
   280         }
   282         if ((_b & EncodingConstants.DOCUMENT_STANDALONE_FLAG) > 0) {
   283             /*boolean standalone = (*/read()/* > 0) ? true : false*/ ;
   284             /*
   285              * TODO
   286              * how to report the standalone flag?
   287              */
   288         }
   290         if ((_b & EncodingConstants.DOCUMENT_VERSION_FLAG) > 0) {
   291             decodeVersion();
   292             /*
   293              * TODO
   294              * how to report the document version?
   295              */
   296         }
   297     }
   299     protected final void processEII(QualifiedName name, boolean hasAttributes) throws FastInfosetException, IOException {
   300         if (_prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
   301             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qnameOfEIINotInScope"));
   302         }
   304         final Node parentCurrentNode = _currentNode;
   306         _currentNode = _currentElement = createElement(name.namespaceName, name.qName, name.localName);
   308         if (_namespaceAttributesIndex > 0) {
   309             for (int i = 0; i < _namespaceAttributesIndex; i++) {
   310                 _currentElement.setAttributeNode(_namespaceAttributes[i]);
   311                 _namespaceAttributes[i] = null;
   312             }
   313             _namespaceAttributesIndex = 0;
   314         }
   316         if (hasAttributes) {
   317             processAIIs();
   318         }
   320         parentCurrentNode.appendChild(_currentElement);
   322         while(!_terminate) {
   323             _b = read();
   324             switch(DecoderStateTables.EII(_b)) {
   325                 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
   326                     processEII(_elementNameTable._array[_b], false);
   327                     break;
   328                 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
   329                     processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
   330                     break;
   331                 case DecoderStateTables.EII_INDEX_MEDIUM:
   332                     processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   333                     break;
   334                 case DecoderStateTables.EII_INDEX_LARGE:
   335                     processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   336                     break;
   337                 case DecoderStateTables.EII_LITERAL:
   338                 {
   339                     final QualifiedName qn = processLiteralQualifiedName(
   340                             _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
   341                             _elementNameTable.getNext());
   342                     _elementNameTable.add(qn);
   343                     processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
   344                     break;
   345                 }
   346                 case DecoderStateTables.EII_NAMESPACES:
   347                     processEIIWithNamespaces();
   348                     break;
   349                 case DecoderStateTables.CII_UTF8_SMALL_LENGTH:
   350                 {
   351                     _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
   352                     + 1;
   353                     appendOrCreateTextData(processUtf8CharacterString());
   354                     break;
   355                 }
   356                 case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH:
   357                 {
   358                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
   359                     appendOrCreateTextData(processUtf8CharacterString());
   360                     break;
   361                 }
   362                     case DecoderStateTables.CII_UTF8_LARGE_LENGTH:
   363                 {
   364                     _octetBufferLength = (read() << 24) |
   365                             (read() << 16) |
   366                             (read() << 8) |
   367                             read();
   368                     _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
   369                     appendOrCreateTextData(processUtf8CharacterString());
   370                     break;
   371                 }
   372                 case DecoderStateTables.CII_UTF16_SMALL_LENGTH:
   373                 {
   374                     _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
   375                     + 1;
   376                     String v = decodeUtf16StringAsString();
   377                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
   378                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
   379                     }
   381                     appendOrCreateTextData(v);
   382                     break;
   383                 }
   384                 case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH:
   385                 {
   386                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
   387                     String v = decodeUtf16StringAsString();
   388                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
   389                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
   390                     }
   392                     appendOrCreateTextData(v);
   393                     break;
   394                 }
   395                 case DecoderStateTables.CII_UTF16_LARGE_LENGTH:
   396                 {
   397                     _octetBufferLength = (read() << 24) |
   398                             (read() << 16) |
   399                             (read() << 8) |
   400                             read();
   401                     _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
   402                     String v = decodeUtf16StringAsString();
   403                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
   404                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
   405                     }
   407                     appendOrCreateTextData(v);
   408                     break;
   409                 }
   410                 case DecoderStateTables.CII_RA:
   411                 {
   412                     final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
   414                     // Decode resitricted alphabet integer
   415                     _identifier = (_b & 0x02) << 6;
   416                     _b = read();
   417                     _identifier |= (_b & 0xFC) >> 2;
   419                     decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
   421                     String v = decodeRestrictedAlphabetAsString();
   422                     if (addToTable) {
   423                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
   424                     }
   426                     appendOrCreateTextData(v);
   427                     break;
   428                 }
   429                 case DecoderStateTables.CII_EA:
   430                 {
   431                     final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
   432                     // Decode encoding algorithm integer
   433                     _identifier = (_b & 0x02) << 6;
   434                     _b = read();
   435                     _identifier |= (_b & 0xFC) >> 2;
   437                     decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
   438                     final String s = convertEncodingAlgorithmDataToCharacters(false);
   439                     if (addToTable) {
   440                         _characterContentChunkTable.add(s.toCharArray(), s.length());
   441                     }
   442                     appendOrCreateTextData(s);
   443                     break;
   444                 }
   445                 case DecoderStateTables.CII_INDEX_SMALL:
   446                 {
   447                     final String s = _characterContentChunkTable.getString(_b & EncodingConstants.INTEGER_4TH_BIT_SMALL_MASK);
   449                     appendOrCreateTextData(s);
   450                     break;
   451                 }
   452                 case DecoderStateTables.CII_INDEX_MEDIUM:
   453                 {
   454                     final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_MEDIUM_MASK) << 8) | read())
   455                     + EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT;
   456                     final String s = _characterContentChunkTable.getString(index);
   458                     appendOrCreateTextData(s);
   459                     break;
   460                 }
   461                 case DecoderStateTables.CII_INDEX_LARGE:
   462                 {
   463                     int index = ((_b & EncodingConstants.INTEGER_4TH_BIT_LARGE_MASK) << 16) |
   464                             (read() << 8) |
   465                             read();
   466                     index += EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT;
   467                     final String s = _characterContentChunkTable.getString(index);
   469                     appendOrCreateTextData(s);
   470                     break;
   471                 }
   472                 case DecoderStateTables.CII_INDEX_LARGE_LARGE:
   473                 {
   474                     int index = (read() << 16) |
   475                             (read() << 8) |
   476                             read();
   477                     index += EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT;
   478                     final String s = _characterContentChunkTable.getString(index);
   480                     appendOrCreateTextData(s);
   481                     break;
   482                 }
   483                 case DecoderStateTables.COMMENT_II:
   484                     processCommentII();
   485                     break;
   486                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
   487                     processProcessingII();
   488                     break;
   489                 case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II:
   490                 {
   491                     String entity_reference_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
   493                     String system_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_SYSTEM_IDENTIFIER_FLAG) > 0)
   494                     ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
   495                     String public_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_PUBLIC_IDENTIFIER_FLAG) > 0)
   496                     ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
   498                     // TODO create Node
   499                     break;
   500                 }
   501                 case DecoderStateTables.TERMINATOR_DOUBLE:
   502                     _doubleTerminate = true;
   503                 case DecoderStateTables.TERMINATOR_SINGLE:
   504                     _terminate = true;
   505                     break;
   506                 default:
   507                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEII"));
   508             }
   509         }
   511         _terminate = _doubleTerminate;
   512         _doubleTerminate = false;
   514         _currentNode = parentCurrentNode;
   515     }
   517     private void appendOrCreateTextData(String textData) {
   518         Node lastChild = _currentNode.getLastChild();
   519         if (lastChild instanceof Text) {
   520             ((Text) lastChild).appendData(textData);
   521         } else {
   522             _currentNode.appendChild(
   523                     _document.createTextNode(textData));
   524         }
   525     }
   527     private final String processUtf8CharacterString() throws FastInfosetException, IOException {
   528         if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
   529             _characterContentChunkTable.ensureSize(_octetBufferLength);
   530             final int charactersOffset = _characterContentChunkTable._arrayIndex;
   531             decodeUtf8StringAsCharBuffer(_characterContentChunkTable._array, charactersOffset);
   532             _characterContentChunkTable.add(_charBufferLength);
   533             return _characterContentChunkTable.getString(_characterContentChunkTable._cachedIndex);
   534         } else {
   535             decodeUtf8StringAsCharBuffer();
   536             return new String(_charBuffer, 0, _charBufferLength);
   537         }
   538     }
   540     protected final void processEIIWithNamespaces() throws FastInfosetException, IOException {
   541         final boolean hasAttributes = (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0;
   543         if (++_prefixTable._declarationId == Integer.MAX_VALUE) {
   544             _prefixTable.clearDeclarationIds();
   545         }
   547         String prefix;
   548         Attr a = null;
   549         final int start = _namespacePrefixesIndex;
   550         int b = read();
   551         while ((b & EncodingConstants.NAMESPACE_ATTRIBUTE_MASK) == EncodingConstants.NAMESPACE_ATTRIBUTE) {
   552             if (_namespaceAttributesIndex == _namespaceAttributes.length) {
   553                 final Attr[] newNamespaceAttributes = new Attr[_namespaceAttributesIndex * 3 / 2 + 1];
   554                 System.arraycopy(_namespaceAttributes, 0, newNamespaceAttributes, 0, _namespaceAttributesIndex);
   555                 _namespaceAttributes = newNamespaceAttributes;
   556             }
   558             if (_namespacePrefixesIndex == _namespacePrefixes.length) {
   559                 final int[] namespaceAIIs = new int[_namespacePrefixesIndex * 3 / 2 + 1];
   560                 System.arraycopy(_namespacePrefixes, 0, namespaceAIIs, 0, _namespacePrefixesIndex);
   561                 _namespacePrefixes = namespaceAIIs;
   562             }
   565             switch (b & EncodingConstants.NAMESPACE_ATTRIBUTE_PREFIX_NAME_MASK) {
   566                 // no prefix, no namespace
   567                 // Undeclaration of default namespace
   568                 case 0:
   569                     a = createAttribute(
   570                             EncodingConstants.XMLNS_NAMESPACE_NAME,
   571                             EncodingConstants.XMLNS_NAMESPACE_PREFIX,
   572                             EncodingConstants.XMLNS_NAMESPACE_PREFIX);
   573                     a.setValue("");
   575                     _prefixIndex = _namespaceNameIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
   576                     break;
   577                     // no prefix, namespace
   578                     // Declaration of default namespace
   579                 case 1:
   580                     a = createAttribute(
   581                             EncodingConstants.XMLNS_NAMESPACE_NAME,
   582                             EncodingConstants.XMLNS_NAMESPACE_PREFIX,
   583                             EncodingConstants.XMLNS_NAMESPACE_PREFIX);
   584                     a.setValue(decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(false));
   586                     _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
   587                     break;
   588                     // prefix, no namespace
   589                     // Undeclaration of namespace
   590                 case 2:
   591                     prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(false);
   592                     a = createAttribute(
   593                             EncodingConstants.XMLNS_NAMESPACE_NAME,
   594                             createQualifiedNameString(prefix),
   595                             prefix);
   596                     a.setValue("");
   598                     _namespaceNameIndex = -1;
   599                     _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
   600                     break;
   601                     // prefix, namespace
   602                     // Declaration of prefixed namespace
   603                 case 3:
   604                     prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(true);
   605                     a = createAttribute(
   606                             EncodingConstants.XMLNS_NAMESPACE_NAME,
   607                             createQualifiedNameString(prefix),
   608                             prefix);
   609                     a.setValue(decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(true));
   611                     _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
   612                     break;
   613             }
   615             _prefixTable.pushScope(_prefixIndex, _namespaceNameIndex);
   617             _namespaceAttributes[_namespaceAttributesIndex++] = a;
   619             b = read();
   620         }
   621         if (b != EncodingConstants.TERMINATOR) {
   622             throw new IOException(CommonResourceBundle.getInstance().getString("message.EIInamespaceNameNotTerminatedCorrectly"));
   623         }
   624         final int end = _namespacePrefixesIndex;
   626         _b = read();
   627         switch(DecoderStateTables.EII(_b)) {
   628             case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
   629                 processEII(_elementNameTable._array[_b], hasAttributes);
   630                 break;
   631             case DecoderStateTables.EII_INDEX_MEDIUM:
   632                 processEII(decodeEIIIndexMedium(), hasAttributes);
   633                 break;
   634             case DecoderStateTables.EII_INDEX_LARGE:
   635                 processEII(decodeEIIIndexLarge(), hasAttributes);
   636                 break;
   637             case DecoderStateTables.EII_LITERAL:
   638             {
   639                 final QualifiedName qn = processLiteralQualifiedName(
   640                         _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
   641                         _elementNameTable.getNext());
   642                 _elementNameTable.add(qn);
   643                 processEII(qn, hasAttributes);
   644                 break;
   645             }
   646             default:
   647                 throw new IOException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEIIAfterAIIs"));
   648         }
   650         for (int i = start; i < end; i++) {
   651             _prefixTable.popScope(_namespacePrefixes[i]);
   652         }
   653         _namespacePrefixesIndex = start;
   655     }
   657     protected final QualifiedName processLiteralQualifiedName(int state, QualifiedName q)
   658     throws FastInfosetException, IOException {
   659         if (q == null) q = new QualifiedName();
   661         switch (state) {
   662             // no prefix, no namespace
   663             case 0:
   664                 return q.set(
   665                         null,
   666                         null,
   667                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
   668                         -1,
   669                         -1,
   670                         _identifier,
   671                         null);
   672                 // no prefix, namespace
   673             case 1:
   674                 return q.set(
   675                         null,
   676                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false),
   677                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
   678                         -1,
   679                         _namespaceNameIndex,
   680                         _identifier,
   681                         null);
   682                 // prefix, no namespace
   683             case 2:
   684                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName"));
   685                 // prefix, namespace
   686             case 3:
   687                 return q.set(
   688                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true),
   689                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true),
   690                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
   691                         _prefixIndex,
   692                         _namespaceNameIndex,
   693                         _identifier,
   694                         _charBuffer);
   695             default:
   696                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII"));
   697         }
   698     }
   700     protected final QualifiedName processLiteralQualifiedName(int state)
   701     throws FastInfosetException, IOException {
   702         switch (state) {
   703             // no prefix, no namespace
   704             case 0:
   705                 return new QualifiedName(
   706                         null,
   707                         null,
   708                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
   709                         -1,
   710                         -1,
   711                         _identifier,
   712                         null);
   713                 // no prefix, namespace
   714             case 1:
   715                 return new QualifiedName(
   716                         null,
   717                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false),
   718                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
   719                         -1,
   720                         _namespaceNameIndex,
   721                         _identifier,
   722                         null);
   723                 // prefix, no namespace
   724             case 2:
   725                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName"));
   726                 // prefix, namespace
   727             case 3:
   728                 return new QualifiedName(
   729                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true),
   730                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true),
   731                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
   732                         _prefixIndex,
   733                         _namespaceNameIndex,
   734                         _identifier,
   735                         _charBuffer);
   736             default:
   737                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII"));
   738         }
   739     }
   741     protected final void processAIIs() throws FastInfosetException, IOException {
   742         QualifiedName name;
   743         int b;
   744         String value;
   746         if (++_duplicateAttributeVerifier._currentIteration == Integer.MAX_VALUE) {
   747             _duplicateAttributeVerifier.clear();
   748         }
   750         do {
   751             // AII qualified name
   752             b = read();
   753             switch (DecoderStateTables.AII(b)) {
   754                 case DecoderStateTables.AII_INDEX_SMALL:
   755                     name = _attributeNameTable._array[b];
   756                     break;
   757                 case DecoderStateTables.AII_INDEX_MEDIUM:
   758                 {
   759                     final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
   760                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
   761                     name = _attributeNameTable._array[i];
   762                     break;
   763                 }
   764                 case DecoderStateTables.AII_INDEX_LARGE:
   765                 {
   766                     final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
   767                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
   768                     name = _attributeNameTable._array[i];
   769                     break;
   770                 }
   771                 case DecoderStateTables.AII_LITERAL:
   772                     name = processLiteralQualifiedName(
   773                             b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
   774                             _attributeNameTable.getNext());
   775                     name.createAttributeValues(DuplicateAttributeVerifier.MAP_SIZE);
   776                     _attributeNameTable.add(name);
   777                     break;
   778                 case DecoderStateTables.AII_TERMINATOR_DOUBLE:
   779                     _doubleTerminate = true;
   780                 case DecoderStateTables.AII_TERMINATOR_SINGLE:
   781                     _terminate = true;
   782                     // AIIs have finished break out of loop
   783                     continue;
   784                 default:
   785                     throw new IOException(CommonResourceBundle.getInstance().getString("message.decodingAIIs"));
   786             }
   788             if (name.prefixIndex > 0 && _prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
   789                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.AIIqNameNotInScope"));
   790             }
   792             _duplicateAttributeVerifier.checkForDuplicateAttribute(name.attributeHash, name.attributeId);
   794             Attr a = createAttribute(
   795                     name.namespaceName,
   796                     name.qName,
   797                     name.localName);
   799             // [normalized value] of AII
   801             b = read();
   802             switch(DecoderStateTables.NISTRING(b)) {
   803                 case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
   804                 {
   805                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
   806                     _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
   807                     value = decodeUtf8StringAsString();
   808                     if (addToTable) {
   809                         _attributeValueTable.add(value);
   810                     }
   812                     a.setValue(value);
   813                     _currentElement.setAttributeNode(a);
   814                     break;
   815                 }
   816                 case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
   817                 {
   818                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
   819                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
   820                     value = decodeUtf8StringAsString();
   821                     if (addToTable) {
   822                         _attributeValueTable.add(value);
   823                     }
   825                     a.setValue(value);
   826                     _currentElement.setAttributeNode(a);
   827                     break;
   828                 }
   829                 case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
   830                 {
   831                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
   832                     final int length = (read() << 24) |
   833                             (read() << 16) |
   834                             (read() << 8) |
   835                             read();
   836                     _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
   837                     value = decodeUtf8StringAsString();
   838                     if (addToTable) {
   839                         _attributeValueTable.add(value);
   840                     }
   842                     a.setValue(value);
   843                     _currentElement.setAttributeNode(a);
   844                     break;
   845                 }
   846                 case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH:
   847                 {
   848                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
   849                     _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
   850                     value = decodeUtf16StringAsString();
   851                     if (addToTable) {
   852                         _attributeValueTable.add(value);
   853                     }
   855                     a.setValue(value);
   856                     _currentElement.setAttributeNode(a);
   857                     break;
   858                 }
   859                 case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH:
   860                 {
   861                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
   862                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
   863                     value = decodeUtf16StringAsString();
   864                     if (addToTable) {
   865                         _attributeValueTable.add(value);
   866                     }
   868                     a.setValue(value);
   869                     _currentElement.setAttributeNode(a);
   870                     break;
   871                 }
   872                 case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH:
   873                 {
   874                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
   875                     final int length = (read() << 24) |
   876                             (read() << 16) |
   877                             (read() << 8) |
   878                             read();
   879                     _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
   880                     value = decodeUtf16StringAsString();
   881                     if (addToTable) {
   882                         _attributeValueTable.add(value);
   883                     }
   885                     a.setValue(value);
   886                     _currentElement.setAttributeNode(a);
   887                     break;
   888                 }
   889                 case DecoderStateTables.NISTRING_RA:
   890                 {
   891                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
   892                     // Decode resitricted alphabet integer
   893                     _identifier = (b & 0x0F) << 4;
   894                     b = read();
   895                     _identifier |= (b & 0xF0) >> 4;
   897                     decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
   899                     value = decodeRestrictedAlphabetAsString();
   900                     if (addToTable) {
   901                         _attributeValueTable.add(value);
   902                     }
   904                     a.setValue(value);
   905                     _currentElement.setAttributeNode(a);
   906                     break;
   907                 }
   908                 case DecoderStateTables.NISTRING_EA:
   909                 {
   910                     final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
   911                     _identifier = (b & 0x0F) << 4;
   912                     b = read();
   913                     _identifier |= (b & 0xF0) >> 4;
   915                     decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
   916                     value = convertEncodingAlgorithmDataToCharacters(true);
   917                     if (addToTable) {
   918                         _attributeValueTable.add(value);
   919                     }
   920                     a.setValue(value);
   921                     _currentElement.setAttributeNode(a);
   922                     break;
   923                 }
   924                 case DecoderStateTables.NISTRING_INDEX_SMALL:
   925                     value = _attributeValueTable._array[b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK];
   927                     a.setValue(value);
   928                     _currentElement.setAttributeNode(a);
   929                     break;
   930                 case DecoderStateTables.NISTRING_INDEX_MEDIUM:
   931                 {
   932                     final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
   933                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
   934                     value = _attributeValueTable._array[index];
   936                     a.setValue(value);
   937                     _currentElement.setAttributeNode(a);
   938                     break;
   939                 }
   940                 case DecoderStateTables.NISTRING_INDEX_LARGE:
   941                 {
   942                     final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
   943                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
   944                     value = _attributeValueTable._array[index];
   946                     a.setValue(value);
   947                     _currentElement.setAttributeNode(a);
   948                     break;
   949                 }
   950                 case DecoderStateTables.NISTRING_EMPTY:
   951                     a.setValue("");
   952                     _currentElement.setAttributeNode(a);
   953                     break;
   954                 default:
   955                     throw new IOException(CommonResourceBundle.getInstance().getString("message.decodingAIIValue"));
   956             }
   958         } while (!_terminate);
   960         // Reset duplication attribute verfifier
   961         _duplicateAttributeVerifier._poolCurrent = _duplicateAttributeVerifier._poolHead;
   963         _terminate = _doubleTerminate;
   964         _doubleTerminate = false;
   965     }
   967     protected final void processCommentII() throws FastInfosetException, IOException {
   968         switch(decodeNonIdentifyingStringOnFirstBit()) {
   969             case NISTRING_STRING:
   970             {
   971                 final String s = new String(_charBuffer, 0, _charBufferLength);
   972                 if (_addToTable) {
   973                     _v.otherString.add(new CharArrayString(s, false));
   974                 }
   976                 _currentNode.appendChild(_document.createComment(s));
   977                 break;
   978             }
   979             case NISTRING_ENCODING_ALGORITHM:
   980                 throw new IOException(CommonResourceBundle.getInstance().getString("message.commentIIAlgorithmNotSupported"));
   981             case NISTRING_INDEX:
   982             {
   983                 final String s = _v.otherString.get(_integer).toString();
   985                 _currentNode.appendChild(_document.createComment(s));
   986                 break;
   987             }
   988             case NISTRING_EMPTY_STRING:
   989                 _currentNode.appendChild(_document.createComment(""));
   990                 break;
   991         }
   992     }
   994     protected final void processProcessingII() throws FastInfosetException, IOException {
   995         final String target = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
   997         switch(decodeNonIdentifyingStringOnFirstBit()) {
   998             case NISTRING_STRING:
   999             {
  1000                 final String data = new String(_charBuffer, 0, _charBufferLength);
  1001                 if (_addToTable) {
  1002                     _v.otherString.add(new CharArrayString(data, false));
  1005                 _currentNode.appendChild(_document.createProcessingInstruction(target, data));
  1006                 break;
  1008             case NISTRING_ENCODING_ALGORITHM:
  1009                 throw new IOException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
  1010             case NISTRING_INDEX:
  1012                 final String data = _v.otherString.get(_integer).toString();
  1014                 _currentNode.appendChild(_document.createProcessingInstruction(target, data));
  1015                 break;
  1017             case NISTRING_EMPTY_STRING:
  1018                 _currentNode.appendChild(_document.createProcessingInstruction(target, ""));
  1019                 break;
  1023     protected Element createElement(String namespaceName, String qName, String localName) {
  1024         return _document.createElementNS(namespaceName, qName);
  1027     protected Attr createAttribute(String namespaceName, String qName, String localName) {
  1028         return _document.createAttributeNS(namespaceName, qName);
  1031     protected String convertEncodingAlgorithmDataToCharacters(boolean isAttributeValue) throws FastInfosetException, IOException {
  1032         StringBuffer buffer = new StringBuffer();
  1033         if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
  1034             Object array = BuiltInEncodingAlgorithmFactory.getAlgorithm(_identifier).
  1035                     decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
  1036             BuiltInEncodingAlgorithmFactory.getAlgorithm(_identifier).convertToCharacters(array,  buffer);
  1037         } else if (_identifier == EncodingAlgorithmIndexes.CDATA) {
  1038             if (!isAttributeValue) {
  1039                 // Set back buffer position to start of encoded string
  1040                 _octetBufferOffset -= _octetBufferLength;
  1041                 return decodeUtf8StringAsString();
  1043             throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported"));
  1044         } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
  1045             final String URI = _v.encodingAlgorithm.get(_identifier - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
  1046             final EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
  1047             if (ea != null) {
  1048                 final Object data = ea.decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
  1049                 ea.convertToCharacters(data, buffer);
  1050             } else {
  1051                 throw new EncodingAlgorithmException(
  1052                         CommonResourceBundle.getInstance().getString("message.algorithmDataCannotBeReported"));
  1055         return buffer.toString();

mercurial