src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/dom/DOMDocumentParser.java

Wed, 12 Jun 2013 14:47:09 +0100

author
mkos
date
Wed, 12 Jun 2013 14:47:09 +0100
changeset 384
8f2986ff0235
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
permissions
-rw-r--r--

8013021: Rebase 8005432 & 8003542 against the latest jdk8/jaxws
8003542: Improve processing of MTOM attachments
8005432: Update access to JAX-WS
Reviewed-by: mullan

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

mercurial