1 /*
2  * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
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      */
setBuffer(XMLStreamBuffer buffer)129     protected final void setBuffer(XMLStreamBuffer buffer) {
130         setBuffer(buffer,buffer.isFragment());
131     }
setBuffer(XMLStreamBuffer buffer, boolean fragmentMode)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 
peekStructure()156     protected final int peekStructure() {
157         if (_structurePtr < _structure.length) {
158             return _structure[_structurePtr] & 255;
159         }
160 
161         return readFromNextStructure(0);
162     }
163 
readStructure()164     protected final int readStructure() {
165         if (_structurePtr < _structure.length) {
166             return _structure[_structurePtr++] & 255;
167         }
168 
169         return readFromNextStructure(1);
170     }
171 
readEiiState()172     protected final int readEiiState() {
173         return _eiiStateTable[readStructure()];
174     }
175 
getEIIState(int item)176     protected static int getEIIState(int item) {
177         return _eiiStateTable[item];
178     }
179 
getNIIState(int item)180     protected static int getNIIState(int item) {
181         return _niiStateTable[item];
182     }
183 
getAIIState(int item)184     protected static int getAIIState(int item) {
185         return _aiiStateTable[item];
186     }
187 
readStructure16()188     protected final int readStructure16() {
189         return (readStructure() << 8) | readStructure();
190     }
191 
readFromNextStructure(int v)192     private int readFromNextStructure(int v) {
193         _structurePtr = v;
194         _currentStructureFragment = _currentStructureFragment.getNext();
195         _structure = _currentStructureFragment.getArray();
196         return _structure[0] & 255;
197     }
198 
readStructureString()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 
readContentString()210     protected final String readContentString() {
211         return (String)readContentObject();
212     }
213 
readContentCharactersCopy()214     protected final char[] readContentCharactersCopy() {
215         return (char[])readContentObject();
216     }
217 
readContentCharactersBuffer(int length)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 
readContentObject()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 
getQName(String prefix, String localName)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 
getPrefixFromQName(String qName)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 }
260