/src/mozilla-central/dom/xslt/xpath/txNodeSet.h
Line | Count | Source (jump to first uncovered line) |
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 | | void setReverse() |
96 | 0 | { |
97 | 0 | mDirection = -1; |
98 | 0 | } |
99 | | void unsetReverse() |
100 | 0 | { |
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 | | bool contains(const txXPathNode& aNode) const |
134 | 0 | { |
135 | 0 | return indexOf(aNode) >= 0; |
136 | 0 | } |
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 | | bool isEmpty() const |
150 | 0 | { |
151 | 0 | return mStart ? mStart == mEnd : true; |
152 | 0 | } |
153 | | |
154 | | /** |
155 | | * Returns the number of elements in the NodeSet |
156 | | * @return the number of elements in the NodeSet |
157 | | */ |
158 | | int32_t size() const |
159 | 0 | { |
160 | 0 | return mStart ? mEnd - mStart : 0; |
161 | 0 | } |
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 | | static void destroyElements(const txXPathNode* aStart, |
196 | | const txXPathNode* aEnd) |
197 | 0 | { |
198 | 0 | while (aStart < aEnd) { |
199 | 0 | aStart->~txXPathNode(); |
200 | 0 | ++aStart; |
201 | 0 | } |
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 |