aoqi@0: /* aoqi@0: * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.stream.buffer; aoqi@0: aoqi@0: /** aoqi@0: * Base class for classes that processes {@link XMLStreamBuffer} aoqi@0: * and produces infoset in API-specific form. aoqi@0: */ aoqi@0: public abstract class AbstractProcessor extends AbstractCreatorProcessor { aoqi@0: protected static final int STATE_ILLEGAL = 0; aoqi@0: aoqi@0: protected static final int STATE_DOCUMENT = 1; aoqi@0: protected static final int STATE_DOCUMENT_FRAGMENT = 2; aoqi@0: protected static final int STATE_ELEMENT_U_LN_QN = 3; aoqi@0: protected static final int STATE_ELEMENT_P_U_LN = 4; aoqi@0: protected static final int STATE_ELEMENT_U_LN = 5; aoqi@0: protected static final int STATE_ELEMENT_LN = 6; aoqi@0: protected static final int STATE_TEXT_AS_CHAR_ARRAY_SMALL = 7; aoqi@0: protected static final int STATE_TEXT_AS_CHAR_ARRAY_MEDIUM = 8; aoqi@0: protected static final int STATE_TEXT_AS_CHAR_ARRAY_COPY = 9; aoqi@0: protected static final int STATE_TEXT_AS_STRING = 10; aoqi@0: protected static final int STATE_TEXT_AS_OBJECT = 11; aoqi@0: protected static final int STATE_COMMENT_AS_CHAR_ARRAY_SMALL = 12; aoqi@0: protected static final int STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM = 13; aoqi@0: protected static final int STATE_COMMENT_AS_CHAR_ARRAY_COPY = 14; aoqi@0: protected static final int STATE_COMMENT_AS_STRING = 15; aoqi@0: protected static final int STATE_PROCESSING_INSTRUCTION = 16; aoqi@0: protected static final int STATE_END = 17; aoqi@0: private static final int[] _eiiStateTable = new int[256]; aoqi@0: aoqi@0: protected static final int STATE_NAMESPACE_ATTRIBUTE = 1; aoqi@0: protected static final int STATE_NAMESPACE_ATTRIBUTE_P = 2; aoqi@0: protected static final int STATE_NAMESPACE_ATTRIBUTE_P_U = 3; aoqi@0: protected static final int STATE_NAMESPACE_ATTRIBUTE_U = 4; aoqi@0: private static final int[] _niiStateTable = new int[256]; aoqi@0: aoqi@0: protected static final int STATE_ATTRIBUTE_U_LN_QN = 1; aoqi@0: protected static final int STATE_ATTRIBUTE_P_U_LN = 2; aoqi@0: protected static final int STATE_ATTRIBUTE_U_LN = 3; aoqi@0: protected static final int STATE_ATTRIBUTE_LN = 4; aoqi@0: protected static final int STATE_ATTRIBUTE_U_LN_QN_OBJECT = 5; aoqi@0: protected static final int STATE_ATTRIBUTE_P_U_LN_OBJECT = 6; aoqi@0: protected static final int STATE_ATTRIBUTE_U_LN_OBJECT = 7; aoqi@0: protected static final int STATE_ATTRIBUTE_LN_OBJECT = 8; aoqi@0: private static final int[] _aiiStateTable = new int[256]; aoqi@0: aoqi@0: static { aoqi@0: /* aoqi@0: * Create a state table from information items and options. aoqi@0: * The swtich statement using such states will often generate a more aoqi@0: * efficient byte code representation that can be hotspotted using aoqi@0: * jump tables. aoqi@0: */ aoqi@0: _eiiStateTable[T_DOCUMENT] = STATE_DOCUMENT; aoqi@0: _eiiStateTable[T_DOCUMENT_FRAGMENT] = STATE_DOCUMENT_FRAGMENT; aoqi@0: _eiiStateTable[T_ELEMENT_U_LN_QN] = STATE_ELEMENT_U_LN_QN; aoqi@0: _eiiStateTable[T_ELEMENT_P_U_LN] = STATE_ELEMENT_P_U_LN; aoqi@0: _eiiStateTable[T_ELEMENT_U_LN] = STATE_ELEMENT_U_LN; aoqi@0: _eiiStateTable[T_ELEMENT_LN] = STATE_ELEMENT_LN; aoqi@0: _eiiStateTable[T_TEXT_AS_CHAR_ARRAY_SMALL] = STATE_TEXT_AS_CHAR_ARRAY_SMALL; aoqi@0: _eiiStateTable[T_TEXT_AS_CHAR_ARRAY_MEDIUM] = STATE_TEXT_AS_CHAR_ARRAY_MEDIUM; aoqi@0: _eiiStateTable[T_TEXT_AS_CHAR_ARRAY_COPY] = STATE_TEXT_AS_CHAR_ARRAY_COPY; aoqi@0: _eiiStateTable[T_TEXT_AS_STRING] = STATE_TEXT_AS_STRING; aoqi@0: _eiiStateTable[T_TEXT_AS_OBJECT] = STATE_TEXT_AS_OBJECT; aoqi@0: _eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_SMALL] = STATE_COMMENT_AS_CHAR_ARRAY_SMALL; aoqi@0: _eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_MEDIUM] = STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM; aoqi@0: _eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_COPY] = STATE_COMMENT_AS_CHAR_ARRAY_COPY; aoqi@0: _eiiStateTable[T_COMMENT_AS_STRING] = STATE_COMMENT_AS_STRING; aoqi@0: _eiiStateTable[T_PROCESSING_INSTRUCTION] = STATE_PROCESSING_INSTRUCTION; aoqi@0: _eiiStateTable[T_END] = STATE_END; aoqi@0: aoqi@0: _niiStateTable[T_NAMESPACE_ATTRIBUTE] = STATE_NAMESPACE_ATTRIBUTE; aoqi@0: _niiStateTable[T_NAMESPACE_ATTRIBUTE_P] = STATE_NAMESPACE_ATTRIBUTE_P; aoqi@0: _niiStateTable[T_NAMESPACE_ATTRIBUTE_P_U] = STATE_NAMESPACE_ATTRIBUTE_P_U; aoqi@0: _niiStateTable[T_NAMESPACE_ATTRIBUTE_U] = STATE_NAMESPACE_ATTRIBUTE_U; aoqi@0: aoqi@0: _aiiStateTable[T_ATTRIBUTE_U_LN_QN] = STATE_ATTRIBUTE_U_LN_QN; aoqi@0: _aiiStateTable[T_ATTRIBUTE_P_U_LN] = STATE_ATTRIBUTE_P_U_LN; aoqi@0: _aiiStateTable[T_ATTRIBUTE_U_LN] = STATE_ATTRIBUTE_U_LN; aoqi@0: _aiiStateTable[T_ATTRIBUTE_LN] = STATE_ATTRIBUTE_LN; aoqi@0: _aiiStateTable[T_ATTRIBUTE_U_LN_QN_OBJECT] = STATE_ATTRIBUTE_U_LN_QN_OBJECT; aoqi@0: _aiiStateTable[T_ATTRIBUTE_P_U_LN_OBJECT] = STATE_ATTRIBUTE_P_U_LN_OBJECT; aoqi@0: _aiiStateTable[T_ATTRIBUTE_U_LN_OBJECT] = STATE_ATTRIBUTE_U_LN_OBJECT; aoqi@0: _aiiStateTable[T_ATTRIBUTE_LN_OBJECT] = STATE_ATTRIBUTE_LN_OBJECT; aoqi@0: } aoqi@0: aoqi@0: protected XMLStreamBuffer _buffer; aoqi@0: aoqi@0: /** aoqi@0: * True if this processor should create a fragment of XML, without the start/end document markers. aoqi@0: */ aoqi@0: protected boolean _fragmentMode; aoqi@0: aoqi@0: protected boolean _stringInterningFeature = false; aoqi@0: aoqi@0: /** aoqi@0: * Number of remaining XML element trees that should be visible aoqi@0: * through this {@link AbstractProcessor}. aoqi@0: */ aoqi@0: protected int _treeCount; aoqi@0: aoqi@0: /** aoqi@0: * @deprecated aoqi@0: * Use {@link #setBuffer(XMLStreamBuffer, boolean)} aoqi@0: */ aoqi@0: protected final void setBuffer(XMLStreamBuffer buffer) { aoqi@0: setBuffer(buffer,buffer.isFragment()); aoqi@0: } aoqi@0: protected final void setBuffer(XMLStreamBuffer buffer, boolean fragmentMode) { aoqi@0: _buffer = buffer; aoqi@0: _fragmentMode = fragmentMode; aoqi@0: aoqi@0: _currentStructureFragment = _buffer.getStructure(); aoqi@0: _structure = _currentStructureFragment.getArray(); aoqi@0: _structurePtr = _buffer.getStructurePtr(); aoqi@0: aoqi@0: _currentStructureStringFragment = _buffer.getStructureStrings(); aoqi@0: _structureStrings = _currentStructureStringFragment.getArray(); aoqi@0: _structureStringsPtr = _buffer.getStructureStringsPtr(); aoqi@0: aoqi@0: _currentContentCharactersBufferFragment = _buffer.getContentCharactersBuffer(); aoqi@0: _contentCharactersBuffer = _currentContentCharactersBufferFragment.getArray(); aoqi@0: _contentCharactersBufferPtr = _buffer.getContentCharactersBufferPtr(); aoqi@0: aoqi@0: _currentContentObjectFragment = _buffer.getContentObjects(); aoqi@0: _contentObjects = _currentContentObjectFragment.getArray(); aoqi@0: _contentObjectsPtr = _buffer.getContentObjectsPtr(); aoqi@0: aoqi@0: _stringInterningFeature = _buffer.hasInternedStrings(); aoqi@0: _treeCount = _buffer.treeCount; aoqi@0: } aoqi@0: aoqi@0: protected final int peekStructure() { aoqi@0: if (_structurePtr < _structure.length) { aoqi@0: return _structure[_structurePtr] & 255; aoqi@0: } aoqi@0: aoqi@0: return readFromNextStructure(0); aoqi@0: } aoqi@0: aoqi@0: protected final int readStructure() { aoqi@0: if (_structurePtr < _structure.length) { aoqi@0: return _structure[_structurePtr++] & 255; aoqi@0: } aoqi@0: aoqi@0: return readFromNextStructure(1); aoqi@0: } aoqi@0: aoqi@0: protected final int readEiiState() { aoqi@0: return _eiiStateTable[readStructure()]; aoqi@0: } aoqi@0: aoqi@0: protected static int getEIIState(int item) { aoqi@0: return _eiiStateTable[item]; aoqi@0: } aoqi@0: aoqi@0: protected static int getNIIState(int item) { aoqi@0: return _niiStateTable[item]; aoqi@0: } aoqi@0: aoqi@0: protected static int getAIIState(int item) { aoqi@0: return _aiiStateTable[item]; aoqi@0: } aoqi@0: aoqi@0: protected final int readStructure16() { aoqi@0: return (readStructure() << 8) | readStructure(); aoqi@0: } aoqi@0: aoqi@0: private int readFromNextStructure(int v) { aoqi@0: _structurePtr = v; aoqi@0: _currentStructureFragment = _currentStructureFragment.getNext(); aoqi@0: _structure = _currentStructureFragment.getArray(); aoqi@0: return _structure[0] & 255; aoqi@0: } aoqi@0: aoqi@0: protected final String readStructureString() { aoqi@0: if (_structureStringsPtr < _structureStrings.length) { aoqi@0: return _structureStrings[_structureStringsPtr++]; aoqi@0: } aoqi@0: aoqi@0: _structureStringsPtr = 1; aoqi@0: _currentStructureStringFragment = _currentStructureStringFragment.getNext(); aoqi@0: _structureStrings = _currentStructureStringFragment.getArray(); aoqi@0: return _structureStrings[0]; aoqi@0: } aoqi@0: aoqi@0: protected final String readContentString() { aoqi@0: return (String)readContentObject(); aoqi@0: } aoqi@0: aoqi@0: protected final char[] readContentCharactersCopy() { aoqi@0: return (char[])readContentObject(); aoqi@0: } aoqi@0: aoqi@0: protected final int readContentCharactersBuffer(int length) { aoqi@0: if (_contentCharactersBufferPtr + length < _contentCharactersBuffer.length) { aoqi@0: final int start = _contentCharactersBufferPtr; aoqi@0: _contentCharactersBufferPtr += length; aoqi@0: return start; aoqi@0: } aoqi@0: aoqi@0: _contentCharactersBufferPtr = length; aoqi@0: _currentContentCharactersBufferFragment = _currentContentCharactersBufferFragment.getNext(); aoqi@0: _contentCharactersBuffer = _currentContentCharactersBufferFragment.getArray(); aoqi@0: return 0; aoqi@0: } aoqi@0: aoqi@0: protected final Object readContentObject() { aoqi@0: if (_contentObjectsPtr < _contentObjects.length) { aoqi@0: return _contentObjects[_contentObjectsPtr++]; aoqi@0: } aoqi@0: aoqi@0: _contentObjectsPtr = 1; aoqi@0: _currentContentObjectFragment = _currentContentObjectFragment.getNext(); aoqi@0: _contentObjects = _currentContentObjectFragment.getArray(); aoqi@0: return _contentObjects[0]; aoqi@0: } aoqi@0: aoqi@0: protected final StringBuilder _qNameBuffer = new StringBuilder(); aoqi@0: aoqi@0: protected final String getQName(String prefix, String localName) { aoqi@0: _qNameBuffer.append(prefix).append(':').append(localName); aoqi@0: final String qName = _qNameBuffer.toString(); aoqi@0: _qNameBuffer.setLength(0); aoqi@0: return (_stringInterningFeature) ? qName.intern() : qName; aoqi@0: } aoqi@0: aoqi@0: protected final String getPrefixFromQName(String qName) { aoqi@0: int pIndex = qName.indexOf(':'); aoqi@0: if (_stringInterningFeature) { aoqi@0: return (pIndex != -1) ? qName.substring(0,pIndex).intern() : ""; aoqi@0: } else { aoqi@0: return (pIndex != -1) ? qName.substring(0,pIndex) : ""; aoqi@0: } aoqi@0: } aoqi@0: }