dom/xslt/xpath/txNodeSet.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial