1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is TransforMiiX XSLT processor code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * The MITRE Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1999
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Keith Visco <kvisco@ziplink.net> (Original Author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : /**
40 : * Implementation of an XPath NodeSet
41 : */
42 :
43 : #ifndef txNodeSet_h__
44 : #define txNodeSet_h__
45 :
46 : #include "txExprResult.h"
47 : #include "txError.h"
48 : #include "txXPathNode.h"
49 :
50 : class txNodeSet : public txAExprResult
51 : {
52 : public:
53 : /**
54 : * Creates a new empty NodeSet
55 : */
56 : txNodeSet(txResultRecycler* aRecycler);
57 :
58 : /**
59 : * Creates a new NodeSet with one node.
60 : */
61 : txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler);
62 :
63 : /**
64 : * Creates a new txNodeSet, copying the node references from the source
65 : * NodeSet.
66 : */
67 : txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler);
68 :
69 : /**
70 : * Destructor for txNodeSet, deletes the nodes.
71 : */
72 : virtual ~txNodeSet();
73 :
74 : /**
75 : * Adds the specified txXPathNode to this NodeSet if it is not already
76 : * in this NodeSet. The node is inserted according to document order.
77 : *
78 : * @param aNode the txXPathNode to add to the NodeSet
79 : * @return errorcode.
80 : */
81 : nsresult add(const txXPathNode& aNode);
82 :
83 : /**
84 : * Adds the nodes in specified NodeSet to this NodeSet. The resulting
85 : * NodeSet is sorted in document order and does not contain any duplicate
86 : * nodes.
87 : *
88 : * @param aNodes the NodeSet to add, must be in document order.
89 : * @return errorcode.
90 : */
91 : nsresult add(const txNodeSet& aNodes);
92 : nsresult addAndTransfer(txNodeSet* aNodes);
93 :
94 : /**
95 : * Append API
96 : * These functions should be used with care.
97 : * They are intended to be used when the caller assures that the resulting
98 : * NodeSet remains in document order.
99 : * Abuse will break document order, and cause errors in the result.
100 : * These functions are significantly faster than the add API, as no
101 : * order info operations will be performed.
102 : */
103 :
104 : /**
105 : * Appends the specified Node to the end of this NodeSet
106 : * @param aNode the Node to append to the NodeSet
107 : * @return errorcode.
108 : */
109 : nsresult append(const txXPathNode& aNode);
110 :
111 : /**
112 : * Appends the nodes in the specified NodeSet to the end of this NodeSet
113 : * @param aNodes the NodeSet to append to the NodeSet
114 : * @return errorcode.
115 : */
116 : nsresult append(const txNodeSet& aNodes);
117 :
118 : /**
119 : * API to implement reverse axes in LocationStep.
120 : *
121 : * Before adding nodes to the nodeset for a reversed axis, call
122 : * setReverse(). This will make the append(aNode) and get() methods treat
123 : * the nodeset as required. Do only call append(aNode), get(), mark()
124 : * and sweep() while the nodeset is reversed.
125 : * Afterwards, call unsetReverse(). The nodes are stored in document
126 : * order internally.
127 : */
128 0 : void setReverse()
129 : {
130 0 : mDirection = -1;
131 0 : }
132 42 : void unsetReverse()
133 : {
134 42 : mDirection = 1;
135 42 : }
136 :
137 : /**
138 : * API to implement predicates in PredicateExpr
139 : *
140 : * mark(aIndex) marks the specified member of the nodeset.
141 : * sweep() clears all members of the nodeset that haven't been
142 : * marked before and clear the mMarks array.
143 : */
144 : nsresult mark(PRInt32 aIndex);
145 : nsresult sweep();
146 :
147 : /**
148 : * Removes all nodes from this nodeset
149 : */
150 : void clear();
151 :
152 : /**
153 : * Returns the index of the specified Node,
154 : * or -1 if the Node is not contained in the NodeSet
155 : * @param aNode the Node to get the index for
156 : * @param aStart index to start searching at
157 : * @return index of specified node or -1 if the node does not exist
158 : */
159 : PRInt32 indexOf(const txXPathNode& aNode, PRUint32 aStart = 0) const;
160 :
161 : /**
162 : * Returns true if the specified Node is contained in the set.
163 : * @param aNode the Node to search for
164 : * @return true if specified Node is contained in the NodeSet
165 : */
166 0 : bool contains(const txXPathNode& aNode) const
167 : {
168 0 : return indexOf(aNode) >= 0;
169 : }
170 :
171 : /**
172 : * Returns the Node at the specified node in this NodeSet.
173 : * @param aIndex the node of the Node to return
174 : * @return Node at specified node
175 : */
176 : const txXPathNode& get(PRInt32 aIndex) const;
177 :
178 : /**
179 : * Returns true if there are no Nodes in the NodeSet.
180 : * @return true if there are no Nodes in the NodeSet.
181 : */
182 126 : bool isEmpty() const
183 : {
184 126 : return mStart ? mStart == mEnd : true;
185 : }
186 :
187 : /**
188 : * Returns the number of elements in the NodeSet
189 : * @return the number of elements in the NodeSet
190 : */
191 42 : PRInt32 size() const
192 : {
193 42 : return mStart ? mEnd - mStart : 0;
194 : }
195 :
196 : TX_DECL_EXPRRESULT
197 :
198 : private:
199 : /**
200 : * Ensure that this nodeset can take another aSize nodes.
201 : *
202 : * Changes mStart and mEnd as well as mBufferStart and mBufferEnd.
203 : */
204 : bool ensureGrowSize(PRInt32 aSize);
205 :
206 : /**
207 : * Finds position in the buffer where a node should be inserted
208 : * to keep the nodeset in document order. Searches the positions
209 : * aFirst-aLast, including aFirst, but not aLast.
210 : * @param aNode Node to find insert position for.
211 : * @param aFirst First item of the search range, included.
212 : * @param aLast Last item of the search range, excluded.
213 : * @param aDupe out-param. Will be set to true if the node already
214 : * exists in the NodeSet, false if it should be
215 : * inserted.
216 : * @return pointer where to insert the node. The node should be inserted
217 : * before the given node. This value is always set, even if aNode
218 : * already exists in the NodeSet
219 : */
220 : txXPathNode* findPosition(const txXPathNode& aNode,
221 : txXPathNode* aFirst,
222 : txXPathNode* aLast, bool& aDupe) const;
223 :
224 : static void copyElements(txXPathNode* aDest, const txXPathNode* aStart,
225 : const txXPathNode* aEnd);
226 : static void transferElements(txXPathNode* aDest, const txXPathNode* aStart,
227 : const txXPathNode* aEnd);
228 44 : static void destroyElements(const txXPathNode* aStart,
229 : const txXPathNode* aEnd)
230 : {
231 130 : while (aStart < aEnd) {
232 42 : aStart->~txXPathNode();
233 42 : ++aStart;
234 : }
235 44 : }
236 :
237 : typedef void (*transferOp) (txXPathNode* aDest, const txXPathNode* aStart,
238 : const txXPathNode* aEnd);
239 : typedef void (*destroyOp) (const txXPathNode* aStart,
240 : const txXPathNode* aEnd);
241 : nsresult add(const txNodeSet& aNodes, transferOp aTransfer,
242 : destroyOp aDestroy);
243 :
244 : txXPathNode *mStart, *mEnd, *mStartBuffer, *mEndBuffer;
245 : PRInt32 mDirection;
246 : // used for mark() and sweep() in predicates
247 : bool* mMarks;
248 : };
249 :
250 : #endif
|