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

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

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

merge

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

mercurial