1 /* 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.stream.buffer; 27 28 /** 29 * Base class for classes that processes {@link XMLStreamBuffer} 30 * and produces infoset in API-specific form. 31 */ 32 public abstract class AbstractProcessor extends AbstractCreatorProcessor { 33 protected static final int STATE_ILLEGAL = 0; 34 35 protected static final int STATE_DOCUMENT = 1; 36 protected static final int STATE_DOCUMENT_FRAGMENT = 2; 37 protected static final int STATE_ELEMENT_U_LN_QN = 3; 38 protected static final int STATE_ELEMENT_P_U_LN = 4; 39 protected static final int STATE_ELEMENT_U_LN = 5; 40 protected static final int STATE_ELEMENT_LN = 6; 41 protected static final int STATE_TEXT_AS_CHAR_ARRAY_SMALL = 7; 42 protected static final int STATE_TEXT_AS_CHAR_ARRAY_MEDIUM = 8; 43 protected static final int STATE_TEXT_AS_CHAR_ARRAY_COPY = 9; 44 protected static final int STATE_TEXT_AS_STRING = 10; 45 protected static final int STATE_TEXT_AS_OBJECT = 11; 46 protected static final int STATE_COMMENT_AS_CHAR_ARRAY_SMALL = 12; 47 protected static final int STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM = 13; 48 protected static final int STATE_COMMENT_AS_CHAR_ARRAY_COPY = 14; 49 protected static final int STATE_COMMENT_AS_STRING = 15; 50 protected static final int STATE_PROCESSING_INSTRUCTION = 16; 51 protected static final int STATE_END = 17; 52 private static final int[] _eiiStateTable = new int[256]; 53 54 protected static final int STATE_NAMESPACE_ATTRIBUTE = 1; 55 protected static final int STATE_NAMESPACE_ATTRIBUTE_P = 2; 56 protected static final int STATE_NAMESPACE_ATTRIBUTE_P_U = 3; 57 protected static final int STATE_NAMESPACE_ATTRIBUTE_U = 4; 58 private static final int[] _niiStateTable = new int[256]; 59 60 protected static final int STATE_ATTRIBUTE_U_LN_QN = 1; 61 protected static final int STATE_ATTRIBUTE_P_U_LN = 2; 62 protected static final int STATE_ATTRIBUTE_U_LN = 3; 63 protected static final int STATE_ATTRIBUTE_LN = 4; 64 protected static final int STATE_ATTRIBUTE_U_LN_QN_OBJECT = 5; 65 protected static final int STATE_ATTRIBUTE_P_U_LN_OBJECT = 6; 66 protected static final int STATE_ATTRIBUTE_U_LN_OBJECT = 7; 67 protected static final int STATE_ATTRIBUTE_LN_OBJECT = 8; 68 private static final int[] _aiiStateTable = new int[256]; 69 70 static { 71 /* 72 * Create a state table from information items and options. 73 * The swtich statement using such states will often generate a more 74 * efficient byte code representation that can be hotspotted using 75 * jump tables. 76 */ 77 _eiiStateTable[T_DOCUMENT] = STATE_DOCUMENT; 78 _eiiStateTable[T_DOCUMENT_FRAGMENT] = STATE_DOCUMENT_FRAGMENT; 79 _eiiStateTable[T_ELEMENT_U_LN_QN] = STATE_ELEMENT_U_LN_QN; 80 _eiiStateTable[T_ELEMENT_P_U_LN] = STATE_ELEMENT_P_U_LN; 81 _eiiStateTable[T_ELEMENT_U_LN] = STATE_ELEMENT_U_LN; 82 _eiiStateTable[T_ELEMENT_LN] = STATE_ELEMENT_LN; 83 _eiiStateTable[T_TEXT_AS_CHAR_ARRAY_SMALL] = STATE_TEXT_AS_CHAR_ARRAY_SMALL; 84 _eiiStateTable[T_TEXT_AS_CHAR_ARRAY_MEDIUM] = STATE_TEXT_AS_CHAR_ARRAY_MEDIUM; 85 _eiiStateTable[T_TEXT_AS_CHAR_ARRAY_COPY] = STATE_TEXT_AS_CHAR_ARRAY_COPY; 86 _eiiStateTable[T_TEXT_AS_STRING] = STATE_TEXT_AS_STRING; 87 _eiiStateTable[T_TEXT_AS_OBJECT] = STATE_TEXT_AS_OBJECT; 88 _eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_SMALL] = STATE_COMMENT_AS_CHAR_ARRAY_SMALL; 89 _eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_MEDIUM] = STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM; 90 _eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_COPY] = STATE_COMMENT_AS_CHAR_ARRAY_COPY; 91 _eiiStateTable[T_COMMENT_AS_STRING] = STATE_COMMENT_AS_STRING; 92 _eiiStateTable[T_PROCESSING_INSTRUCTION] = STATE_PROCESSING_INSTRUCTION; 93 _eiiStateTable[T_END] = STATE_END; 94 95 _niiStateTable[T_NAMESPACE_ATTRIBUTE] = STATE_NAMESPACE_ATTRIBUTE; 96 _niiStateTable[T_NAMESPACE_ATTRIBUTE_P] = STATE_NAMESPACE_ATTRIBUTE_P; 97 _niiStateTable[T_NAMESPACE_ATTRIBUTE_P_U] = STATE_NAMESPACE_ATTRIBUTE_P_U; 98 _niiStateTable[T_NAMESPACE_ATTRIBUTE_U] = STATE_NAMESPACE_ATTRIBUTE_U; 99 100 _aiiStateTable[T_ATTRIBUTE_U_LN_QN] = STATE_ATTRIBUTE_U_LN_QN; 101 _aiiStateTable[T_ATTRIBUTE_P_U_LN] = STATE_ATTRIBUTE_P_U_LN; 102 _aiiStateTable[T_ATTRIBUTE_U_LN] = STATE_ATTRIBUTE_U_LN; 103 _aiiStateTable[T_ATTRIBUTE_LN] = STATE_ATTRIBUTE_LN; 104 _aiiStateTable[T_ATTRIBUTE_U_LN_QN_OBJECT] = STATE_ATTRIBUTE_U_LN_QN_OBJECT; 105 _aiiStateTable[T_ATTRIBUTE_P_U_LN_OBJECT] = STATE_ATTRIBUTE_P_U_LN_OBJECT; 106 _aiiStateTable[T_ATTRIBUTE_U_LN_OBJECT] = STATE_ATTRIBUTE_U_LN_OBJECT; 107 _aiiStateTable[T_ATTRIBUTE_LN_OBJECT] = STATE_ATTRIBUTE_LN_OBJECT; 108 } 109 110 protected XMLStreamBuffer _buffer; 111 112 /** 113 * True if this processor should create a fragment of XML, without the start/end document markers. 114 */ 115 protected boolean _fragmentMode; 116 117 protected boolean _stringInterningFeature = false; 118 119 /** 120 * Number of remaining XML element trees that should be visible 121 * through this {@link AbstractProcessor}. 122 */ 123 protected int _treeCount; 124 125 /** 126 * @deprecated 127 * Use {@link #setBuffer(XMLStreamBuffer, boolean)} 128 */ 129 protected final void setBuffer(XMLStreamBuffer buffer) { 130 setBuffer(buffer,buffer.isFragment()); 131 } 132 protected final void setBuffer(XMLStreamBuffer buffer, boolean fragmentMode) { 133 _buffer = buffer; 134 _fragmentMode = fragmentMode; 135 136 _currentStructureFragment = _buffer.getStructure(); 137 _structure = _currentStructureFragment.getArray(); 138 _structurePtr = _buffer.getStructurePtr(); 139 140 _currentStructureStringFragment = _buffer.getStructureStrings(); 141 _structureStrings = _currentStructureStringFragment.getArray(); 142 _structureStringsPtr = _buffer.getStructureStringsPtr(); 143 144 _currentContentCharactersBufferFragment = _buffer.getContentCharactersBuffer(); 145 _contentCharactersBuffer = _currentContentCharactersBufferFragment.getArray(); 146 _contentCharactersBufferPtr = _buffer.getContentCharactersBufferPtr(); 147 148 _currentContentObjectFragment = _buffer.getContentObjects(); 149 _contentObjects = _currentContentObjectFragment.getArray(); 150 _contentObjectsPtr = _buffer.getContentObjectsPtr(); 151 152 _stringInterningFeature = _buffer.hasInternedStrings(); 153 _treeCount = _buffer.treeCount; 154 } 155 156 protected final int peekStructure() { 157 if (_structurePtr < _structure.length) { 158 return _structure[_structurePtr] & 255; 159 } 160 161 return readFromNextStructure(0); 162 } 163 164 protected final int readStructure() { 165 if (_structurePtr < _structure.length) { 166 return _structure[_structurePtr++] & 255; 167 } 168 169 return readFromNextStructure(1); 170 } 171 172 protected final int readEiiState() { 173 return _eiiStateTable[readStructure()]; 174 } 175 176 protected static int getEIIState(int item) { 177 return _eiiStateTable[item]; 178 } 179 180 protected static int getNIIState(int item) { 181 return _niiStateTable[item]; 182 } 183 184 protected static int getAIIState(int item) { 185 return _aiiStateTable[item]; 186 } 187 188 protected final int readStructure16() { 189 return (readStructure() << 8) | readStructure(); 190 } 191 192 private int readFromNextStructure(int v) { 193 _structurePtr = v; 194 _currentStructureFragment = _currentStructureFragment.getNext(); 195 _structure = _currentStructureFragment.getArray(); 196 return _structure[0] & 255; 197 } 198 199 protected final String readStructureString() { 200 if (_structureStringsPtr < _structureStrings.length) { 201 return _structureStrings[_structureStringsPtr++]; 202 } 203 204 _structureStringsPtr = 1; 205 _currentStructureStringFragment = _currentStructureStringFragment.getNext(); 206 _structureStrings = _currentStructureStringFragment.getArray(); 207 return _structureStrings[0]; 208 } 209 210 protected final String readContentString() { 211 return (String)readContentObject(); 212 } 213 214 protected final char[] readContentCharactersCopy() { 215 return (char[])readContentObject(); 216 } 217 218 protected final int readContentCharactersBuffer(int length) { 219 if (_contentCharactersBufferPtr + length < _contentCharactersBuffer.length) { 220 final int start = _contentCharactersBufferPtr; 221 _contentCharactersBufferPtr += length; 222 return start; 223 } 224 225 _contentCharactersBufferPtr = length; 226 _currentContentCharactersBufferFragment = _currentContentCharactersBufferFragment.getNext(); 227 _contentCharactersBuffer = _currentContentCharactersBufferFragment.getArray(); 228 return 0; 229 } 230 231 protected final Object readContentObject() { 232 if (_contentObjectsPtr < _contentObjects.length) { 233 return _contentObjects[_contentObjectsPtr++]; 234 } 235 236 _contentObjectsPtr = 1; 237 _currentContentObjectFragment = _currentContentObjectFragment.getNext(); 238 _contentObjects = _currentContentObjectFragment.getArray(); 239 return _contentObjects[0]; 240 } 241 242 protected final StringBuilder _qNameBuffer = new StringBuilder(); 243 244 protected final String getQName(String prefix, String localName) { 245 _qNameBuffer.append(prefix).append(':').append(localName); 246 final String qName = _qNameBuffer.toString(); 247 _qNameBuffer.setLength(0); 248 return (_stringInterningFeature) ? qName.intern() : qName; 249 } 250 251 protected final String getPrefixFromQName(String qName) { 252 int pIndex = qName.indexOf(':'); 253 if (_stringInterningFeature) { 254 return (pIndex != -1) ? qName.substring(0,pIndex).intern() : ""; 255 } else { 256 return (pIndex != -1) ? qName.substring(0,pIndex) : ""; 257 } 258 } 259 }