Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : /**
7 : * Implementation of an XPath NodeSet
8 : */
9 :
10 : #ifndef txNodeSet_h__
11 : #define txNodeSet_h__
12 :
13 : #include "txExprResult.h"
14 : #include "nsError.h"
15 : #include "txXPathNode.h"
16 :
17 : class txNodeSet : public txAExprResult
18 : {
19 : public:
20 : /**
21 : * Creates a new empty NodeSet
22 : */
23 : explicit txNodeSet(txResultRecycler* aRecycler);
24 :
25 : /**
26 : * Creates a new NodeSet with one node.
27 : */
28 : txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler);
29 :
30 : /**
31 : * Creates a new txNodeSet, copying the node references from the source
32 : * NodeSet.
33 : */
34 : txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler);
35 :
36 : /**
37 : * Destructor for txNodeSet, deletes the nodes.
38 : */
39 : virtual ~txNodeSet();
40 :
41 : /**
42 : * Adds the specified txXPathNode to this NodeSet if it is not already
43 : * in this NodeSet. The node is inserted according to document order.
44 : *
45 : * @param aNode the txXPathNode to add to the NodeSet
46 : * @return errorcode.
47 : */
48 : nsresult add(const txXPathNode& aNode);
49 :
50 : /**
51 : * Adds the nodes in specified NodeSet to this NodeSet. The resulting
52 : * NodeSet is sorted in document order and does not contain any duplicate
53 : * nodes.
54 : *
55 : * @param aNodes the NodeSet to add, must be in document order.
56 : * @return errorcode.
57 : */
58 : nsresult add(const txNodeSet& aNodes);
59 : nsresult addAndTransfer(txNodeSet* aNodes);
60 :
61 : /**
62 : * Append API
63 : * These functions should be used with care.
64 : * They are intended to be used when the caller assures that the resulting
65 : * NodeSet remains in document order.
66 : * Abuse will break document order, and cause errors in the result.
67 : * These functions are significantly faster than the add API, as no
68 : * order info operations will be performed.
69 : */
70 :
71 : /**
72 : * Appends the specified Node to the end of this NodeSet
73 : * @param aNode the Node to append to the NodeSet
74 : * @return errorcode.
75 : */
76 : nsresult append(const txXPathNode& aNode);
77 :
78 : /**
79 : * Appends the nodes in the specified NodeSet to the end of this NodeSet
80 : * @param aNodes the NodeSet to append to the NodeSet
81 : * @return errorcode.
82 : */
83 : nsresult append(const txNodeSet& aNodes);
84 :
85 : /**
86 : * API to implement reverse axes in LocationStep.
87 : *
88 : * Before adding nodes to the nodeset for a reversed axis, call
89 : * setReverse(). This will make the append(aNode) and get() methods treat
90 : * the nodeset as required. Do only call append(aNode), get(), mark()
91 : * and sweep() while the nodeset is reversed.
92 : * Afterwards, call unsetReverse(). The nodes are stored in document
93 : * order internally.
94 : */
95 0 : void setReverse()
96 : {
97 0 : mDirection = -1;
98 0 : }
99 0 : void unsetReverse()
100 : {
101 0 : mDirection = 1;
102 0 : }
103 :
104 : /**
105 : * API to implement predicates in PredicateExpr
106 : *
107 : * mark(aIndex) marks the specified member of the nodeset.
108 : * sweep() clears all members of the nodeset that haven't been
109 : * marked before and clear the mMarks array.
110 : */
111 : nsresult mark(int32_t aIndex);
112 : nsresult sweep();
113 :
114 : /**
115 : * Removes all nodes from this nodeset
116 : */
117 : void clear();
118 :
119 : /**
120 : * Returns the index of the specified Node,
121 : * or -1 if the Node is not contained in the NodeSet
122 : * @param aNode the Node to get the index for
123 : * @param aStart index to start searching at
124 : * @return index of specified node or -1 if the node does not exist
125 : */
126 : int32_t indexOf(const txXPathNode& aNode, uint32_t aStart = 0) const;
127 :
128 : /**
129 : * Returns true if the specified Node is contained in the set.
130 : * @param aNode the Node to search for
131 : * @return true if specified Node is contained in the NodeSet
132 : */
133 0 : bool contains(const txXPathNode& aNode) const
134 : {
135 0 : return indexOf(aNode) >= 0;
136 : }
137 :
138 : /**
139 : * Returns the Node at the specified node in this NodeSet.
140 : * @param aIndex the node of the Node to return
141 : * @return Node at specified node
142 : */
143 : const txXPathNode& get(int32_t aIndex) const;
144 :
145 : /**
146 : * Returns true if there are no Nodes in the NodeSet.
147 : * @return true if there are no Nodes in the NodeSet.
148 : */
149 0 : bool isEmpty() const
150 : {
151 0 : return mStart ? mStart == mEnd : true;
152 : }
153 :
154 : /**
155 : * Returns the number of elements in the NodeSet
156 : * @return the number of elements in the NodeSet
157 : */
158 0 : int32_t size() const
159 : {
160 0 : return mStart ? mEnd - mStart : 0;
161 : }
162 :
163 : TX_DECL_EXPRRESULT
164 :
165 : private:
166 : /**
167 : * Ensure that this nodeset can take another aSize nodes.
168 : *
169 : * Changes mStart and mEnd as well as mBufferStart and mBufferEnd.
170 : */
171 : bool ensureGrowSize(int32_t aSize);
172 :
173 : /**
174 : * Finds position in the buffer where a node should be inserted
175 : * to keep the nodeset in document order. Searches the positions
176 : * aFirst-aLast, including aFirst, but not aLast.
177 : * @param aNode Node to find insert position for.
178 : * @param aFirst First item of the search range, included.
179 : * @param aLast Last item of the search range, excluded.
180 : * @param aDupe out-param. Will be set to true if the node already
181 : * exists in the NodeSet, false if it should be
182 : * inserted.
183 : * @return pointer where to insert the node. The node should be inserted
184 : * before the given node. This value is always set, even if aNode
185 : * already exists in the NodeSet
186 : */
187 : txXPathNode* findPosition(const txXPathNode& aNode,
188 : txXPathNode* aFirst,
189 : txXPathNode* aLast, bool& aDupe) const;
190 :
191 : static void copyElements(txXPathNode* aDest, const txXPathNode* aStart,
192 : const txXPathNode* aEnd);
193 : static void transferElements(txXPathNode* aDest, const txXPathNode* aStart,
194 : const txXPathNode* aEnd);
195 0 : static void destroyElements(const txXPathNode* aStart,
196 : const txXPathNode* aEnd)
197 : {
198 0 : while (aStart < aEnd) {
199 0 : aStart->~txXPathNode();
200 0 : ++aStart;
201 : }
202 0 : }
203 :
204 : typedef void (*transferOp) (txXPathNode* aDest, const txXPathNode* aStart,
205 : const txXPathNode* aEnd);
206 : typedef void (*destroyOp) (const txXPathNode* aStart,
207 : const txXPathNode* aEnd);
208 : nsresult add(const txNodeSet& aNodes, transferOp aTransfer,
209 : destroyOp aDestroy);
210 :
211 : txXPathNode *mStart, *mEnd, *mStartBuffer, *mEndBuffer;
212 : int32_t mDirection;
213 : // used for mark() and sweep() in predicates
214 : bool* mMarks;
215 : };
216 :
217 : #endif
|