sax2dtm2.java
来自「JAVA 所有包」· Java 代码 · 共 2,403 行 · 第 1/5 页
JAVA
2,403 行
if (m_size >= m_ancestors.length) { int[] newAncestors = new int[m_size * 2]; System.arraycopy(m_ancestors, 0, newAncestors, 0, m_ancestors.length); m_ancestors = newAncestors; } m_ancestors[m_size++] = makeNodeHandle(nodeID); } nodeID = _parent2(nodeID); } } else { while (nodeID != END) { int eType = _exptype2(nodeID); if ((eType < DTM.NTYPES && eType == nodeType) || (eType >= DTM.NTYPES && m_extendedTypes[eType].getNodeType() == nodeType)) { if (m_size >= m_ancestors.length) { int[] newAncestors = new int[m_size * 2]; System.arraycopy(m_ancestors, 0, newAncestors, 0, m_ancestors.length); m_ancestors = newAncestors; } m_ancestors[m_size++] = makeNodeHandle(nodeID); } nodeID = _parent2(nodeID); } } m_ancestorsPos = m_size - 1; _currentNode = (m_ancestorsPos>=0) ? m_ancestors[m_ancestorsPos] : DTM.NULL; return resetPosition(); } return this; } /** * Return the node at the given position. */ public int getNodeByPosition(int position) { if (position > 0 && position <= m_size) { return m_ancestors[position-1]; } else return DTM.NULL; } /** * Returns the position of the last node within the iteration, as * defined by XPath. */ public int getLast() { return m_size; } } // end of TypedAncestorIterator /** * Iterator that returns the descendants of a given node. */ public class DescendantIterator extends InternalAxisIteratorBase { /** * Set start to END should 'close' the iterator, * i.e. subsequent call to next() should return END. * * @param node Sets the root of the iteration. * * @return A DTMAxisIterator set to the start of the iteration. */ public DTMAxisIterator setStartNode(int node) {//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily if (node == DTMDefaultBase.ROOTNODE) node = getDocument(); if (_isRestartable) { node = makeNodeIdentity(node); _startNode = node; if (_includeSelf) node--; _currentNode = node; return resetPosition(); } return this; } /** * Tell if this node identity is a descendant. Assumes that * the node info for the element has already been obtained. * * This one-sided test works only if the parent has been * previously tested and is known to be a descendent. It fails if * the parent is the _startNode's next sibling, or indeed any node * that follows _startNode in document order. That may suffice * for this iterator, but it's not really an isDescendent() test. * %REVIEW% rename? * * @param identity The index number of the node in question. * @return true if the index is a descendant of _startNode. */ protected final boolean isDescendant(int identity) { return (_parent2(identity) >= _startNode) || (_startNode == identity); } /** * Get the next node in the iteration. * * @return The next node handle in the iteration, or END. */ public int next() { final int startNode = _startNode; if (startNode == NULL) { return NULL; } if (_includeSelf && (_currentNode + 1) == startNode) return returnNode(makeNodeHandle(++_currentNode)); // | m_dtmIdent); int node = _currentNode; int type; // %OPT% If the startNode is the root node, do not need // to do the isDescendant() check. if (startNode == ROOTNODE) { int eType; do { node++; eType = _exptype2(node); if (NULL == eType) { _currentNode = NULL; return END; } } while (eType == TEXT_NODE || (type = m_extendedTypes[eType].getNodeType()) == ATTRIBUTE_NODE || type == NAMESPACE_NODE); } else { do { node++; type = _type2(node); if (NULL == type ||!isDescendant(node)) { _currentNode = NULL; return END; } } while(ATTRIBUTE_NODE == type || TEXT_NODE == type || NAMESPACE_NODE == type); } _currentNode = node; return returnNode(makeNodeHandle(node)); // make handle. } /** * Reset. * */ public DTMAxisIterator reset() { final boolean temp = _isRestartable; _isRestartable = true; setStartNode(makeNodeHandle(_startNode)); _isRestartable = temp; return this; } } // end of DescendantIterator /** * Typed iterator that returns the descendants of a given node. */ public final class TypedDescendantIterator extends DescendantIterator { /** The extended type ID that was requested. */ private final int _nodeType; /** * Constructor TypedDescendantIterator * * * @param nodeType Extended type ID being requested. */ public TypedDescendantIterator(int nodeType) { _nodeType = nodeType; } /** * Get the next node in the iteration. * * @return The next node handle in the iteration, or END. */ public int next() { final int startNode = _startNode; if (_startNode == NULL) { return NULL; } int node = _currentNode; int expType; final int nodeType = _nodeType; if (nodeType != DTM.ELEMENT_NODE) { do { node++; expType = _exptype2(node); if (NULL == expType || _parent2(node) < startNode && startNode != node) { _currentNode = NULL; return END; } } while (expType != nodeType); } // %OPT% If the start node is root (e.g. in the case of //node), // we can save the isDescendant() check, because all nodes are // descendants of root. else if (startNode == DTMDefaultBase.ROOTNODE) { do { node++; expType = _exptype2(node); if (NULL == expType) { _currentNode = NULL; return END; } } while (expType < DTM.NTYPES || m_extendedTypes[expType].getNodeType() != DTM.ELEMENT_NODE); } else { do { node++; expType = _exptype2(node); if (NULL == expType || _parent2(node) < startNode && startNode != node) { _currentNode = NULL; return END; } } while (expType < DTM.NTYPES || m_extendedTypes[expType].getNodeType() != DTM.ELEMENT_NODE); } _currentNode = node; return returnNode(makeNodeHandle(node)); } } // end of TypedDescendantIterator /** * Iterator that returns a given node only if it is of a given type. */ public final class TypedSingletonIterator extends SingletonIterator { /** The extended type ID that was requested. */ private final int _nodeType; /** * Constructor TypedSingletonIterator * * * @param nodeType The extended type ID being requested. */ public TypedSingletonIterator(int nodeType) { _nodeType = nodeType; } /** * Get the next node in the iteration. * * @return The next node handle in the iteration, or END. */ public int next() { final int result = _currentNode; if (result == END) return DTM.NULL; _currentNode = END; if (_nodeType >= DTM.NTYPES) { if (_exptype2(makeNodeIdentity(result)) == _nodeType) { return returnNode(result); } } else { if (_type2(makeNodeIdentity(result)) == _nodeType) { return returnNode(result); } } return NULL; } } // end of TypedSingletonIterator /******************************************************************* * End of nested iterators *******************************************************************/ // %OPT% Array references which are used to cache the map0 arrays in // SuballocatedIntVectors. Using the cached arrays reduces the level // of indirection and results in better performance than just calling // SuballocatedIntVector.elementAt(). private int[] m_exptype_map0; private int[] m_nextsib_map0; private int[] m_firstch_map0; private int[] m_parent_map0; // Double array references to the map arrays in SuballocatedIntVectors. private int[][] m_exptype_map; private int[][] m_nextsib_map; private int[][] m_firstch_map; private int[][] m_parent_map; // %OPT% Cache the array of extended types in this class protected ExtendedType[] m_extendedTypes; // A Vector which is used to store the values of attribute, namespace, // comment and PI nodes. // // %OPT% These values are unlikely to be equal. Storing // them in a plain Vector is more efficient than storing in the // DTMStringPool because we can save the cost for hash calculation. // // %REVISIT% Do we need a custom class (e.g. StringVector) here? protected Vector m_values; // The current index into the m_values Vector. private int m_valueIndex = 0; // The maximum value of the current node index. private int m_maxNodeIndex; // Cache the shift and mask values for the SuballocatedIntVectors. protected int m_SHIFT; protected int m_MASK; protected int m_blocksize; /** %OPT% If the offset and length of a Text node are within certain limits, * we store a bitwise encoded value into an int, using 10 bits (max. 1024) * for length and 21 bits for offset. We can save two SuballocatedIntVector * calls for each getStringValueX() and dispatchCharacterEvents() call by * doing this. */ // The number of bits for the length of a Text node. protected final static int TEXT_LENGTH_BITS = 10; // The number of bits for the offset of a Text node. protected final static int TEXT_OFFSET_BITS = 21; // The maximum length value protected final static int TEXT_LENGTH_MAX = (1<<TEXT_LENGTH_BITS) - 1; // The maximum offset value protected final static int TEXT_OFFSET_MAX = (1<<TEXT_OFFSET_BITS) - 1; // True if we want to build the ID index table. protected boolean m_buildIdIndex = true; // Constant for empty String private static final String EMPTY_STR = ""; // Constant for empty XMLString private static final XMLString EMPTY_XML_STR = new XMLStringDefault(""); /** * Construct a SAX2DTM2 object using the default block size. */ public SAX2DTM2(DTMManager mgr, Source source, int dtmIdentity, DTMWSFilter whiteSpaceFilter, XMLStringFactory xstringfactory, boolean doIndexing) { this(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory, doIndexing, DEFAULT_BLOCKSIZE, true, true, false); } /** * Construct a SAX2DTM2 object using the given block size. */ public SAX2DTM2(DTMManager mgr, Source source, int dtmIdentity, DTMWSFilter whiteSpaceFilter, XMLStringFactory xstringfactory, boolean doIndexing, int blocksize, boolean usePrevsib, boolean buildIdIndex, boolean newNameTable) { super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable); // Initialize the values of m_SHIFT and m_MASK. int shift; for(shift=0; (blocksize>>>=1) != 0; ++shift); m_blocksize = 1<<shift; m_SHIFT = shift; m_MASK = m_blocksize - 1; m_buildIdIndex = buildIdIndex; // Some documents do not have attribute nodes. That is why // we set the initial size of this Vector to be small and set // the increment to a bigger number. m_values = new Vector(32, 512); m_maxNodeIndex = 1 << DTMManager.IDENT_DTM_NODE_BITS; // Set the map0 values in the constructor. m_exptype_map0 = m_exptype.getMap0(); m_nextsib_map0 = m_nextsib.getMap0(); m_firstch_map0 = m_firstch.getMap0(); m_parent_map0 = m_parent.getMap0(); } /** * Override DTMDefaultBase._exptype() by dropping the incremental code. * * <p>This one is less efficient than _exptype2. It is only used during * DTM building. _exptype2 is used after the document is fully built. */ public final int _exptype(int identity) { return m_exptype.elementAt(identity); } /************************************************************************ * DTM base accessor interfaces * * %OPT% The code in the following interfaces (e.g. _exptype2, etc.) are * very important to the DTM performance. To have the best performace, * these several interfaces have direct access to the internal arrays of * the SuballocatedIntVectors. The final modifier also has a noticeable * impact on performance. ***********************************************************************/ /** * The optimized version of DTMDefaultBase._exptype(). * * @param identity A node identity, which <em>must not</em> be equal to * <code>DTM.NULL</code> */ public final int _exptype2(int identity) { //return m_exptype.elementAt(identity); if (identity < m_blocksize)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?