summaryrefslogtreecommitdiffstats
path: root/dom/xslt/xpath/txNodeSet.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xslt/xpath/txNodeSet.h')
-rw-r--r--dom/xslt/xpath/txNodeSet.h199
1 files changed, 199 insertions, 0 deletions
diff --git a/dom/xslt/xpath/txNodeSet.h b/dom/xslt/xpath/txNodeSet.h
new file mode 100644
index 0000000000..8c5e805d6b
--- /dev/null
+++ b/dom/xslt/xpath/txNodeSet.h
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Implementation of an XPath NodeSet
+ */
+
+#ifndef txNodeSet_h__
+#define txNodeSet_h__
+
+#include "txExprResult.h"
+#include "nsError.h"
+#include "txXPathNode.h"
+
+class txNodeSet : public txAExprResult {
+ public:
+ /**
+ * Creates a new empty NodeSet
+ */
+ explicit txNodeSet(txResultRecycler* aRecycler);
+
+ /**
+ * Creates a new NodeSet with one node.
+ */
+ txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler);
+
+ /**
+ * Creates a new txNodeSet, copying the node references from the source
+ * NodeSet.
+ */
+ txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler);
+
+ /**
+ * Destructor for txNodeSet, deletes the nodes.
+ */
+ virtual ~txNodeSet();
+
+ /**
+ * Adds the specified txXPathNode to this NodeSet if it is not already
+ * in this NodeSet. The node is inserted according to document order.
+ *
+ * @param aNode the txXPathNode to add to the NodeSet
+ * @return errorcode.
+ */
+ nsresult add(const txXPathNode& aNode);
+
+ /**
+ * Adds the nodes in specified NodeSet to this NodeSet. The resulting
+ * NodeSet is sorted in document order and does not contain any duplicate
+ * nodes.
+ *
+ * @param aNodes the NodeSet to add, must be in document order.
+ * @return errorcode.
+ */
+ nsresult add(const txNodeSet& aNodes);
+ nsresult addAndTransfer(txNodeSet* aNodes);
+
+ /**
+ * Append API
+ * These functions should be used with care.
+ * They are intended to be used when the caller assures that the resulting
+ * NodeSet remains in document order.
+ * Abuse will break document order, and cause errors in the result.
+ * These functions are significantly faster than the add API, as no
+ * order info operations will be performed.
+ */
+
+ /**
+ * Appends the specified Node to the end of this NodeSet
+ * @param aNode the Node to append to the NodeSet
+ * @return errorcode.
+ */
+ nsresult append(const txXPathNode& aNode);
+
+ /**
+ * Appends the nodes in the specified NodeSet to the end of this NodeSet
+ * @param aNodes the NodeSet to append to the NodeSet
+ * @return errorcode.
+ */
+ nsresult append(const txNodeSet& aNodes);
+
+ /**
+ * API to implement reverse axes in LocationStep.
+ *
+ * Before adding nodes to the nodeset for a reversed axis, call
+ * setReverse(). This will make the append(aNode) and get() methods treat
+ * the nodeset as required. Do only call append(aNode), get(), mark()
+ * and sweep() while the nodeset is reversed.
+ * Afterwards, call unsetReverse(). The nodes are stored in document
+ * order internally.
+ */
+ void setReverse() { mDirection = -1; }
+ void unsetReverse() { mDirection = 1; }
+
+ /**
+ * API to implement predicates in PredicateExpr
+ *
+ * mark(aIndex) marks the specified member of the nodeset.
+ * sweep() clears all members of the nodeset that haven't been
+ * marked before and clear the mMarks array.
+ */
+ nsresult mark(int32_t aIndex);
+ nsresult sweep();
+
+ /**
+ * Removes all nodes from this nodeset
+ */
+ void clear();
+
+ /**
+ * Returns the index of the specified Node,
+ * or -1 if the Node is not contained in the NodeSet
+ * @param aNode the Node to get the index for
+ * @param aStart index to start searching at
+ * @return index of specified node or -1 if the node does not exist
+ */
+ int32_t indexOf(const txXPathNode& aNode, uint32_t aStart = 0) const;
+
+ /**
+ * Returns true if the specified Node is contained in the set.
+ * @param aNode the Node to search for
+ * @return true if specified Node is contained in the NodeSet
+ */
+ bool contains(const txXPathNode& aNode) const { return indexOf(aNode) >= 0; }
+
+ /**
+ * Returns the Node at the specified node in this NodeSet.
+ * @param aIndex the node of the Node to return
+ * @return Node at specified node
+ */
+ const txXPathNode& get(int32_t aIndex) const;
+
+ /**
+ * Returns true if there are no Nodes in the NodeSet.
+ * @return true if there are no Nodes in the NodeSet.
+ */
+ bool isEmpty() const { return mStart ? mStart == mEnd : true; }
+
+ /**
+ * Returns the number of elements in the NodeSet
+ * @return the number of elements in the NodeSet
+ */
+ int32_t size() const { return mStart ? mEnd - mStart : 0; }
+
+ TX_DECL_EXPRRESULT
+
+ private:
+ /**
+ * Ensure that this nodeset can take another aSize nodes.
+ *
+ * Changes mStart and mEnd as well as mBufferStart and mBufferEnd.
+ */
+ bool ensureGrowSize(int32_t aSize);
+
+ /**
+ * Finds position in the buffer where a node should be inserted
+ * to keep the nodeset in document order. Searches the positions
+ * aFirst-aLast, including aFirst, but not aLast.
+ * @param aNode Node to find insert position for.
+ * @param aFirst First item of the search range, included.
+ * @param aLast Last item of the search range, excluded.
+ * @param aDupe out-param. Will be set to true if the node already
+ * exists in the NodeSet, false if it should be
+ * inserted.
+ * @return pointer where to insert the node. The node should be inserted
+ * before the given node. This value is always set, even if aNode
+ * already exists in the NodeSet
+ */
+ txXPathNode* findPosition(const txXPathNode& aNode, txXPathNode* aFirst,
+ txXPathNode* aLast, bool& aDupe) const;
+
+ static void copyElements(txXPathNode* aDest, const txXPathNode* aStart,
+ const txXPathNode* aEnd);
+ static void transferElements(txXPathNode* aDest, const txXPathNode* aStart,
+ const txXPathNode* aEnd);
+ static void destroyElements(const txXPathNode* aStart,
+ const txXPathNode* aEnd) {
+ while (aStart < aEnd) {
+ aStart->~txXPathNode();
+ ++aStart;
+ }
+ }
+
+ using transferOp = void (*)(txXPathNode* aDest, const txXPathNode* aStart,
+ const txXPathNode* aEnd);
+ using destroyOp = void (*)(const txXPathNode* aStart,
+ const txXPathNode* aEnd);
+ nsresult add(const txNodeSet& aNodes, transferOp aTransfer,
+ destroyOp aDestroy);
+
+ txXPathNode *mStart, *mEnd, *mStartBuffer, *mEndBuffer;
+ int32_t mDirection;
+ // used for mark() and sweep() in predicates
+ bool* mMarks;
+};
+
+#endif