1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/xslt/xpath/txNodeSet.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,217 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/** 1.10 + * Implementation of an XPath NodeSet 1.11 + */ 1.12 + 1.13 +#ifndef txNodeSet_h__ 1.14 +#define txNodeSet_h__ 1.15 + 1.16 +#include "txExprResult.h" 1.17 +#include "nsError.h" 1.18 +#include "txXPathNode.h" 1.19 + 1.20 +class txNodeSet : public txAExprResult 1.21 +{ 1.22 +public: 1.23 + /** 1.24 + * Creates a new empty NodeSet 1.25 + */ 1.26 + txNodeSet(txResultRecycler* aRecycler); 1.27 + 1.28 + /** 1.29 + * Creates a new NodeSet with one node. 1.30 + */ 1.31 + txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler); 1.32 + 1.33 + /** 1.34 + * Creates a new txNodeSet, copying the node references from the source 1.35 + * NodeSet. 1.36 + */ 1.37 + txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler); 1.38 + 1.39 + /** 1.40 + * Destructor for txNodeSet, deletes the nodes. 1.41 + */ 1.42 + virtual ~txNodeSet(); 1.43 + 1.44 + /** 1.45 + * Adds the specified txXPathNode to this NodeSet if it is not already 1.46 + * in this NodeSet. The node is inserted according to document order. 1.47 + * 1.48 + * @param aNode the txXPathNode to add to the NodeSet 1.49 + * @return errorcode. 1.50 + */ 1.51 + nsresult add(const txXPathNode& aNode); 1.52 + 1.53 + /** 1.54 + * Adds the nodes in specified NodeSet to this NodeSet. The resulting 1.55 + * NodeSet is sorted in document order and does not contain any duplicate 1.56 + * nodes. 1.57 + * 1.58 + * @param aNodes the NodeSet to add, must be in document order. 1.59 + * @return errorcode. 1.60 + */ 1.61 + nsresult add(const txNodeSet& aNodes); 1.62 + nsresult addAndTransfer(txNodeSet* aNodes); 1.63 + 1.64 + /** 1.65 + * Append API 1.66 + * These functions should be used with care. 1.67 + * They are intended to be used when the caller assures that the resulting 1.68 + * NodeSet remains in document order. 1.69 + * Abuse will break document order, and cause errors in the result. 1.70 + * These functions are significantly faster than the add API, as no 1.71 + * order info operations will be performed. 1.72 + */ 1.73 + 1.74 + /** 1.75 + * Appends the specified Node to the end of this NodeSet 1.76 + * @param aNode the Node to append to the NodeSet 1.77 + * @return errorcode. 1.78 + */ 1.79 + nsresult append(const txXPathNode& aNode); 1.80 + 1.81 + /** 1.82 + * Appends the nodes in the specified NodeSet to the end of this NodeSet 1.83 + * @param aNodes the NodeSet to append to the NodeSet 1.84 + * @return errorcode. 1.85 + */ 1.86 + nsresult append(const txNodeSet& aNodes); 1.87 + 1.88 + /** 1.89 + * API to implement reverse axes in LocationStep. 1.90 + * 1.91 + * Before adding nodes to the nodeset for a reversed axis, call 1.92 + * setReverse(). This will make the append(aNode) and get() methods treat 1.93 + * the nodeset as required. Do only call append(aNode), get(), mark() 1.94 + * and sweep() while the nodeset is reversed. 1.95 + * Afterwards, call unsetReverse(). The nodes are stored in document 1.96 + * order internally. 1.97 + */ 1.98 + void setReverse() 1.99 + { 1.100 + mDirection = -1; 1.101 + } 1.102 + void unsetReverse() 1.103 + { 1.104 + mDirection = 1; 1.105 + } 1.106 + 1.107 + /** 1.108 + * API to implement predicates in PredicateExpr 1.109 + * 1.110 + * mark(aIndex) marks the specified member of the nodeset. 1.111 + * sweep() clears all members of the nodeset that haven't been 1.112 + * marked before and clear the mMarks array. 1.113 + */ 1.114 + nsresult mark(int32_t aIndex); 1.115 + nsresult sweep(); 1.116 + 1.117 + /** 1.118 + * Removes all nodes from this nodeset 1.119 + */ 1.120 + void clear(); 1.121 + 1.122 + /** 1.123 + * Returns the index of the specified Node, 1.124 + * or -1 if the Node is not contained in the NodeSet 1.125 + * @param aNode the Node to get the index for 1.126 + * @param aStart index to start searching at 1.127 + * @return index of specified node or -1 if the node does not exist 1.128 + */ 1.129 + int32_t indexOf(const txXPathNode& aNode, uint32_t aStart = 0) const; 1.130 + 1.131 + /** 1.132 + * Returns true if the specified Node is contained in the set. 1.133 + * @param aNode the Node to search for 1.134 + * @return true if specified Node is contained in the NodeSet 1.135 + */ 1.136 + bool contains(const txXPathNode& aNode) const 1.137 + { 1.138 + return indexOf(aNode) >= 0; 1.139 + } 1.140 + 1.141 + /** 1.142 + * Returns the Node at the specified node in this NodeSet. 1.143 + * @param aIndex the node of the Node to return 1.144 + * @return Node at specified node 1.145 + */ 1.146 + const txXPathNode& get(int32_t aIndex) const; 1.147 + 1.148 + /** 1.149 + * Returns true if there are no Nodes in the NodeSet. 1.150 + * @return true if there are no Nodes in the NodeSet. 1.151 + */ 1.152 + bool isEmpty() const 1.153 + { 1.154 + return mStart ? mStart == mEnd : true; 1.155 + } 1.156 + 1.157 + /** 1.158 + * Returns the number of elements in the NodeSet 1.159 + * @return the number of elements in the NodeSet 1.160 + */ 1.161 + int32_t size() const 1.162 + { 1.163 + return mStart ? mEnd - mStart : 0; 1.164 + } 1.165 + 1.166 + TX_DECL_EXPRRESULT 1.167 + 1.168 +private: 1.169 + /** 1.170 + * Ensure that this nodeset can take another aSize nodes. 1.171 + * 1.172 + * Changes mStart and mEnd as well as mBufferStart and mBufferEnd. 1.173 + */ 1.174 + bool ensureGrowSize(int32_t aSize); 1.175 + 1.176 + /** 1.177 + * Finds position in the buffer where a node should be inserted 1.178 + * to keep the nodeset in document order. Searches the positions 1.179 + * aFirst-aLast, including aFirst, but not aLast. 1.180 + * @param aNode Node to find insert position for. 1.181 + * @param aFirst First item of the search range, included. 1.182 + * @param aLast Last item of the search range, excluded. 1.183 + * @param aDupe out-param. Will be set to true if the node already 1.184 + * exists in the NodeSet, false if it should be 1.185 + * inserted. 1.186 + * @return pointer where to insert the node. The node should be inserted 1.187 + * before the given node. This value is always set, even if aNode 1.188 + * already exists in the NodeSet 1.189 + */ 1.190 + txXPathNode* findPosition(const txXPathNode& aNode, 1.191 + txXPathNode* aFirst, 1.192 + txXPathNode* aLast, bool& aDupe) const; 1.193 + 1.194 + static void copyElements(txXPathNode* aDest, const txXPathNode* aStart, 1.195 + const txXPathNode* aEnd); 1.196 + static void transferElements(txXPathNode* aDest, const txXPathNode* aStart, 1.197 + const txXPathNode* aEnd); 1.198 + static void destroyElements(const txXPathNode* aStart, 1.199 + const txXPathNode* aEnd) 1.200 + { 1.201 + while (aStart < aEnd) { 1.202 + aStart->~txXPathNode(); 1.203 + ++aStart; 1.204 + } 1.205 + } 1.206 + 1.207 + typedef void (*transferOp) (txXPathNode* aDest, const txXPathNode* aStart, 1.208 + const txXPathNode* aEnd); 1.209 + typedef void (*destroyOp) (const txXPathNode* aStart, 1.210 + const txXPathNode* aEnd); 1.211 + nsresult add(const txNodeSet& aNodes, transferOp aTransfer, 1.212 + destroyOp aDestroy); 1.213 + 1.214 + txXPathNode *mStart, *mEnd, *mStartBuffer, *mEndBuffer; 1.215 + int32_t mDirection; 1.216 + // used for mark() and sweep() in predicates 1.217 + bool* mMarks; 1.218 +}; 1.219 + 1.220 +#endif