tor-browser

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

txResultRecycler.cpp (4794B)


      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 #include "txResultRecycler.h"
      7 
      8 #include "txExprResult.h"
      9 #include "txNodeSet.h"
     10 
     11 txResultRecycler::txResultRecycler()
     12    : mEmptyStringResult(new StringResult(nullptr)),
     13      mTrueResult(new BooleanResult(true)),
     14      mFalseResult(new BooleanResult(false)) {}
     15 
     16 txResultRecycler::~txResultRecycler() {
     17  txStackIterator stringIter(&mStringResults);
     18  while (stringIter.hasNext()) {
     19    delete static_cast<StringResult*>(stringIter.next());
     20  }
     21  txStackIterator nodesetIter(&mNodeSetResults);
     22  while (nodesetIter.hasNext()) {
     23    delete static_cast<txNodeSet*>(nodesetIter.next());
     24  }
     25  txStackIterator numberIter(&mNumberResults);
     26  while (numberIter.hasNext()) {
     27    delete static_cast<NumberResult*>(numberIter.next());
     28  }
     29 }
     30 
     31 void txResultRecycler::recycle(txAExprResult* aResult) {
     32  NS_ASSERTION(aResult->mRefCnt == 0, "In-use txAExprResult recycled");
     33  RefPtr<txResultRecycler> kungFuDeathGrip;
     34  aResult->mRecycler.swap(kungFuDeathGrip);
     35 
     36  switch (aResult->getResultType()) {
     37    case txAExprResult::STRING: {
     38      mStringResults.push(static_cast<StringResult*>(aResult));
     39      return;
     40    }
     41    case txAExprResult::NODESET: {
     42      static_cast<txNodeSet*>(aResult)->clear();
     43      mNodeSetResults.push(static_cast<txNodeSet*>(aResult));
     44      return;
     45    }
     46    case txAExprResult::NUMBER: {
     47      mNumberResults.push(static_cast<NumberResult*>(aResult));
     48      return;
     49    }
     50    default: {
     51      delete aResult;
     52    }
     53  }
     54 }
     55 
     56 nsresult txResultRecycler::getStringResult(StringResult** aResult) {
     57  if (mStringResults.isEmpty()) {
     58    *aResult = new StringResult(this);
     59  } else {
     60    *aResult = static_cast<StringResult*>(mStringResults.pop());
     61    (*aResult)->mValue.Truncate();
     62    (*aResult)->mRecycler = this;
     63  }
     64  NS_ADDREF(*aResult);
     65 
     66  return NS_OK;
     67 }
     68 
     69 nsresult txResultRecycler::getStringResult(const nsAString& aValue,
     70                                           txAExprResult** aResult) {
     71  if (mStringResults.isEmpty()) {
     72    *aResult = new StringResult(aValue, this);
     73  } else {
     74    StringResult* strRes = static_cast<StringResult*>(mStringResults.pop());
     75    strRes->mValue = aValue;
     76    strRes->mRecycler = this;
     77    *aResult = strRes;
     78  }
     79  NS_ADDREF(*aResult);
     80 
     81  return NS_OK;
     82 }
     83 
     84 void txResultRecycler::getEmptyStringResult(txAExprResult** aResult) {
     85  *aResult = mEmptyStringResult;
     86  NS_ADDREF(*aResult);
     87 }
     88 
     89 nsresult txResultRecycler::getNodeSet(txNodeSet** aResult) {
     90  if (mNodeSetResults.isEmpty()) {
     91    *aResult = new txNodeSet(this);
     92  } else {
     93    *aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
     94    (*aResult)->mRecycler = this;
     95  }
     96  NS_ADDREF(*aResult);
     97 
     98  return NS_OK;
     99 }
    100 
    101 nsresult txResultRecycler::getNodeSet(txNodeSet* aNodeSet,
    102                                      txNodeSet** aResult) {
    103  if (mNodeSetResults.isEmpty()) {
    104    *aResult = new txNodeSet(*aNodeSet, this);
    105  } else {
    106    *aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
    107    (*aResult)->append(*aNodeSet);
    108    (*aResult)->mRecycler = this;
    109  }
    110  NS_ADDREF(*aResult);
    111 
    112  return NS_OK;
    113 }
    114 
    115 nsresult txResultRecycler::getNodeSet(const txXPathNode& aNode,
    116                                      txAExprResult** aResult) {
    117  if (mNodeSetResults.isEmpty()) {
    118    *aResult = new txNodeSet(aNode, this);
    119  } else {
    120    txNodeSet* nodes = static_cast<txNodeSet*>(mNodeSetResults.pop());
    121    nodes->append(aNode);
    122    nodes->mRecycler = this;
    123    *aResult = nodes;
    124  }
    125  NS_ADDREF(*aResult);
    126 
    127  return NS_OK;
    128 }
    129 
    130 nsresult txResultRecycler::getNumberResult(double aValue,
    131                                           txAExprResult** aResult) {
    132  if (mNumberResults.isEmpty()) {
    133    *aResult = new NumberResult(aValue, this);
    134  } else {
    135    NumberResult* numRes = static_cast<NumberResult*>(mNumberResults.pop());
    136    numRes->value = aValue;
    137    numRes->mRecycler = this;
    138    *aResult = numRes;
    139  }
    140  NS_ADDREF(*aResult);
    141 
    142  return NS_OK;
    143 }
    144 
    145 void txResultRecycler::getBoolResult(bool aValue, txAExprResult** aResult) {
    146  *aResult = aValue ? mTrueResult : mFalseResult;
    147  NS_ADDREF(*aResult);
    148 }
    149 
    150 nsresult txResultRecycler::getNonSharedNodeSet(txNodeSet* aNodeSet,
    151                                               txNodeSet** aResult) {
    152  if (aNodeSet->mRefCnt > 1) {
    153    return getNodeSet(aNodeSet, aResult);
    154  }
    155 
    156  *aResult = aNodeSet;
    157  NS_ADDREF(*aResult);
    158 
    159  return NS_OK;
    160 }
    161 
    162 void txAExprResult::Release() {
    163  --mRefCnt;
    164  NS_LOG_RELEASE(this, mRefCnt, "txAExprResult");
    165  if (mRefCnt == 0) {
    166    if (mRecycler) {
    167      mRecycler->recycle(this);
    168    } else {
    169      delete this;
    170    }
    171  }
    172 }