tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

txNodeSet.h (6687B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      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 "nsError.h"
     14 #include "txExprResult.h"
     15 #include "txXPathNode.h"
     16 
     17 class txNodeSet : public txAExprResult {
     18 public:
     19  /**
     20   * Creates a new empty NodeSet
     21   */
     22  explicit txNodeSet(txResultRecycler* aRecycler);
     23 
     24  /**
     25   * Creates a new NodeSet with one node.
     26   */
     27  txNodeSet(const txXPathNode& aNode, txResultRecycler* aRecycler);
     28 
     29  /**
     30   * Creates a new txNodeSet, copying the node references from the source
     31   * NodeSet.
     32   */
     33  txNodeSet(const txNodeSet& aSource, txResultRecycler* aRecycler);
     34 
     35  /**
     36   * Destructor for txNodeSet, deletes the nodes.
     37   */
     38  virtual ~txNodeSet();
     39 
     40  /**
     41   * Adds the specified txXPathNode to this NodeSet if it is not already
     42   * in this NodeSet. The node is inserted according to document order.
     43   *
     44   * @param  aNode the txXPathNode to add to the NodeSet
     45   * @return errorcode.
     46   */
     47  nsresult add(const txXPathNode& aNode) { return add(txXPathNode(aNode)); }
     48  nsresult add(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    return append(txXPathNode(aNode));
     78  }
     79  nsresult append(txXPathNode&& aNode);
     80 
     81  /**
     82   * Appends the nodes in the specified NodeSet to the end of this NodeSet
     83   * @param  aNodes the NodeSet to append to the NodeSet
     84   * @return errorcode.
     85   */
     86  nsresult append(const txNodeSet& aNodes);
     87 
     88  /**
     89   * API to implement reverse axes in LocationStep.
     90   *
     91   * Before adding nodes to the nodeset for a reversed axis, call
     92   * setReverse(). This will make the append(aNode) and get() methods treat
     93   * the nodeset as required. Do only call append(aNode), get(), mark()
     94   * and sweep() while the nodeset is reversed.
     95   * Afterwards, call unsetReverse(). The nodes are stored in document
     96   * order internally.
     97   */
     98  void setReverse() { mDirection = -1; }
     99  void unsetReverse() { mDirection = 1; }
    100 
    101  /**
    102   * API to implement predicates in PredicateExpr
    103   *
    104   * mark(aIndex) marks the specified member of the nodeset.
    105   * sweep() clears all members of the nodeset that haven't been
    106   * marked before and clear the mMarks array.
    107   */
    108  nsresult mark(int32_t aIndex);
    109  nsresult sweep();
    110 
    111  /**
    112   * Removes all nodes from this nodeset
    113   */
    114  void clear();
    115 
    116  /**
    117   * Returns the index of the specified Node,
    118   * or -1 if the Node is not contained in the NodeSet
    119   * @param  aNode the Node to get the index for
    120   * @param  aStart index to start searching at
    121   * @return index of specified node or -1 if the node does not exist
    122   */
    123  int32_t indexOf(const txXPathNode& aNode, uint32_t aStart = 0) const;
    124 
    125  /**
    126   * Returns true if the specified Node is contained in the set.
    127   * @param  aNode the Node to search for
    128   * @return true if specified Node is contained in the NodeSet
    129   */
    130  bool contains(const txXPathNode& aNode) const { return indexOf(aNode) >= 0; }
    131 
    132  /**
    133   * Returns the Node at the specified node in this NodeSet.
    134   * @param  aIndex the node of the Node to return
    135   * @return Node at specified node
    136   */
    137  const txXPathNode& get(int32_t aIndex) const;
    138 
    139  /**
    140   * Returns true if there are no Nodes in the NodeSet.
    141   * @return true if there are no Nodes in the NodeSet.
    142   */
    143  bool isEmpty() const { return mStart ? mStart == mEnd : true; }
    144 
    145  /**
    146   * Returns the number of elements in the NodeSet
    147   * @return the number of elements in the NodeSet
    148   */
    149  int32_t size() const { return mStart ? mEnd - mStart : 0; }
    150 
    151  TX_DECL_EXPRRESULT
    152 
    153 private:
    154  /**
    155   * Ensure that this nodeset can take another aSize nodes.
    156   *
    157   * Changes mStart and mEnd as well as mBufferStart and mBufferEnd.
    158   */
    159  bool ensureGrowSize(int32_t aSize);
    160 
    161  /**
    162   * Finds position in the buffer where a node should be inserted
    163   * to keep the nodeset in document order. Searches the positions
    164   * aFirst-aLast, including aFirst, but not aLast.
    165   * @param  aNode   Node to find insert position for.
    166   * @param  aFirst  First item of the search range, included.
    167   * @param  aLast   Last item of the search range, excluded.
    168   * @param  aDupe   out-param. Will be set to true if the node already
    169   *                 exists in the NodeSet, false if it should be
    170   *                 inserted.
    171   * @return pointer where to insert the node. The node should be inserted
    172   *         before the given node. This value is always set, even if aNode
    173   *         already exists in the NodeSet
    174   */
    175  txXPathNode* findPosition(const txXPathNode& aNode, txXPathNode* aFirst,
    176                            txXPathNode* aLast, bool& aDupe) const;
    177 
    178  static void copyElements(txXPathNode* aDest, const txXPathNode* aStart,
    179                           const txXPathNode* aEnd);
    180  static void transferElements(txXPathNode* aDest, const txXPathNode* aStart,
    181                               const txXPathNode* aEnd);
    182  static void destroyElements(const txXPathNode* aStart,
    183                              const txXPathNode* aEnd) {
    184    while (aStart < aEnd) {
    185      aStart->~txXPathNode();
    186      ++aStart;
    187    }
    188  }
    189 
    190  using transferOp = void (*)(txXPathNode* aDest, const txXPathNode* aStart,
    191                              const txXPathNode* aEnd);
    192  using destroyOp = void (*)(const txXPathNode* aStart,
    193                             const txXPathNode* aEnd);
    194  nsresult add(const txNodeSet& aNodes, transferOp aTransfer,
    195               destroyOp aDestroy);
    196 
    197  txXPathNode *mStart, *mEnd, *mStartBuffer, *mEndBuffer;
    198  int32_t mDirection;
    199  // used for mark() and sweep() in predicates
    200  bool* mMarks;
    201 };
    202 
    203 #endif