Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/. */
6 /**
7 * Implementation of an XPath NodeSet
8 */
10 #ifndef txNodeSet_h__
11 #define txNodeSet_h__
13 #include "txExprResult.h"
14 #include "nsError.h"
15 #include "txXPathNode.h"
17 class txNodeSet : public txAExprResult
18 {
19 public:
20 /**
21 * Creates a new empty NodeSet
22 */
23 txNodeSet(txResultRecycler* aRecycler);
25 /**
26 * Creates a new NodeSet with one node.
27 */
28 txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler);
30 /**
31 * Creates a new txNodeSet, copying the node references from the source
32 * NodeSet.
33 */
34 txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler);
36 /**
37 * Destructor for txNodeSet, deletes the nodes.
38 */
39 virtual ~txNodeSet();
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);
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);
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 */
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);
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);
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 {
97 mDirection = -1;
98 }
99 void unsetReverse()
100 {
101 mDirection = 1;
102 }
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();
114 /**
115 * Removes all nodes from this nodeset
116 */
117 void clear();
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;
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 {
135 return indexOf(aNode) >= 0;
136 }
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;
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 {
151 return mStart ? mStart == mEnd : true;
152 }
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 {
160 return mStart ? mEnd - mStart : 0;
161 }
163 TX_DECL_EXPRRESULT
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);
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;
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 {
198 while (aStart < aEnd) {
199 aStart->~txXPathNode();
200 ++aStart;
201 }
202 }
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);
211 txXPathNode *mStart, *mEnd, *mStartBuffer, *mEndBuffer;
212 int32_t mDirection;
213 // used for mark() and sweep() in predicates
214 bool* mMarks;
215 };
217 #endif