1/*
2 * Copyright (c) 2005, 2013, 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
26package 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 */
32public 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}
260